Difference between f(s::String) and f(::String)

Viewed 154

What is the difference between the following two functions?

julia> one(s::String) = return 1
one (generic function with 1 method)

julia> one(::String) = return 1
one (generic function with 1 method)

Both seem to be allowed and there doesn't seem to be a difference between them. I suppose not including the v could signal to the compiler that the value of the argument is not used, but then again this is something the compiler can figure out, right? (Disclaimer: I have no idea how compilers work)

1 Answers

There is no difference if you don't use the argument, and yes, for the compiler this should be trivial.

You can use _ as an actual "discard argument" though, and the parser will prevent you from using it:

julia> f(_) = _ + 1
ERROR: syntax: all-underscore identifier used as rvalue around REPL[9]:1

That's useful in some situations:

julia> _, _, z = (1,2,3)
(1, 2, 3)

julia> z
3

julia> _
ERROR: all-underscore identifier used as rvalue

while

julia> x, x, z = (1,2,3)
(1, 2, 3)

julia> x
2

is slightly confusing.


More technicalities

An unused argument is preseved in IR, though:

julia> one(::String) = return 1
one (generic function with 1 method)

julia> one2(s::String) = return 1
one2 (generic function with 1 method)

julia> ir = @code_lowered one("sdf")
CodeInfo(
1 ─     return 1
)

julia> ir.slotnames
2-element Array{Symbol,1}:
 Symbol("#self#")  
 Symbol("#unused#")

julia> ir2 = @code_lowered one2("sdf")
CodeInfo(
1 ─     return 1
)

julia> ir2.slotnames
2-element Array{Symbol,1}:
 Symbol("#self#")
 :s 

If you ever care about slot names. I can't imagine how this would change further compilation, but it can be a corner case in metaprogramming.

Related