Using "where" syntax to parametrize a function in Julia [duplicate] - julia

This question already has an answer here:
`where` in function definitions in julia-0.6
(1 answer)
Closed 5 years ago.
Reading the Julia documentation on parametric methods, I can't for the life of me figure out the difference between these two definitions
julia> function f{T<:Real}(x::T)
println("$x with type $T")
end
julia> function g(x::T) where {T<:Real}
println("$x with type $T")
end
Any guidance on the semantic difference between these two definitions would be highly appreciated.

The former is deprecated (in most instances) for the latter. where replaces the old syntax in v0.7 and onwards, and the first will not exist in 1.0.
One exception is inner constructors. The first syntax will still exist for them. But in that case type parameters means something very different. Example: Array{Float64,2}() the inner constructor takes in the parameters from the user. This was confusing before because type parameters had a dual meaning for these different constructs, but now this way of parameterizing only exists for inner constructors and only means this, whereas everything else uses where.

Related

Why is there a function undefined message whereas it's about variable

Let's say I'm invoking something like this
Enum.count(list)
And list is not defined in 'upper scope'. In most of languages you'll probably get something like Variable list is undefined, but in Elixir (it comes from Erlang, so I hope it's same behaviour) you'll be getting undefined function list/0 (there is no such import).
What's the difference in Elixir from other (let's say imperative) programming languages in sense of distinction between variable and function?
Also I've noticed you can make a function in module, and if it takes zero arguments, you can call it without parentheses, I was wondering what's special about that. (was answered below by #sabiwara)
Elixir used to consider parentheses optional for all function calls, including 0-arity functions like Kernel.node/0:
iex> node
:nonode#nohost
This behavior has since been deprecated and will emit a compile time warning:
warning: variable "node" does not exist and is being expanded to "node()", please use parentheses to remove the ambiguity or change the variable name
Parentheses for non-qualified calls are optional, except for zero-arity calls, which would then be ambiguous with variables.
But since it would be a breaking change to just change this behavior, it still works and gets interpreted, in your case, as list().
This might change in Elixir 2.0. A discussion on this topic here.

Can I define variable in Julia just like in Fortran

I am new to Julia. Have a quick question.
In Fortran, we can do
implicit none
Therefore whenever we use a variable, we need to define it first. Otherwise it will give error.
In Julia, I want to do the same time thing. I want to define the type of each variable first, like Float64, Int64, etc. So that I wish that Julia no longer need to automatically do type conversion, which may slow down the code.
Because I know if Julia code looks like Fortran it usually runs fast.
So, in short, is there a way in Julia such that, I can force it to only use variables whose types has been defined, and otherwise give me an error message? I just want to be strict.
I just wanted to define all the variables first, then use them. Just like Fortran does.
Thanks!
[Edit]
As suggested by the experts who answers the questions, thank you very much! I know that perhaps in Julia there is no need to manually define each variables one by one. Because for one thing, if I do that, the code will become just like Fortran, and it can be very very long especially if I have many variables.
But if I do not define the type of the each variables, is Julia smart enough to know the type? Will it do some conversions which may slow down the code?
Also, even if there is no need to define variables one by one, is there in some situations we may have to manually define the type manually?
No, this is not possible* as such. You can, however, add type annotations at any point in your code, which will raise an error if the variable is not of the expected type:
julia> i = 1
1
julia> i::Int64
1
julia> i = 1.0
1.0
julia> i::Int64
ERROR: TypeError: in typeassert, expected Int64, got a value of type Float64
Stacktrace:
[1] top-level scope
# REPL[4]:1
julia> i=0x01::UInt8
0x01
*Julia is a dynamically-typed language, though there are packages such as https://github.com/aviatesk/JET.jl for static type-checking (i.e., no type annotations required) and https://github.com/JuliaDebug/Cthulhu.jl for exploring Julia's type inference system.
Strict type declaration is not how you achieve performance in Julia.
You achieve the performance by type stability.
Moreover declaring the types is usually not recommended because it decreases interoperability.
Consider the following function:
f(x::Int) = rand() < 4+x ? 1 : "0"
The types of everything seem to be known. However, this is a terrible (from performance point of view) function because the type of output can not be calcuated by looking types of input. And this is exactly how you write the performant code with regard to types.
So how to check your code? There is a special macro #code_warntype to detect such cases so you can correct your code:
Another type related issue are the containers that should not be specified by abstract elements. So you never want to have neither Vector{Any} nor Vector{Real} - rather than that you want Vector{Int} or Vector{Float64}.
See also https://docs.julialang.org/en/v1/manual/performance-tips/ for further discussion.

We can change immutable variable in Elixir. Can we not say rebind equals mutable? [duplicate]

This question already has answers here:
Are Elixir variables really immutable?
(5 answers)
Closed 1 year ago.
I am new for function language. i practised some thing but i wonder one thing. Elixir says me that everything is immutable but i can change variable in elixir. Is there something that I dont know about it?
My example is
defmodule Practise do
def boxes(total) do
size_50 = div(total, 50)
total = rem(total, 50)
{"big: #{size_50} total: #{total}"}
end
end
I can change total variable with new value in same named function. So that i think it is immutable. Is it correct?
Reusing variable names (which is often referred to as rebinding) is just a convenience in Elixir - it's equivalent to using a temporary variable but with the same name. The reference to your original total gets lost in the scope of the function Practice.boxes. But that doesn't matter to you since you don't need it again - you just need the new one.
This is a rare concession made by the designers of Elixir towards imperative programming. Indeed, an expression such as x = x + 1 might be mistaken for pattern matching phrase.

golang nil pointer assignment with ignored output - (*)(nil) [duplicate]

This question already has answers here:
What does an underscore and interface name after keyword var mean?
(2 answers)
Closed 4 years ago.
while going through this tutorial on writing FUSE filesystems in go, I came across this cryptic assignment:
var _ fs.Node = (*Dir)(nil)
Can someone explain the mechanics of this syntax, and how does it fit in the context in which it is declared? As I understand the outcome of the assignment is actually ignored (and what does the right hand expression even result in? a nil Dir pointer?)
This makes the compiler check if type *Dir fulfills fs.Node interface.
Take a nil pointer, make it a *Dir pointer and assign it to an unnamed variable of interface type fs.Node. Since we never use this variable, we have to make it unnamed.

`where` in function definitions in julia-0.6

I am trying to understand the new type system in Julia v0.6, based on reading the release notes.
Can anyone tell me what
inv(M::Matrix{T}) where T <: AbstractFloat
gives me which is different from using the classic
inv{T<:AbstractFloat}(M::Matrix{T})
?
The new syntax means the same thing but can be used in more circumstances and can express more constructs and eliminates a number of conceptual ambiguities, especially surrounding parametric constructors. The old syntax will be deprecated in 0.6 and some of the old syntax will be reclaimed with different meaning in 1.0. Fundamentally, the problem with F{T}(args...) is that the F{T} part is conceptually ambiguous – the parser knows what it means, but it's often confusing to humans:
In isolation F{T} means the parametric type F with type parameter T.
Followed by parens, not as part of a method definition, F{T}(args...) means to apply the type F{T} to the arguments args... as a function, typically constructing an instance of the type F{T}.
Followed by parens and equals, i.e. as part of a method definition as in F{T}(args...) = expr, it means to define a method for F as a function, with type parameters T formal arguments args... and definition expr.
In particular, there is no syntax for either of these:
Adding a method to F{T} for the concrete value of T in the current scope.
Adding a method to F{T} for each parametric value T.
This situation causes constructor syntax in Julia 0.5 and prior to be more confusing and unintuitive than necessary. In Julia 1.0 type parameters and constructors will be both more intuitive and consistent, following these principles:
The syntax used to define a method always matches the syntax used to call it.
The F{T} syntax always refers to the type F with parameter T.
Type parameters are always introduced by where clauses.
There will be a more detailed explanation of the changes when 0.6 comes out, probably in a blog post on highlights of the 0.6 release.

Resources