Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Deprecate is_<os> functions in favor of is<os> #22182

Merged
merged 1 commit into from
Jul 11, 2017
Merged

Conversation

ararslan
Copy link
Member

@ararslan ararslan commented Jun 2, 2017

This PR deprecates the OS predicate functions which contain underscores in favor of ones without underscores, thereby making them consistent with the vast majority of Base predicates, which simply prefix with is rather than is_. That is, is_unix for example is now isunix.

This is part of the underscore audit as mentioned in #20402.

@ararslan ararslan added the kind:deprecation This change introduces or involves a deprecation label Jun 2, 2017
@deprecate $f() $newf()
end
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Five-liner (also seems simpler?):

@deprecate is_apple   isapple
@deprecate is_bsd     isbsd
@deprecate is_linux   islinux
@deprecate is_unix    isunix
@deprecate is_windows iswindows

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't realize you could do it without explicitly providing the methods. Thanks.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works because all methods of is_apple etc. are deprecated, so it is not necessary to single out some of them :)

@dpsanders
Copy link
Contributor

Can't we replace them eg. by a single isos command?

@ararslan
Copy link
Member Author

ararslan commented Jun 2, 2017

Can't we replace them eg. by a single isos command?

Probably, though that would take some design brainstorming to come up with something decently ergonomic. Personally I like the simplicity of just being able to say iswindows(), for example.

@dpsanders
Copy link
Contributor

I do see that, but it's also a bit strange, since it doesn't say what is windows.

@ararslan
Copy link
Member Author

ararslan commented Jun 2, 2017

I do agree with that, I just think of it like a less annoying way of saying iswindows(Sys.KERNEL) and that helps me feel better about it.

We could ramp up the complexity and do a type-based approach, like struct MacOS end and if @__OS__ == MacOS or if @__OS__ isa UnixBasedOS. Kind of fun, if impractical. 😛

@vtjnash
Copy link
Sponsor Member

vtjnash commented Jun 2, 2017

I'm not sure this is a net benefit. I think the goal of the underscore audit is to tend towards single word functions (possible compound), not to make them harder to read. (And I much prefer function_with_many_adjectives over fun(Val{true}, Val{'c'}) any day)

@ararslan
Copy link
Member Author

ararslan commented Jun 2, 2017

Audit or not, with this I was more striving for consistency with other predicates, since we have 74 Base functions that begin with is and only 6 (5 of which are these) begin with is_. It seems unfortunate to keep this as basically the sole exception.

@nalimilan
Copy link
Member

We could ramp up the complexity and do a type-based approach, like struct MacOS end and if @OS == MacOS or if @OS isa UnixBasedOS. Kind of fun, if impractical. 😛

Why would that be impractical? We would just need one type for each of the currently supported functions.

@tkelman
Copy link
Contributor

tkelman commented Jun 2, 2017

I hate the churn of renaming these again, but the original PR should have had a bit more naming discussion on it. These shouldn't have had underscores in them when they were exported.

@dpsanders
Copy link
Contributor

Are there scripts available for automatic conversion of these kinds of things?

@dpsanders
Copy link
Contributor

To update source code to the new version, I mean.

@giordano
Copy link
Contributor

giordano commented Jun 2, 2017

@dpsanders would you like this isos?

abstract type OS end
struct Linux <: OS end
struct MacOS <: OS end
struct Windows <: OS end
isos(os::Type{<:OS}) = Sys.KERNEL === Symbol(os)

so you can use

julia> isos(Linux)
true

julia> isos(Windows)
false

Actually I don't know what Sys.KERNEL gives on other systems, I tried only on GNU/Linux.

However, I see that this probably doesn't solve all issues, because these functions actually look at the kernel, rather than the system, and there are some systems (Apple, BSD, Windows) associated with different kernels.

@ararslan
Copy link
Member Author

ararslan commented Jun 2, 2017

Why would that be impractical?

We'd end up needing a type for every OS under the sun.

@dpsanders
Copy link
Contributor

Could just be an enum.

@ararslan
Copy link
Member Author

ararslan commented Jun 2, 2017

I suppose. I don't see that as being much more convenient than status quo though.

