Enum types
Having enum types would allow for stronger type checking.
Before:
// th.um
type Platform* = int
const (
PlatformUnknown* = 0
PlatformLinux*
PlatformWindows*
PlatformMacOs*
PlatformWeb*
)
// main.um
import "th.um"
fn foo(p: th.Platform) {}
fn main() {
foo(th.Platform.Linux) // OK
foo(th.white) // OK
}
After:
// th.um
type Platform* = enum { // With optional base type, such as enum(int) or enum(uint8)
Unknown
Linux
Windows
MacOs
Web
}
// main.um
import "th.um"
fn foo(p: th.Platform) {}
fn main() {
foo(th.Platform.Linux) // OK
foo(th.white) // Error
}
I still think this might be extra, I do this to enforce type checking.
type Platform = int;
const (
Unknown = Platform(0)
Linux = Platform(1)
Windows = Platform(2)
MacOs = Platform(3)
Web = Platform(4)
)
fn foo(p: Platform) {}
fn main() {
foo(Linux) // OK
foo(th.white) // Error
}
The only difference here is that the enum isn't finite, so anyone can construct it, however it can be prevented if the type is private and all in one module.
@skejeton I get no error in this case:
type Color = int
const (
white* = Color(255)
)
type Platform = int
const (
Unknown* = Platform(0)
Linux* = Platform(1)
Windows* = Platform(2)
MacOs* = Platform(3)
Web* = Platform(4)
)
fn foo(p: Platform) {
printf("%v\n", p)
}
fn main() {
foo(Linux) // 1
foo(white) // 255
}
Huh that's strange, I almost swear I checked that, since I used it in my now deleted UI rewrite: https://github.com/skejeton/save-game/blob/89a80cda6ef77c0ac87f45d582b9034b6d233b55/src/d_ui.um#L91 Maybe it's a good idea to make the type conversions strict?