# Ignore{N} similar to Fix{N}

**URL:** https://discourse.julialang.org/t/ignore-n-similar-to-fix-n/136932
**Category:** General Usage
**Tags:** question
**Created:** [April 30, 2026, 12:39pm UTC](https://discourse.julialang.org/t/ignore-n-similar-to-fix-n/136932 "2026-04-30T12:39:44Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [April 30, 2026, 12:39pm UTC](https://discourse.julialang.org/t/ignore-n-similar-to-fix-n/136932/1 "2026-04-30T12:39:44Z")

</div>

I am occasionally finding something like this useful:

```julia
struct Ignore{N,F}
    f::F
    Ignore{N}(f::F) where {N,F} = new{N,F}(f) # no checks etc, just an MWE
end

function (f::Ignore{N})(args::Vararg{Any,M}) where {N,M}
    f.f(args[begin:begin+(N-2)]..., args[begin+N:end]...)
end

julia> Ignore{3}((x...,) -> x)(1:5...)
(1, 2, 4, 5)

```

so I am wondering if it would make sense to add this to `Base` to complement `Fix`.

---

<div class="post-metadata">

### Author: ![lilachint](https://avatars.discourse-cdn.com/v4/letter/l/ee7513/32.png) [@lilachint](https://discourse.julialang.org/u/lilachint)
#### Post date: [April 30, 2026, 1:48pm UTC](https://discourse.julialang.org/t/ignore-n-similar-to-fix-n/136932/2 "2026-04-30T13:48:52Z")

</div>

This is interesting. Since I rarely use argument spreading, may you provide a more practical example to demonstrate how it could be used?

---

<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: [April 30, 2026, 2:41pm UTC](https://discourse.julialang.org/t/ignore-n-similar-to-fix-n/136932/3 "2026-04-30T14:41:49Z")

</div>

I think the main reason for `Base.Fix` is that functions can have specialized methods for the case where one argument is fixed, and hence some things can be precomputed. Otherwise, an anonymous function would work just as well.

I’m not sure why this would be true for `Ignore`?

---

<div class="post-metadata">

### Author: ![lilachint](https://avatars.discourse-cdn.com/v4/letter/l/ee7513/32.png) [@lilachint](https://discourse.julialang.org/u/lilachint)
#### Post date: [May 1, 2026, 3:49am UTC](https://discourse.julialang.org/t/ignore-n-similar-to-fix-n/136932/4 "2026-05-01T03:49:47Z")

</div>

I believe `Base.Fix{N}` is used to eliminate closures (not sure if that’s still a thing in Julia though), or to facilitate constant propagation. However, the theoretical use cases of `Ignore{N}` doesn’t involve those, so this might not be too useful?

---

<div class="post-metadata">

### Author: ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)
#### Post date: [May 1, 2026, 2:56pm UTC](https://discourse.julialang.org/t/ignore-n-similar-to-fix-n/136932/5 "2026-05-01T14:56:56Z")

</div>

As I recall, the more specific reason for `Base.Fix` is so that we don’t create, compile, and carry N distinct anonymous functions for N different places in the code where we would write (e.g.) `x -> x < y`. Instead, we only have one `Base.Fix2{typeof(<), typeof(y)})` function for each `typeof(y)`.

```julia-repl
julia> (x -> x < 0) === (x -> x < 0)
false

julia> <(0) === <(0)
true

```

The `Base.Fix` is itself a closure, so it’s not that it “prevents” a closure per-se. And it’s worse for constant propagation, not better. For example:

```julia-repl
julia> code_llvm(x -> x < 0, (UInt,); debuginfo=:none) # const-prop the 0
; Function Signature: var"#29"(UInt64)
define i8 @"julia_#29_5695"(i64 zeroext %"x::UInt64") #0 {
top:
  ret i8 0
}

julia> code_llvm(<(0), (UInt,); debuginfo=:none) # does not const-prop because it's a generic closure
; Function Signature: (::Base.Fix{2, typeof(Base.:(<)), Int64})(UInt64)
define i8 @julia_Fix_5289(ptr nocapture noundef nonnull readonly align 8 dereferenceable(8) %"f::Fix", i64 zeroext %"arg::UInt64") #0 {
top:
  %"f::Fix.unbox" = load i64, ptr %"f::Fix", align 8
  %0 = icmp sgt i64 %"f::Fix.unbox", -1
  %1 = icmp ugt i64 %"f::Fix.unbox", %"arg::UInt64"
  %2 = and i1 %0, %1
  %3 = zext i1 %2 to i8
  ret i8 %3
}

```

Still, in many cases the constant propagation would be of little/no value and the code reuse of `Base.Fix` is pure up-side.

---

<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: [May 1, 2026, 4:01pm UTC](https://discourse.julialang.org/t/ignore-n-similar-to-fix-n/136932/6 "2026-05-01T16:01:14Z")

</div>

> [@mikmoore](#):
>
> As I recall, the more specific reason for `Base.Fix` is so that we don’t create, compile, and carry N distinct anonymous functions for N different places in the code

In fact, it was initially introduced to replace exactly two cases that already had specialized implementations `EqualsTo` and `OccursIn` of partial evaluation:

> <https://github.com/JuliaLang/julia/pull/26436>
>
> These were my silly idea, so I'll try to clean it up. I think this is nicer, fre…es up \`occursin\`, and easily generalizes to other functions.
> 
> This is really just currying on the second argument, but it's especially useful for comparisons since e.g. \`in(xs)\` checks whether something is in \`xs\`, and \`\<(3)\` (if implemented) checks whether something is less than 3, etc. Dispatching on something like \`Curry2{typeof(in), ...}\` ~~would be a bit obscure, so I opted for \`CompareTo{in, ...}\` instead~~.

But, digging deeper, the motivation for `EqualsTo` was indeed (in part) to “cut down the number of function types”:

> <https://github.com/JuliaLang/julia/pull/23812>
>
> I also tried out using \`equalto(x)\` as a predicate, and I really think we should… adopt it. It reads nicely (\`!equalto(x)\` also works) and will cut down the number of function types.
> 
> fix #23120, fix #19186
> 
> Part of https://github.com/JuliaLang/julia/issues/10593.

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [May 1, 2026, 4:31pm UTC](https://discourse.julialang.org/t/ignore-n-similar-to-fix-n/136932/7 "2026-05-01T16:31:02Z")

</div>

> [@Tamas\_Papp](#):
>
> I am wondering if it would make sense to add this to `Base` to complement `Fix`

Putting aside `Ignore`’s specific merits momentarily, I think there’s too much in `Base` as-is, so I prefer new things to live in packages if the rest of `Base` doesn’t use it. If that ever changes, the package can just be deprecated and suggest the `Base` version.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [May 3, 2026, 7:02am UTC](https://discourse.julialang.org/t/ignore-n-similar-to-fix-n/136932/8 "2026-05-03T07:02:17Z")

</div>

Thanks for all the answers. Just to clarify the motivation: I consider `Ignore{N}`, which is (semantically) equivalent to a `(a, _b, c) -> f(a, c)` closure, a natural complement to `Fix{N}`, which does `(a, c) -> f(a, fixed_b, c)`.

But other than that, there is indeed no strong reason to do this. The main motivation for `Fix{1|2}` was indeed specialization. Though occasionally, the knowledge that an argument is not used could simplify a reduction, that I think is pretty rare to warrant a special case.

That said, `Fix{N}` branched into its own mini-language to eliminate closures used solely for partial application. I am not aware of anyone _specializing_ on, say, `Fix{3}` of a method. Introducing `Ignore{N}` could be viewed as compounding a design mistake further.

> [@mikmoore](#):
>
> the more specific reason for `Base.Fix` is so that we don’t create, compile, and carry N distinct anonymous functions for N different places

Yes, I heard that argument, but AFAIK it is only costly when the closure is created at top-level. Within a function it should be fine.

I wonder if it would make sense to have the language could just recognize semantically equivalent closures as equivalent, eg `(a, b) -> a > b` vs `(x, y) -> x > y`. It would not have to be perfect and could stop the analysis above some expression complexity.

---

<div class="post-metadata">

### Author: ![lilachint](https://avatars.discourse-cdn.com/v4/letter/l/ee7513/32.png) [@lilachint](https://discourse.julialang.org/u/lilachint)
#### Post date: [May 3, 2026, 10:01am UTC](https://discourse.julialang.org/t/ignore-n-similar-to-fix-n/136932/9 "2026-05-03T10:01:40Z")

</div>

I believe treating semantically equivalent closures as equivalent just adds unnecessary complexities to both the compiler and the user. The handling of scopes and shadowing, no matter how good, could introduce many confusions and potential glitches. The added complexity of the compiler would outweigh the relatively trivial cost of an extra closure.
