7 ms·
Null safety is absolutely essential for me. It's 2020, why are we still having NullPointerExceptions? However I'm curious about the next frontier of safety. We'
by hardwaregeek 6y ago
Null safety is absolutely essential for me. It's 2020, why are we still having NullPointerExceptions? However I'm curious about the next frontier of safety. We've slowly added a lot of nice features around safe use of values and safe memory. I wonder what's next.
Personally I've been thinking about safe use of arrays. Arrays are such an important data structure and yet they're horribly unsafe. Every time I do index math I get that same nervousness that I used to get accessing fields in nullable data structures. I'd love for a way to verify array indices that doesn't involve too much dependent typing.
- bigyikes 6y agoI think twice about writing for loops. Functional style APIs make these kinds of mistakes way less common
- catalogia 6y agoPersonally I'm a fan of list comprehension, particularly as implemented by rackets for/list forms. I certainly don't use them for everything, sometimes a plain old map fits the circumstance better, but I find myself using for/list fairly often. And I don't think it's error prone in the same way that a traditional C-style for loop would be. https://docs.racket-lang.org/reference/for.html?q=for%2Flist#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._for%2Flist%29%29 https://docs.racket-lang.org/reference/for.html?q=for%2Flist... > (for/list ([i '(1 2 3)] [j "abc"] #:when (odd? i) [k #(#t #f)]) (list i j k)) '((1 #\a #t) (1 #\a #f) (3 #\c #t) (3 #\c #f))
- foolfoolz 6y agocollections apis have solved this. i haven’t used an array in many years
- riffraff 6y agoBut some things at the lower level still need indexes, don't they? Think of in place sort routines.
- hardwaregeek 6y agoYeah, maybe it's just my niche but I've used a lot of indices recently in my compiler. I have a bunch of tables for types, names, etc. and indices play a big role with them
- gameswithgo 6y agomap filter fold etc.
- baddox 6y agoIn my view the next nice thing to have is algebraic data types with compile-type exhaustiveness checks. I believe several languages implement null safety using a simple algebraic data type that can be “Nothing” or “Some(‘a)” where “a” is a type. The compiler can enforce that you can never access the “a” without checking for both cases: “Nothing” and “Some(‘a)”. That extends naturally to any number of types. For example, a type representing a network request can be “Loading” or “Loaded(‘data)” or “Error(‘error)” and you can’t just blindly access the data without also handling loading states and error states. I absolutely love this when doing frontend work in ReasonML, and I miss it in JavaScript. TypeScript definitely has this functionality but I’ve never felt that it was natural to use.
- blandflakes 6y agoI'd agree; if I had to guess what's most likely to become mainstream soon, it would be union types with matching (like Either or Result types). Strange that Go did the lazy thing and made the type signature a tuple, requiring you to match yourself...
- saagarjha 6y agoGo explicitly eschews more advanced features in its type system–it not being "lazy", it thinks that such things are too complicated to be in the language. Most other up-and-coming languages have chosen to include proper sum types, including Swift and Rust.
- mumblemumble 6y ago> it thinks that such things are too complicated to be in the language. Yep. Though, there are two ways to interpret that statement. One of the things that has always slightly annoyed me about Go's messaging is that it conflates "complicated for the language's implementers" and "complicated for the language's users." To the point where it sometimes verges on being a sort of mild gaslighting.
- 6y ago
- johnfn 6y agoI think the next frontier is things like Rust. I've griped about Rust in the past but I do think that the borrow checker often feels like I'm coding in the future - it understands my code on a much deeper level than any other statically typed language I've used. I definitely agree with your feelings around array indices. I feel the same nervousness every time I do a slice or count backwards from the end of an array. I'm not really sure what the fix would be here, until I can just tell the computer what I want it to do, though...
- RivieraKid 6y agoBut the advantage of that doesn't apply in garbage collected languages, right?
- johnfn 6y agoActually, I wouldn't say so. e.g. Rust verifies that only one copy of my data is mutable at any one time. This is actually the kind of thing you'd always want to verify, even with a GC, because having two (say) classes that could mutate the same data instance could become a huge mess. e.g. even in GC'd languages there are libraries to provide immutable data structures because we understand that having multiple writers to data is a mess. The true ideal (for coding ergonomics) is exactly 1 writer, but there was no way to statically verify that.
- saagarjha 6y agoYou'd like to verify this always, but the Rust compiler is limited in that it can only verify this at compile time with proper annotations. As such, it rejects some valid programs.
- saurik 6y agoThat there will exist valid programs which will be rejected is true of all type systems, and that you need "proper annotations" is true of almost all type systems (and if this was worded only slightly more broadly, to discuss "proper structure" or something, it would again be true of all type systems); this shouldn't be considered a theoretical problem unless it accepts invalid programs (though it might be considered a practical problem if it is nearly impossible to correctly structure/annotate a program to make it accepted).
- RivieraKid 6y agoStatically typed metaprogramming. Ceylon is the only language that has that. No idea whether it's useful in real world though. Also, one feature I would love to see implemented in a modern language is this: numbers..toString() // Equivalent to numbers.map(x => x.toString())
- dunefox 6y ago> numbers..toString() // Equivalent to numbers.map(x => x.toString()) You mean something like string.(1:5) in Julia?
- RivieraKid 6y agoYes. I really like Julia but I wish there was language that had all of the advantages of Julia but none of the drawbacks (for me it's lack of static typing, function(object) vs the more readable object.function(), 1-based indexing).
- dunefox 6y agoThe indexing really isn't a problem in practice after a while. function(object) isn't just a readability thing, it's due to multiple dispatch which is ingenious. Lack of static typing, well... yeah.
- RivieraKid 6y agoMost of the problems I've seen that multiple dispatch solves can be solved with extensions.
- dunefox 6y agoAnd everything can be implemented in assembly, that doesn't mean that there aren't superior alternatives.
- cygx 6y agoAlso, one feature I would love to see implemented in a modern language [...] In Raku (the language formerly known as Perl6), that is spelled numbers>>.toString() or using proper idioms @numbers>>.Str