-
Notifications
You must be signed in to change notification settings - Fork 50
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
Value of null
?
#111
Comments
I'd like to incrementally move away from nullable types, perhaps introducing In Virgil, functions can be
|
Yeah. In my subjective experience with Rust, it can litter the code with
Feels like |
Though Virgil already has a lot of:
which would be cleaned up by the The major way I've seen |
One possible migration path would be to introduce the option type constructor first, while keeping the nullability of class and array types as it is now. The option type constructor applied to type For syntax, I like postfix Overall, this kind of change requires the compiler to support the union of the old language behavior and the new language behavior, selectable with a command-line flag. (Similar to how I did the To support the union of behaviors I would first introduce non-nullable types in the compiler's representation of Virgil types. They wouldn't necessarily have a source syntax, but it would allow working on the verifier rules. Thus the verifier could be incrementally migrated to generate errors, enabled by the command-line flag. |
Yes that makes sense to me. What do you imagine the semantics of a nullable type are? For the sake of argument, let's take a user defined type
In Rust, you can't access the internal type Also, semantics-wise, it'd be good to have predefined functions on every nullable type such as Rust optimizes While we're here, how does Virgil want to support errors/exception handling? The Rust (or sort of functional) style with the fn some_function() -> Result<f64, Err> {
let f = some_other_function()?;
// use f
} is equivalent to fn some_function() -> Result<f64, Err> {
let f = match some_other_function() {
Ok(f) => f;
Err(e) => return Err(e);
};
// use f
} If the goal is to have explicit error propagation like with a |
I think an error for accessing fields or calling methods on a nullable type would be in order. (Otherwise, what's the point, ja?)
I think I like some shorthands for either forcing a nullcheck (with The expression
Sure, you could just use
Yeah, I want to generally upgrade the middle of the compiler to represent ADTs more efficiently, so it's effectively like using a tag bit for non-reference types and just using a null pointer for reference types.
No on using Java-style exceptions, so more in the style of encoding errors into return types (sometimes as ADTs). It turns out I sometimes end up encoding errors as configurable behavior on an object, like how
I can see the value of having an explicit kind of error-propagating type, so if there was a way to integrate that in a more Virgilistic way (I avoid build too many named types, particularly capitalized named types), that'd be neat. |
Haha yes of course. I meant more about the syntax and UX, I guess.
I think ideally it's the same syntax for accessing a field and a method like how Kotlin does it.
Exactly yeah. Just better to have semantic/descriptive function names in my personal subjective opinion.
Ah right -- I just realized that yeah Virgil does not have built-in types that start with a capital letter other than Could do something like an |
Yes, I am trying to keep a very strict separation between what is a library and what is in the language, and language types looking like library types can cause some confusion.
Perhaps. One thing about errors that I have dealt with a lot recently is that the error cases basically have arguments, such as which file or line number they occurred at, etc. There is some application-level data that might be programmatically attached and useful. |
Right. But these fields can be transparently inserted by the compiler at compilation time without the user having to specify them (well I don't know if it's specifically easy to do in Virgil, but it is theoretically possible at least). Unless you imagine exposing these fields (i.e. file name, line number) to the programmer? I don't immediately see how it's useful or relevant, since generally something like an enum with a field (describing the error) is good enough for the programmer to report errors. |
We could do something like:
or some other similar syntax for returning errors. Here Though maybe this discussion should be moved to a separate GitHub issue. |
Having been programming in Rust for the last couple of years, I will say the one feature I'd like to import from Rust into Virgil is that references aren't allowed to be
null
, i.e. they have to be theOption
(orResult
) type. I quite like this as the type system forces you to check a potentially nullable reference at compile time and you avoid the nasty!NullPointerException
errors (and yes -- I know many languages have had this for ages, but Rust was my first serious exposure to this). Virgil already has support for ADTs etc., so a nativeOption
type is already possible except for the fact thatnull
still exists (as you can just set anOption
variable tonull
, which defeats the purpose ofOption
).Hence, my question is, do you think there is still value in keeping
null
? I think it'd be nicer to not havenull
, but I understand it's a very significant change to the language and will require major refactoring.The text was updated successfully, but these errors were encountered: