4 ms·
If you like this, you're probably also going to like Haskell/OCaml/Ada/F#/Coq (ML family of languages?): I'll leave links for Haskell since the only one of tho
by hardwaresofton 9y ago
If you like this, you're probably also going to like Haskell/OCaml/Ada/F#/Coq (ML family of languages?):
I'll leave links for Haskell since the only one of those I've tried and liked personally:
https://www.haskell.org/ https://www.haskell.org/
http://learnyouahaskell.com/ http://learnyouahaskell.com/
IMO Haskell is the type system you wanted Java to have, with even more strictness. While it's possible to write unsafe haskell, just about everything you will read, and the language itself encourages you to push as many worries as you can to be solved by the type system.
If that doesn't get you excited, there's actually a saying that is mostly true in my experience writing Haskell -- "If it compiles, it works"(tm).
Also Haskell on the JVM if you want to dip your toes in:
- https://eta-lang.org/ https://eta-lang.org/
- https://github.com/Frege/frege https://github.com/Frege/frege
[EDIT] - If you try to learn haskell you'll inevitably run into the M word which rhymes with Gonad. The best guide I've ever read is @ http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html http://adit.io/posts/2013-04-17-functors,_applicatives,_and_...
BTW, be ye warned: when you start understanding/getting cozy with the concepts introduced by Haskell you'll wish they were everywhere, and they're not. Languages without proper union types will look dumb to you, easy function composition/points free style will be a daily desire, and monadic composition of a bunch of functions will be frustratingly absent/ugly in other languages, not doing errors-as-values will look ironically error-prone.
[EDIT 2] - More relevant to the actual post, how you would do this in Haskell is using the `type` keyword (type aliasing, e.g. `type Email = String`) or the `newtype` keyword, which creates a new type that is basically identical (what the article talks about). Here's some discussion on newtype:
- http://degoes.net/articles/newtypes-suck http://degoes.net/articles/newtypes-suck (this article is good, it describes the premise, promise, shortcomings, and workarounds, forgive the clickbaity title)
- https://www.reddit.com/r/haskell/comments/4jnwjg/why_use_newtype/ https://www.reddit.com/r/haskell/comments/4jnwjg/why_use_new...
- Silhouette 9y agoAlthough Haskell has a relatively powerful and useful type system, you are perhaps being a little kind to it here. Haskell also has partial functions, including quite a few dangerous examples in the standard library, various mechanisms to escape the type system entirely, and 27 different ways to handle errors, 28 of which look a bit like exceptions but need handling in 29 different ways. And it still can't handle basic record types very elegantly, nor dependent types such as fixed-size arrays/matrices. Haskell's type system does have a lot going for it and it also makes a useful laboratory for experiments with type-based techniques, but as far as safety goes it has never really lived up to the hype, and for all its advanced magic, it is surprisingly lacking in support for some basic features that are widely available in other languages.
- hardwaresofton 9y agoYou are absolutely right -- there are other ML-family languages that do a better job at avoiding some of the pitfalls (but surely with other tradeoffs). Most of the stuff you've mentioned is actively recognized by the Haskell community and has been somewhat improved: > Haskell also has partial functions, including quite a few dangerous examples in the standard library, Partial functions -> https://wiki.haskell.org/Avoiding_partial_functions https://wiki.haskell.org/Avoiding_partial_functions (introduces the safe library @ https://hackage.haskell.org/package/safe https://hackage.haskell.org/package/safe) > various mechanisms to escape the type system entirely Type systems are leaky abstractions. While that's just a random assertion with no fact to back it up, I think it is a good idea design wise to account for that possibility, and give people the ability to completely bin the type system when they need to. Most of that stuff is marked with some wording that strongly suggests against use, but does not prohibit (e.g. unsafePerformIO) > 27 different ways to handle errors Could you elaborate? I understand this is hyperbole, but I feel like the number in actuality is <= 3... which might make your statement ~90% hyperbole, which is a bit much. > still can't handle basic record types very elegantly Compared to which language? Records in Haskell are indeed a PITA to get values out of when they're deeply nested, and you have to destructure or string to gether the accessor functions or something, but I still like it more than other languages which take a looser approach, often leading to runtime errors. If I do a obj.something.somethingElse, that line might blow up at runtime, but in Haskell I have some guarantees/checking that it won't. C#'s `?.` operator is pretty good for accessors when dealing with nullable values as well. The lens library helps with that, but though it's simple in function, the mathematics around it that are often introduced at the same time complicate things. > nor dependent types https://www.reddit.com/r/haskell/comments/8cp2zg/whats_the_status_on_dependent_types_in_ghc_as_of/ https://www.reddit.com/r/haskell/comments/8cp2zg/whats_the_s... > laboratory for experiments with type-based techniques Haskell is less of a laboratory these days, people are actually using it for production stuff now, and they can't change core pieces of the languages so quickly -- I'm sure people would love to go back and eliminate partial functions from the standard library where reasonable. Languages like Ada might be better for experimental type stuff? > never really lived up to the hype Compared to what? Would you consider Haskell better for type safety than say Java/C#? Because I certainly do (I'd love to be proven wrong as well). I assume you meant the features you noted above as missing (easy record types, coherent error handling, lack of partial functions) in Haskell but widely available in other languages -- could you note which ones you had in mind? Java is what I've seen used most in enterprise and every function is basically a huge walking partial function -- Haskell's type system (at the very least) seems like a huge step up there. Things got better with 1.8 and the introduction of Optional (and are probably even better these days) but back when I wrote a lot of Java, it didn't seem right to 'poison' all the code with Optional<>s everywhere... Now I know better, I wasn't poisioning the code, I was writing better code but couldn't recognize it at the time. Contrast this with Java that waited until 1.8 for functions as a first class object.
- YouAreGreat 9y ago> points free style will be a daily desire Not...really.
- mic47 9y agoThat is why they call it pointless style sometimes. Point free is good for short functions, like 1-3 compositions is fine (maybe little more), but if you overuse it, it's actually much less flexible and you have to rewrite more code if you want to change something. "Point-free style can (clearly) lead to Obfuscation when used unwisely. As higher-order functions are chained together, it can become harder to mentally infer the types of expressions. The mental cues to an expression's type (explicit function arguments, and the number of arguments) go missing. Point-free style often times leads to code which is difficult to modify. A function written in a pointfree style may have to be radically changed to make minor changes in functionality. This is because the function becomes more complicated than a composition of lambdas and other functions, and compositions must be changed to application for a pointful function. Perhaps these are why pointfree style is sometimes (often?) referred to as pointless style. " https://wiki.haskell.org/Pointfree https://wiki.haskell.org/Pointfree