# AD vs argument lists

**URL:** https://discourse.julialang.org/t/ad-vs-argument-lists/125207
**Category:** General Usage
**Created:** [January 25, 2025, 7:36pm UTC](https://discourse.julialang.org/t/ad-vs-argument-lists/125207 "2025-01-25T19:36:55Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)
#### Post date: [January 25, 2025, 7:36pm UTC](https://discourse.julialang.org/t/ad-vs-argument-lists/125207/1 "2025-01-25T19:36:55Z")

</div>

To enable AD I must do something about argument types. Let us say I have a function like this:

```julia
add_btdb_ut_only!(Ke::Matrix{T}, B::Matrix{T}, Jac_w::T, D::Matrix{T}, DB::Matrix{T}) where {T}

```

I might be able to guess which arguments will need to be typed for ForwardDiff.Dual use, or I might not.

What is a good way of dealing with this situation?

---

<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: [January 25, 2025, 8:41pm UTC](https://discourse.julialang.org/t/ad-vs-argument-lists/125207/2 "2025-01-25T20:41:23Z")

</div>

> [@PetrKryslUCSD](#):
>
> What is a good way of dealing with this situation?

Relax the types? Why do the elements all need to be the same? Why do they need to be `Matrix` and not `AbstractMatrix`?

---

<div class="post-metadata">

### Author: ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)
#### Post date: [January 25, 2025, 9:40pm UTC](https://discourse.julialang.org/t/ad-vs-argument-lists/125207/3 "2025-01-25T21:40:59Z")

</div>

So, four matrix subtypes of AbstractMatrix + plus one scalar type?  
Or, should I just drop all types? `function add_btdb_ut_only!(Ke, B, Jac_w::T, D, DB) where {T<:Real}`…  
The latter seems appealing. `Dual` is a subtype of `Real`, so this should work for all possible combinations of inputs, I think.

---

<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: [January 25, 2025, 10:04pm UTC](https://discourse.julialang.org/t/ad-vs-argument-lists/125207/4 "2025-01-25T22:04:56Z")

</div>

> [@PetrKryslUCSD](#):
>
> So, four matrix subtypes of AbstractMatrix + plus one scalar type?

I mean just:

```julia
add_btdb_ut_only!(Ke::AbstractMatrix, B::AbstractMatrix, Jac_w::Number, D::AbstractMatrix, DB::AbstractMatrix)

```

Why do you need a `where` clause at all? If you need to enforce that they are all `Real`, do:

```julia
add_btdb_ut_only!(Ke::AbstractMatrix{<:Real}, B::AbstractMatrix{<:Real}, Jac_w::Real, D::{<:Real}, DB::{<:Real})

```

> [@PetrKryslUCSD](#):
>
> Or, should I just drop all types?

That’s always an option: just duck-type.

---

<div class="post-metadata">

### Author: ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)
#### Post date: [January 25, 2025, 10:10pm UTC](https://discourse.julialang.org/t/ad-vs-argument-lists/125207/5 "2025-01-25T22:10:05Z")

</div>

But now, with duck typing, I should probably document the types of the arguments in the doc string. Previously the signature served as a documentation…

---

<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: [January 26, 2025, 12:27am UTC](https://discourse.julialang.org/t/ad-vs-argument-lists/125207/6 "2025-01-26T00:27:06Z")

</div>

Well, you can always do `add_btdb_ut_only!(Ke::AbstractMatrix{<:Real}, B::AbstractMatrix{<:Real}, Jac_w::Real, D::{<:Real}, DB::{<:Real})`. The point is that the previous signature was simply narrower than (presumably) the function required.

Note, however, that if you want to support arbitrary types like this, you should be more careful in implementing the function too. e.g. if you need to allocate an array within the function, you should compute its type from the arguments rather than simply assuming it should be `Float64`.  
Type-generic programming takes a bit of practice, but is worth it in the long run.
