I'm not fully convinced. FP is such a different paradigm than the leading imperative/OO design that most are comfortable with. Other languages that are too different like lisp, forth, Apl, Haskell, and Prolog are just too different for the average person IMO. I've given Haskell/OCaml/F# a go a few times and enjoy learning new paradigms and it certainly didn't click for me. I have a feeling it'll be even harder with more normal people not into this as a hobby.
Here is how to read a text file in Haskell (I assume a standard way):
I could be biased, but it certainly seems like Python has a lot less conceptual hurdles here. You basically specify a filepath and then for loop through each line and print. The Haskell solution requires more steps and theory.
I know Haskell is a very awesome and cool language and super powerful for all kinds of uses that Python may be inferior at (example compilers). You'll get no argument there. I'm just pointing out that I think wide adoption may be difficult. I drank the koolaid and read dozens of blog posts and a couple of Haskell books and really wanted to make it work. I'm an engineer and like math and puzzles and learning new programming languages...and yet I couldn't make it that far (without sinking a whole lot more time into it than I had) and ultimately gave up.
It's not really that Haskell is "powerful", but the type system will catch a lot of errors for you and make refactoring much easier.
Also, I wouldn't recommend starting FP with Haskell. It's hard, mostly because of the monads (and laziness can make things more confusing too). Also the syntax which is confusing because indentation is meaningful in some places, but not others.
On the other hand, a language like Scheme is really super easy. Even OCaml is super simple if you stick to the classic ML subset of the language which can take you a very long way. These languages have been using to teach programming to complete beginners. Seriously, OCaml is arguably simpler than Python, and without doubt order of magnitude simpler than C++.
If you're familiar with things like lambda, closures and functions like map or filter in Python, you already know most of what you need to write OCaml code.
> FP is such a different paradigm than the leading imperative/OO design that most are comfortable with.
I don't think most of FP is at all hard for most programmers to understand. Hell I interviewed plenty of Javascript devs that couldn't solve a simple fizzbuzz level question because they didn't know how to do for loops - they only knew how to use `.forEach()`!
The hard bits in Haskell are:
1. Purity. I get it, but it definitely makes things harder.
2. Weird syntax: pervasive currying / single argument functions / lack of grouping syntax / waaaay too many operators, etc. E.g. from your link:
let singlewords = words contents
list = f singlewords
This is just a collection of words. No clue of what is a function call, what is a variable name, etc. Allow me to recreate the experience of reading Haskell, if you think the above is reasonable:
file read lines put
lines iter while cbr empty
for do <~> x IO::print
3. General unfriendliness to people who aren't hardcore Haskellers. E.g. suppose I want to match a regex. In Go, Python, Rust, Javascript, etc. there's one obvious way to do it. Haskell? How about you pick between 8 alternatives... https://wiki.haskell.org/index.php?title=Regular_expressions
There are other flaws, like global type inference & lazy IO, but I think those are the main ones.
Haskell doesn't have operators, it's based on expressions consisting of function compositions, some of which can be infix and look like operators.
> This is just a collection of words. No clue of what is a function call, what is a variable name, etc.
That's by design, because all of them are expressions that can either reduce immediately or require runtime data to reduce fully.
> How about you pick between 8 alternatives...
How about you pick either of those and start using for real, and then come to the point it either works well or you find inefficiencies to look specific alternatives for? It doesn't take much.
The Haskell version parses the contents of the file. One answer also explains how to lazily read the file to process it as it's read, using the ByteString package. I think part of the overhead here is due to this lazy processing, plus the fact that there are basically 3 String in Haskell: String, ByteString and Text.
The python version simply loads the whole file into memory. The equivalent Haskell would be to call Data.Text.IO.readFile. What would the python version of the lazy parsing / processing of a file look like ?
There were several Python versions shown at the link and the latter one that I was referring to does not read it all into memory. It loops through each line in only three lines of code, not like 1/4 of a page.
I tried just pasting the code into the window, but never learned how to format HN on mobile. Sorry for the confusion. After the colon there are indents, so 3 separate lines.
with open('testfile.txt') as f:
for line in f:
print(line.strip())
I think Haskell seems harder because it's built on another set of abstractions (laziness, typeclasses) where Python abstractions (iterators in this case, plus the with statement for resource acquisition/cleanup) are more common, but I could be wrong (I've been working with Scala for close to a decade now so functional style looks more familiar that imperative now.)
if you want the oop style you can just change "foo bar baz" to "bar `foo` baz" which is effectively the same thing as doing bar.foo(baz), because for some reason people are obsessed with passing an argument by putting a dot after it.
> The Haskell solution requires more steps and theory.
Really? The suggested Haskell solution is
main = do
contents <- readFile "test.txt"
print . map readInt . words $ contents
which is no more complex than the Python code. The entire file contents is read as a String into content. words breaks it into a list of words, and readInt parses each word into an Int. Finally the list of ints is printed.
yes, it looks all good, until you want to change it. For instance, to make the file name a CLI parameter, you need to understand things like type classes, specifically Monad, Functor and Applicative. You may need a long time to be at ease with these things and a superficial understanding will not take you very far. In Python, it'll take you a few minutes to do the same thing.
What do you mean by "long time"? Why wouldn't it apply just the same to some Python file that defines a Maybe with a bit of unwrap and bind and orElse or whatever?
Instead of things going boom and spewing a stack sometimes they just go Nothing instead, you don't need much more understanding than that. There is a lot of syntax in Haskell that is somewhat hard to understand at first but you don't actually need it to write stuff yourself.
This idea that you need to talk a particular way and be able to teach CS theory at uni and whatnot to build stuff in Haskell is probably not very healthy.
Long time, I mean possibly several weeks of full-time studying for an intermediate Python or C++ programmer.
I'm not saying you need any CS theory to write Haskell or that it's super hard. But I think the learning curve is pretty steep, and it's hard to write code without a good understanding of the concepts. Just tweaking until it type checks isn't going to cut it.
Consider this code. Generated from ChatGPT. This is supposed to be a simple command line option parsing. I don't think it's obvious what all the operators mean.
Sure, you can try to reuse this, and extend it. But I think sooner than later you'll be stuck with some undecipherable error messages and you'll have to sit down and understand what it all means.
data Options = Options
{ optVerbose :: Bool
, optInput :: String
} deriving Show
optionsParser :: Parser Options
optionsParser = Options
<$> switch
( long "verbose"
<> short 'v'
<> help "Enable verbose mode" )
<\*> strOption
( long "input"
<> short 'i'
<> metavar "FILENAME"
<> help "Input file name" )
This is a really good point. I have coworkers that don't really code, but can use ChatGPT to help them put together a Python app that does what they need with some common sense changes. I don't think I could even do the same with Haskell with a fair amount of coding experience+ reading up a lot on Haskell over the years. It may be obvious to those select few who are drawn to Haskell, but I think they greatly underestimate the challenges for the average person. That's the essence of what I've been saying to the parent thread that believes a subset of Haskell will become popular some day. I could be wrong, but just can't see it.
It is obvious, as long as you know what Functors and Semigroups for custom data types are. If you don't know it, you can still use it freely without fully understanding the meaning of `<>` and `<$>`, because they are written almost as plain bullet points of components to treat as a single whole.
I'd say a lot more is going on there conceptually than the Python code. Imagine through the eyes of a beginner. You have some main do thing, then you appear to read it all into memory and assign a variable, then you do a bunch of composition to words and readInt and map it to print?
With the python version, you see the file handle as a variable and then for loop on that iterable and you can print each line or parse it however you want. Even when I was learning to program and had no clue what an iterable object was, there seemed to be an obvious three line idiom for processing text files that was easy to use.
I think the issue that many people have with Haskell is the order of expression evaluation is not structured left-to-right and top-to-bottom. At least it's what makes it difficult to read Haskell for me. Compare it with F# (and OCaml family in general):
open System.IO
(File.ReadAllText "text.txt").Split()
|> Seq.map int
|> Seq.iter (printfn "%d")
It doesn't really matter on simple expressions but as you keep chaining the operations the reverse order gets more difficult to follow.
Here is how to read a text file in Haskell (I assume a standard way):
https://stackoverflow.com/questions/7867723/haskell-file-rea...
From a Python tutorial:
https://www.pythontutorial.net/python-basics/python-read-tex...
I could be biased, but it certainly seems like Python has a lot less conceptual hurdles here. You basically specify a filepath and then for loop through each line and print. The Haskell solution requires more steps and theory.
I know Haskell is a very awesome and cool language and super powerful for all kinds of uses that Python may be inferior at (example compilers). You'll get no argument there. I'm just pointing out that I think wide adoption may be difficult. I drank the koolaid and read dozens of blog posts and a couple of Haskell books and really wanted to make it work. I'm an engineer and like math and puzzles and learning new programming languages...and yet I couldn't make it that far (without sinking a whole lot more time into it than I had) and ultimately gave up.