# Is it possible to splat into ccall?

**URL:** <https://discourse.julialang.org/t/is-it-possible-to-splat-into-ccall/95761>\
**Category:** General Usage\
**Tags:** ccall\
**Created:** [March 8, 2023, 7:49pm UTC](https://discourse.julialang.org/t/is-it-possible-to-splat-into-ccall/95761 "2023-03-08T19:49:46Z")\
**Posts on this page:** 1\
**Showing post:** 4

<div class="post-metadata">

**Author:** ![lmtzx9h4qqnt](https://avatars.discourse-cdn.com/v4/letter/l/74df32/32.png) [@lmtzx9h4qqnt](https://discourse.julialang.org/u/lmtzx9h4qqnt)\
**Post date:** [March 9, 2023, 5:44pm UTC](https://discourse.julialang.org/t/is-it-possible-to-splat-into-ccall/95761/4 "2023-03-09T17:44:01Z")

</div>

Well, the canonical example would be varargs functions in C (e. g. as linked in my original post):

> [@Why is ccall syntax?](https://discourse.julialang.org/t/why-is-ccall-syntax/72427/7):
>
> You can splat into the AST which @ccall is a part of, provided you do it before macro expansion. For example: @eval @ccall printf("%d %d %d %d %d\n"::Cstring, $((:($i::Cint) for i in 1:5)...))::Cint But it’s unlikely that it’s a good idea to use @eval like this! What’s your surrounding code look like for this use case?

I used `pow` as an example because I wanted to focus on the syntax without adding the complications that come with varargs. Using @uniment’s method, the linked `printf` example becomes

```julia
julia> ccaller{:printf, :Cint, (:Cstring, ntuple(_ -> :Cint, 5)...)}("%d %d %d %d %d\n", (1:5)...);
1 2 3 4 5

```

without `@eval` – much better!

But to be honest, that isn’t even how I came across this question. I just have some C functions (in an external library) with annoyingly long argument lists (9 arguments) that I wanted to call and validate/transform the arguments for. Instead of copy-pasting the same code 9 times to handle each argument, I tried to pack them in a tuple and process them in a loop instead. So now I already have the arguments as a tuple, so the easiest (and least error-prone!) way of passing them to `ccall` would be to use splatting. Of course I _could_ also just index all 9 arguments individually, but that just seems stupid when splatting exists! We’re not writing C here after all.

So just for illustration, what I wanted to write was

```julia
function external_func_wrapper(args::NTuple{9, Integer})
	for x in args
		validate(x) || error(x)
	end
	return ccall(
		:external_func, Cdouble,
		(Cint, Cint, Cint, Cint, Cint, Cint, Cint, Cint, Cint),
		(transform(x) for x in args)...
	)
end

```

But since that’s not allowed, I’d have to change it to

```julia
function external_func_wrapper(args::NTuple{9, Integer})
	for x in args
		validate(x) || error(x)
	end
	arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 =
		(transform(x) for x in args)
	return ccall(
		:external_func, Cdouble,
		(Cint, Cint, Cint, Cint, Cint, Cint, Cint, Cint, Cint),
		arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9
	)
end

```

which makes me list the entire indexed argument list _twice_, instead of not at all if splatting were allowed.

> [@c42f](#):
>
> And the presence of hacks is a sign that something “might be wrong” and you should be doing it a different way.

I don’t really agree with this. I’d even almost say it’s the opposite: The fact that “hacks” like @uniment’s method exist demonstrates that there isn’t any fundamental reason why this shouldn’t work. Clearly, Julia has all the information necessary to determine whether the call is valid and carry it out. It’s just that `ccall` arbitrarily rejects this specific syntax. As you say yourself in that same thread I linked above:

> [@Why is ccall syntax?](https://discourse.julialang.org/t/why-is-ccall-syntax/72427/3):
>
> #### The basic answer
> 
> It doesn’t need to be syntax. `@ccall` is a more recent and much more attractive syntax for the same thing which doesn’t need special support from the parser or lowering.

---

_[View the full topic](https://discourse.julialang.org/t/is-it-possible-to-splat-into-ccall/95761)._
