digitalmars.D - Predefined Versions for Apple Operating Systems
- Walter Bright (29/29) Jun 21 Currently, the following predefined versions exist for Apple operating s...
- Richard (Rikki) Andrew Cattermole (5/43) Jun 21 Darwin is still relevant:
- Walter Bright (6/11) Jun 21 When I googled which was preferable, __APPLE__ was the preferred identif...
- Sergey (5/11) Jun 21 Darwin is still widely used:
- Walter Bright (2/15) Jun 21 __APPLE__ is used by ImportC, as that's what I found in the OSX system ....
- Walter Bright (1/1) Jun 21 Hmm, the formatter removed the underscores from `__APPLE__`
- Jonathan M Davis (36/65) Jun 21 At the end of the day, I don't care enough to fight over this issue, but
- Walter Bright (9/9) Jun 21 Lots of good points, Jonathan.
- Jonathan M Davis (20/29) Jun 21 It would be nice.
- Walter Bright (2/4) Jun 21 I wouldn't inflict that on you!
- Luna (7/18) Jun 22 I’d propose 2 predefined versions;
- Hipreme (3/12) Jun 22 I like Luna's Solution. I already use `AppleOS` in my engine as
- Sergey (62/66) Jun 22 Maybe in that case we can fix all other versions as well..
- Walter Bright (3/3) Jun 22 Unfortunately, due to the needs of legacy compatibility, one winds up wi...
- Quirin Schroll (23/32) Jun 26 A different approach could be to special-case version identifiers
- Walter Bright (4/5) Jun 26 predefines.
- xoxo (19/25) Jun 26 Most of the time, following C is a mistake, but in most cases,
- Ogi (25/29) Jun 28 How about a Phobos module that wraps version identifiers in a
- Walter Bright (6/6) Jun 28 I'm glad to see you use static assert to signal unsupported combinations...
- Hipreme (4/33) Jun 29 We already have quite a bit of that inside `std.system`.
- Walter Bright (2/2) Jun 22 And a PR:
Currently, the following predefined versions exist for Apple operating systems: OSX iOS TVOS WatchOS VisionOS When I look at druntime source code, I see things like: ```d version (OSX) version = Darwin; else version (iOS) version = Darwin; else version (TVOS) version = Darwin; else version (WatchOS) version = Darwin; ``` and: ```d ```d version (OSX) {} else version (iOS) {} else version (TVOS) {} else version (WatchOS) {} else: ``` appearing ad nauseam. (note the conspicuous absence of VisionOS appearing in druntime) I propose, like Windows encompassing Win32 and Win64, that __APPLE__ encompass OSX, iOS, TVOS, WatchOS, and VisionOS. __APPLE__ is already standardized in C headers for that purpose. The use of "darwin" or "Darwin" appears to be quite obsolete. This will clean up a lot of version algebra in the druntime files.
Jun 21
On 22/06/2025 8:24 AM, Walter Bright wrote:Currently, the following predefined versions exist for Apple operating systems: OSX iOS TVOS WatchOS VisionOS When I look at druntime source code, I see things like: ```d version (OSX) version = Darwin; else version (iOS) version = Darwin; else version (TVOS) version = Darwin; else version (WatchOS) version = Darwin; ``` and: ```d ```d version (OSX) {} else version (iOS) {} else version (TVOS) {} else version (WatchOS) {} else: ``` appearing ad nauseam. (note the conspicuous absence of VisionOS appearing in druntime) I propose, like Windows encompassing Win32 and Win64, that __APPLE__ encompass OSX, iOS, TVOS, WatchOS, and VisionOS. __APPLE__ is already standardized in C headers for that purpose. The use of "darwin" or "Darwin" appears to be quite obsolete. This will clean up a lot of version algebra in the druntime files.Darwin is still relevant: https://en.wikipedia.org/wiki/Darwin_(operating_system) It encompasses all those Apple OS's according to Wikipedia, and its already in place.
Jun 21
On 6/21/2025 1:28 PM, Richard (Rikki) Andrew Cattermole wrote:Darwin is still relevant: https://en.wikipedia.org/wiki/Darwin_(operating_system) It encompasses all those Apple OS's according to Wikipedia, and its already in place.When I googled which was preferable, __APPLE__ was the preferred identifier for OSX and newer. We don't support earlier systems than OSX. https://sourceforge.net/p/predef/wiki/OperatingSystems/ Darwin also suffers from multiple incantations: darwin Darwin __DARWIN__ DARWIN __MACH__
Jun 21
On Saturday, 21 June 2025 at 21:26:08 UTC, Walter Bright wrote:On 6/21/2025 1:28 PM, Richard (Rikki) Andrew Cattermole wrote:Darwin is still widely used: https://doc.rust-lang.org/beta/std/os/darwin/index.html https://go.dev/wiki/Darwin https://github.com/ziglang/zig/blob/master/lib/std/c/darwin.zigDarwin is still relevant: https://en.wikipedia.org/wiki/Darwin_(operating_system)Darwin also suffers from multiple incantations: darwin Darwin __DARWIN__ DARWIN __MACH__
Jun 21
On 6/21/2025 2:45 PM, Sergey wrote:On Saturday, 21 June 2025 at 21:26:08 UTC, Walter Bright wrote:__APPLE__ is used by ImportC, as that's what I found in the OSX system .h files.On 6/21/2025 1:28 PM, Richard (Rikki) Andrew Cattermole wrote:Darwin is still widely used: https://doc.rust-lang.org/beta/std/os/darwin/index.html https://go.dev/wiki/Darwin https://github.com/ziglang/zig/blob/master/lib/std/c/darwin.zigDarwin is still relevant: https://en.wikipedia.org/wiki/Darwin_(operating_system)Darwin also suffers from multiple incantations: darwin Darwin __DARWIN__ DARWIN __MACH__
Jun 21
Hmm, the formatter removed the underscores from `__APPLE__`
Jun 21
On Saturday, June 21, 2025 2:24:34 PM Mountain Daylight Time Walter Bright via Digitalmars-d wrote:Currently, the following predefined versions exist for Apple operating systems: OSX iOS TVOS WatchOS VisionOS When I look at druntime source code, I see things like: ```d version (OSX) version = Darwin; else version (iOS) version = Darwin; else version (TVOS) version = Darwin; else version (WatchOS) version = Darwin; ``` and: ```d ```d version (OSX) {} else version (iOS) {} else version (TVOS) {} else version (WatchOS) {} else: ``` appearing ad nauseam. (note the conspicuous absence of VisionOS appearing in druntime) I propose, like Windows encompassing Win32 and Win64, that __APPLE__ encompass OSX, iOS, TVOS, WatchOS, and VisionOS. __APPLE__ is already standardized in C headers for that purpose. The use of "darwin" or "Darwin" appears to be quite obsolete. This will clean up a lot of version algebra in the druntime files.At the end of the day, I don't care enough to fight over this issue, but IMHO, the fact that the version identifiers try to follow C #defines has been a cause of bugs and that it was a mistake to ever try that over simply using our own consistent naming scheme - in particular, the fact that linux is lowercase when the other OSes typically start with an uppercase later has been problematic. And since you don't get an error if you mistype the identifier (at least not if having code not versioned in doesn't create a compiler error), it's often easy to miss the mistake (especially with bindings that don't always have tests associated with them). So, personally, I think that naming it `__APPLE__` is a bad idea and that if we want something like that, it should just be something like Apple or AppleOS. Though honestly, if we were redoing all version identifiers, I'd be tempted to argue that they should just all be required to be lowercase so that we had fewer bugs due to typos and less confusion over casing. It's not a problem with identifiers in general, because you get errors if you get those wrong, but the fact that we can't do that with version identifiers makes the inconsistencies in their names error-prone. On the other hand, if we were redoing them, maybe it would be better to just make them all of the predefined ones start with `__` so that any that start with `__` but aren't known are an error, significantly reducing the bugs related to mistyping version identifers - not that that would entirely fix the problem, since someone could still forget a `_` and make it look like a user-defined one (and of course, we can't fix the problem with user-defined ones unless we do something like require that a list of all valid version identifiers be provided somehow). In any case, the version identifiers are already a bug-prone mess, so maybe it doesn't matter if we use `__APPLE__` instead of something like Apple or AppleOS, but the naming inconsistencies that we already have have been causing bugs for years when a more consistent naming scheme would have at least reduced the problem. As for Darwin or whether we need `__APPLE__` (or whatever we call it) as a replacement, well, I'm not familiar enough with Apple's OSes to weigh in on that. - Jonathan M Davis
Jun 21
Lots of good points, Jonathan. The current situation for C #defines for operating systems is an utter disaster. I can find zero official guidance from Apple on what to use. People have remarked that I was denigrating Linux by using lowercase "linux" as the version, but nothing of the sort was my intention. It was simply that "linux" was the most commonly used predefine in the Linux world. Maybe we should simply go with "Apple" as the umbrella for the various Apple operating systems, and be done with it. Maybe we can set a positive trend there! Wouldn't that be nice!
Jun 21
On Saturday, June 21, 2025 9:40:44 PM Mountain Daylight Time Walter Bright via Digitalmars-d wrote:Lots of good points, Jonathan. The current situation for C #defines for operating systems is an utter disaster. I can find zero official guidance from Apple on what to use. People have remarked that I was denigrating Linux by using lowercase "linux" as the version, but nothing of the sort was my intention. It was simply that "linux" was the most commonly used predefine in the Linux world. Maybe we should simply go with "Apple" as the umbrella for the various Apple operating systems, and be done with it. Maybe we can set a positive trend there! Wouldn't that be nice!It would be nice. And now that I think of it, much as having multiple names for the same thing is usually a bad idea, maybe we should consider adding the Linux version identifier as an alternate spelling for linux? That would increase confusion, because folks would wonder about the difference (which is a big part of why having duplicate names is usually a bad idea), but it seems like folks screw that one up a lot. I don't know. It's just a thought. In any case, I was aware of your reasoning for why you made it linux and not the past has been problematic - and thus why I think that we should just pick a reasonable name for this new one based on our naming conventions (especially when the C ones are all over the place). LOL. Either way, as a non-Mac person, it would be nice if what needed to be done with version identifiers were clear. There are a ton of them, and I'd thought that Darwin was supposed to be the one to combine them all where possible, but then folks were talking like it wasn't a thing anymore, and it's all quite confusing. I guess that it's yet one more thing that I should arguably pay more attention to... - Jonathan M Davis
Jun 21
On 6/21/2025 9:16 PM, Jonathan M Davis wrote:I guess that it's yet one more thing that I should arguably pay more attention to...I wouldn't inflict that on you!
Jun 21
On Sunday, 22 June 2025 at 03:40:44 UTC, Walter Bright wrote:Lots of good points, Jonathan. The current situation for C #defines for operating systems is an utter disaster. I can find zero official guidance from Apple on what to use. People have remarked that I was denigrating Linux by using lowercase "linux" as the version, but nothing of the sort was my intention. It was simply that "linux" was the most commonly used predefine in the Linux world. Maybe we should simply go with "Apple" as the umbrella for the various Apple operating systems, and be done with it. Maybe we can set a positive trend there! Wouldn't that be nice!I’d propose 2 predefined versions; 'AppleOS` for all Darwin/mach derived apple OSes 'AppleMobileOS` for all apple OSes that use the mobile set of APIs (there’s different APIs between the mobile and desktop APIs) This would make it easier to write software that targets both desktop and mobile Apple OSes.
Jun 22
On Sunday, 22 June 2025 at 14:25:37 UTC, Luna wrote:On Sunday, 22 June 2025 at 03:40:44 UTC, Walter Bright wrote:I like Luna's Solution. I already use `AppleOS` in my engine as well for handling that same issue.[...]I’d propose 2 predefined versions; 'AppleOS` for all Darwin/mach derived apple OSes 'AppleMobileOS` for all apple OSes that use the mobile set of APIs (there’s different APIs between the mobile and desktop APIs) This would make it easier to write software that targets both desktop and mobile Apple OSes.
Jun 22
On Sunday, 22 June 2025 at 00:44:42 UTC, Jonathan M Davis wrote:As for Darwin or whether we need `__APPLE__` (or whatever we call it) as a replacement, well, I'm not familiar enough with Apple's OSes to weigh in on that. - Jonathan M DavisMaybe in that case we can fix all other versions as well.. And just some examples from other langs (from gpt) ```rust use std::env; fn main() { let os = if cfg!(target_os = "linux") { "linux" } else if cfg!(target_os = "macos") { "macos (Darwin)" } else if cfg!(target_os = "ios") { "ios (Darwin)" } else if cfg!(target_os = "windows") { "windows" } else { "unknown" }; println!("Running on: {}", os); } ``` Rust: all small letters - consistent ```swift import Foundation func getOSName() -> String { #if os(Linux) return "linux" #elseif os(macOS) return "macos (Darwin)" #elseif os(iOS) return "ios (Darwin)" #else return "unknown" #endif } print("Running on: \(getOSName())") ``` Swift: playing with all proper names (see Linux with capital) ```go package main import ( "fmt" "runtime" ) func main() { os := runtime.GOOS var osName string switch os { case "linux": osName = "linux" case "ios": osName = "darwin (iOS)" case "darwin": osName = "darwin (macOS)" default: osName = "unknown" } fmt.Printf("Running on: %s\n", osName) } ``` Go: all small letters as well ("ios" support is a bit cumbersome though) Consistency everywhere
Jun 22
Unfortunately, due to the needs of legacy compatibility, one winds up with multiple ways to express the same thing. Then we wind up with Apple's conundrum with Darwin, darwin, DARWIN, `__DARWIN__`, `__APPLE__`, `__MACH__`, etc.
Jun 22
On Sunday, 22 June 2025 at 00:44:42 UTC, Jonathan M Davis wrote:[I]f we were redoing them, maybe it would be better to just make them all of the predefined ones start with `__` so that any that start with `__` but aren't known are an error, significantly reducing the bugs related to mistyping version identifers - not that that would entirely fix the problem, since someone could still forget a `_` and make it look like a user-defined one (and of course, we can't fix the problem with user-defined ones unless we do something like require that a list of all valid version identifiers be provided somehow).A different approach could be to special-case version identifiers and require them to be ASCII-only and partially case-insensitive. The latter means that `X` and `x` are considered essentially the same, but only one of them is correct and defining it makes using the other an error. That means the built-in ones `linux`, `Windows`, `iOS`, etc., make it an error to use `Linux`, `windows`, or `IOS`. The error message can tell you what the correct spelling is. There’s no use case for the same identifier with different casing. I’d also ban version user-defined version identifiers with upper-case letters and reserve them for the language. Maybe also change all the built-in ones to include an upper case letter. It’s a breaking change, but one that can be mitigated by search and replace. ```d version(Linux) {} // error: Use `linux` version(OSx) {} // error: Use `OSX` version(Win) {} // error: `Win` is not a built-in version identifier version(win) {} // okay ```
Jun 26
I'd never thought of that, I was just following normal C practice with thepredefines. Your idea is a good one, but I think it's a bit too late. I'm concerned about the disruption it could cause. People with a lot of code just don't care for even simple changes like search/replace. We've inflicted enough of that.
Jun 26
On Thursday, 26 June 2025 at 17:03:33 UTC, Walter Bright wrote:Most of the time, following C is a mistake, but in most cases, it's okay (simplicity & efficiency). It is obvious that following C is incorrect when it comes to OS predefines. In my view, `version (OS)` was a mistake. 1. Not type safe 2. Inconsistent 3. Prone to mistakes D needs secure built-ins that are type-checked at COMPILE time. ``` static if (builtin.OS.tag == $Linux) {} `` The benefit of using $ is that it eliminates the need to enforce an import, prevents internal modules from being revealed, or just eliminates the need to use the unsafe `version`. By default, the most compelling and user-friendly code should be the most secure. It should be annoying to use something unsafe.I'd never thought of that, I was just following normal Cpractice with the predefines. Your idea is a good one, but I think it's a bit too late. I'm concerned about the disruption it could cause. People with a lot of code just don't care for even simple changes like search/replace. We've inflicted enough of that.
Jun 26
On Thursday, 26 June 2025 at 17:03:33 UTC, Walter Bright wrote:Your idea is a good one, but I think it's a bit too late. I'm concerned about the disruption it could cause. People with a lot of code just don't care for even simple changes like search/replace. We've inflicted enough of that.How about a Phobos module that wraps version identifiers in a type-safe manner? Draft: https://gist.github.com/Ogi-kun/3946759f86ef03ba59dacc81cd6e63e6 ```D import std.config; static if (isPosix) { /*...*/ } else static if (platform == Platform.windows) { /*...*/ } else static assert(0, "Unsupported platform"); static if (arch == Arch.x86) { static if (pointerWidth == P64) { /*...*/ } else static if (pointerWidth == P32) { /*...*/ } else static assert(0, "This CPU does not exist"); } else static assert(0, "Unsupported architecture"); ```
Jun 28
I'm glad to see you use static assert to signal unsupported combinations, rather than falling into the trap of "what does the default do"! There was an attempt a few years back to replace versions with `static if(Expression)`, as then version algebra could be used in druntime. It got overly complicated and had chicken-and-egg problems. I replaced it with versions.
Jun 28
On Saturday, 28 June 2025 at 12:04:36 UTC, Ogi wrote:On Thursday, 26 June 2025 at 17:03:33 UTC, Walter Bright wrote:We already have quite a bit of that inside `std.system`. You can get the operating system and architecture the user is in by using `std.system.os` and instructionSetArchitectureYour idea is a good one, but I think it's a bit too late. I'm concerned about the disruption it could cause. People with a lot of code just don't care for even simple changes like search/replace. We've inflicted enough of that.How about a Phobos module that wraps version identifiers in a type-safe manner? Draft: https://gist.github.com/Ogi-kun/3946759f86ef03ba59dacc81cd6e63e6 ```D import std.config; static if (isPosix) { /*...*/ } else static if (platform == Platform.windows) { /*...*/ } else static assert(0, "Unsupported platform"); static if (arch == Arch.x86) { static if (pointerWidth == P64) { /*...*/ } else static if (pointerWidth == P32) { /*...*/ } else static assert(0, "This CPU does not exist"); } else static assert(0, "Unsupported architecture"); ```
Jun 29
And a PR: https://github.com/dlang/dmd/pull/21471
Jun 22