Why `eye` has been deprecated?

I saw that eye has been deprecated in Julia v0.7. The message that appears is:

Warning: `eye(m::Integer)` has been deprecated in favor of `I` and `Matrix` constructors. For a direct replacement, consider `Matrix(1.0I, m, m)` or `Matrix{Float64}(I, m, m)`. If `Float64` element type is not necessary, consider the shorter `Matrix(I, m, m)` (with default `eltype(I)` `Bool`).

On the other hand, the NEWS shows:

eye(::Type{Diagonal{T}}, m::Integer) has been deprecated in favor of Diagonal{T}(I, m) (#24413).

In this bug report, I did not find a specific mention to eye. Hence, I am wondering why eye was removed. This is something so much consolidated in every scientific programming language.

Can’t we have something like:

eye(T, m::Int) = Matrix{T}(I,m,m)
4 Likes

The decision was made last fall: make I(n) behave as `Diagonal` / `eye`? · Issue #23156 · JuliaLang/julia · GitHub

The idea is that in most cases, there’s no need to actually allocate the identity matrix, given that we have the UniformScaling operator I.

6 Likes

Thanks for the link! But, instead of deprecate and remove eye entirely, can’t we just make it use the new feature?

1 Like

I doesn’t have specified dimensions and isn’t a normal function, and defining eye(m,n) = I would obscure that. I also get the sense that any time the devs have a chance to expunge Matlab idioms from the language, they take it. Do you have a use case where I doesn’t suffice?

edit: To help catch and redirect wayward Matlab/Python users, the deprecation warning should probably be permanent if it isn’t already. It’d also be nice to have a succinct description of the UniformScaling operator’s behavior (not just its existence) included in the deprecation.

1 Like

Actually no, it is just that eye is pretty consolidated in MATLAB, Octave, and numpy.

I completely agree with that.

1 Like

This has been discussed on here before on this thread:

One thing that I do not like about I is that it is not an AbstractMatrix, but is considered a scalar for broadcasting purpouses. So while zeros(3,3) .+ eye(3) does exactly what you think it does, zeros(3,3) .+ I is equivalent to zeros(3,3) .+ 1.

(In this particular case, one could use + instead of .+, but that does not work in general.)

(Sadly)So do I.

2 Likes

That’s slated to be fixed; it’s just gotta be deprecated first.

One rationale here is simply that the name eye is pretty bad. It’s a literal pun that depends upon knowledge of the English pronunciation of both eye and I and the ability to connect them.

Julia is not MATLAB — there’s a MatlabCompat package that would make for a nice place for these kinds of simple aliases.

17 Likes

I am not sure about this. My impression is that parts of the core language and the standard libraries are re-examined from time to time, in order to

  1. provide an interface that is more consistent (eg #25545),
  2. take advantage of compiler developments (#25472), and
  3. extend behavior across types (#24774)

(these examples are deliberately picked for one set of functions, there are many others).

I think this is a good thing. Since Matlab/Octave/R/… inspired a lot of the original API, these are bound to disappear when changes happen, but there is not necessarily anything anti-Matlab/Octave/R/… in the changes per se.

Also, in contrast to many other languages, Julia developers have a strong tendency to search for the “right solution”, even at the expense of occasional widely disruptive changes. Again, this is a matter of preference, the great advantage is getting a much better language in the long run.

14 Likes

There’s a lazy Eye(n,m) in FillArrays.jl.

3 Likes

I suspect that most of the cheatsheets out there will need substantial revisions. Taking the QuantEcon Matlab-Julia-Python cheatsheet as an example,

[1 2 3]'            # produces LinearAlgebra.Adjoint{...} instead of "column vector"
linspace(1, 5, k)   # tragically deprecated :'(
eye(2, 2)           # deprecated to push users towards I; requires 'using LinearAlgebra'
diagm([1; 2; 3])    # deprecated in Base, requires 'using LinearAlgebra'
A.'                 # deprecated in favor of several more-verbose options
flipdim(A, 2)       # deprecated to reverse(A, dims=d)
repmat(A, 3, 4)     # deprecated to repeat(...)
diag(A)             # deprecated in Base, requires 'using LinearAlgebra'
dot(A, B)           # deprecated in Base, requires 'using LinearAlgebra'
det(A)              # deprecated in Base, requires 'using LinearAlgebra'
eig(A)              # deprecated to LinearAlgebra.eigen(A).values
norm(A)             # deprecated in Base, requires 'using LinearAlgebra'

sum(A, 1)
maximum(A, 1)
minimum(A, 1)
cumsum(A, 1)
etc...              # all deprecated in favor of <reduction>(A, dims=dims)

All told, out of the 55 basic operations described in the cheat sheet, 17 are deprecated. The rationale for these changes is solid, but scattered across a hundred Github issues, and this will hardly be the last time this sort of question comes up. I really wish JuliaComputing would hire a dedicated technical writer, but wishes aren’t dollars.

4 Likes

I really does not have an opinion about it. However I agree that the name eye is not, let’s say, the best choice :sweat_smile:

But, should I replace eye with Diagonal as stated in the NEWS or Matrix as stated in warning?

Which is why there is a NEWS.md.

Using Matrix will produce something exactly equivalent to eye, which is why it is given in the deprecation message. However, for almost all use cases, you can do something much more efficient than a dense matrix using either I or Diagonal, which is why eye was deprecated.

9 Likes

Whether or not it’s accurate, you see the result–what is the issue that you have with it?

… and what about it makes you sad?

(Honestly asking here)

MATLAB Syntax is very well established and often very succinct and convenient. I can see the reasons why it is being deprecated, but I am not always happy about it myself. I feel it depends on whether you want Julia to be a MATLAB like scientific computing environment (which is how it started) or something more general purpose. There are advantages both ways. Long-term I imagine the right decisions are being made here.

4 Likes

At the risk of pointing out the obvious, there is evidently an expectation from some users (actual and potential) that Julia syntax is similar to Matlab, and probably having eye and some of the others that have been mentioned in earlier releases helped reinforce those expectations, and their deprecation has predictable results among that group. You can imagine that users coming from other languages might have similar reactions for different deprecations (and/or just syntax/features they wish would be part of Julia and aren’t).

Personally one of the things I really like about Julia is that the developers seem not to be limiting themselves to what are (currently) familiar syntax/idioms from older languages, and often as I learn more about Julia and some of the reasons behind these choices my appreciation for Julia’s design grows.

Constructively, and I suspect it’s been suggested before (and it looks like perhaps worked on at least at some point [1]), but, one of the nice things about Julia is that we can extend it easily. That fact can be used to help those who would prefer that something like eye still be available (just to take a specific example) while not requiring everyone else to have it in their namespace. And in fact I think it can be better than including these in the base language (or stdlib) because if for example you are writing MatlabToJulia.eye it can be more geared towards those coming from Matlab than, say, PythonToJulia.eye. By doing this on a language-by-language basis you could also probably use the deprecation system to optionally give helpful guidance towards a more Julian implementation that is appropriate for the source language when these functions are used.

I think with some forethought (avoiding a huge set of dependencies would be a concern, I think), a<LanguageX>ToJulia.jl packages could be a useful tool. I’d be open to working on something like this (for MatlabToJulia.jl) as it would complement what I’m trying to do with the Julia for MATLAB Users Wikibook. Any other potential contributors? :slight_smile:

Somewhat related thread: Should we mimic R (, MATLAB, ...) functions?

[1] https://github.com/MatlabCompat/MatlabCompat.jl

2 Likes

The similarity to the Matlab syntax was big selling point when Julia first appeared and honestly it was what attracted me more. Having symilarities does not mean that Julia cannot follow its own way, but I sincerely cannot feel happy when functions like linspace or others in the list provided above, are deprecated. I know that laziness in memorizing new function names is part of the reason but laziness is part of programing too.

6 Likes

To be clear, I don’t have an issue with the changes themselves (except for linspace, RIP. linspace(0, pi) is so much nicer for interactive use than range(0, stop=pi, length=50).

That said, it isn’t anybody’s first priority to communicate these changes clearly, and as a result, that communication often doesn’t happen, or when it does, it can be scattered. Writing documentation isn’t stimulating work, the lead devs have better things to do, and less-experienced users lack the ecosystem knowledge to write anything besides very granular descriptions of what a function does. When the stars align and a power user writes a blog post, hallelujah! But the language’s velocity over the past few years has been hard to keep up with, and much of the extant material will be out of date when 1.0 is released. It’ll probably be v1.2 before all the fires across the ecosystem are put out and full attention can be diverted to documentation/quality of life.

This isn’t MathWorks, Inc., and Julia’s blessedly free of cruft because of that. But with all the moving fast and breaking things, there’s a bit of a mess, and volunteer janitors are hard to find.

2 Likes