Fix1 (analogue of Base.Fix2)

I was very happy to see Base.Fix2 since it saves typing for creating closures.

Would it make sense to introduce a Fix1 that does the same, except for fixing the first argument?

1 Like

On the other hand, https://github.com/JuliaLang/julia/pull/24990 would turn Fix2(f, x) into f(_, x) and the hypothetical Fix1(f, x) into f(x, _) which I personally like quite a lot.

I guess another question would be whether you want the result of Fix1(f, x) to be y -> f(x, y) as above or the more general (args...) -> f(x, args...) ? Fix2 seems more clear in its purpose, since it assumes that f has exactly two arguments, but it feels odd for Fix1 to make the same assumption.

1 Like

I don’t remember where I saw the discussion, but last I heard the core devs seemed quite resolved to support general currying with _ as in #24990, just not in 1.0. (I think I remember seeing 1.x, but I don’t want to put words in anyone’s mouth.) So, I have a pretty strong feeling that this is something we’ll have in the not-so-distant future.

1 Like

I would distinguish

  1. having a parametric type that embodies partial application, eg Fix2 above,

  2. surface syntax for partial application, eg the proposed syntax with _.

(1) exposes the components of what would be an otherwise opaque closure, and allows neat things like a show method for certain function/argument combinations (this is what I want to use it for, actually).

(2) is syntactic sugar.

They can be done independently.

3 Likes

I guess I’m lacking in imagination. Could you give an example of what you have in mind?

Sure, want to make a PR?

1 Like

Imagine an interface with

loglikelihood(model::SomeModel, parameters)

where SomeModel is a user-defined type.

Now with

loglikelihood(model) = Fix1(loglikelihood, model) # hypothetical

function Base.show(io::IO, l::Fix1{typeof(loglikelihood), M}) where M
    println(io, "log likelihood callable for model $(l.x)")
end

one could do custom printing.

1 Like

Yes, will make on tomorrow.

5 Likes

Note that this is already planned. See e.g. replace `equalto` and `occursin` with curried `isequal`, `==`, and `in` by JeffBezanson · Pull Request #26436 · JuliaLang/julia · GitHub

PR done:
https://github.com/JuliaLang/julia/pull/26708

3 Likes

Merged.

1 Like

Would it make sense to go in the direction of C++ std::bind (see examples section)?