# Array of random Rationals

**URL:** <https://discourse.julialang.org/t/array-of-random-rationals/33994>\
**Category:** New to Julia\
**Created:** [January 30, 2020, 6:32pm UTC](https://discourse.julialang.org/t/array-of-random-rationals/33994 "2020-01-30T18:32:56Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![squirrel](https://avatars.discourse-cdn.com/v4/letter/s/96bed5/32.png) [@squirrel](https://discourse.julialang.org/u/squirrel)\
**Post date:** [January 30, 2020, 6:32pm UTC](https://discourse.julialang.org/t/array-of-random-rationals/33994/1 "2020-01-30T18:32:56Z")

</div>

I’d like to extend rand to make a vector of rational numbers, and I’m having difficulty defining the function. For example, here’s one of the several versions I’ve tried.

```julia
function rand(::Rational{T}, n) where T<:Integer
    println("Congratulations!!! You Won!!!")
end
rand(Rational{Int64}, 6)

```

> ERROR: MethodError: no method matching rand(::Type{Rational{Int64}}, ::Int64)  
> You may have intended to import Base.rand

I’d also like to define a method for Rational{BigInt}.

Thanks for reading.

---

<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:** [January 30, 2020, 6:48pm UTC](https://discourse.julialang.org/t/array-of-random-rationals/33994/2 "2020-01-30T18:48:22Z")

</div>

The main reason this doesn’t work is that you’ve defined a method which expects to be given an _instance_ of a `Rational{T}`, not the _type_ `Rational{T}`:

```julia
julia> function foo(::Int)
         println("I got an actual Int")
       end
foo (generic function with 1 method)

julia> function foo(::Type{Int})
         println("I got the *type* Int")
       end
foo (generic function with 2 methods)

julia> foo(1)
I got an actual Int

julia> foo(Int)
I got the *type* Int

```

It also won’t do what you’re expecting because your new `rand` function will shadow the existing `Base.rand` function. That’s why your code prints a warning:

```julia
You may have intended to import Base.rand

```

it’s true–you probably wanted to do:

```julia
import Base: rand

function rand(....)
  ...

```

I personally strongly prefer to be explicit about this, and do:

```julia
function Base.rand(....)
   ...

```

which makes it obvious that you’re extending Base.rand and doesn’t require you to remember whether you `import`ed or not.

Finally, a word of warning: what you are doing is the exact definition of “type piracy”: you are defining a method of a function you don’t own (rand) for a type you don’t own (Rational). This will work, but it can interact badly with anyone _else_ who tries to do the same thing in their code. After all, if you define `rand(::Type{Rational})` and they define `rand(::Type{Rational})`, then which one should be called if you import both packages?

If you want to be able to construct random rationals within your own code, that’s totally fine. You just may want to create your own function rather than extending `Base.rand`:

```julia
my_rand(args...) = rand(args...) # by default, `my_rand` just calls `rand`
my_rand(::Type{Rational}, ...) = ... # but my_rand also knows about Rational
```

---

<div class="post-metadata">

**Author:** ![squirrel](https://avatars.discourse-cdn.com/v4/letter/s/96bed5/32.png) [@squirrel](https://discourse.julialang.org/u/squirrel)\
**Post date:** [January 30, 2020, 7:59pm UTC](https://discourse.julialang.org/t/array-of-random-rationals/33994/3 "2020-01-30T19:59:40Z")

</div>

Thanks! This was driving me crazy.

This is really just so I can make vectors for benchmarking, so conflicting with other packages isn’t a concern, but that’s a really good point for future use that I’m glad you told me. I had never heard of type piracy before.

---

<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:** [January 31, 2020, 10:43am UTC](https://discourse.julialang.org/t/array-of-random-rationals/33994/4 "2020-01-31T10:43:56Z")

</div>

In addition to @rdeits’s excellent answer (especially note type piracy: I would recommend that you define a custom type like `struct SomeRationalDistribution end` and a sampler for that), note that there is a recommended way of doing this:

[https://docs.julialang.org/en/latest/stdlib/Random/#Generating-random-values-of-custom-types-1](https://docs.julialang.org/en/latest/stdlib/Random/#Generating-random-values-of-custom-types-1)
