They are identical if the type is correct though, right?
e.g., signature level:
julia -e 'function g(x::A)::(A.name.wrapper{T,N-1}) where {T,N,A<:AbstractArray{T,N}}; dropdims(x, dims=(1,)); end; x = ones(32, 1); import InteractiveUtils: @code_llvm; @code_llvm g(x)' \
2>&1 > signature_level.txt
Function level:
julia -e 'function g(x::A) where {T,N,A<:AbstractArray{T,N}}; dropdims(x, dims=(1,))::(A.name.wrapper{T,N-1}); end; x = ones(32, 1); import InteractiveUtils: @code_llvm; @code_llvm g(x)' \
2>&1 > function_level.txt
The diff is just different addresses:
< store atomic i64 140599633651680, i64* %15 unordered, align 8
---
> store atomic i64 139832940386272, i64* %15 unordered, align 8
45c45
< store {}* inttoptr (i64 140599707586240 to {}*), {}** %16, align 8
---
> store {}* inttoptr (i64 139833014320832 to {}*), {}** %16, align 8
93c93
< store atomic i64 140599633764176, i64* %28 unordered, align 8
---
> store atomic i64 139832940498768, i64* %28 unordered, align 8
97c97
< %30 = call nonnull {}* inttoptr (i64 140600165136976 to {}* ({}*, {}*, {}*)*)({}* inttoptr (i64 140599635100832 to {}*), {}* nonnull %0, {}* nonnull %26)
---
> %30 = call nonnull {}* inttoptr (i64 139833471871568 to {}* ({}*, {}*, {}*)*)({}* inttoptr (i64 139832941835424 to {}*), {}* nonnull %0, {}* nonnull %26)
I think it’s nicer when you have multiple return statements, and also for documentation if a user is looking at the signature, maybe. I wish there was cleaner syntax though…