@oscardssmith
Copy link
Member

Is that many type thing bad? Inheritance seems a fairly sane way of representing the relationship between different OSs. We could have a unix class with subtypes linux, mac and bsd etc. Is there a reason having a function for each is better than a type for each?

@ararslan
Copy link
Member Author

ararslan commented Jun 2, 2017

I maintain that this PR is the path of least resistance, since it's a one-character change from status quo, and the current status quo came after a huge code churn that turned OS-specific macros into function calls. Moving to yet another approach will result in significantly more code churn for (IMHO) little benefit.

If people are really interested in a type-based approach, I made a prototype in https://github.com/ararslan/OperatingSystems.jl. Feel free to play around with that and see if you like it.

@o314
Copy link
Contributor

o314 commented Jun 3, 2017

@dpsanders it's an enum way of thinking.
but the way @enum is currently implemented do not deserve well a language such as julia. it's too much tricky.
@giordano touches substantilly a very important point : how to map subtyping and union type cleanly.
we will have to adress more and more api over the internet and that will leads to json schema and lately bnf. this proposal is far more robust in this way.

i don't know a lot about the last status quo, but generally the coupling with macro and functions are due to other concerns, mainly maintaining readability during macro expansion.

i am not so much affirmative telling this refactoring has to be done there and now. but i guess those kind of data concern will popup more and more frequently. untill one day we may have official guideline (to what i consider may be as the unique weakness of julia today) :)

@nalimilan
Copy link
Member

We'd end up needing a type for every OS under the sun.

I don't see the difference with the current functions. We don't provide isdragonfly, so why would we have to provide a DragonFly type? The type-based approach would allow us to return BSD for Dragonfly, just like we now have isbsd. Then if one day it turns out we need to distinguish Dragonfly, we'll be able to introduce a Dragonfly <: BSD type, and ensure backward compatibility.

I'm not saying this necessarily The Right Approach, but any code churn is annoying for packages, so I think it's worth ensuring we won't break this again later. A one-char change is almost as annoying as moving to a different expression, as long as a systematic replacement can be applied.

@ararslan
Copy link
Member Author

ararslan commented Jun 4, 2017

I've opened #22214 to discuss alternate approaches. If possible, I think we should keep the discussion in this PR limited to the approach implemented herein and move discussion of alternate systems to the linked issue.

@ararslan
Copy link
Member Author

@stevengj made a good point in #22214 that even if we have an alternate system for representing operating systems, it's hard to beat the convenience of iswindows(). Having a concise representation for this is desirable as these checks can be quite common. We can always switch out the implementation of iswindows() to be Sys.OS <: Sys.Windows (or whatever) later without removing these functions, but in the meantime I think we should go ahead with this change.

Copy link
Member

@omus omus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look good. Personally I prefer underscore separated words but that ship has sailed.

@nalimilan
Copy link
Member

Fine with me. I'm not totally convinced that iswindows is so much better than Sys.OS <: Sys.Windows, but if that's the general sentiment, then better remove the underscore now.

