# Function that only accepts odd number argument

**URL:** <https://discourse.julialang.org/t/function-that-only-accepts-odd-number-argument/27502>\
**Category:** General Usage\
**Tags:** type\
**Created:** [August 13, 2019, 4:12pm UTC](https://discourse.julialang.org/t/function-that-only-accepts-odd-number-argument/27502 "2019-08-13T16:12:41Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![mthelm85](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mthelm85/32/224164_2.png) [@mthelm85](https://discourse.julialang.org/u/mthelm85)\
**Post date:** [August 13, 2019, 4:12pm UTC](https://discourse.julialang.org/t/function-that-only-accepts-odd-number-argument/27502/1 "2019-08-13T16:12:41Z")

</div>

If I have a function that should only accept odd integers, what’s the best way to implement this? Should I create a new OddInt type and only allow that, or just check whether the integer is odd inside the function and throw an error if it’s not? How would I even create an OddInt type in Julia?

```julia
function oddball(n::OddInt)
    println("I won't even bother if n isn't odd")
end

```

OR

```julia
function oddball(n::Int64)
    if isodd(n)
        println("good job")
    else
        throw("the int must be odd!")
    end
end

```

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [August 13, 2019, 4:29pm UTC](https://discourse.julialang.org/t/function-that-only-accepts-odd-number-argument/27502/2 "2019-08-13T16:29:22Z")

</div>

The easiest and perhaps cleanest approach is to use a function barrier (an outer function and then another function that handles the real work).

```julia
function oddball(n::Int)
    if isodd(n) 
       return thisoddball(n)
    end
    throw(DomainError("$n is not odd"))
end

function thisoddball(n::Int)
   # do stuff
   return result
end

```

---

<div class="post-metadata">

**Author:** ![hendri54](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hendri54/32/9621_2.png) [@hendri54](https://discourse.julialang.org/u/hendri54)\
**Post date:** [August 13, 2019, 4:45pm UTC](https://discourse.julialang.org/t/function-that-only-accepts-odd-number-argument/27502/3 "2019-08-13T16:45:04Z")

</div>

You would create an `OddInt` with an inner constructor that performs validation:

```julia
struct OddInt
    value :: Int

    function OddInt(x :: Int)
        if isodd(x)
            return new(x)
        else
            throw(DomainError("$x is not odd"))
        end
    end
end

function thisoddball(n :: OddInt)
    return n
end

```

whether that is any better than the function barrier probably depends on context.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [August 13, 2019, 5:02pm UTC](https://discourse.julialang.org/t/function-that-only-accepts-odd-number-argument/27502/4 "2019-08-13T17:02:53Z")

</div>

An `OddInt` type feels like overkill unless you actually need to treat these `OddInt`s as first-class citizens in your code. Do you have functions that always produce `OddInt`s? Or lots of functions that always take `OddInt`s? If so, then having a dedicated type might be helpful. Otherwise, a simple runtime check should be quite effective. You can be more explicit about the kind of error you throw by using an `ArgumentError`, which provides more helpful information to future users of your code:

```julia
if !isodd(n)
  throw(ArgumentError("should be odd!"))
end

```

or, more tersely:

```julia
isodd(n) || throw(ArgumentError("should be odd!"))

```

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [August 13, 2019, 5:39pm UTC](https://discourse.julialang.org/t/function-that-only-accepts-odd-number-argument/27502/5 "2019-08-13T17:39:16Z")

</div>

It should be noted that LLVM is increadibly clever, so checking that an integer is odd might be a no-op. Example:

```julia
julia> function f(x)
         y = 2x+1
         (y & 1) == 0 ? error("y is not odd!") : y
       end
f (generic function with 1 method)

julia> @code_llvm f(0)

; @ REPL[17]:2 within `f'
define i64 @julia_f_13872(i64) {
top:
; ┌ @ int.jl:54 within `*'
   %1 = shl i64 %0, 1
; └
; ┌ @ int.jl:53 within `+'
   %2 = or i64 %1, 1
; └
; @ REPL[17]:3 within `f'
  ret i64 %2
}

```

The LLVM code contains no trace of the second line of `f`.

---

<div class="post-metadata">

**Author:** ![mthelm85](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mthelm85/32/224164_2.png) [@mthelm85](https://discourse.julialang.org/u/mthelm85)\
**Post date:** [August 13, 2019, 6:46pm UTC](https://discourse.julialang.org/t/function-that-only-accepts-odd-number-argument/27502/6 "2019-08-13T18:46:04Z")

</div>

@rdeits This is nice, I was unaware of this syntax and I’ll definitely be using it 😉:

` isodd(n) || throw(ArgumentError("should be odd!"))`

Thanks!

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [August 13, 2019, 7:12pm UTC](https://discourse.julialang.org/t/function-that-only-accepts-odd-number-argument/27502/7 "2019-08-13T19:12:22Z")

</div>

You can likewise use `&&` to do something only if some other condition is true. In other words,

```julia
a() && b()

```

is the same as:

```julia
if a()
  b()
end

```

---

<div class="post-metadata">

**Author:** ![mthelm85](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mthelm85/32/224164_2.png) [@mthelm85](https://discourse.julialang.org/u/mthelm85)\
**Post date:** [August 13, 2019, 7:48pm UTC](https://discourse.julialang.org/t/function-that-only-accepts-odd-number-argument/27502/8 "2019-08-13T19:48:20Z")

</div>

Awesome, thanks so much!

---

<div class="post-metadata">

**Author:** ![mdavezac](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mdavezac/32/1472_2.png) [@mdavezac](https://discourse.julialang.org/u/mdavezac)\
**Post date:** [August 14, 2019, 12:05pm UTC](https://discourse.julialang.org/t/function-that-only-accepts-odd-number-argument/27502/9 "2019-08-14T12:05:11Z")

</div>

Maybe the function should take `n` as the argument, as in `2n+1`?

---

<div class="post-metadata">

**Author:** ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)\
**Post date:** [August 14, 2019, 12:48pm UTC](https://discourse.julialang.org/t/function-that-only-accepts-odd-number-argument/27502/10 "2019-08-14T12:48:17Z")

</div>

This is precisly the sort of thing you could do if we finally had implemented `inductive` types in Julia

> **[Inductive type](https://en.m.wikipedia.org/wiki/Inductive_type)**
>
> In type theory, a system has inductive types if it has facilities for creating a new type from constants and functions that create terms of that type. The feature serves a role similar to data structures in a programming language and allows a type theory to add concepts like numbers, relations, and trees. As the name suggests, inductive types can be self-referential, but usually only in a way that permits structural recursion.
> The standard example is encoding the natural numbers using Peano's ...

> [@Julia with respect to reliability, sustainability, critical application, dynamic/static typing, big data, HPC?](https://discourse.julialang.org/t/julia-with-respect-to-reliability-sustainability-critical-application-dynamic-static-typing-big-data-hpc/23135/14):
>
> Another formalistic language I want Julia to learn from is [agda](https://en.wikipedia.org/wiki/Agda_(programming_language)).
> 
> > Programming in pure type theory involves a lot of tedious and repetitive proofs, and Agda has no support for tactics. Instead, Agda has support for automation via [reflection](https://en.wikipedia.org/wiki/Reflection_(computer_programming)). The reflection mechanism allows one to quote program fragments into – or unquote them from – the abstract syntax tree. The way reflection is used is similar to the way Template Haskell works.[[8]](https://en.wikipedia.org/wiki/Agda_(programming_language)#cite_note-8)
> 
> Reflection is also what Julia metaprogramming is based on, so extend the type system of Julia?

> [@Julia with respect to reliability, sustainability, critical application, dynamic/static typing, big data, HPC?](https://discourse.julialang.org/t/julia-with-respect-to-reliability-sustainability-critical-application-dynamic-static-typing-big-data-hpc/23135/17):
>
> The new features don’t have to exactly resemble a previous language, just learn from it.
> 
> Are [inductive types](https://en.m.wikipedia.org/wiki/Inductive_type) threatening to other aspects of the Julia language that would cause trade-off?

> [@Julia with respect to reliability, sustainability, critical application, dynamic/static typing, big data, HPC?](https://discourse.julialang.org/t/julia-with-respect-to-reliability-sustainability-critical-application-dynamic-static-typing-big-data-hpc/23135/19):
>
> A new keyword like `inductive type` could be used to generalize Julia from only type dispatch to make julia able of more general proofs.

> [@Julia with respect to reliability, sustainability, critical application, dynamic/static typing, big data, HPC?](https://discourse.julialang.org/t/julia-with-respect-to-reliability-sustainability-critical-application-dynamic-static-typing-big-data-hpc/23135/21):
>
> The only reason I mention it is purely due to my interest in the mathematics of it, I recommend looking at the referenced paper [Engineering Proof by Reflection in Agda](http://hal.inria.fr/docs/00/98/76/10/PDF/ReflectionProofs.pdf)
> 
> > Abstract. This paper explores the recent addition to Agda enabling reflection, in the style of Lisp and Template Haskell. It gives a brief introduction to using reflection, and details the complexities encountered when automating certain proofs with proof by reflection. It presents a library that can be used for automatically quoting a class of concrete Agda terms to a non-dependent, user-defined inductive data type, alleviating some of the burden a programmer faces when using reflection in a practical setting.

What you want is an `inductive` type so that the type system can make formal proofs about odd and even integers… I’ve been wanting this for a long time now.

@jeff.bezanson this is on more people’s wishlist now!

---

<div class="post-metadata">

**Author:** ![non-Jedi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-jedi/32/3645_2.png) [@non-Jedi](https://discourse.julialang.org/u/non-Jedi)\
**Post date:** [August 14, 2019, 1:06pm UTC](https://discourse.julialang.org/t/function-that-only-accepts-odd-number-argument/27502/11 "2019-08-14T13:06:17Z")

</div>

> In [type theory](https://en.m.wikipedia.org/wiki/Type_theory), a system has **inductive types** if it has facilities for creating a new type along with constants and functions that create terms of that type.

- “creating a new type” : `struct`
- “constants” : `const`
- “functions that create terms of that type” : `f()::MyType = ...`

What’s missing? Please don’t read this as antagonistic; I’m genuinely curious.

---

<div class="post-metadata">

**Author:** ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)\
**Post date:** [August 14, 2019, 1:08pm UTC](https://discourse.julialang.org/t/function-that-only-accepts-odd-number-argument/27502/12 "2019-08-14T13:08:22Z")

</div>

What’s different is that you want the type system to be able to prove whether an input is even or odd… so, the need to extend the type system to handle inductive types.

This is about proofs in the type system. Can Julia type system currently prove whether an element of Peano arithmetic is even or odd? Don’t think so, hence the thread.

---

<div class="post-metadata">

**Author:** ![4mSwell](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/4mswell/32/37469_2.png) [@4mSwell](https://discourse.julialang.org/u/4mSwell)\
**Post date:** [June 27, 2022, 8:27am UTC](https://discourse.julialang.org/t/function-that-only-accepts-odd-number-argument/27502/13 "2022-06-27T08:27:27Z")

</div>

I realise this is an old thread but my question may be useful for others.

The above OddInt structure and inner constructor (hendri54) do not work for me. I have spent much time on this and would really like to understand where I am going wrong.

I get “Error: Method Error: No method matching this oddball(::Int64)” …Julia 1.6

As far as I can tell, this oddball is trying to enforce OddInt (as expected). But the OddInt constructor is returning an Int64 type instead of an “OddInt” type.

Is there a workaround for this. I know I can achieve the same validation via a function. In my case I have many functions that deal with the same argument validation. I would like to enforce argument validation in each function using a custom type . In my case this should provide much more readable code.

---

<div class="post-metadata">

**Author:** ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)\
**Post date:** [June 27, 2022, 9:05am UTC](https://discourse.julialang.org/t/function-that-only-accepts-odd-number-argument/27502/14 "2022-06-27T09:05:54Z")

</div>

Please start a new thread with the exact code that you’re using for this. I don’t see the issue that you’re describing

```julia
julia> struct OddInt
           value :: Int

           function OddInt(x :: Int)
               if isodd(x)
                   return new(x)
               else
                   throw(DomainError(x, "is not odd"))
               end
           end
       end

julia> OddInt(2)
ERROR: DomainError with 2:
is not odd
Stacktrace:
 [1] OddInt(x::Int64)
   @ Main ./REPL[5]:8
 [2] top-level scope
   @ REPL[6]:1

julia> OddInt(1)
OddInt(1)

```

---

<div class="post-metadata">

**Author:** ![4mSwell](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/4mswell/32/37469_2.png) [@4mSwell](https://discourse.julialang.org/u/4mSwell)\
**Post date:** [June 27, 2022, 12:16pm UTC](https://discourse.julialang.org/t/function-that-only-accepts-odd-number-argument/27502/15 "2022-06-27T12:16:30Z")

</div>

Thanks for your help. I have started new thread with further explanation of when error is thrown.
