To try everything Brilliant has to offer-free-for a full 30 days, visit brilliant.org/GavinFreeborn . The first 200 of you will get 20% off Brilliant’s annual premium subscription.
@@olaniyanayodele5986 I started off doing code puzzles on www.codewars.com/. Looking at the top voted solutions and comparing it to my own was very helpful in learning some best practices. I have also been doing puzzles at adventofcode.com/. Now I have a couple of small hobby projects going where I'm learning to use some of the popular libraries (like megaparsec, servant, aeson) A great tutorial series here on youtube: Haskell for Imperative Programmers www.youtube.com/@philipphagenlocher I have been listening a lot to a Haskell podcast here on youtube called @HaskellWeekly. They have short episodes covering one topic per episode: www.youtube.com/@HaskellWeekly I found a couple of online books that look promising (but for me personally I learn faster by doing real projects and through youtube): book.realworldhaskell.org/read/ (The author of this one has an old but great talk here: th-cam.com/video/ZR3Jirqk6W8/w-d-xo.html) learnyouahaskell.com/chapters Let me know if you know any other good resources!
i think every programmer realizes eventually you need a very high level language like haskell and a low level one (rust, c, zig) and the rest in the middle like js php java are all trash
I don't know who said this, but the quote was some version of "I love writing Haskell code, and I hate everything about Haskell that's not the writing code part." And I very much agree with the sentiment. The toolchain is really just... not great. That's why things like OCaml are gaining such popularity when it comes to functional languages, imo. A language success these days is (and should be!) more than just about the language, but also about the tools to work with that language. Something like rust & cargo and so on.
That person was Tsoding, and while his experience in the language *was* accurate, it is not anymore. The ecosystem has grown a lot since then and it's way more nice to use than your `npm`s and your `pip`s, which just so happen to be the package managers of the two most popular programming languages right now. Just go with Cabal, and you'll have a great time. As of right now, I would say Haskell's ecosystem is way better than OCaml's. Dune is really painful to work with in comparison to Cabal and it's much more annoying to learn.
In my experience ocaml has been substantially worse when it comes to tooling 😞. Constant issues with build tools and packaging. Maybe something big has changed in the last few years
don’t really know much about cabal, but, as alternative build tool, stack is really great, it’s very intuitive and i havent run into any problems with it, either way, things are for the most part, really great
@@ribosomerocker Cabal still cannot do simple things like add dependencies to your .cabal file. You don't even know how long it took me to get a project even started in Haskell, because I just could not understand why HLS wouldn't work with my version of GHC, or why cabal just wouldn't download files from the internet, or even just installing an IHaskell environment locally was impossible without running it in docker. The lib situation is also not great, you just get something super barebones. Compare that to Rust, which just works.
I also heard and believed this to be the case, but I don't think it's true. I am still new to the ecosystem so maybe it has improved a lot recently? For me the tooling has worked wonders! HLS is probably the most useful language server that I've worked with (comparing to Pyright for Python and clangd for C++). Cabal for me has also "just worked" and I've had less trouble with it than with Pip. One of my favourite tools is ghcid, which is truly amazing for iterating quickly. Come to think of it (having worked as a professional C++ programmer for 10 years) this is probably the best tooling I've used. Maybe I'm still in the honeymoon phase and haven't encountered the really bad parts yet...
I'm writing a book on Haskell, because I found Haskell documentation to be really messy and inefficient. They don't talk to developers, they tend to talk to mathematician wannabes. Hope it will help.
Good luck on that. It would be nice to have something aimed more at people with experience programming rather than studying abstract algebra :) though I must admit it did lead me to learn quite a bit about abstract algebra.
The way you described the documentation might be just the most spot-on description of it I've heard. I hope your book will be just as spot-on, fingers crossed :)
@@vikingthedude Not a website. A simple PDF (maybe an epub, but that's not currently a goal). I really dislike websites for long-term documentation, core concepts and explanations. PS: it's been a while since I contributed to it, I should get back to it.
I totally agree. Having worked with haskell professionally for several years, I have to say, with a well designed haskell code base, different layers of the app well layed out, and domains well modelled. It's not only very easy to test, scale, but it's also almost impossible for newcomers to screw up. Also refactoring is very cheap. And yeah STM is amazing for concurrency/transactions. Haskell is the only language I reach out for other than Bash. I have had to work with several other languages in the past, but nothing, I mean nothing really beats Haskell for my needs.
"... almost impossible for newcomers to screw up..." Ha! You have obviously never managed a team of more than 3 or 4 programmers. Really, though, it's the self-perceived 'experienced' programmers that will find a way to finagle something disastrous into the works.
@@AndreiGeorgescu-j9p Static typing is not necessary to have a useful language. Immutability makes the typing issues generally a lot less problematic than typing issues in something like JS.
Rust actually compiles iterators into a single for loop, and doesn't loop through a whole collection at every Iterator method. But what haskell does is still impresive
Haskell does a ton of optimization at compile time. A simple relevant example is that it will pickout patterns like `fmap f . fmap g` and convert them into `fmap (f . g)`. The former would be two loops and the latter is a single loop. It can do this because of the referential transparency and purity mentioned in the video. Due to the type signature of `fmap`, ghc knows that `f` and `g` have to be pure and that the fmap calls can be combined in this way.
Functional Core Imperative/Reactive Shell is quite the dial just like Entity Component Systems. Feels like the biggest reasons to have imperative stuff in code that's supposed to be functional is either tech bravados who won't compromise in their messy core ideals or the company has no idea of the product's vision/overly reactive to customer demands. Just when you think the engineers have a "good enough" vision, all it takes is one seemingly harmless request before it all tumbles down as months of unnecessary refactoring effort are made from a house of cards that holds the architecture together.
the reason you need an imperative shell is to "drive" the functional core such that it's able to "interact" with users. otherwise your program would do nothing but heat up the cpu
@@zachary4725 That or all the calculations would only be done at compile time and the final program will just be null and void. As far as algorithms themselves, you would hope that compilers were smart enough to translate any functional block into a block that was either imperative or functional, whichever was faster, smaller, and more parallel/concurrency friendly. Maybe that day will come when CPUs permanently separate from the 80+ yo Von Neumann design, but for now, there will be a time and place for imperative and functional algorithms.
All code is concurrent, but its stripped from languages and given to the Compiler to sort out. Time is stripped from languages, but unfortunately it exists on computers in like... reality. Things like CSP create temporal boundaries with channels and processes to give the compiler a much easier time of it. The reason we find concurrency hard is we are trained to ignore time. When we bump into time we're lost.
@@idiomaxiom Your right, but that's not what I meant. With imperative languages, programs primarily consist of statements executed step-by-step (yes, in practice CPUs break this assumption, but that's the mental model the programmer keeps in mind). In purely functional languages, the mental model is "expressions that evaluate to something". It's quite powerful, because it not only simplifies problems that aren't "execution", but more importantly it lets you model other approaches just as well. If you want step-by-step execution there are the ST and IO data types. If you need continuous time, you can go with FRP.
@@mskiptr Generally time exists in the compiler. Load A A + X Wait.... there are 200 cycles in between those. What would you like to do with them? Just isn't a thing. FP's current struggles largely come from trying to bake time back in. Somehow. We're getting there though.
@@idiomaxiom What do you mean it exists in the compiler? If this is about CPU instructions in codegen then sure, but that's just an implementation detail. It's unrelated to what the programmer usually has to keep in mind when writing code. If you want precise control over the machine code then use ASM, C or maybe Rust | C++. Or wait a couple years until I finally try implementing that 'assembly as a Haskell EDSL' idea I had some time ago. But also, that doesn't have to be the case. Pure FP code can instead be compiled to silicon circuits or whatever.
@@mskiptr A compiler wrangling concurrency is an implementation detail? Once FP handles time in its logic, you won't need ASM for tight execution control. ASM doesn't have time either, the Compiler or the developer currently has it.
Happy to see some Haskell love. It is absolutely a mind expanding experience. I would love to use it in anger but it is hard to find mature, well maintained libraries. That makes it a hard sell.
Definitely, coming from all the lisping haskell has a much more active ecosystem. I get where you are coming from though. Especially when it comes to the more obscure stuff.
Once you try Haskell, you cannot go back to a language without sumtype (algebraic data type has always been there but all the hype with OOP made programming language designers ignore it) and pattern matching. By trying Haskell one learns a few things but also becomes much more intolerant to other languages in a way
True ADTs are incredibly helpful when the language supports them. I keep finding myself reaching for them no matter what language I'm working in because they elegantly capture what I'm trying to encode with minimal boilerplate... If the language actually supports them natively. If not, then you're stuck reimplementing a bunch of functionality that should have been there from the start :/ Rust is one of the few languages that supports them though, so there is that I guess (of course, then you have to deal with the headache of the borrow checker).
@@Bobbias I totally do the same. For example C++ has support for sumtype (called variant) but it's pattern matching is a bit complicated (if not a hack). I personally like Rust design, you can really see the influence of ml languages
I particularly don't understand Higher Kind Types. Why does the Haskell needs them? You mentioned that RUst doesn't have higher kinds, but is would it be beneficial to have them?
Typeclasses don't require and dont give you higher kinded types. You happened to write a typeclass instance (Functor) for a higher kinded type (Box) but they are orthogonal concepts. `Num`, `Read`, and `Show` are examples of typeclasses that don't require a higher kinded type.
You realize Type Classes are yet another workaround (similar to templates in other languages) caused by constraints of a strongly typed language? Javascript, Python etc simply don't have this problem because they're weakly typed. Which is my preference honestly
That is certainly one way to see it. To me and many others it is far more than a workaround. They let a function handle many types and be extended to handle more. This unfortunately isn't a native feature that comes with most dynamic languages and requires dynamic dispatch, modifying the function, or modifying the class to support the operation as seen in javascript and python. Adding methods is great and all and if the language allows it like in the case of JavaScript it's fine but in the case of python that isn't an option. There is a reason both languages have a common iteration interface. It's to fill this gap.
I wanna preface this by saying I love your videos and hope you continue to make them. You have fallen (albeit slightly) into the classic problem with Haskell. Introductory videos of Haskell should NOT be talking about functors, applicative and monads. They make sense to you and me (I only have a little amateurish experience), but for someone who hasn't looked at Haskell before, it's all greek. The sort of greek that makes it too intimidating to consider learning. Looking at the available literature, one would be forgiven for thinking you can't program in Haskell unless you know these theoretical concepts. I'd rather people show how to build stuff with Haskell, then introduce these 'patterns' that they've been using all along and how they fit together, before formalising them into type classes with some intuitive names. Then maybe giving them their actual correct names and exploring a bit of theory behind them as a recommended advanced extension. I mean, Javascript has Promises - which behave a lot like monads. They envelope data and support chaining. But you won't find mention of that in Javascript for dummies.
If seeing that there's an entire world you don't know scares you off then you're not cut out for this field and should stick with Python. Showing making some random software won't do anything to really show why it's special. And being an engineer means you use math to solve problems. Abstract factory Singleton Bean is not engineering and is more scary in my opinion. Promises are not like monads except superficially. You don't know haskell at all if you don't know what a functor and applicative are in category theory
@@A5A5A5A5h "Good" OOP is basically declarative OOP which is just two sides of the same coin with FP. The decision of which "lens" to look at your code through comes down to which side of the expression problem you're trying to solve. Subtyping is probably one of the worst ideas in all of programming and it's combination with ad hoc polymorphism is exactly what creates so many issues with variance which even seasoned programmers and computer scientists get confused by. FP has adhoc polymorphism and in a much more elegant manner through typeclasses and pattern matching (sort've). If you notice, a lot of OOP theory is basically "how do we fix this mess" with bandaid fixes like double-defensive copying and such. This is why most serious programming theory and nearly all of the research done in the past decade or two has been exclusively on FP or logic languages. "real" engineering languages are denotational and have math backing them. Imperative languages were completely adhoc in construction and sometimes random. They do not have math backing them. I don't know what your main point is though. Idk what Abstract et all is.
There is a huge list of languages I would like to learn out of curiosity or principle, and there is small list of languages I should learn for practicality and the sake of my career. Haskell certainly has no place in the latter. Same for various LISPs. I learned Scheme through SICP, and that was pretty cool, and maybe I'll switch from Neovim to Emacs at some point and learn ELisp, but it's otherwise impractical to learn niche languages. I'll 100% jump at the opportunity to learn them on the clock though, but that seems unlikely to ever happen.
Ya I admit that learning most of these was driven by my desire to learn and a few ideas for side projects. I cant say I have used them directly at my day job but maybe one day I will. I still apply many things I learnt day to day. Especially the things I learnt from haskell.
Type classes are closer to the original idea behind C++ concepts in combination with templates. Going into their differences is a little outside the scope of a simple comment. A good way to look at the differences is that C++ templates rely more on "Duck Typing" to ensure everything works. With haskell typeclasses you get a similar concept of inheritance from typeclasses (similar to OOP inheritance in some ways but for templates). This lets you override the template for different types if that makes sense. You can also restrict and "express" the types and functions a type/class must support in a template. Sorry if that doesn't give the best explanation but I would recommend looking into C++0x concepts which do a much better job at simulating typeclasses
I am unfortunately using emacs for this video but you can try zepl for a simple way to integrate repls into vim/neovim. There are more complex solutions but zepl is my goto when using vim. In addition, I tend to also use the haskell language server which I recommend. If you use vim you can use vim-lsp and if you use neovim you can use the built in language server support.
You conveniently forgot to mention how complicated Haskell is and how much mental gymnastics you have to go through to understand things that are straightforward in other languages. Only reason I was able to pick up Haskell was because I was already comfortable with OCaml. I wouldn't willingly use it for any project
I get where you are coming from. Learning Haskell isn't easy; some things may seem more complicated than other languages (especially IO operations). I find it easy to get a handle on it once you have more practice. It's a language that teaches you a whole new way to program. In return you get powerful features languages like OCaml just can't offer. Languages like OCaml give you some features you see in Haskell without changing how you program. It's nice if you have experience but is often closer to a crutch. It's all personal preference on what is worth it to you.
I like haskell but personally if I had a choice I'd probably either use ocaml or elixir for most things. The new ocaml modes that Jane Street is adding to the compiler are also extremely compelling because they effectively add ownership and borrowing to the language in a way that is intuitive and easier to understand then the rust implementation. It basically removes any potential for data races too. It's especially cool to see in a garbage collected language like ocaml. I worked with elixir in the last professional project I was on, It was great to use because we were also able to mix it with rust nifs. So we got the insane concurrency of Erlang with the speed of rust. Not to mention the productivity boosts they come with working with a language like elixir are significant. I literally built an entire blockchain (in rust with substrate), matching engine, graphql API, cacheing system, and decentralized no SQL crdt/raft database in about 8 months. I've worked with Haskell a few times but I always get hung up on the syntax. I find that it gets kind of messy if you are not careful. I love the type system, the stm concurrency and the currying but the syntax for closures for instance or threading macros can be a little messy. Elm had a similar syntax but they definitely cleaned it up considerably. Scala and ocaml both have higher kinded types but I wouldn't say they are as intuitive as the ones in Haskell. Btw, really love that you're using org mode to do your videos. Love me some org mode.
The syntax isn't messy at all, it's as clean as it gets and is basically nearly exactly how math is written... Haskell is a significantly more advanced language than everything you've mentioned Closure syntax? What does that mean And idk why you keep mentioning rust, it's not fp and is a systems language
@@AndreiGeorgescu-j9p me not liking Haskells syntax is not a personal attack on you, just FYI. I wouldn't say it's a more advanced language than elixir or ocaml, and what does it matter? This is not a competition, they might all be functional programming languages but they all fill different domains. To be clear, I still use Haskell despite the fact that I don't like it syntax as much as I like many other languages. I still use Scala even though I don't like the way that it does certain things as well (many of the problems were fixed in Scala 3 but not all of them). Haskell's syntax might be similar to math if you are just talking about the type system and maybe the way it does boolean logic but rarely do you use those two features in isolation. I specifically highlighted the threading macros as well as the closures aka capturing functions. In Haskell, you use parentheses filled by a \ to indicate a closure, which is fine on its own but you almost rarely are going to just have a closure surrounded by nothing. The way the language uses white space in general can be pretty messy in my opinion. At the end of the day though, all of this is subjective opinion. I personally really like lisp and scheme (which are both basically implementations of lambda calculus) and I know a lot of people who hate those languages because of their syntax. I'm not going to take personal offense to somebody saying they don't like lisp. The reason I keep mentioning rust is because I'm talking about enterprise projects where I have used it in production alongside these other languages. It might not be a strictly functional language but it has a lot of functional features, even though it's certainly a first class imperative language.
@@draakisback me not using moral relativity as a convenient way to claim anything I want without rebuttal is not a personal attack on you, just FYI. "I wouldn't say it's a more advanced language than elixir or ocaml" Your "truth" doesn't change the fact that it is objectively a more advanced language " and what does it matter? This is not a competition" Ah so you can claim things about how some syntax is better and compare languages but then somebody coming in to tell you that you're comparing apples to oranges makes it no longer a competition and not something relevant. How convenient. I wish I could warp reality this way " they might all be functional programming languages but they all fill different domains." It's more that they have different histories. For example OCaml is only really used because Jane Street needed a language they could basically mold to fit their needs. They picked a dead language nobody cared about being there wasn't competition. It's politics, same reason they abandoned their project to give Haskell a dependent type system because it competed with them too heavily. "Haskell's syntax might be similar to math if you are just talking about the type system and maybe the way it does boolean logic but rarely do you use those two features in isolation." No it's similar to math in nearly everything to how it's based on category theory, function composition is a dot from a Semigroupoid, lambda notation is directly from lamba calculus, function notation is directly from set/type theory, how every operator is a function, abstract data types, quantifiable/existential types are directly from set/type theory, it uses typeclasses to directly model algebras, and the fact that everybody who doesn't like it has to mention at some point that it "looks like math". " I specifically highlighted the threading macros as well as the closures aka capturing functions." Closures are not "capturing functions" and all functions in Haskell are closures. "In Haskell, you use parentheses filled by a \ to indicate a closure" No you don't, you use that syntax to create a lambda aka anonymous function. That's not at all the same thing as a closure. This is something I'd expect a javascript soydev to say. "which is fine on its own but you almost rarely are going to just have a closure surrounded by nothing." What "The way the language uses white space in general can be pretty messy in my opinion. " You're right, let's clean it up by putting curly braces, semicolons, and massives piles of boilerplate everywhere. Oh but somehow Python is really clean and the perfect syntax "At the end of the day though, all of this is subjective opinion. " Copout. Nobody thinks java is cleaner than Kotlin. Nobody thinks C++ templates are cleaner than Haskell generics. You just want an excuse to not like Haskell because you don't understand it very well. "I personally really like lisp and scheme (which are both basically implementations of lambda calculus)" Unironically liking Lisp's syntax means you like a syntax that was only created that way to be nearly identical to the AST, aka the language completely ignored actually making an ergonomic syntax to make the entire language manipulatable. The language designers very literally made it ugly and you think that's good. "The reason I keep mentioning rust is because I'm talking about enterprise projects where I have used it in production alongside these other languages. It might not be a strictly functional language but it has a lot of functional features, even though it's certainly a first class imperative language." So you randomly brought it up, ok Overall it sounds like you're unironically a soydev who doesn't really understand computer science very well and thinks that low-level blue collar work like threads, memory plumbing, and CRUD APIs are "serious programming" instead of the software version of being a car mechanic vs a mechanical engineer. Go learn category theory or frankly some baby's first lambda calculus because you don't know what a lambda is apparently. Then I'll take your "opinions" seriously, but something tells me you'll go play with memory and threads instead
@@AndreiGeorgescu-j9p I considered writing a long reply to yours but honestly its not worth it. I have nothing to prove to someone who is clearly just out to pick a fight. The fact that you seemingly have a problem with threading and "memory plumbing" (btw, wtf does that mean?) and also use terms like soydev (had to look that one up) just shows how much of a reddit warrior you are. Given how much of a 10000x dev you seem to be, I am sure you are aware that Haskell uses threads internally under its STM abstraction and it also has a GC. You know, some languages use the term closure for all lambdas and vice versa. Swift for example calls all anonymous functions closures and most modern programming languages implement lambdas with the potential to work as closures because its generally safer to copy/clone an instance of the external variable then to reference it. You know, its not uncommon to use both terms interchangeably even if its technically wrong. This is a youtube comment section, it doesn't matter if the terms are perfect. Does it make you angry that there are people who write nothing but JavaScript for a living and they make more money then you probably ever will? Anyhow, have fun doing "serious programming"... Id love to see what you think is "serious programming"... By all means, enlighten my ignorant self on how wrong I've been for the past 30 years of my career.
@@draakisback Wow if that's a short response, I wouldn't want to see a long one. Memory plumbing is when you focus on moving memory around instead of actually creating software that solves problems. It's like how a mechanic focuses on banging the carburetor instead of designing vehicles. Nope don't use reddit, they're the worst. In fact they're the mecca of soydevs and would ban you for using that word. Nice try though Yeah never said threads are bad lol, that's just a tool, not the job. "You know, some languages use the term closure for all lambdas and vice versa." No they don't, the soydevs who don't know the difference between all the words do. And closures have nothing to do with lambdas, two different concepts entirely. A named function is still a closure in Haskell and probably most of those languages too. "it's ok to use wrong words on youtube" lol the goalpost moving is hilarious "Does it make you angry that there are people who write nothing but JavaScript for a living and they make more money then you probably ever will? " Ugh why would a soydev with a 4 month bootcamp who does something a teenager in India does make more money than me? Like please explain that logic because if that were true I could at go learn the latest javascript framework in a week and get hired making that same amount. You have to think out your insults better brother. "Anyhow, have fun doing "serious programming"... Id love to see what you think is "serious programming"... By all means, enlighten my ignorant self on how wrong I've been for the past 30 years of my career." LOL 30 years and you don't even know what a lambda or closure are. Geez. What have you been doing for 30 years, sitting around? But yes in general it's the old guys who are the absolute worst, they learned some meme imperative nonsense back in the before-times and they never change because "I've been doing this for 30 years". Maybe go actually learn computer science after 3 decades if you have some self respect instead of playing around with pointers.
What sort of jobs can you get using haskell? So many places are getting into rust and a few famous ones (Jane Street) even use ocaml. Given Haskell's very quirky toolchain, it can be hard to justify delving into the language vs the alternatives that are almost as language nerdy but much more employable (rust).
There are plenty of companies using Haskell today. It's definitely not gaining adoption at the rate of rust but about on par if not ahead of ocaml. Jane Street using ocaml is great but it's also one of the only things keeping the language going. Haskell sure isn't used for all companies core infrastructure but it's used in tons of domains. Web, compilers and other fields reach into the Haskell world. E.g. Facebook has used it for multiple internal tools and lex-pass, same goes for Google, Microsoft uses it for Bond and sponsors Haskell development. Hope that answers your question. Let me know if I misunderstood 😁 Edit: as far as rust being more enjoyable that depends person to person.
@@GavinFreeborn thanks! I definitely enjoy it more than rust (though not as much as Lisp, but that's just my haskell ignorance), which feels like extra frustrating C++. Let's hope Val takes off, as I think that'll span the gap between C++ and Haskell
Haskell's toolchain is not quirky, it's a 1 button install to get everything. Rust is enjoyable lol? It's a systems language that deals with a bunch of messy hardware details instead of actual computer science. All of its interesting ideas were taken from FP. otherwise it's just not as bad C. And calling these things "nerdy" is pretty much just saying they're intelligently designed languages instead of adhoc blue collar memory moving languages
Hi Gavin, I never once used or even saw code for a functional programming language like Haskell. I've been thinking about it lately to learn a bit about either Haskell or Scala, but I don't know which would be better if your main purpose is to learn how recursion works or for improving your skills in algorithms. I don't know how true this is? But I read some article which stated learning a functional programming language can help you a great deal in understanding data structures and algorithms. Also, I was considering Scala over Haskell because I am already focused on Kotlin and I know JavaScript. I figured since Scala runs on the JVM maybe there is similarities from what I am learning with Kotlin? Anyways, I would be interested in hearing which would you recommend? Haskell or Scala? Or it doesn't matter? Anyways, thank you.
i’d say that you should go for haskell, it’s pure, so it (for the most part) forces you to think in functional terms without escape hatches, (like other languages do, especially regarding recursive functions and loops) it’s possibly more difficult to learn at first than scala (as far as i know, scala “cheats” a bit and, allows a more imperative approach) but is definitely worth it, it gives you a very difficult way to look at programming in general
@@rogergalindo7318 Great, thank you! I've been coding for about 1 year and a half with JavaScript now Kotlin. But I need something to twist and bend my mind and give me a different perspective in thinking. Thanks Roger. What is your recommended IDE or editor for Haskell?
Most people use vscode. I personally find Emacs to be great but wouldn't recommend investing time into learning it if the end goal is just to learn haskell. vscode is more than friendly enough
@@GavinFreeborn At the moment I don't have a clear defined goal with functional programming. It was something I was and am still considering to improve my skills in programming and gain a different perspective. But I've heard of Emacs as well as NeoVim and Vim. I am strongly considering these options, I appreciate the feedback thank you.
"Functional core, imperative shell." Here's a technique for handling input that comes from the imperative shell to the functional core: Monadic Parsers at the Input Boundary. th-cam.com/video/LLkbzt4ms6M/w-d-xo.html
@@Instr oh. this is my first time hearing about Template Haskell. thanks for pointing me in that direction! i do wonder why function couldn't do the same job as a macro
@@xybersurfer Functions can't read raw code, given a function, the most a higher order function can do is to apply the function to data, preprocess the inputs of the function, or postprocess the outputs of the function. It can also inject effects, obviously, but in Haskell effect injection / actions is somewhat complicated (you end up in a monadic type context of some kind, many of which cannot be exited trivially or safely).
For browser support there is recent support for compiling Haskell to JavaScript but if you want something more mature look at purescript. It's basically Haskell that compiles to js without lazy evaluation and a few extra features. I've used it for a few projects and can happily recommend it.
@@GavinFreebornPureScript is way too behind the ghc and is definitely not getting dependent types because nobody is going to put in that effort. Might as well just stick to haskell. There's frontends like Miso
Almost every language now is trying to emulate / port all of the great features of Haskell. At some point you have to ask yourself... Why not just learn Haskell? Its a great language.
Someone once saw me using Lisp and said something to the effect of "You should try Haskell, it's like Lisp but with less parentheses". My response was "Oh, that's too bad. Sounds good otherwise though!"
Oh yes, it hurts so bad to have the choice to write: foo = bar . baz . quux or foo a = bar (baz (quux a)) rather than: (define (foo a) (bar (baz (quux a)))) Absolutely intolerable... The parenthesis aren't what you like about s-expressions anyway. It's more likely the regularity, lending itself easily to manipulation, whether you see it as code or data. And Haskell really isn't very lisp-like, particularly with the static type system. We wouldn't have a procedure like number? (pardon the Scheme) but a declaration like foo :: Num a => a -> a making that predicate moot. Or you use a sum type, perhaps from Aeson or S-cargot.
@@defaultxrs expressions are objectively bad. The only reason it's a thing is because LISP wanted it's surface syntax to be nearly identical to AST so they they could treat code as data, which as well as know now is a terrible idea unless you're specifically making a DSL
I have no idea how this popped up on my feed but I remember your name from a programming discord I used to be part of. Possibly because I'm learning Ocaml right now. Subbed, I guess.
Haskell fits quite neatly into a family of languages that seems to cater to people who spend more time talking about writing code than actually writing or shipping code.
First of all, in modern days nobody uses Lisp language, it's known as a language family. Second, projects developing by Clojure (which is a lisp lang btw) and Haskell are published in corresponding pages, which could be easily found, instead of wasting time to make another bs statement on "useless" languages.
Writing a function needs to be really really easy, because breaking up programs needs to be something a programmer does with very low activation energy. Haskell gave me the impression that I was signing a contract with a lawyer present every time i tried to write a function
foo arg1 = bar. What's the problem? Unless you're TyDDing it, you can pass off the type signature to the IDE, which will mutate the type signature via inference as you write the function; when you're done, click the code shadow. If the signature looks wrong, you probably screwed up somewhere anyways. Also, it's idiomatic to skip type sigs in where clauses, so you can just define an IO action then write the functions it uses in the where clauses. What's the problem?
Rust is imperative programming with some features inspired by the functional world and extra formalism around generics and lifetimes. Haskell on the other hand is a language that sometimes likes to dress-up functional programming to resemble the imperative model. But in the end all the constructs behind it are alien to those who have lived in the imperative land (unless they have background in math, I guess).
"purely" functional, as long as you don't look under the hood, but its a great language, and you cant fault it for how computers work and the factual limitations of reality.
You take away the purely functional branding and the syntax reduces to Python with much better functional programming support, performance, and type safety. The entire purely functional thing is a mirage, anyways. It's all lambda calculus under the hood, but Haskell supports immutable pointers to mutable variables and replaces for loops with higher order functions that are much more descriptive, including for and for_ hofs.
There's nothing about purely functional that doesn't allow any mutation whatsoever. It's just that you have to mark mutable objects as part of your type system. For example, ST does mutate, IO is dependent on outside output, IORef is both mutable and IO.
The way I see it is that the developer sort of integrates their pure functions into a monad (IO) that keeps the impure parts away from them. Those impure parts are a part of the runtime. But yeah, obviously it can't be absolutely pure, as it would be completely useless then, unable to achieve any effect. It just tries to put a barrier between the pure and impure parts of it.
@@MRL8770 One trend I'm investigating is the one wherein the IO parts just get replaced by a framework. It's ironically very natural for Haskell, since IO is an unfortunate sacrifice to pragmatism, but why not hide the entire IO part of the system with a framework? Then you just plug in pure functions, values, and callbacks into the framework and it's way more expressive and powerful than anything you could do with a conventional language. Or, in other words, you go from "Haskell is for Wizards" to "Haskell is a Wizard" and you just specify the callbacks and values you want for the mechanism.
Haskell has no practical usage, waist of time unless you want to go deep in the theory. Your example of `add a b` function is practical demonstration of putting the lipstick on a pig. Clearly both 'a' and 'b' are integers so `return (a + b)` would logically be simple integer, But for some reason you wrap up the integer into the strange 'IO' thingy as 'IO Integer'. Why the f..k for such a simple thing like adding 2 numbers and printing the debug log one have to dedicate time to lengthy study about the monads and eventually learn that IO monad is just the one out of plethora of monads used in Haskell and to deal with them all one has to learn even more impractical and useless and crazy concept of monad transformers just to be able to push the same simple value between monad domains? In every practical programming language making adder function and printing the result is dead simple except of Haskell.
Ya if your program is simply adding two static numbers and print the result I certainly wouldn't choose haskell. Choose the right tool for the job. I do find it nice for developing more complex applications personally for exactly the reason it seems to bother you. Doing things that often lead to trouble like mutating state and general io operations are more of a bit more work but mean you don't have to worry about them leading to unforeseen errors later down the road. All just my own opinions though. I have had so many problems crop up related to these issues at multiple companies on multiple projects. Just because someone did a quick mutation they didn't notice they costed someone else a day or more of debugging to fix it.
I attempted to learn haskell in the past and had the feeling. Now with ghcup and cabal becoming more fully featured I find haskell much more user friendly. I'd say for the age of the language the tooling is decent and mostly lacking in learning opportunities. With the love this video has gotten I plan to make videos helping new users get to grips with the newer tooling. www.haskell.org/ghcup/ cabal.readthedocs.io/
Technically, functional languages are procedural. The only exception is that any data has a type signature, which cannot be changed or ignored. Purely procedural languages have a very week type system. If I remember correctly, C used to have only binary, integers and characters, everything else including floats and strings had to be build from scratch and you could change types by accident.
To try everything Brilliant has to offer-free-for a full 30 days, visit brilliant.org/GavinFreeborn . The first 200 of you will get 20% off Brilliant’s annual premium subscription.
I'm happy to see that you are posting Haskell content. I recently started learning Haskell and I really love it. Keep up the good work.
What resources are you using?
@@olaniyanayodele5986 I started off doing code puzzles on www.codewars.com/. Looking at the top voted solutions and comparing it to my own was very helpful in learning some best practices. I have also been doing puzzles at adventofcode.com/. Now I have a couple of small hobby projects going where I'm learning to use some of the popular libraries (like megaparsec, servant, aeson)
A great tutorial series here on youtube:
Haskell for Imperative Programmers
www.youtube.com/@philipphagenlocher
I have been listening a lot to a Haskell podcast here on youtube called @HaskellWeekly. They have short episodes covering one topic per episode:
www.youtube.com/@HaskellWeekly
I found a couple of online books that look promising (but for me personally I learn faster by doing real projects and through youtube):
book.realworldhaskell.org/read/ (The author of this one has an old but great talk here: th-cam.com/video/ZR3Jirqk6W8/w-d-xo.html)
learnyouahaskell.com/chapters
Let me know if you know any other good resources!
@@olaniyanayodele5986do you still need some?
i think every programmer realizes eventually you need a very high level language like haskell and a low level one (rust, c, zig) and the rest in the middle like js php java are all trash
I don't know who said this, but the quote was some version of "I love writing Haskell code, and I hate everything about Haskell that's not the writing code part." And I very much agree with the sentiment. The toolchain is really just... not great. That's why things like OCaml are gaining such popularity when it comes to functional languages, imo. A language success these days is (and should be!) more than just about the language, but also about the tools to work with that language. Something like rust & cargo and so on.
That person was Tsoding, and while his experience in the language *was* accurate, it is not anymore. The ecosystem has grown a lot since then and it's way more nice to use than your `npm`s and your `pip`s, which just so happen to be the package managers of the two most popular programming languages right now. Just go with Cabal, and you'll have a great time.
As of right now, I would say Haskell's ecosystem is way better than OCaml's. Dune is really painful to work with in comparison to Cabal and it's much more annoying to learn.
In my experience ocaml has been substantially worse when it comes to tooling 😞. Constant issues with build tools and packaging. Maybe something big has changed in the last few years
don’t really know much about cabal, but, as alternative build tool, stack is really great, it’s very intuitive and i havent run into any problems with it, either way, things are for the most part, really great
@@ribosomerocker Cabal still cannot do simple things like add dependencies to your .cabal file. You don't even know how long it took me to get a project even started in Haskell, because I just could not understand why HLS wouldn't work with my version of GHC, or why cabal just wouldn't download files from the internet, or even just installing an IHaskell environment locally was impossible without running it in docker. The lib situation is also not great, you just get something super barebones. Compare that to Rust, which just works.
I also heard and believed this to be the case, but I don't think it's true. I am still new to the ecosystem so maybe it has improved a lot recently?
For me the tooling has worked wonders! HLS is probably the most useful language server that I've worked with (comparing to Pyright for Python and clangd for C++). Cabal for me has also "just worked" and I've had less trouble with it than with Pip. One of my favourite tools is ghcid, which is truly amazing for iterating quickly.
Come to think of it (having worked as a professional C++ programmer for 10 years) this is probably the best tooling I've used. Maybe I'm still in the honeymoon phase and haven't encountered the really bad parts yet...
I'm writing a book on Haskell, because I found Haskell documentation to be really messy and inefficient.
They don't talk to developers, they tend to talk to mathematician wannabes.
Hope it will help.
Good luck on that. It would be nice to have something aimed more at people with experience programming rather than studying abstract algebra :) though I must admit it did lead me to learn quite a bit about abstract algebra.
The way you described the documentation might be just the most spot-on description of it I've heard.
I hope your book will be just as spot-on, fingers crossed :)
@@MRL8770 Thanks! I'll do what I can. I write it as I learn, basically. So it's slow, but I'm committed to make it useful. :)
Awesome. WIll you make it available as a website?
@@vikingthedude Not a website. A simple PDF (maybe an epub, but that's not currently a goal). I really dislike websites for long-term documentation, core concepts and explanations.
PS: it's been a while since I contributed to it, I should get back to it.
I totally agree. Having worked with haskell professionally for several years, I have to say, with a well designed haskell code base, different layers of the app well layed out, and domains well modelled. It's not only very easy to test, scale, but it's also almost impossible for newcomers to screw up. Also refactoring is very cheap. And yeah STM is amazing for concurrency/transactions. Haskell is the only language I reach out for other than Bash. I have had to work with several other languages in the past, but nothing, I mean nothing really beats Haskell for my needs.
"... almost impossible for newcomers to screw up..."
Ha!
You have obviously never managed a team of more than 3 or 4 programmers. Really, though, it's the self-perceived 'experienced' programmers that will find a way to finagle something disastrous into the works.
where is haskell used professionally tho
The tsoding channel has some pretty fun Haskell programming videos.
Just been offered a full-time graduate full-stack engineering position working with haskell and typescript... very excited!
Congrats! Wish you the best
I’d like to see a comparison between clojure and Haskell. Maybe throw in elixir as well
They're meme languages because they're not static
This, Yes! # best languages out there.
@@AndreiGeorgescu-j9p Static typing is not necessary to have a useful language.
Immutability makes the typing issues generally a lot less problematic than typing issues in something like JS.
@@user-pe7gf9rv4m yes it is
Rust actually compiles iterators into a single for loop, and doesn't loop through a whole collection at every Iterator method.
But what haskell does is still impresive
Yep. That's what I meant by iterators being an alternative to iterating through a collection multiple times
Haskell does a ton of optimization at compile time. A simple relevant example is that it will pickout patterns like `fmap f . fmap g` and convert them into `fmap (f . g)`. The former would be two loops and the latter is a single loop. It can do this because of the referential transparency and purity mentioned in the video. Due to the type signature of `fmap`, ghc knows that `f` and `g` have to be pure and that the fmap calls can be combined in this way.
Functional Core Imperative/Reactive Shell is quite the dial just like Entity Component Systems. Feels like the biggest reasons to have imperative stuff in code that's supposed to be functional is either tech bravados who won't compromise in their messy core ideals or the company has no idea of the product's vision/overly reactive to customer demands. Just when you think the engineers have a "good enough" vision, all it takes is one seemingly harmless request before it all tumbles down as months of unnecessary refactoring effort are made from a house of cards that holds the architecture together.
the reason you need an imperative shell is to "drive" the functional core such that it's able to "interact" with users. otherwise your program would do nothing but heat up the cpu
@@zachary4725 That or all the calculations would only be done at compile time and the final program will just be null and void.
As far as algorithms themselves, you would hope that compilers were smart enough to translate any functional block into a block that was either imperative or functional, whichever was faster, smaller, and more parallel/concurrency friendly. Maybe that day will come when CPUs permanently separate from the 80+ yo Von Neumann design, but for now, there will be a time and place for imperative and functional algorithms.
The best one-line explanation of pure FP I found is: _let's get rid of time_
All code is concurrent, but its stripped from languages and given to the Compiler to sort out. Time is stripped from languages, but unfortunately it exists on computers in like... reality. Things like CSP create temporal boundaries with channels and processes to give the compiler a much easier time of it.
The reason we find concurrency hard is we are trained to ignore time. When we bump into time we're lost.
@@idiomaxiom Your right, but that's not what I meant.
With imperative languages, programs primarily consist of statements executed step-by-step (yes, in practice CPUs break this assumption, but that's the mental model the programmer keeps in mind).
In purely functional languages, the mental model is "expressions that evaluate to something". It's quite powerful, because it not only simplifies problems that aren't "execution", but more importantly it lets you model other approaches just as well. If you want step-by-step execution there are the ST and IO data types. If you need continuous time, you can go with FRP.
@@mskiptr Generally time exists in the compiler.
Load A
A + X
Wait.... there are 200 cycles in between those. What would you like to do with them?
Just isn't a thing.
FP's current struggles largely come from trying to bake time back in. Somehow. We're getting there though.
@@idiomaxiom What do you mean it exists in the compiler? If this is about CPU instructions in codegen then sure, but that's just an implementation detail. It's unrelated to what the programmer usually has to keep in mind when writing code.
If you want precise control over the machine code then use ASM, C or maybe Rust | C++. Or wait a couple years until I finally try implementing that 'assembly as a Haskell EDSL' idea I had some time ago.
But also, that doesn't have to be the case. Pure FP code can instead be compiled to silicon circuits or whatever.
@@mskiptr A compiler wrangling concurrency is an implementation detail?
Once FP handles time in its logic, you won't need ASM for tight execution control.
ASM doesn't have time either, the Compiler or the developer currently has it.
Happy to see some Haskell love. It is absolutely a mind expanding experience. I would love to use it in anger but it is hard to find mature, well maintained libraries. That makes it a hard sell.
Definitely, coming from all the lisping haskell has a much more active ecosystem. I get where you are coming from though. Especially when it comes to the more obscure stuff.
It's got 35 years of libraries. And unlike imperative most don't need to be constantly maintained
Once you try Haskell, you cannot go back to a language without sumtype (algebraic data type has always been there but all the hype with OOP made programming language designers ignore it) and pattern matching. By trying Haskell one learns a few things but also becomes much more intolerant to other languages in a way
True ADTs are incredibly helpful when the language supports them. I keep finding myself reaching for them no matter what language I'm working in because they elegantly capture what I'm trying to encode with minimal boilerplate... If the language actually supports them natively. If not, then you're stuck reimplementing a bunch of functionality that should have been there from the start :/
Rust is one of the few languages that supports them though, so there is that I guess (of course, then you have to deal with the headache of the borrow checker).
@@Bobbias I totally do the same. For example C++ has support for sumtype (called variant) but it's pattern matching is a bit complicated (if not a hack).
I personally like Rust design, you can really see the influence of ml languages
I've been seeing a lot of buzz about Ocaml, could we get a comparison between Ocaml and Haskell?
I'd love to. Considering all the times it's been mentioned I think it would be a great comparison
It's a meme language pushed by Jane Street because they wanted to take some dead language and use it like a puppet for their company
Love it!
Haskell is definitely a mental challenge. Purescript might be easier syntactically.
Isn't the syntax the same except cleaned up a little?
Yes
The functional danger triad of despair: haskell, lisps(CL you have my heart) and apl derivatives.
I particularly don't understand Higher Kind Types. Why does the Haskell needs them? You mentioned that RUst doesn't have higher kinds, but is would it be beneficial to have them?
Typeclasses don't require and dont give you higher kinded types. You happened to write a typeclass instance (Functor) for a higher kinded type (Box) but they are orthogonal concepts. `Num`, `Read`, and `Show` are examples of typeclasses that don't require a higher kinded type.
You realize Type Classes are yet another workaround (similar to templates in other languages) caused by constraints of a strongly typed language? Javascript, Python etc simply don't have this problem because they're weakly typed. Which is my preference honestly
That is certainly one way to see it. To me and many others it is far more than a workaround. They let a function handle many types and be extended to handle more. This unfortunately isn't a native feature that comes with most dynamic languages and requires dynamic dispatch, modifying the function, or modifying the class to support the operation as seen in javascript and python. Adding methods is great and all and if the language allows it like in the case of JavaScript it's fine but in the case of python that isn't an option. There is a reason both languages have a common iteration interface. It's to fill this gap.
Братан, хорош, давай, давай, вперёд! Контент в кайф, можно ещё? Вообще красавчик!
Let’s goooo Haskell os very good, and I basically all the money I did on software was with haskell
I wanna preface this by saying I love your videos and hope you continue to make them.
You have fallen (albeit slightly) into the classic problem with Haskell. Introductory videos of Haskell should NOT be talking about functors, applicative and monads. They make sense to you and me (I only have a little amateurish experience), but for someone who hasn't looked at Haskell before, it's all greek. The sort of greek that makes it too intimidating to consider learning. Looking at the available literature, one would be forgiven for thinking you can't program in Haskell unless you know these theoretical concepts.
I'd rather people show how to build stuff with Haskell, then introduce these 'patterns' that they've been using all along and how they fit together, before formalising them into type classes with some intuitive names. Then maybe giving them their actual correct names and exploring a bit of theory behind them as a recommended advanced extension. I mean, Javascript has Promises - which behave a lot like monads. They envelope data and support chaining. But you won't find mention of that in Javascript for dummies.
I totally agree. I should have minimized the number technical terms. Especially those usually only covered in math and Haskell
If seeing that there's an entire world you don't know scares you off then you're not cut out for this field and should stick with Python. Showing making some random software won't do anything to really show why it's special. And being an engineer means you use math to solve problems. Abstract factory Singleton Bean is not engineering and is more scary in my opinion.
Promises are not like monads except superficially.
You don't know haskell at all if you don't know what a functor and applicative are in category theory
@@A5A5A5A5h "Good" OOP is basically declarative OOP which is just two sides of the same coin with FP. The decision of which "lens" to look at your code through comes down to which side of the expression problem you're trying to solve.
Subtyping is probably one of the worst ideas in all of programming and it's combination with ad hoc polymorphism is exactly what creates so many issues with variance which even seasoned programmers and computer scientists get confused by.
FP has adhoc polymorphism and in a much more elegant manner through typeclasses and pattern matching (sort've).
If you notice, a lot of OOP theory is basically "how do we fix this mess" with bandaid fixes like double-defensive copying and such. This is why most serious programming theory and nearly all of the research done in the past decade or two has been exclusively on FP or logic languages. "real" engineering languages are denotational and have math backing them. Imperative languages were completely adhoc in construction and sometimes random. They do not have math backing them.
I don't know what your main point is though. Idk what Abstract et all is.
What about OCaml?
There is a huge list of languages I would like to learn out of curiosity or principle, and there is small list of languages I should learn for practicality and the sake of my career. Haskell certainly has no place in the latter. Same for various LISPs. I learned Scheme through SICP, and that was pretty cool, and maybe I'll switch from Neovim to Emacs at some point and learn ELisp, but it's otherwise impractical to learn niche languages. I'll 100% jump at the opportunity to learn them on the clock though, but that seems unlikely to ever happen.
Ya I admit that learning most of these was driven by my desire to learn and a few ideas for side projects. I cant say I have used them directly at my day job but maybe one day I will. I still apply many things I learnt day to day. Especially the things I learnt from haskell.
Rust's traits are very similar to Haskell's typeclasses
I've been thinking about learning Haskell for years. Thanks for sharing your perspective on this topic!
Would be interested in your take on Erlang.
Do a video about Clojure as well! It's kind of the other side of the functional coin.
Hey Gavin, great content. What ide are you using?
I use Emacs :)
The main reason to learn Haskell is to feel really, REALLY smart.
What font are you using?
Nice Video
Type classes seem very similar to C++ templates. Are they really that different?
Type classes are closer to the original idea behind C++ concepts in combination with templates. Going into their differences is a little outside the scope of a simple comment. A good way to look at the differences is that C++ templates rely more on "Duck Typing" to ensure everything works. With haskell typeclasses you get a similar concept of inheritance from typeclasses (similar to OOP inheritance in some ways but for templates). This lets you override the template for different types if that makes sense. You can also restrict and "express" the types and functions a type/class must support in a template. Sorry if that doesn't give the best explanation but I would recommend looking into C++0x concepts which do a much better job at simulating typeclasses
What haskell plugins are you using in vim?
I am unfortunately using emacs for this video but you can try zepl for a simple way to integrate repls into vim/neovim. There are more complex solutions but zepl is my goto when using vim. In addition, I tend to also use the haskell language server which I recommend. If you use vim you can use vim-lsp and if you use neovim you can use the built in language server support.
You conveniently forgot to mention how complicated Haskell is and how much mental gymnastics you have to go through to understand things that are straightforward in other languages.
Only reason I was able to pick up Haskell was because I was already comfortable with OCaml. I wouldn't willingly use it for any project
I get where you are coming from. Learning Haskell isn't easy; some things may seem more complicated than other languages (especially IO operations). I find it easy to get a handle on it once you have more practice. It's a language that teaches you a whole new way to program. In return you get powerful features languages like OCaml just can't offer. Languages like OCaml give you some features you see in Haskell without changing how you program. It's nice if you have experience but is often closer to a crutch. It's all personal preference on what is worth it to you.
I like haskell but personally if I had a choice I'd probably either use ocaml or elixir for most things. The new ocaml modes that Jane Street is adding to the compiler are also extremely compelling because they effectively add ownership and borrowing to the language in a way that is intuitive and easier to understand then the rust implementation. It basically removes any potential for data races too. It's especially cool to see in a garbage collected language like ocaml.
I worked with elixir in the last professional project I was on, It was great to use because we were also able to mix it with rust nifs. So we got the insane concurrency of Erlang with the speed of rust. Not to mention the productivity boosts they come with working with a language like elixir are significant. I literally built an entire blockchain (in rust with substrate), matching engine, graphql API, cacheing system, and decentralized no SQL crdt/raft database in about 8 months.
I've worked with Haskell a few times but I always get hung up on the syntax. I find that it gets kind of messy if you are not careful. I love the type system, the stm concurrency and the currying but the syntax for closures for instance or threading macros can be a little messy. Elm had a similar syntax but they definitely cleaned it up considerably. Scala and ocaml both have higher kinded types but I wouldn't say they are as intuitive as the ones in Haskell.
Btw, really love that you're using org mode to do your videos. Love me some org mode.
The syntax isn't messy at all, it's as clean as it gets and is basically nearly exactly how math is written...
Haskell is a significantly more advanced language than everything you've mentioned
Closure syntax? What does that mean
And idk why you keep mentioning rust, it's not fp and is a systems language
@@AndreiGeorgescu-j9p me not liking Haskells syntax is not a personal attack on you, just FYI.
I wouldn't say it's a more advanced language than elixir or ocaml, and what does it matter? This is not a competition, they might all be functional programming languages but they all fill different domains. To be clear, I still use Haskell despite the fact that I don't like it syntax as much as I like many other languages. I still use Scala even though I don't like the way that it does certain things as well (many of the problems were fixed in Scala 3 but not all of them).
Haskell's syntax might be similar to math if you are just talking about the type system and maybe the way it does boolean logic but rarely do you use those two features in isolation. I specifically highlighted the threading macros as well as the closures aka capturing functions. In Haskell, you use parentheses filled by a \ to indicate a closure, which is fine on its own but you almost rarely are going to just have a closure surrounded by nothing. The way the language uses white space in general can be pretty messy in my opinion.
At the end of the day though, all of this is subjective opinion. I personally really like lisp and scheme (which are both basically implementations of lambda calculus) and I know a lot of people who hate those languages because of their syntax. I'm not going to take personal offense to somebody saying they don't like lisp.
The reason I keep mentioning rust is because I'm talking about enterprise projects where I have used it in production alongside these other languages. It might not be a strictly functional language but it has a lot of functional features, even though it's certainly a first class imperative language.
@@draakisback me not using moral relativity as a convenient way to claim anything I want without rebuttal is not a personal attack on you, just FYI.
"I wouldn't say it's a more advanced language than elixir or ocaml"
Your "truth" doesn't change the fact that it is objectively a more advanced language
" and what does it matter? This is not a competition"
Ah so you can claim things about how some syntax is better and compare languages but then somebody coming in to tell you that you're comparing apples to oranges makes it no longer a competition and not something relevant. How convenient. I wish I could warp reality this way
" they might all be functional programming languages but they all fill different domains."
It's more that they have different histories. For example OCaml is only really used because Jane Street needed a language they could basically mold to fit their needs. They picked a dead language nobody cared about being there wasn't competition. It's politics, same reason they abandoned their project to give Haskell a dependent type system because it competed with them too heavily.
"Haskell's syntax might be similar to math if you are just talking about the type system and maybe the way it does boolean logic but rarely do you use those two features in isolation."
No it's similar to math in nearly everything to how it's based on category theory, function composition is a dot from a Semigroupoid, lambda notation is directly from lamba calculus, function notation is directly from set/type theory, how every operator is a function, abstract data types, quantifiable/existential types are directly from set/type theory, it uses typeclasses to directly model algebras, and the fact that everybody who doesn't like it has to mention at some point that it "looks like math".
" I specifically highlighted the threading macros as well as the closures aka capturing functions."
Closures are not "capturing functions" and all functions in Haskell are closures.
"In Haskell, you use parentheses filled by a \ to indicate a closure"
No you don't, you use that syntax to create a lambda aka anonymous function. That's not at all the same thing as a closure. This is something I'd expect a javascript soydev to say.
"which is fine on its own but you almost rarely are going to just have a closure surrounded by nothing."
What
"The way the language uses white space in general can be pretty messy in my opinion. "
You're right, let's clean it up by putting curly braces, semicolons, and massives piles of boilerplate everywhere. Oh but somehow Python is really clean and the perfect syntax
"At the end of the day though, all of this is subjective opinion. "
Copout. Nobody thinks java is cleaner than Kotlin. Nobody thinks C++ templates are cleaner than Haskell generics. You just want an excuse to not like Haskell because you don't understand it very well.
"I personally really like lisp and scheme (which are both basically implementations of lambda calculus)"
Unironically liking Lisp's syntax means you like a syntax that was only created that way to be nearly identical to the AST, aka the language completely ignored actually making an ergonomic syntax to make the entire language manipulatable. The language designers very literally made it ugly and you think that's good.
"The reason I keep mentioning rust is because I'm talking about enterprise projects where I have used it in production alongside these other languages. It might not be a strictly functional language but it has a lot of functional features, even though it's certainly a first class imperative language."
So you randomly brought it up, ok
Overall it sounds like you're unironically a soydev who doesn't really understand computer science very well and thinks that low-level blue collar work like threads, memory plumbing, and CRUD APIs are "serious programming" instead of the software version of being a car mechanic vs a mechanical engineer. Go learn category theory or frankly some baby's first lambda calculus because you don't know what a lambda is apparently. Then I'll take your "opinions" seriously, but something tells me you'll go play with memory and threads instead
@@AndreiGeorgescu-j9p I considered writing a long reply to yours but honestly its not worth it. I have nothing to prove to someone who is clearly just out to pick a fight. The fact that you seemingly have a problem with threading and "memory plumbing" (btw, wtf does that mean?) and also use terms like soydev (had to look that one up) just shows how much of a reddit warrior you are. Given how much of a 10000x dev you seem to be, I am sure you are aware that Haskell uses threads internally under its STM abstraction and it also has a GC.
You know, some languages use the term closure for all lambdas and vice versa. Swift for example calls all anonymous functions closures and most modern programming languages implement lambdas with the potential to work as closures because its generally safer to copy/clone an instance of the external variable then to reference it. You know, its not uncommon to use both terms interchangeably even if its technically wrong. This is a youtube comment section, it doesn't matter if the terms are perfect.
Does it make you angry that there are people who write nothing but JavaScript for a living and they make more money then you probably ever will? Anyhow, have fun doing "serious programming"... Id love to see what you think is "serious programming"... By all means, enlighten my ignorant self on how wrong I've been for the past 30 years of my career.
@@draakisback Wow if that's a short response, I wouldn't want to see a long one.
Memory plumbing is when you focus on moving memory around instead of actually creating software that solves problems. It's like how a mechanic focuses on banging the carburetor instead of designing vehicles.
Nope don't use reddit, they're the worst. In fact they're the mecca of soydevs and would ban you for using that word. Nice try though
Yeah never said threads are bad lol, that's just a tool, not the job.
"You know, some languages use the term closure for all lambdas and vice versa."
No they don't, the soydevs who don't know the difference between all the words do. And closures have nothing to do with lambdas, two different concepts entirely. A named function is still a closure in Haskell and probably most of those languages too.
"it's ok to use wrong words on youtube" lol the goalpost moving is hilarious
"Does it make you angry that there are people who write nothing but JavaScript for a living and they make more money then you probably ever will? "
Ugh why would a soydev with a 4 month bootcamp who does something a teenager in India does make more money than me? Like please explain that logic because if that were true I could at go learn the latest javascript framework in a week and get hired making that same amount. You have to think out your insults better brother.
"Anyhow, have fun doing "serious programming"... Id love to see what you think is "serious programming"... By all means, enlighten my ignorant self on how wrong I've been for the past 30 years of my career."
LOL 30 years and you don't even know what a lambda or closure are. Geez. What have you been doing for 30 years, sitting around? But yes in general it's the old guys who are the absolute worst, they learned some meme imperative nonsense back in the before-times and they never change because "I've been doing this for 30 years". Maybe go actually learn computer science after 3 decades if you have some self respect instead of playing around with pointers.
What sort of jobs can you get using haskell? So many places are getting into rust and a few famous ones (Jane Street) even use ocaml. Given Haskell's very quirky toolchain, it can be hard to justify delving into the language vs the alternatives that are almost as language nerdy but much more employable (rust).
There are plenty of companies using Haskell today. It's definitely not gaining adoption at the rate of rust but about on par if not ahead of ocaml. Jane Street using ocaml is great but it's also one of the only things keeping the language going. Haskell sure isn't used for all companies core infrastructure but it's used in tons of domains. Web, compilers and other fields reach into the Haskell world. E.g. Facebook has used it for multiple internal tools and lex-pass, same goes for Google, Microsoft uses it for Bond and sponsors Haskell development. Hope that answers your question. Let me know if I misunderstood 😁
Edit: as far as rust being more enjoyable that depends person to person.
@@GavinFreeborn thanks! I definitely enjoy it more than rust (though not as much as Lisp, but that's just my haskell ignorance), which feels like extra frustrating C++. Let's hope Val takes off, as I think that'll span the gap between C++ and Haskell
Haskell's toolchain is not quirky, it's a 1 button install to get everything.
Rust is enjoyable lol? It's a systems language that deals with a bunch of messy hardware details instead of actual computer science. All of its interesting ideas were taken from FP. otherwise it's just not as bad C.
And calling these things "nerdy" is pretty much just saying they're intelligently designed languages instead of adhoc blue collar memory moving languages
Hi Gavin, I never once used or even saw code for a functional programming language like Haskell. I've been thinking about it lately to learn a bit about either Haskell or Scala, but I don't know which would be better if your main purpose is to learn how recursion works or for improving your skills in algorithms. I don't know how true this is? But I read some article which stated learning a functional programming language can help you a great deal in understanding data structures and algorithms.
Also, I was considering Scala over Haskell because I am already focused on Kotlin and I know JavaScript. I figured since Scala runs on the JVM maybe there is similarities from what I am learning with Kotlin?
Anyways, I would be interested in hearing which would you recommend? Haskell or Scala? Or it doesn't matter? Anyways, thank you.
i’d say that you should go for haskell, it’s pure, so it (for the most part) forces you to think in functional terms without escape hatches, (like other languages do, especially regarding recursive functions and loops)
it’s possibly more difficult to learn at first than scala (as far as i know, scala “cheats” a bit and, allows a more imperative approach) but is definitely worth it, it gives you a very difficult way to look at programming in general
different* way to look at programming
@@rogergalindo7318 Great, thank you! I've been coding for about 1 year and a half with JavaScript now Kotlin. But I need something to twist and bend my mind and give me a different perspective in thinking. Thanks Roger.
What is your recommended IDE or editor for Haskell?
Most people use vscode. I personally find Emacs to be great but wouldn't recommend investing time into learning it if the end goal is just to learn haskell. vscode is more than friendly enough
@@GavinFreeborn At the moment I don't have a clear defined goal with functional programming. It was something I was and am still considering to improve my skills in programming and gain a different perspective.
But I've heard of Emacs as well as NeoVim and Vim. I am strongly considering these options, I appreciate the feedback thank you.
Where's the link to the Haskell talk you mentioned @ ~1:59?
Nice save I will add that now
th-cam.com/video/DebDaiYev2M/w-d-xo.html&pp=ygUZd2hhdCBtYWtlcyBoYXNrZWxsIHVuaXF1ZQ%3D%3D
"Functional core, imperative shell."
Here's a technique for handling input that comes from the imperative shell to the functional core: Monadic Parsers at the Input Boundary. th-cam.com/video/LLkbzt4ms6M/w-d-xo.html
Why learn it??? because it helps you get good at Elm.... which will destory Javascript in the long run.... a worthy goal for anyone.
is there a Haskell equivalent for LISP macros? i've only used something like Haskell
Template Haskell. Very well-known to be unergonomic, but it's Haskell forcing "never use a macro when a function will do".
@@Instr oh. this is my first time hearing about Template Haskell. thanks for pointing me in that direction! i do wonder why function couldn't do the same job as a macro
@@xybersurfer Functions can't read raw code, given a function, the most a higher order function can do is to apply the function to data, preprocess the inputs of the function, or postprocess the outputs of the function. It can also inject effects, obviously, but in Haskell effect injection / actions is somewhat complicated (you end up in a monadic type context of some kind, many of which cannot be exited trivially or safely).
I presume Haskell is mostly for backeneders?
For browser support there is recent support for compiling Haskell to JavaScript but if you want something more mature look at purescript. It's basically Haskell that compiles to js without lazy evaluation and a few extra features. I've used it for a few projects and can happily recommend it.
@@GavinFreebornPureScript is way too behind the ghc and is definitely not getting dependent types because nobody is going to put in that effort. Might as well just stick to haskell. There's frontends like Miso
Almost every language now is trying to emulate / port all of the great features of Haskell.
At some point you have to ask yourself... Why not just learn Haskell? Its a great language.
It has a weird syntax. Other languages translate into English, whereas Haskell translates into mathematical formulas.
Or at least that's how I see it.
@@astral6749lol no it looks exactly like math and reads like English. C absolutely does not read like English and is the weird one
The only downside of Haskell is, the syntax is not S-expression
Someone once saw me using Lisp and said something to the effect of "You should try Haskell, it's like Lisp but with less parentheses". My response was "Oh, that's too bad. Sounds good otherwise though!"
Oh yes, it hurts so bad to have the choice to write:
foo = bar . baz . quux
or
foo a = bar (baz (quux a))
rather than:
(define (foo a) (bar (baz (quux a))))
Absolutely intolerable...
The parenthesis aren't what you like about s-expressions anyway. It's more likely the regularity, lending itself easily to manipulation, whether you see it as code or data. And Haskell really isn't very lisp-like, particularly with the static type system. We wouldn't have a procedure like number? (pardon the Scheme) but a declaration like foo :: Num a => a -> a making that predicate moot. Or you use a sum type, perhaps from Aeson or S-cargot.
@@0LoneTech Oh my, you're very passionate! I'm happy that you like Haskell so much. :)
@@defaultxrs expressions are objectively bad. The only reason it's a thing is because LISP wanted it's surface syntax to be nearly identical to AST so they they could treat code as data, which as well as know now is a terrible idea unless you're specifically making a DSL
@@AndreiGeorgescu-j9p [citation needed]
I always found Haskell weird but that's how it differentiates from other languages.
mark my words next year the video title is gonna change to 2025
I'll set a reminder 😉
Why do near 30% of programmers tend to give you "uncanny valley" vibe in their videos?😅
Probably because they are extremely uncomfortable reading scripted content. I really need to work on that
Haha so basically the reason why you moved from Go to Haskell is that your devs didn't understand the design. Rofl!
I have no idea how this popped up on my feed but I remember your name from a programming discord I used to be part of. Possibly because I'm learning Ocaml right now. Subbed, I guess.
haskell is a math language
Haskell fits quite neatly into a family of languages that seems to cater to people who spend more time talking about writing code than actually writing or shipping code.
Definitely, so concise you don't end up having to write all that much code 😅
What might those other languages be?
@@yxtqwf SmallTalk, Lisp, Closure, Lustre ... that kind of nonsense.
First of all, in modern days nobody uses Lisp language, it's known as a language family. Second, projects developing by Clojure (which is a lisp lang btw) and Haskell are published in corresponding pages, which could be easily found, instead of wasting time to make another bs statement on "useless" languages.
@@qandak Case in point.
Do you live in a tiny house, Gavin? Give us a tour! :D
Just a small studio with a loft. I'll do a quick tour for the 10K subscriber milestone :)
Am I the only who think Haskell syntax is beautiful?
Writing a function needs to be really really easy, because breaking up programs needs to be something a programmer does with very low activation energy. Haskell gave me the impression that I was signing a contract with a lawyer present every time i tried to write a function
foo arg1 = bar. What's the problem? Unless you're TyDDing it, you can pass off the type signature to the IDE, which will mutate the type signature via inference as you write the function; when you're done, click the code shadow. If the signature looks wrong, you probably screwed up somewhere anyways.
Also, it's idiomatic to skip type sigs in where clauses, so you can just define an IO action then write the functions it uses in the where clauses. What's the problem?
The syntax is very literally created to make defining and using functions as simple as humanly possible. Areuslow?
@@Instrlowiq people who want to protect their egos by mocking something they don't understand
Are you in an RV?
Just a small studio haha
@@GavinFreeborn No joke Gavin, you inspire me so much. 👍
You look too happy, haskell can't be any good😂😂😂
Tbh I found Rust way simpler than Haskell is it just me or ?
Rust is imperative programming with some features inspired by the functional world and extra formalism around generics and lifetimes.
Haskell on the other hand is a language that sometimes likes to dress-up functional programming to resemble the imperative model. But in the end all the constructs behind it are alien to those who have lived in the imperative land (unless they have background in math, I guess).
Haskell code is like: traverse this that
Rust code is like Foo::Arc
ur house looks cool
"purely" functional, as long as you don't look under the hood, but its a great language, and you cant fault it for how computers work and the factual limitations of reality.
Ya, look into the caves and there be many dragons
You take away the purely functional branding and the syntax reduces to Python with much better functional programming support, performance, and type safety.
The entire purely functional thing is a mirage, anyways. It's all lambda calculus under the hood, but Haskell supports immutable pointers to mutable variables and replaces for loops with higher order functions that are much more descriptive, including for and for_ hofs.
There's nothing about purely functional that doesn't allow any mutation whatsoever. It's just that you have to mark mutable objects as part of your type system. For example, ST does mutate, IO is dependent on outside output, IORef is both mutable and IO.
The way I see it is that the developer sort of integrates their pure functions into a monad (IO) that keeps the impure parts away from them. Those impure parts are a part of the runtime.
But yeah, obviously it can't be absolutely pure, as it would be completely useless then, unable to achieve any effect. It just tries to put a barrier between the pure and impure parts of it.
@@MRL8770
One trend I'm investigating is the one wherein the IO parts just get replaced by a framework. It's ironically very natural for Haskell, since IO is an unfortunate sacrifice to pragmatism, but why not hide the entire IO part of the system with a framework? Then you just plug in pure functions, values, and callbacks into the framework and it's way more expressive and powerful than anything you could do with a conventional language.
Or, in other words, you go from "Haskell is for Wizards" to "Haskell is a Wizard" and you just specify the callbacks and values you want for the mechanism.
Haskell has no practical usage, waist of time unless you want to go deep in the theory. Your example of `add a b` function is practical demonstration of putting the lipstick on a pig. Clearly both 'a' and 'b' are integers so `return (a + b)` would logically be simple integer, But for some reason you wrap up the integer into the strange 'IO' thingy as 'IO Integer'. Why the f..k for such a simple thing like adding 2 numbers and printing the debug log one have to dedicate time to lengthy study about the monads and eventually learn that IO monad is just the one out of plethora of monads used in Haskell and to deal with them all one has to learn even more impractical and useless and crazy concept of monad transformers just to be able to push the same simple value between monad domains? In every practical programming language making adder function and printing the result is dead simple except of Haskell.
Ya if your program is simply adding two static numbers and print the result I certainly wouldn't choose haskell. Choose the right tool for the job. I do find it nice for developing more complex applications personally for exactly the reason it seems to bother you. Doing things that often lead to trouble like mutating state and general io operations are more of a bit more work but mean you don't have to worry about them leading to unforeseen errors later down the road. All just my own opinions though. I have had so many problems crop up related to these issues at multiple companies on multiple projects. Just because someone did a quick mutation they didn't notice they costed someone else a day or more of debugging to fix it.
Beautiful language. Horrible tooling.
I attempted to learn haskell in the past and had the feeling. Now with ghcup and cabal becoming more fully featured I find haskell much more user friendly. I'd say for the age of the language the tooling is decent and mostly lacking in learning opportunities. With the love this video has gotten I plan to make videos helping new users get to grips with the newer tooling.
www.haskell.org/ghcup/
cabal.readthedocs.io/
It's literally a 1 button install
Don't say haskell . Just say lisp.
Because it's in University's curriculum 😢
Pure functional languages don't exist.
Everything is procedural in the end.
Chemistry doesnt exist. Everything is physics in the end. Oh wait…
Technically, functional languages are procedural. The only exception is that any data has a type signature, which cannot be changed or ignored. Purely procedural languages have a very week type system. If I remember correctly, C used to have only binary, integers and characters, everything else including floats and strings had to be build from scratch and you could change types by accident.
OOP and Structured doesn't exist, it's all binary
Binary doesn't exist it's all nand gates
Do you know howdum u sound?
@@PhthaloJohnsonno they're not technically procedural. These are all high level languages including C. Roomtempiq
Ocaml > Haskell
Nobody except a finance bro who wants to work at Jane Street thinks this
What are you smoking lol?
Better spend time learning AI/ML haskell is a waste of time
"data scientists" make me lol. Bad at statistics and bad at engineering. Filled with chicks who have marketing degrees