@ararslan ararslan force-pushed the aa/os_underscores branch 2 times, most recently from ffbfa04 to 8260c13 Compare June 29, 2017 20:15
NEWS.md Outdated
@@ -120,6 +120,10 @@ Deprecated or removed
* The `corrected` positional argument to `cov` has been deprecated in favor of
a keyword argument with the same name (#21709).

* The operation identification functions: `is_linux`, `is_bsd`, `is_apple`, `is_unix`, and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

operating system

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whops

base/osutils.jl Outdated
@static

Partially evaluates an expression at parse time.

For example, `@static is_windows() ? foo : bar` will evaluate `is_windows()` and insert either `foo` or `bar` into the expression.
For example, `@static iswindows() ? foo : bar` will evaluate `iswindows()` and insert either
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sys.iswindows

@ararslan ararslan force-pushed the aa/os_underscores branch 2 times, most recently from a70e6ae to d3ca6fa Compare June 30, 2017 01:38
base/c.jl Outdated
@@ -4,6 +4,11 @@

import Core.Intrinsics: cglobal, bitcast

# Equivalent to Sys.iswindows(), but that's not yet defined
const _WINDOWS = let k = ccall(:jl_get_UNAME, Any, ())
Copy link
Contributor

@tkelman tkelman Jun 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kind of annoying to give this a name. I think we have control over jl_get_UNAME on windows so it should only ever return a single value

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we check it for :Windows or :NT in iswindows then? Does that mean we could simplify that conditional as well?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because it can take a symbol input, and partly backwards compatibility

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should only ever return a single value

Which value is it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NT

FLAGS += -DJL_BUILD_UNAME='"NT"'

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a necessary change? Giving it a name at least avoids having to do the ccall several times, plus calling it Windows here is clearer than having to know that the Windows uname is NT. I don't care too much though, just seems unnecessary to change what's here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

giving it a name means it's there in Base for everyone to misuse. the ccall happens only at system image build time. otherwise could use a let to avoid occupying namespace in Base

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

base/c.jl Outdated
@@ -49,7 +50,7 @@ Equivalent to the native `wchar_t` c-type ([`Int32`](@ref)).
"""
Cwchar_t

if !is_windows()
if ccall(:jl_get_UNAME, Any, ()) !== :NT
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this wrong? It seems to be causing a SIGABRT on Windows...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works locally? Maybe there's something strange about evaluating it eagerly, maybe (()->ccall(:jl_get_UNAME, Any, ()))() would defer it to runtime or something? But then how did the const version that you had before work?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have absolutely no idea.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also the first ccall works fine, it's just this second one that's getting upset

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems like a bug to me

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we go with a workaround in the meantime? I'm not sure how to reproduce, much less diagnose.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've gone with a workaround but added a note.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I agree it's very strange that the const version works but without the const it does not. It sounds like it could be dangerous to go with the workaround unless the issue is understood.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workaround is harmless, its necessity is just mysterious. I'm submitting an issue to track the underlying bug but in the meantime this should be fine.

@ararslan ararslan force-pushed the aa/os_underscores branch 2 times, most recently from e325593 to 7122b2e Compare July 8, 2017 19:30
@ararslan
Copy link
Member Author

ararslan commented Jul 8, 2017

Previous AppVeyor SIGABRT reported here: #22713

base/c.jl Outdated
@@ -18,7 +24,8 @@ Equivalent to the native `char` c-type.
"""
Cchar

if is_windows()
# The ccall is equivalent to Sys.iswindows(), but that's not defined yet
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment no longer applies. I'll remove that in a separate, CI skipped commit once the current CI run finishes, since removing the comment is a non-functional change and is not worth rerunning CI over.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed my mind and just squashed it into the other commit so that AV gets a chance to run now that a fix for the libgit2-online test has been merged.

@ararslan ararslan force-pushed the aa/os_underscores branch 2 times, most recently from 3864bc2 to 7114ddf Compare July 9, 2017 06:47
Copy link
Contributor

@tkelman tkelman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm if ci is clear

@ararslan
Copy link
Member Author

ararslan commented Jul 9, 2017

Both 32- and 64-bit Linux timed out. 😑 Tests passed on Windows and macOS (which in particular means @static fixed the SIGABRT issue). Should I restart the Linux builds?

@ararslan ararslan force-pushed the aa/os_underscores branch 2 times, most recently from 31e223a to 423cf04 Compare July 10, 2017 22:47
This makes them consistent with the vast majority of Base predicates,
which simply prefix with `is` rather than `is_`. It also moves to
requiring the `Sys.` prefix, which helps explain the intent behind the
function names.
@ararslan
Copy link
Member Author

32-bit Linux is a timeout, previous run passed. Merging.

@ararslan ararslan merged commit 7cb31a8 into master Jul 11, 2017
@ararslan ararslan deleted the aa/os_underscores branch July 11, 2017 18:52
jeffwong pushed a commit to jeffwong/julia that referenced this pull request Jul 24, 2017
This makes them consistent with the vast majority of Base predicates,
which simply prefix with `is` rather than `is_`. It also moves to
requiring the `Sys.` prefix, which helps explain the intent behind the
function names.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:deprecation This change introduces or involves a deprecation
Projects
None yet
Development

Successfully merging this pull request may close these issues.