# Need help implementing evenness test for larger integer types

**URL:** https://discourse.julialang.org/t/need-help-implementing-evenness-test-for-larger-integer-types/127607
**Category:** Offtopic
**Tags:** joke
**Created:** [April 1, 2025, 7:43pm UTC](https://discourse.julialang.org/t/need-help-implementing-evenness-test-for-larger-integer-types/127607 "2025-04-01T19:43:40Z")
**Posts on this page:** 6
**Page:** 1

<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: [April 1, 2025, 7:43pm UTC](https://discourse.julialang.org/t/need-help-implementing-evenness-test-for-larger-integer-types/127607/1 "2025-04-01T19:43:40Z")

</div>

I need to check if built-in integers are even or odd, so I asked ChatGPT to make a function for me:

```julia
function even(x::UInt8)
    if x==0 true
    elseif x==1 false
    elseif x==2 true
    elseif x==3 false
    # continue pattern

```

but it only did a few lines and told me to write the rest myself. Luckily Julia has first-resort metaprogramming to save a lot of typing. `Expr` seems hard so I just used strings, which is just as safe.

```julia
let T = UInt8
  header = "function even(x::$T)\n"
  ifheader = " if x==0 true\n"
  elseifs = join([" elseif x==$i $bool"
                  for (i, bool) in zip(1:typemax(T),
                      Iterators.cycle((false, true)))
                 ], "\n")
  ends = " end\nend"
  join([header, ifheader, elseifs, ends])
end |> Meta.parse |> eval

```

Worked like a charm:

```julia
julia> join([even(UInt8(i)) for i in 0:9], ", ")
"true, false, true, false, true, false, true, false, true, false"

```

Problem is when I move onto bigger integer types, I get this strange parsing error after several minutes. This is what happens for `T = UInt16`:

```julia
┌ Error: JuliaSyntax parser failed — falling back to flisp!
│ This is not your fault. Please submit a bug report to https://github.com/JuliaLang/JuliaSyntax.jl/issues
│ exception =
│ StackOverflowError:
│ Stacktrace:
│ [1] parse_call_chain(ps::Base.JuliaSyntax.ParseState, mark::Base.JuliaSyntax.ParseStreamPosition, is_macrocall::Bool)
│ @ Base.JuliaSyntax C:\workdir\base\JuliaSyntax\src\parser.jl:1459
...

```

I submitted a bug report as instructed, but does somebody with more experience in metaprogramming know of a way I can work around this long execution time and error for the rest of the builtin integer types? No rush, but I need to push to prod by today.

---

<div class="post-metadata">

### Author: ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)
#### Post date: [April 1, 2025, 7:53pm UTC](https://discourse.julialang.org/t/need-help-implementing-evenness-test-for-larger-integer-types/127607/2 "2025-04-01T19:53:26Z")

</div>

Perhaps too obvious, so I may be missing something, but… why not just call `iseven`?

---

<div class="post-metadata">

### Author: ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)
#### Post date: [April 1, 2025, 8:38pm UTC](https://discourse.julialang.org/t/need-help-implementing-evenness-test-for-larger-integer-types/127607/3 "2025-04-01T20:38:29Z")

</div>

Ah, on second thought… April’s fool, right? 😊

---

<div class="post-metadata">

### Author: ![barucden](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/barucden/32/26154_2.png) [@barucden](https://discourse.julialang.org/u/barucden)
#### Post date: [April 1, 2025, 8:56pm UTC](https://discourse.julialang.org/t/need-help-implementing-evenness-test-for-larger-integer-types/127607/4 "2025-04-01T20:56:29Z")

</div>

Clearly a task for meta-programming as normal programming is just not as performant imho.

Your code does not work for `BigInt` (something with `typemax`), so I came up with a solution, and I am currently trying to run it. Let me get back to you — my laptop always freezes before it finishes…

---

<div class="post-metadata">

### Author: ![nhz2](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nhz2/32/44428_2.png) [@nhz2](https://discourse.julialang.org/u/nhz2)
#### Post date: [April 2, 2025, 12:31am UTC](https://discourse.julialang.org/t/need-help-implementing-evenness-test-for-larger-integer-types/127607/6 "2025-04-02T00:31:13Z")

</div>

Have you tried making a new package for each case to take advantage of precompilation?

```julia
using Pkg
Pkg.activate(temp=true)
vals = 0:typemax(UInt16)
for (i, bool) in zip(vals,
    Iterators.cycle((true, false)))
    package = "IsEvenCase$i"
    if !isdir(package)
        Pkg.generate(package)
        write(package*"/src/"*package*".jl", """
        module $package
            const iseven = $bool
        end
        """
        )
    end
end
Pkg.develop([(;path="IsEvenCase$i") for i in vals])
even(i) = "import IsEvenCase$i; IsEvenCase$i.iseven" |> Meta.parse |> eval
print(join([even(i) for i in 0:9], ", "))

```

Seems to work well for me.

---

<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: [April 2, 2025, 4:50am UTC](https://discourse.julialang.org/t/need-help-implementing-evenness-test-for-larger-integer-types/127607/7 "2025-04-02T04:50:34Z")

</div>

After taking advice from this thread (10%) and LLaMa (90%), I decided to leverage the power of multiple dispatch to work around the parser’s recursion issue with large expressions:

```julia
even(x) = even(Val(x))

let T = UInt16
  for value in typemin(T):typemax(T)
    @eval even(x::Val{$value}) = $(iseven(value))
  end
end

```

It runs fine:

```julia
julia> join([even(UInt16(i)) for i in 0:9], ", ") # comprehensive unit test
"true, false, true, false, true, false, true, false, true, false"

julia> @time [even(UInt16(i)) for i in 0:60000]; # peak performance
  0.112477 seconds (92.46 k allocations: 2.628 MiB, 33.53% compilation time)

```

Just don’t check `even` or `methods(even)` in the REPL because that’ll hang for 3 minutes before possibly printing thousands of methods for another minute, and just for `UInt16`. Time to toss this into another loop over integer values and precompile it in a package. I’ll just throw in a `#TODO Val{x::BigInt}` for the next contributor.
