JuliaLang/julia — pull request #5029 by simonster (2013-12-04 06:25:14+00:00)
Title: RFC: ifpkg macro

We're getting to the point where package authors might want to execute different code depending on the version of another package or the version of Julia itself. This PR proposes an `@ifpkg` macro for doing so. `@ifpkg` accepts a requirement line of the same form as the REQUIRE file and determines whether that requirement is satisfied by an installed package. If it is satisfied, it substitutes its second argument. Otherwise it substitutes its third argument, or nothing if no third argument is specified.

Some examples of how this might be used:
```julia
@ifpkg "julia 0.3-" eigvecs(A, ev) eigvecs(A, ev)[1]
@ifpkg "DataFrames 0.4" begin
# DataFrames interface code goes here
end
```

There are two practical problems with the approach I'm using here. First, at least on my machine, `Pkg.installed()` is takes more than a second to execute. Since this macro calls the same Pkg functions, it takes just as long, which is not really acceptable for code that will be executed when loading packages. Second, I don't expect that this would work as implemented with Julia workers running on a different machine.

I am also unsure whether this macro is the right approach to this problem. It's arguable that it isn't necessary at all since you could just use `@eval`:

```julia
@eval $(VERSION >= v"0.3-") ? eigvecs(A, ev) : eigvecs(A, ev)[1]
@eval if $(isdir(Pkg.dir("DataFrames")))
# DataFrames interface code goes here
end
```

although this gets messy if you want code to execute only if a package is registered in the user's METADATA checkout, it is installed, and it is newer than a certain version. But maybe the right approach is a new function, not a new macro.