17 ms·
Yeah this is almost completely wrong IMHO, could you give some concrete examples of when this happened to you or someone you know? I'm writing a relatively sma
by hardwaresofton 9y ago
Yeah this is almost completely wrong IMHO, could you give some concrete examples of when this happened to you or someone you know?
I'm writing a relatively small haskell app, and though I've had large swaths of time where I had to think about the types I was writing exclusively, I almost always come out of the 30 minutes or so understanding my code, and what I'm trying to do so much better.
Forcing you to spend time thinking about type structures and their relationships is (dare I say) the essence of programming. Programming is in the end about transforming data for some useful end (and some side effects along the way), and no one wants to work with 0s and 1s directly.
Integrating with third party modules in haskell is no more painful than integrating with 3rd party modules in Java, in fact is way way way simpler, given Java's infamous verbosity and love of enterprise patterns (tm).
- grosjona 9y agoJava gets away with it because it has a very large core library which defines pretty much any type that a developer could think of. For example, there is even a standard class type for URLs which all good Java developers must agree on. All these standardized types are often unnecessarily restrictive and demand too much attention and global awareness of the environment. It's often possible to write good code without necessarily understanding everything that is happening above or below a particular unit of logic; so why force the developer to internalize all these rigid concepts?
- hardwaresofton 9y agoThe larger standard library of languages like Java is indeed a big benefit -- I think I see more where you're coming from now. Haskell does not have a large standard library like other languages, but people usually build on one or two libraries in a given problem space to avoid duplication (checking to see if someone has a lib you can use instead of writing one yourself is pretty natural). In my experience, it's been rare to find two libraries that need to interoperate that defined two different classes for URLs (for example) -- but you're absolutely right, it could be a problem. The problem would be solved if Haskell were to adopt a large standard library, but I still don't see this as a problem with types, this is more a language/community issue. Speaking more concretely, I'd consider understanding the types flowing in and out of a function/abstraction that you got from a library table stakes for writing good code. IMO it's rare that you can just import a library, write strictly glue code (without thinking about the concepts) that magically solves all your problems. For example, lets say you needed to parse a ISO 8601 date string (and it isn't in your standard library) -- in that kind of case you can just pull down a library and run one function and be done. Usually though, you'll need to at least understand the functions inputs (unless the function is defined for every kind of input you could give it), and understand the output...
- yen223 9y agoNot the OP, but I remembered writing something in Haskell, and being extremely frustrated when I chose to model something as a List.NonEmpty, because it wasn't straightforward to pass them around to functions that expected List.
- hardwaresofton 9y agoMaybe it's the stockholm syndrome talking, but this sounds like a feature to me -- The type that represents a non-empty list and one that can be empty are distinct. If a function is a mapping of inputs to outputs, then those two functions are (and should be treated as?) distinct, despite the fact that one result space is clearly the subset of another. The problem is I don't know much about the List.NonEmpty type -- it seems like it would be almost trivial to implement it while maintaining List-compatability, but clearly it's not (and was frustrating to use) so... Your point is definitely true, some things like that are very frustrating to deal with in Haskell -- especially when you expect something like that to 'just work' and it doesn't.
- Zalastax 9y agoI would not call it a feature. The clean solution would be dependent types so we can model the proposition "that list is not empty" in the type system. It is very neat to have the standard list as your data-type, but accompanying it is a proof that the list has elements. However, dependent types are not mainstream yet and we need a lot more research before that can change.
- gizmo686 9y agoHaskell does not have OOP style inheritance. If you define a new type, it is impossible to use it where you were expected a value from a concrete old type. The way around this is typeclasses, which are essentially interfaces. But this would require that the functions you are calling (which may be written by a third party) be written against a generic typeclass instead of the concrete List type. Haskell is improving in this regard, but there is still many places that are written expecting a List. Also, if the function needs any beyond simple iteration, the typeclass it would use would have a scary name like Semigroup (even iteration uses Foldable, which might not be clear to beginners) There is the IsList typeclass. But the intended use for that is to enable a list-like datatype to be represented with list literals in source code. Even with all of these difficulties, the worst case scenario is to spam your code with NonEmpty.toList and NonEmpty.fromList (or its safe sister NonEmpty.nonEmpty which returns an error value instead of throwing when given an empty list.