My question is, why throw is a function in Julia? Why is it not a keyword just like the case in many other languages?
The short answer it that keywords are only used when necessary.
That’s the answer I expect (and agree with). Still, the question is now “to what extent can throw be regarded as a function”. For example, how can throw(which changes the control flow) be implemented using some other functions?
mythrow(x) = ccall(:jl_throw, Cvoid, (Any,), x)
Note that since it’s not a tfunc like throw, it doesn’t have the same type inference support, so in some cases, this might result in worse type inference than throw.
To the extent that it obeys the semantics of a function, ie you can call it with arguments.
Not without reaching for internals, it is a built-in function.
That said, I am not really sure what the purpose of this discussion is though. Like all languages, Julia needs a primitive to throw exceptions, it has throw, and it works fine.
One reason is that many static languages have no multiple dispatch, so they can’t have a polymorphic throw function, since there are many different types of errors. But Haskell indeed has a throw function, and its type signature is quite complicated.
For some dynamic languages like Python, using a keyword can prevent you redefining the function accidentally. So it’s illegal to write down raise=1 or throw=print…
Though strictly speaking Julia’s throw is a built-in function, not a generic function. But at least it acts like a generic function.
That makes me think if could be a small macro instead of a keyword. for, too. That would make the language simpler and things like symbolic execution easier.
My 2c. I think it makes much more sense for throw to be a built-in function in Julia. There are also other built-in functions which are impossible to implement without accessing internal functions (e.g. getfield and setfield!). If you need a method, you can wrap these functions in some custom function (e.g. getproperty and setproperty!).
I understand why other languages implement throw as a keyword, but I don’t think it makes sense to do that in Julia. Take Scheme languages, for instance, there are a lot of them which implement Call/cc, which changes control flow in a much more complex way than Julia’s throw (or any language’s throw keyword) and they are still functions.