# Function discovery

**URL:** <https://discourse.julialang.org/t/function-discovery/107652>\
**Category:** New to Julia\
**Created:** [December 15, 2023, 10:04am UTC](https://discourse.julialang.org/t/function-discovery/107652 "2023-12-15T10:04:17Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![glebm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/glebm/32/205499_2.png) [@glebm](https://discourse.julialang.org/u/glebm)\
**Post date:** [December 15, 2023, 10:04am UTC](https://discourse.julialang.org/t/function-discovery/107652/1 "2023-12-15T10:04:17Z")

</div>

Today I wrote my first program in Julia ([solution](https://github.com/glebm/advent-of-code/blob/main/2023/15/part2.jl) for Advent of Code 15)!

A problem I immediately hit is function discovery. E.g. if have an object `x`, what can I do with it? In many other languages I type `x.` and the IDE helpfully autocompletes the list of things I can do with it. Not so in Julia (I’m using VS Code with the Julia plugin btw).

Perhaps Julia could benefit from some syntax sugar similar to Rust, where `x.f(args..)` is equivalent to `f(x, args...)`?

Alternatively, if `|>` did currying, then `x |> f(args...)` could trigger the autocompletion instead. What do you think?

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [December 15, 2023, 10:43am UTC](https://discourse.julialang.org/t/function-discovery/107652/2 "2023-12-15T10:43:40Z")

</div>

This has been discussed many times!

See:

> [@Allowing the object.method(args...) syntax as an alias for method(object, args ...)](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/119):
>
> That’s indeed useful, and pipes already give the ability. That often requires putting the “main” argument as the last function argument, not the first. Think of common data manipulation functions map/filter/mapreduce/etc: they wouldn’t be convenient with your proposal. Meanwhile, one can use a helper piping package, for example with DataPipes: @p X |\> filter(isodd) |\> map(log) |\> findmax(abs) @p "Hello, world!" |\> split(\_\_, ",") |\> replace.(\_\_, "o"=\>"e") |\> join(\_\_, ":") Autocomplete rela…

> [@Fixing the Piping/Chaining Issue](https://discourse.julialang.org/t/fixing-the-piping-chaining-issue/89654):
>
> Objective To satisfy Julia’s piping/chaining/currying/partial application problem with an elegant and functional approach worthy and idiomatic of Base Julia. If you want, skip the background reading material straight down to the proposal. Background Piping, chaining, threading—whatever people call it, it’s a very common thought pattern to take an object and pull it through a sequence of one or more transformations. In many contexts it’s most natural to think of the object first, and then to th…

> [@My mental load using Julia is much higher than, e.g., in Python. How to reduce it?](https://discourse.julialang.org/t/my-mental-load-using-julia-is-much-higher-than-e-g-in-python-how-to-reduce-it/18902/5):
>
> I think these are all reasonable points, but I hope I can help a little bit. 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: 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…](https://github.com/JuliaLang/julia/pull/24990)

We cant just use `x.f` like that because the syntax is already taken - there can already be an object or a function field at `x.f`.

The Julia alternative is `methodswith(typeof(x))`. It will give you methods that match args at any position.

Yes, its kind of a pain compared to OOP tab completion, one of the very few downsides of using multiple dispatch.

---

<div class="post-metadata">

**Author:** ![glebm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/glebm/32/205499_2.png) [@glebm](https://discourse.julialang.org/u/glebm)\
**Post date:** [December 15, 2023, 11:28am UTC](https://discourse.julialang.org/t/function-discovery/107652/3 "2023-12-15T11:28:52Z")

</div>

> [@Raf](#):
>
> methodswith(typeof(x))

That’s nice, even if it’s only useful in interpreter mode!

From the threads that you’ve linked I’ve also discovered `?("hello")` introduced in [?(x, y)TAB completes methods accepting x, y by timholy · Pull Request #38791 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/38791), though that doesn’t seem to be integrated in the VS Code plugin.

Rust also does multiple dispatch, even more powerful than Julia because it also dispatches on the return type. Uniform Call Syntax is still very useful in that scenario.

Still, there seems to be enough opposition to UCS that I guess it won’t get adopted in Julia. This is a bit surprising given Julia already has sugar for treating the first argument specially when it’s a function (`do ... end`), so it’s not like the language is completely opposed to useful sugar.

Guess I’ll wait until editor plugins adopt `?("hello")` autocompletion or until the `|>` currying comes along.

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [December 15, 2023, 12:28pm UTC](https://discourse.julialang.org/t/function-discovery/107652/4 "2023-12-15T12:28:42Z")

</div>

Rust doesn’t have dynamic multiple dispatch or functions being constantly added at run-time, so the problem is simpler.

If you want editor plugins to adopt something quickly, the best strategy may be to make a PR 😉
