lets talk Functional Programming. Is haskell based? What are some use cases?

lets talk Functional Programming. Is haskell based? What are some use cases? I really want to get into FP, but not sure where to start, between Haskell, OCaml, Elixir which would you pick?

A Conspiracy Theorist Is Talking Shirt $21.68

Ape Out Shirt $21.68

A Conspiracy Theorist Is Talking Shirt $21.68

  1. 2 months ago
    Anonymous

    https://learnyouahaskell.com/

    • 2 months ago
      Anonymous

      I know the basics of haskell, but I want to dive deeper, or take up another FP language

      • 2 months ago
        Anonymous

        >Is haskell based?
        >I know the basics

    • 2 months ago
      Anonymous

      I know the basics of haskell, but I want to dive deeper, or take up another FP language

      >Is haskell based?
      >I know the basics

      • 2 months ago
        Anonymous

        gooh gooh ga ga

      • 2 months ago
        sage

        using an aryan here promotes harmful racial stereotypes

      • 2 months ago
        Anonymous

        gem

    • 2 months ago
      Anonymous

      what's the point of this when you have chatgpt?

      • 2 months ago
        Anonymous

        Shouldn't you be asking chatGPT, stupid homosexual?

    • 1 month ago
      Anonymous

      Wowowowoe! Tutorial in pure html, I am getting wet innere

      • 1 month ago
        Anonymous

        Apparently GHCJS is still not ready for the real world.

      • 1 month ago
        Anonymous

        https://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html

  2. 2 months ago
    Anonymous

    Elixir is an oddball. It's "pragmatically" functional and I like it more for the BEAM and its macro system. I think it's the future but it doesn't scratch the same itch that something like Haskell does

    • 1 month ago
      Anonymous

      Elixir is just ruby syntax applied to BEAM which is an actor programming framework (with built in networking). If your problem is best solved with actors, its awesome. But you also have AKKA and AKKA.net that solves the same problems, maybe not as elegantly as Elixir/BEAM, but close enough.

      Actor pattern is how you scale to discord or twitter like demand.

      Where does F# fit into all of this?

      Its OCaml for .net framework. Its so good C# design team copies everything F# team does in an awkward and incomplete way. Most C# programmers are clueless to this.

      The result of Microsoft unsuccessfully trying to abduct and rape fp enthusiasts. The only reason to use it is if your job is mandating .net everywhere but gives you enough flexibility to use something other than C#. Hardly anyone uses it.

      Its pretty successful, although in its finance niche. Its far more elegant and less verbose than C#. C# is the pajeet choice after Java. F# is the enlightened choice in .net ecosystem, but you will be alone.

      I don't have enough RAM to run a Haskell Hello World.
      Also, F# is cool. It's like OCaml but with the ,NET ecosystem and pretty decent tooling. It's not as "pure" as Haskell.

      > It's not as "pure" as Haskell.
      Not its not, which is why I like it. Haskell is so fricking pedantic it feels like it was designed for proof of concept academic projects.

      • 1 month ago
        Anonymous

        Good luck finding a job in that dead lang.

        • 1 month ago
          Anonymous

          Oh definitely, I cram it into every company I work in like a serial internal git rapist. Usually on some crucial but one off project that they have to use but can't understand the code of. good luck firing me.

  3. 2 months ago
    Anonymous

    Pandoc and hledger are two beautiful softwares written in haskell. I can't name anything written in the other two.

    • 2 months ago
      Anonymous

      Discord is mostly written in elixir
      Idk what ocaml is used for other than Jane Street

      • 2 months ago
        Anonymous

        Compilers.

      • 2 months ago
        Anonymous

        Discord uses Elixir and Rust for the performance critical stuff, they originally used GO but switched to Rust because of the GC.

  4. 2 months ago
    Anonymous

    If you like static typing, try getting started with Haskell or OCaml. See which works better for you
    If you like dynamic typing, try elixir if you're comfortable with lua or ruby, Erlang if you're a based boomer or Clojure if you like lisp
    That's it, Godspeed anon

  5. 2 months ago
    Anonymous

    Where does F# fit into all of this?

    • 2 months ago
      Anonymous

      The result of Microsoft unsuccessfully trying to abduct and rape fp enthusiasts. The only reason to use it is if your job is mandating .net everywhere but gives you enough flexibility to use something other than C#. Hardly anyone uses it.

      • 2 months ago
        Anonymous

        The other reason is if you like OCaml, but want a usable std and ecosystem.

    • 2 months ago
      Anonymous

      its good, have a look at typeproviders for something that may be unique to the language. I used the Fake build system for my C# projects build / deploy toolchains and it worked out really nicely. I'm a fan of F# but haven't used it for anything significant so far.

  6. 2 months ago
    Anonymous

    It is based as frick.

    Because it is.

    Extremely well designed -- they've thought of ~everything without complicating too much (like Scala, which tried everything and failed)
    Long-term evolution: it's been around for decades and has evolved organically
    Beautiful, clear syntax
    Makes writing "correct" code easy
    Surprisingly fast and performant
    For those who think in Types, it gives you very strong tools
    Somewhat hard to pick up, so appeals to the intelligentsia and the morons on IQfy

    • 2 months ago
      Anonymous

      As someone with double digit iq and questionable skin color I can confirm that Haskell appeals to morons.

    • 2 months ago
      Anonymous

      > Extremely well designed
      This language has 3 types of strings and around 5 alternative standard libraries because standart one is so shit everyone wants to create their own. Haskell is as well designed as js when it comes to libraries
      > Long-term evolution: it's been around for decades and has evolved organically
      It doesn't work properly anywhere except x64 Linux and require some library for anything, even dates, jsons and collections
      In haskell, only it's language specification is great. Everything else is so shit you can't use it for anything except cli apps and compilers
      > Surprisingly fast and performant
      Only when you know language very well and able to see what code under all these abstractions and lazy evaluation are doing. And in reality any performant code would look like ugly non idiomatic mess

      • 2 months ago
        Anonymous

        String = [Char]
        Lol.

        Also, originally Monad was not a superclass of Applicative because it came first.

        It indeed has a lot of issues with it. Rust also seemed super clean at the start because it could learn from many of the mistakes of other languages but the warts are starting to show.

        • 2 months ago
          Anonymous

          go cold turkey with haskell. with other choices, you get the tempation of using mutable state as a crutch and thus failing to learn what you sought to learn

          there's also Text and Bytestring, and 2 variants of each. That being said, it's only really an issue when you have to use qualified names everywhere. I hate that shit

          • 2 months ago
            Anonymous

            I more so mean that “String = [Char]” was a terrible decision, those 32-biye chars are boxed by the way.
            A linked list of 32-byte chars, all of them on the heap, to encode a string.

            There's a good reason other functional languages such as Scheme and OCaml never did that but if you ask me String should be a typeclass, not a type which they did do for numbers so it's weird. Then again, I'm not sure why Haskell doesn't have a general Sequence typeclass either. It's obviously easy to define but there are many standard library functions that demand a list in particular that could work fine with any abstract sequence.

            Strings as linked list is a terrible decision, but as said, make it a type class and give them both as lists or as constant time vectors.

          • 2 months ago
            Anonymous

            It's a tug of war between pragmatists and autists.
            >I'm not sure why Haskell doesn't have a general Sequence typeclass either.
            There's lists, functors, foldable and traversable.

          • 2 months ago
            Anonymous

            to be fair, some "looser" versions of polymorphic sequences can already be approximated through existing typeclasses. Traversable and MonadPlus should let you do a lot of the things you want to do with sequences.

            Have you met the monadic-bang gang?

            monadic bang is neat for small examples but is also counterintuitive. for example:
            setRef x "40" >> print !(readRef x)
            doesn't do what you might think

            >between Haskell, OCaml, Elixir which would you pick?
            Clojure

            clojure is cool but frankly it's stupid in a lot of ways

          • 2 months ago
            Anonymous

            >clojure is cool but frankly it's stupid in a lot of ways
            It has a few rough edges I agree, but it's great for people like me who suck at remembering syntax

          • 2 months ago
            Anonymous

            The "right" order isn't a consequence of the simple rule: do !(!mma) !mb = do ma <- mma; b <- mb; !ma b
            We could transform the `>>` into `;` first.
            With Ghc-8.4 LSP understood monadic bang until I split my project into multiple files. The newest GHC/LSP has no problems.

            Yes, there you go, random “where” clause has to be made temporary binding, for what reason?

            Now imagine breaking from a nested loop. It becomes unnecessarily messy very quickly for no good reason.

            Did you try Control.Monad.Cont? I don't use it because mapMaybe or other functions from base and lens don't leave me reaching for deeply nested loops with break.

  7. 2 months ago
    Anonymous

    >he wants use cases
    Scala
    Yes, it's the least pure of the FP languages, but there is more shit build in it than the others (except Erlang but you're not 50 years old)

    • 2 months ago
      Anonymous

      >except Erlang but you're not 50 years old
      Elixir can call any erlang module with technically 0 friction and is syntactically similar to ruby.

      Has there been a single relevant program made using a functional language? If so what one?

      Discord, plenty of others. FP features have been bundled into every corpolang and are now the default way to do certain things (LINQ and lambdas are fricking everywhere in C#).

  8. 2 months ago
    Anonymous

    Elixir is still typeless (until next year)
    Right now if you want to do FP productively, unironically I recommend either Scala or Clojure.

  9. 2 months ago
    Anonymous

    Haskell is cool. Haskell programmers are ALL smug amateurs.

  10. 2 months ago
    Anonymous

    haskell is worth trying as a learning language, I don't think I'd like it for writing serious programs though.

  11. 2 months ago
    Anonymous

    Has there been a single relevant program made using a functional language? If so what one?

    • 2 months ago
      Anonymous

      https://github.com/apache/spark
      >it's not all pure FP
      Yeah, pragmatism wins

    • 2 months ago
      Anonymous

      Telecoms software.
      Big data processing systems.
      Media streaming services.

    • 1 month ago
      Anonymous

      crash bandicoot is one.

    • 1 month ago
      Anonymous

      for haskell specifically:
      GHC
      plutus (for the cardano blockchain)
      pandoc
      xmonad
      criterion (software benchmarking suite)
      hedgewars: the server is written in haskell
      copilot
      there's also software used by companies (such as facebook, mercury, standard chartered, groq) and lots of unshared software (such as a few tools I wrote for myself in haskell)

  12. 2 months ago
    Anonymous

    I don't have enough RAM to run a Haskell Hello World.
    Also, F# is cool. It's like OCaml but with the ,NET ecosystem and pretty decent tooling. It's not as "pure" as Haskell.

  13. 2 months ago
    Anonymous

    In practice, non-strict languages weren't worth it I'd say.
    Idris is also strict though purely functional.

    I don't get this overcomplicated “monad” shit though. Like, is there any real harm in:
    >Language type system has a distinction between pure and impure functions
    >pure functions can only call other pure functions
    >impure functions can call both pure and impure functions
    >main is obviously an impure function

    Like what am I missing? How is that not just as good and far simpler? Is it just so you can say “the language is purely functional” rather than “the type system discriminates between pure and impure functions” even though monads are nothing more than a type system hack that force the optimize to respect a certain sequence and under the hood PutStrLn : String -> IO () is actually just an impure function and “IO” is simply a container around a linear datatype.

    At least Clean wasn't hiding what it was doing and simply returned the “world” type.

    • 2 months ago
      Anonymous

      >Language type system has a distinction between pure and impure functions
      >pure functions can only call other pure functions
      >impure functions can call both pure and impure functions
      >main is obviously an impure function
      homie you can do all that in C23 with [[u sequenced]] and [[reproducible]]
      And in any C standard with GCC/clang attributes pure/const
      That ain't functional programming

      • 2 months ago
        Anonymous

        He was complaining about monads fricking the type system and proposing this instead. I agree with him. The only good thing I can see in monads is not needing explicit error handling (if an error occures in any step in your error monad it is returned by the function)

      • 2 months ago
        Anonymous

        You didn't answer what the effective difference in provability and the benefits of referential transparency was.

        There are more stuff that you expect from a foonctional lang
        some support for recursion optimization. Admittedly even C has it in a very basic form with attribute musttail
        Some way to do higher-order functions that doesn't SUCK. (function pointers fricking SUCK because they never inline)
        Algebraic data types
        Strong type systems in general, shit like covariance/contravariance is hard to do without once you've tasted it
        Some form of generic because you can't go very far with void pointers
        And in general, I'd say functional languages are more about what you can't do than what you can do. The more pure your computation graph is, the more your compiler can do its thing, so enforcement matters. You kinda want to be able to force coding in a way such that the next imperative brained dude who touches your code doesn't destroy your beautiful computation graph.
        So yeah, there's more to FP than "imperative, but lots of pure functions"

        All this has nothing to do with whether monads are used instead of a simple pure/impure distinction. It can exist independently of that.

        Yep. The Jane Street style ecosystem is good but very small. I don't really like OCaml syntax either. But OP didn't give many options, and I'd pick OCaml over Haskell because the Haskell standard library situation is so frustrating.

        [...]
        What? You don't have to use do-notation to use a monad. You can just do something like
        main = putStrLn "Hello, world"

        Your stream alternative has been tried in the past and was far worse, as was passing around a "world" type.
        I seem to have stepped into some kind of Dunning-Kruger thread. Only total beginners who can't program in Haskell think that monads are difficult or complicated. It's like reading these morons on Reddit who complain about Python's indentation or __main__, as if these "problems" weren't insignificant.

        I didn't even mention do-notaation which is purely syntactic sugar.

        The point is get GetLine >>= PutStrLn under the hood simply calls two unpure functions. What actually more or less happens is that two impure functions exist:

        GetLine# :: World -> (String, World)
        PutStrLn# :: (String, World) -> World
        Where “world” is essentially a virtual datum that does nothing, every impure function accepts a “World” argument and returns one. Since they all depend on the World argument returned by the last, the graph reduction algorithm must execute them in sequence. That's what >>= effectively does behind the screens, it unpacks that World argument and feeds it to the next function.

        Monads are simply one giant hack that abstract away a Uniqueness type like Clean has that is never exposed to the user and the IO Monad, which can't be used defined and is simply part of the language handles it behind the screens and ensures that it stay unique.

        Clean works similarly except it makes this visible and requires the programmer to explicitly pass this dummy value around and the type system enforces the constraint upon it that it be Unique which is Clean's way of saying “linear type” but at least it doesn't hide that these functions are basically impure functions wrangled into a type system that acts like they aren't.

        It feels like it mostly exists to say “all our functions are pure”, not to give any greater provability or ability to reason over code.

        • 2 months ago
          Anonymous

          >one giant hack
          You repeating this doesn't make it so. Monads are super simple and easy to understand, and I genuinely don't get why you seem to be so against them. Do you even program in Haskell, or just talk about it?
          Your proposed solution of passing around a World value was tried before, and it just makes things inconvenient for no good reason. It requires the programmer to pass around values, and people would have to reinvent do-like syntactic sugar anyway to make things convenient. I don't understand why you want to do this.

          Also, I never mentioned “streams” either as in what Miranda does. You're arguing against ghosts.

          I said that it's far simpler to simply have the type system discriminate between pure and impure functions and enforce a constraint that:
          >impure functions can call both pure and impure functions
          >pure functions can only call other pure functions

          That's it. Nothing else is needed. No streams, no monads, no uniqueness types.

          I didn't mention this because I thought it's pretty obvious why this isn't done. Impure functions interact extremely poorly with lazy evaluation, and break referential transparency. So you'd have to get rid of the two things that make Haskell Haskell. If you want that, you already have Kotlin (not an insult, Kotlin is actually nice to program in).
          Also, how would it be "far simpler"? Monads are already very simple. You're proposing solutions to imaginary problems.
          And you never addressed that monads are a lot more general than just a system to mark things pure or impure. For example, once you have something like do notation, it can be reused for parsers, async computations, or probabilistic computations.
          If you need a beginner Haskell book, I recommend the purple one.

          • 2 months ago
            Anonymous

            >You repeating this doesn't make it so. Monads are super simple and easy to understand, and I genuinely don't get why you seem to be so against them. Do you even program in Haskell, or just talk about it?
            >Your proposed solution of passing around a World value was tried before, and it just makes things inconvenient for no good reason. It requires the programmer to pass around values, and people would have to reinvent do-like syntactic sugar anyway to make things convenient. I don't understand why you want to do this.
            It isn't my proposed solution. Read.
            I simply said it abstracts that away and does it behind the screens and that these functions aren't pure at all but the hack is hidden from the user by use of Monads.
            My solution is what Koka indeed does. Simply partition the language into pure and impure functions on a type system level and that's it.

            Monads are incredibly overengineered to abstract away effects and on top of that annoying to program in and often read to purely readable code, that's why Do-notation was invented because without it, code would quickly become unreasonable and even with it it's not pretty.

            >I didn't mention this because I thought it's pretty obvious why this isn't done. Impure functions interact extremely poorly with lazy evaluation, and break referential transparency. So you'd have to get rid of the two things that make Haskell Haskell. If you want that, you already have Kotlin (not an insult, Kotlin is actually nice to program in).

            It's pretty easy to make all impure functions strict and make no such condition apply to impure functions.

            But Idris is strict and still uses this IO Monad thing for effects. That's simply weird.

            Also, many impure languages use call by name. Algol already did it. It's quite easy to make Haskell so that even impure functions are called by name, which can of course become call-by-need for any pure functions.

          • 2 months ago
            Anonymous

            >But Idris is strict and still uses this IO Monad thing for effects. That's simply weird.
            It's not weird. Monads are the most elegant way to handle side effects if you want a language that's lazy and/or referentially transparent. The Monad typeclass can be defined in just a few lines of code, and if you add a bit of syntactic sugar, you get a very general abstraction for things that can be sequenced together: I/O operations, parsers, async operations in coroutines, probabilistic computations, etc. Monads are so simple that anyone smart can understand them in 15 minutes, and so useful that people who come from Haskell often miss them in C# or Scala, and want to reinvent them. I find your insistence that they're complicated, difficult, and overengineered is ridiculous. You should go read a beginner Haskell book instead of inventing imaginary problems to justify things you don't understand.

          • 2 months ago
            Anonymous

            Anon, no, all of that can be done in a far simpler way by simply letting the type of the function dictate whether it can have effects or not.

            Everyone understands monads, everyone understands GOTOs as well. Code written with monads quickly becomes completely unreadable without do-notation so that needed to be added at well and at that point what you're left with is simply the same syntax as in an imperative language, but less expressive.

          • 2 months ago
            Anonymous

            >people who come from Haskell often miss them in C# or Scala
            how are they missing in Scala?
            Idk the exact definition and I don't care, but Option and Try work for all the use cases your cited. Using for comprehensions instead of do notation. Not that I use them cause you get 90% of the benefits of FP using map/filter/reduce and pattern matching...

          • 2 months ago
            Anonymous

            Result-like types are also a monad by the way, that's why Either and Just in Haskell are also in that type class.

            Rust syntax with the carrier trait is a lot more convenient though, and Rust's type system can't fully express monads due to the lack of higher-kinded traits.

            But no, monads to trick the type system into believing that impure functions are actually pure without all the disasters the optimizer would do is asinine and overengineered. Simply admit that they aren't pure and be done with that.

            It's a hack like Uniqueness types except it's even more abstracted away. It is literally just secretly handling a Uniqueness type behind the screens and having impure functions without owing up to it, which is IO a is magical and special. It can't actually be defined by the user because it'a a special compiler hack to act like impure functions aren't pure.

            If it were so elegant one would be able to define it oneself and write one's own Monad IO implementation, but one can't; it simply exists.

          • 2 months ago
            Anonymous

            >Option and Try
            >for comprehensions instead of do notation
            Congratulations, you just reinvented them with slightly different syntax
            >Idk the exact definition and I don't care
            Why argue about things you don't understand? You could just google the definition. I swear, the people on this website are getting more moronic by the year.

            Anon, no, all of that can be done in a far simpler way by simply letting the type of the function dictate whether it can have effects or not.

            Everyone understands monads, everyone understands GOTOs as well. Code written with monads quickly becomes completely unreadable without do-notation so that needed to be added at well and at that point what you're left with is simply the same syntax as in an imperative language, but less expressive.

            Okay, so add do notation. What's the problem again? It seems that you really dislike monads but can't formulate any sensible argument against them, you just parrot that they're "overcomplicated" and other methods are "far simpler", which is obviously not true - monads are simultaneously simple and general, and I already pointed out that you can't have impure functions if you want your language to be lazy and/or referentially transparent.

          • 2 months ago
            Anonymous

            Yes, you stated that, and I pointed out that you were wrong and even Algol, which was not referentially transparent also had call-by-name semantics.

            Anon, if you actually believe that monads are simpler than simply having impure functions you're insane. The fact that they needed to add do-notation, which again is less flexible shows this.

            Something extremely basic like like an infinite loop that keeps on running and handles events is, even with do-notation, not that clean in Haskell. You have to create some kind of temporary binding and have the function call itself. You're crazy if you think that
            main = loop
            where loop = do
            <CODE GOES HERE>
            loop

            Is somehow not a convoluted solution for what could be:
            loop {
            <CODE GOES HERE>
            }

            do-notation only solves the most trivial of cases
            Next up is breaking from a loop based on a condition using do-notation which quickly becomes a hack of injecting (), now try breaking from a nested loop...

            Monads aren't problematic. Using them for side-effects is. It's an overengineered solution that quickly results into hard to read code that was simply only invented to be able to say “our language is purely functional, every function is pure”, even though it's really only true as on the type level.

            And on top of that, as I said, it's magical. One can't write the IO Monad oneself as a library function as one can write the Maybe Monad or the Either Monad or the List Monad. It's magic provided by the runtime.

            It's a tug of war between pragmatists and autists.
            >I'm not sure why Haskell doesn't have a general Sequence typeclass either.
            There's lists, functors, foldable and traversable.

            Those are all not really sequences though.

            What I mean is something that has a length and an index operation within that length. Probably also things such as appending and slicing.

          • 2 months ago
            Anonymous

            monads also generalize to things like choice (lists as a monad), failure (maybe / either as a monad), and so on.
            btw your example is moronic. you could just write
            main = forever $ <CODE GOES HERE>

            with forever being either imported or written as a one-liner such as
            forever m = m' where m' = m *> m'
            you can also import or define lots of other constructs as convenient.

            Scala is the only relevant FP language and since Scala 3 it's based af.

            If you want to do pure FP use ZIO and if you simply want to get shit done use Haoyis libraries which are now part of Scala Toolkit.

            scala is irrelevant doe. it's also the troony of programming languages, as it's basically java pretending to be something like haskell. any decent haskeller can sense that there's something wrong with scala, and you can find several write-ups (for example, one from edward kmett) articulating this.

          • 2 months ago
            Anonymous

            >monads also generalize to things like choice (lists as a monad), failure (maybe / either as a monad), and so on.
            Which has nothing to do with and isn't used for side effects.

            Note that all those things can be implemented as library functions while Monad IO is magical.

            >btw your example is moronic. you could just write
            That only works if the entire main be the body of the loop which almost never happens and it certainly doesn't solve breaking from or returning a value from a loop.

            >you can also import or define lots of other constructs as convenient.

            You can, and it turns code unreadable very quickly.

            Please, write this utterly simple logic in the IO Monad:

            loop
            putStr "Please enter your name: "
            name <- getLine ()
            if name == "John" then
            break
            else
            putStrLn "Your name is wrong, let's try again."

            Obviously it's easy to write it, but it will look convoluted, messy, and hard to parse.

          • 2 months ago
            Anonymous

            import System.IO

            main = askName
            where
            askName = do
            putStr "Please enter your name: "
            hFlush stdout
            name <- getLine
            if name == "John" then
            return name
            else do
            putStrLn "Your name is wrong, let's try again."
            askName

            Replace putStr for putStrLn if you don't want to flush buffer.

          • 2 months ago
            Anonymous

            Yes, there you go, random “where” clause has to be made temporary binding, for what reason?

            Now imagine breaking from a nested loop. It becomes unnecessarily messy very quickly for no good reason.

          • 2 months ago
            Anonymous

            main = do
            name <- let loop1 = do
            putStrLn "Name?"
            n <- getLine
            if n == "John" then
            let loop2 = do
            putStrLn "Surname?"
            s <- getLine
            if s == "Doe" then
            return (n ++ " " ++ s)
            else do
            putStrLn "Wrong (nested)."
            loop2
            in loop2
            else do
            putStrLn "Wrong"
            loop1
            in loop1
            putStrLn ("Hello " ++ name)

          • 2 months ago
            Anonymous

            import Control.Monad.Cont
            import Control.Monad.IO.Class
            import Control.Monad

            main = do
            let q prompt = liftIO $ do
            putStrLn prompt
            getLine
            p = liftIO . putStrLn

            name <- runContT `flip` return $ callCC $ exit -> forever $ do
            n <- q "Name"
            if n == "John"
            then forever $ do
            s <- q "Surname?"
            if s == "Doe"
            then exit (n ++ " " ++ s)
            else p "Wrong (nested)."
            else p "Wrong"
            putStrLn ("Hello " ++ name)

          • 2 months ago
            Anonymous

            import Control.Monad.Cont
            import Control.Monad.IO.Class
            import Control.Monad

            main = do
            let q prompt = liftIO $ do
            putStrLn prompt
            getLine
            p = liftIO . putStrLn

            name <- runContT `flip` return $ callCC $ exit -> forever $ do
            n <- q "Name"
            if n == "John"
            then forever $ do
            s <- q "Surname?"
            if s == "Doe"
            then exit (n ++ " " ++ s)
            else p "Wrong (nested)."
            else p "Wrong"
            putStrLn ("Hello " ++ name)

            And would you not agree that this is beyond unreadable compared to a simple nested break from a loop?

            This is why Monads for effects are a bad idea.

            What even is this code opposed to a simple labeled outer loop and a break to it. Even without labeled loops, checking a value to decide to break is much more readable than this monstrosity.

          • 2 months ago
            Anonymous

            But it is labeled outer loop and a break to it. Instead of "label : do {" it's "callCC $ label -> forever $ do". Instead of "break label" it's "label ()". The noise from liftIO, runContT `flip` return and some of the $ is unfortunate but it's not enough to be "unreadable".
            Python can't 'break' from a nested function, so you there are more cases where you can't take a chunk of code in a loop and give a name and restrict scope. If an inner loop is a .map you can't write it as such because "while/break" wasn't designed right. Pythonic is the sour grapes cope.

          • 2 months ago
            Anonymous

            You can do my simple loop1-loop2 solution for readability like other languages or use the Cont monad which is a nuclear bomb to solve it (it solves problems beyond loops, like modeling functions that work with a ton of callbacks)

          • 2 months ago
            Anonymous

            Too bad lazy IO doesn't scale
            import System.IO.Unsafe
            inputLines = do
            x <- unsafeInterleaveIO getLine
            xs <- unsafeInterleaveIO inputLines
            return (x:xs)

            main = do
            ls <- inputLines
            process 0 ls

            process :: Int -> [String] -> IO ()
            process n stack = do
            case n of
            0 -> putStrLn "Name?"
            1 -> putStrLn "Surname?"
            case (stack, n) of
            ("John" : rest, _) -> do
            process 1 rest
            ("Doe" : rest, _) -> do
            putStrLn "Hello John Doe!"
            process 0 rest
            (_:rest, 0) -> do
            putStrLn "Wrong"
            process 0 rest
            (_:rest, 1) -> do
            putStrLn "Wrong (nested)."
            process 1 rest

          • 2 months ago
            Simon Peyton Jones

            >unsafeInterleaveIO
            delete this

          • 2 months ago
            Anonymous

            Proper LinearTypes multiplicity polymorphism when?

          • 2 months ago
            Anonymous

            a lot of imperative languages don't support breaking out of nested loops either :). probably for good reason, too. most nested loops are better done by having a single loop with the combined iterators from the two loops it replaces. other use cases would have to be judged separately to decide whether nested break would be readable

            btw

            import Control.Monad.Cont
            import Control.Monad.IO.Class
            import Control.Monad

            main = do
            let q prompt = liftIO $ do
            putStrLn prompt
            getLine
            p = liftIO . putStrLn

            name <- runContT `flip` return $ callCC $ exit -> forever $ do
            n <- q "Name"
            if n == "John"
            then forever $ do
            s <- q "Surname?"
            if s == "Doe"
            then exit (n ++ " " ++ s)
            else p "Wrong (nested)."
            else p "Wrong"
            putStrLn ("Hello " ++ name)

            is dunking on you for fun

          • 2 months ago
            Anonymous

            I'm guessing that name isn't meant to be scoped in the loop. just do
            name <- untilJust $ do
            t <- getLine
            pure (if t then Just t else putStrLn "Your name is wrong, lets try again" $> Nothing)

            ...

            untilJust m = n where
            n = do
            x <- m
            case x of
            Just a -> pure a
            Nothing -> m

            this could be less verbose, but this way you can make sense of it. you could also just search
            Monad m => m (Maybe a) -> m a
            in Hoogle to find an implementation of untilJust and import it.

          • 2 months ago
            Anonymous

            by "you" in "this way you can make sense of it", I mean someone with basically zero haskell experience.

          • 2 months ago
            Anonymous

            Lmao Haskell cope. Scala is the only FP lang with a decent amount of Jobs out there. You can't find a single large enterprise that isn't using it somewhere. Even Apple has plenty of open Scala positions. Keep coping with your autistic language that no one uses. Pure FP is moronic.

          • 2 months ago
            Anonymous

            If you’re evaluating languages by jobs, stick to Python, JavaScript, and the POO languages.

    • 2 months ago
      sage

      >I don't get this overcomplicated “monad” shit though. Like, is there any real harm in:
      I suggest you check out effect systems. They can solve many of the same problems of monads, but without the ivory tower feeling.

    • 2 months ago
      Anonymous

      There are more stuff that you expect from a foonctional lang
      some support for recursion optimization. Admittedly even C has it in a very basic form with attribute musttail
      Some way to do higher-order functions that doesn't SUCK. (function pointers fricking SUCK because they never inline)
      Algebraic data types
      Strong type systems in general, shit like covariance/contravariance is hard to do without once you've tasted it
      Some form of generic because you can't go very far with void pointers
      And in general, I'd say functional languages are more about what you can't do than what you can do. The more pure your computation graph is, the more your compiler can do its thing, so enforcement matters. You kinda want to be able to force coding in a way such that the next imperative brained dude who touches your code doesn't destroy your beautiful computation graph.
      So yeah, there's more to FP than "imperative, but lots of pure functions"

    • 2 months ago
      Anonymous

      He was complaining about monads fricking the type system and proposing this instead. I agree with him. The only good thing I can see in monads is not needing explicit error handling (if an error occures in any step in your error monad it is returned by the function)

      >overcomplicated “monad”
      How do you not get something this basic despite knowing about so many functional programming languages? Do you just write a hello world in each of them and then move on to the next?

      • 2 months ago
        Anonymous

        Because they're moronic larpers

        Between these, I'd pick OCaml and get into the Jane Street ecosystem.
        If you want Haskell, then the purple book is better than LYAH. But I don't do Haskell anymore. The standard library is terrible, it doesn't even have a decent string type or a hashtable. And I'm not convinced that lazy evaluation is a good default. Monads are totally fine though, people who think they're difficult are just brainlets.

        I broadly agree with you on Haskell but the ocaml ecosystem seems dismal

        • 2 months ago
          Anonymous

          Yep. The Jane Street style ecosystem is good but very small. I don't really like OCaml syntax either. But OP didn't give many options, and I'd pick OCaml over Haskell because the Haskell standard library situation is so frustrating.

          Personally I dislike the effects of monads in the type system. If you want to include in your function something which for whatever reason is provided in a monad, well you are forced to return a monad and thus do the imperative style do notation even though it doesn't have to be that way and your function could have been a one-liner if that stupid thing wasn't provided in a monad. There are alternatives to monads, you could use streams or infinite lists for user input, random numbers and a lot of other monads

          What? You don't have to use do-notation to use a monad. You can just do something like
          main = putStrLn "Hello, world"

          Your stream alternative has been tried in the past and was far worse, as was passing around a "world" type.
          I seem to have stepped into some kind of Dunning-Kruger thread. Only total beginners who can't program in Haskell think that monads are difficult or complicated. It's like reading these morons on Reddit who complain about Python's indentation or __main__, as if these "problems" weren't insignificant.

          • 2 months ago
            Anonymous

            Also, I never mentioned “streams” either as in what Miranda does. You're arguing against ghosts.

            I said that it's far simpler to simply have the type system discriminate between pure and impure functions and enforce a constraint that:
            >impure functions can call both pure and impure functions
            >pure functions can only call other pure functions

            That's it. Nothing else is needed. No streams, no monads, no uniqueness types.

          • 2 months ago
            Anonymous

            >You don't have to use do-notation to use a monad
            You do if something you need to use is provided in a monad
            x <- returnsMonad y
            Were you projecting when you said we don't write anything more than hello world lol?

          • 2 months ago
            Anonymous

            Have you met the monadic-bang gang?

          • 2 months ago
            Anonymous

            >I seem to have stepped into some kind of Dunning-Kruger thread.
            You are on G, after all

      • 2 months ago
        Anonymous

        Personally I dislike the effects of monads in the type system. If you want to include in your function something which for whatever reason is provided in a monad, well you are forced to return a monad and thus do the imperative style do notation even though it doesn't have to be that way and your function could have been a one-liner if that stupid thing wasn't provided in a monad. There are alternatives to monads, you could use streams or infinite lists for user input, random numbers and a lot of other monads

        • 1 month ago
          Anonymous

          >Monads == do-notation
          Uh oh, moron alert!

    • 2 months ago
      Anonymous

      See Koka for a good design of purity/impurity.
      Koka also allows you to specify other function colors, such as async, total/diverging, throwing/noexcept.

      • 2 months ago
        Anonymous

        Is it just typeclasses?

        • 2 months ago
          Anonymous

          It's this thing where you declare an "effect" (=function color) and then label the functions that need that effect.
          You can only call a colored function if either the calling function is also colored, or the function call is wrapped with an effect handler.
          Examples from Koka book:
          fun sqr : (int) -> total int // total: mathematical total function
          fun divide : (int,int) -> exn int // exn: may raise an exception (partial)
          fun turing : (tape) -> div int // div: may not terminate (diverge)
          fun print : (string) -> console () // console: may write to the console
          fun rand : () -> ndet int // ndet: non-deterministic

          fun traverse( xs : list<int> ) : yield () // <-- colored with yield
          match xs
          Cons(x,xx) -> if yield(x) then traverse(xx) else ()
          Nil -> ()

          fun print-elems() : console () // <-- color allows calling println
          with ctl yield(i) // <-- effect handler allows calling traverse
          println("yielded " ++ i.show)
          resume(i<=2)
          traverse([1,2,3,4])

          • 2 months ago
            Anonymous

            That seems like a much better system yes.
            So you can have an effect handler for impure functions inside of pure functions? How that does not seem kosher right?

          • 2 months ago
            Anonymous

            It works out nicely for mutable state that's contained within a single program, because the impurity can't escape outside the effect handler.
            For example:
            effect state<a> // declare color for mutable variable
            fun get() : a
            fun set( x : a ) : ()

            fun sumdown( sum : int = 0 ) : <state<int>,div> int
            val i = get()
            if i <= 0 then sum else
            set( i - 1 )
            sumdown( sum + i )

            fun state( init : a, action : () -> <state<a>,div|e> b ) : <div|e> b
            var st := init
            with handler
            fun get() st
            fun set(i) st := i
            action()

            fun main()
            state(3){ sumdown() } // 6, state is contained in this call
            state(10){ sumdown() } // 55, different state variable than before

            External impurity like I/O is dangerous, yes. It's kind of like Rust's unsafe where the language holds your hand up to a point, but allows hiding impure I/O if you're naughty.
            Generally, the idea is that everything requiring external impurity (e.g. I/O) is colored with the correct label and the effect handlers are near the main func.

          • 2 months ago
            sage

            The first shill in a long time to convince me to try something on IQfy (I'm not even sure you're a shill or just an autist)

          • 2 months ago
            Anonymous

            That's so cool. Is the total/div checked by the compiler or deos it just trust the user?

          • 2 months ago
            Anonymous

            The compiler checks div, or rather automatically infers most recursive functions to be div and adds the effect automatically. Unfortunately, this goes for most terminating functions too because the compiler isn't very good at recursion proofs.
            Total is just a special name for absence of effects.
            In practice, the user can leave most types and effects out because inference just werks.

          • 2 months ago
            Anonymous

            >because the compiler isn't very good at recursion proofs.
            It's the halting problem. The compiler literally cannot solve it. Do total functions recieve any beneftis?

          • 2 months ago
            Anonymous

            Right, so that's just like cats effect's typeclasses innit?

          • 2 months ago
            Anonymous

            See Koka for a good design of purity/impurity.
            Koka also allows you to specify other function colors, such as async, total/diverging, throwing/noexcept.

            >Perceus is an advanced compilation method for reference counting. Together with evidence passing, this lets Koka compile directly to C code without needing a garbage collector or runtime system. Perceus also performs reuse analysis and optimizes functional-style programs to use in-place updates when possible
            I will now try your language

          • 2 months ago
            Anonymous

            The compiler checks div, or rather automatically infers most recursive functions to be div and adds the effect automatically. Unfortunately, this goes for most terminating functions too because the compiler isn't very good at recursion proofs.
            Total is just a special name for absence of effects.
            In practice, the user can leave most types and effects out because inference just werks.

            So what about this div thing? Does it do anything, like throw a warning if your main has div, or can you handle timeout policy somewhere in a centralized place or something?

          • 2 months ago
            Anonymous

            >A warning if your man has div
            Anon... if main couldn't be div the language wouldn't be during complete.

          • 2 months ago
            Anonymous

            Sure, which is why I said a warning.
            I mean, does div do anything apart from existing?

          • 2 months ago
            Anonymous

            It's the opposite that's obviously interesting, that a function is total, which can't be decided but in reverse, if the compiler can prove it then we know that function is total and that that part of the code thus doesn't contain the bug we might be searching for.

            It's useful to avoid bugs to move divergent computations to as few functions as possible, it's like asking:
            >What good does it do knowing for sure that 99% of the functions in the language can't lead to undefined behavior, and only 1% can which are marked as such.
            You know that when you get a segfault that the problem can't be in the 99%.

          • 2 months ago
            Anonymous

            Thank you

    • 1 month ago
      Anonymous

      main is not impure. what you're missing is that functions can define changes of state over time.

      • 1 month ago
        Anonymous

        They can, but such functions aren't used here; they simply have side effects but the IO Monad is effectively having the type system enforce a continuation-passing-style discipline over using them, together with two layers of syntactic sugar that makes that style look like an imperative language again, in order to define a specific sequence of evaluation order over functions that, simply put, have side effects in a language that otherwise can't define sequencing.

        But even in a non-strict language without a defined evaluation order, c.p.s. still defines one.

        • 1 month ago
          Anonymous

          you just said in a complicated way, what i said in a simple way.

          • 1 month ago
            Anonymous

            No, I said something completely different. What I said spoke of functions that have side effects not to mention that time and changes as well as state are irrelevant for what I said. Simply that functions are not referentialy transparent.

          • 1 month ago
            Anonymous

            just because the side effects are modelled with functions doesn't mean they are not pure. side effects only matter at execution time. this is the part you are not understanding. you still think in C unfortunately.

          • 1 month ago
            Anonymous

            Everything only matters at execution time, what even is that argument.
            Let me put it like this, inside of the GHC IO source code it literally defines something like:

            newtype IO a = IO (RealWorld# -> (RealWorld#, a)

            That should tell you that anything of type IO a is really just an impure function hidden behind a newtype so it can't be called directly but what it fundamentally is is simply an impure function.

          • 1 month ago
            Anonymous

            I bet you're the guy who was on here arguing that "monads" are just continuations (wrong). imagine thinking these things when the list monad exists. you don't want to learn anything or think differently.

          • 1 month ago
            Anonymous

            No, I never said “monads” were anything. I said using monads to sequence impure functions in a language is the same as using c.p.s. to sequence them.
            You can't read and think I have something against monads in general; I don't and think they're useful. I simply think using them to express sequencing of impure functions like that and a hack the same way uniqueness types to do the same is a hack.

            There's a good reason that Eq a => Eq [a] is defined, but somehow Eq a => IO a is not. Because the former is not a hack and the latter is. One can already see that by the basic fact that the list monad is implemented in pure Haskell without requiring any compiler magic whereas the IO Monad requires special magical help from the compiler to implement and that one can't write one's own IO Monad and that it requires a magical RealWorld datatype internal to the compiler to work.

          • 1 month ago
            Anonymous

            >a high level language interfacing with low level stuff has to do hacks to abstract it
            POSIX is a hack, not raw dogging your assembly is a hack. Everything is a hack. UGLY.

          • 1 month ago
            Anonymous

            I wouldn't call what Kota does a hack. Also has nothing to do with high or low level.

            I'd call both Uniquess types and monads to sequence impure functions but claiming they're pure a hack though. What Kota does is transparent. It's open about that they are impure and treats them as such.

          • 1 month ago
            Anonymous

            Uniqueness and monads are pure. Given the same computer state as input, and the computation continuation, the result will always be the same next state. The contents are impure, the state never repeats, the clock is always ticking, it may partially repeat and give similar results. Or maybe the PC gets hit by lightning and it gets fried and suffers the ultimate side effect and your square <total<int>> never returns.
            >internally uses monads for effects
            Ok.

          • 1 month ago
            Anonymous

            >Uniqueness and monads are pure. Given the same computer state as input, and the computation continuation, the result will always be the same next state.
            Yeah no, RealWorld in both cases doesn't change and is always the same datum.

            This is entirely different from say a Unique array being mutated by a function that internally mutates it as an optimization which it knows it can perform due to the Unique type. Because it's purely an optimization and program semantics would be the same if it allocated a fresh new array and on top of that the difference can actually be observed because the array before and after can be analysed.

            RealWorld is either a datatype hidden away from the user that can't be compared, or when it can, it's a unit type that remains the same throughout the program, and obviously program semantics would change completely if the side effect were to not happen. It's not merely an optimization.

          • 1 month ago
            Anonymous

            The array mutating as an optimization is an implementation detail.
            RealWorld can't be compared because it's abstract and it represents all the pointers and memory and all the runtime state of everything. The unit type represents that too. They could use an Int instead to represent a returned status code like C.
            Clean's unique World is not just an optimization either, it enables optimizations and ensures purity.

          • 1 month ago
            Anonymous

            >RealWorld can't be compared because it's abstract and it represents all the pointers and memory and all the runtime state of everything.
            It doesn't. It gets deleted at the end of optimization by the compiler.

            It's an entirely magical type that is a zero-sized type that is given magical treatment by the compiler such that:
            >It is a zero-sized unit type so it's deleted entirely at the end
            >But, unlike all other unit types, it does create data-dependencies.

            This needs to be hardcoded into the compiler for the compilation process to work and the order of execution to be kept. If rule 2 did not apply it would order them out of sequence as an optimization. It doesn't “represent” anything in either language. It's a complete hack.

            The unit type most certainly does not represent that. It's a zero-sized type that the compiler erases.

          • 1 month ago
            Anonymous

            >pure Haskell without requiring any compiler magic whereas the IO Monad requires special magical help from the compiler to implement and that one can't write one's own IO Monad and that it requires a magical RealWorld datatype internal to the compiler to work.
            well duh, this is what an abstraction is. I suggest you read some of the papers by wadler and peyton jones back in the early 90s. it's not a hack, the language itself is pure. real world things can be modelled with mathematics.

          • 1 month ago
            Anonymous

            >well duh, this is what an abstraction is.
            >Abstraction means special compiler magic.
            No anon, the list, maybe, either and what-not monads are also abstractions but they can be written in Pure Haskell without requiring a special datatype that the optimizer treats like no other datatype to work.

            >real world things can be modelled with mathematics.
            And they're not modeling it, their “real world” is not a model; it's literally a unit type that's given special treatment by the compiler to only be erased at the end and still create data-dependencies. This is not a model of the “real world”. This is a way to sequence side effects by creating a fictive dependency that otherwise doesn't exist in a lazy language.

            The “real world” here is modeled with side-effects.

          • 1 month ago
            Anonymous

            https://dl.acm.org/doi/pdf/10.1145/158511.158524

            Also, come to think of it, with machine random number generation from quantum uncertainties, which does exist, the “RealWorld” actually cannot model it any more. Referential transparency is truly lost there even in a hypothetical case where the entire state of the world were somehow stored into a datum, a ridiculous thing to begin with even without such true random number generation because even pseudo random number generation literally takes ambient air in the room the machine is standing on as input through temperature censors.

          • 1 month ago
            Anonymous

            https://dl.acm.org/doi/pdf/10.1145/158511.158524

          • 1 month ago
            Anonymous

            And it literally says:
            >But what has become of’ the world values in the final
            >C code? The world value manipulated by the program
            >represents the current stat e of the real world, but since the
            >real world is updated ‘(in ~Jace” the world value carries no
            >useful information. Hence we simply arrange that no code
            >is ever generated to move values of type World. This is
            >easy to do, as type information is preserved throughout
            >the compiler. In particular, the world is never loaded
            >into a register, stored in ZL data structure, or passed to C

            They're not doing the opposite of what you described. They're not modelling side effects by having a RealWorld datum, they're modeling a restricted form of RealWorld by having side effects.

            RealWorld in the full form is strictly more powerful than mere side-effects because it can express storing and restarting states, examining the real world to see if the result be satisfactory, if not, then restart from a certain place and do it again to eventually arrive at the RealWorld one wants. This can't be done with RealWorld as an artifical uniqueness type where one can never get back to a prior state without having a function that could do so, and since all functions work with side effects, not with actually manipulating a RealWorld datum and one wan't unwrite lines to a terminal or undelete a file, such a function can't be made.

            It's the opposite. It's not modeling side-effects with RealWorld, it's modeling a limited version of RealWorld with side effects.

          • 1 month ago
            Anonymous

            >What do you mean I can't compare functions for equality?!

            thread is just a bunch of morons arguing about monads, good job IQfy.

            uwu

            >thread is just a bunch of morons arguing about
            welcome to IQfy, newbie

            Anyone use functional programming for robotics?

            never heard of such a thing, but it's an interesting idea
            you'd probably want some sort of flow based functionalish DSL for robotics though

          • 1 month ago
            Anonymous

            Lisp was used for artificial intelligence and robotics in space with great success until C deposed it because the runtime was too fat.

          • 1 month ago
            Anonymous

            More like:
            >It makes sense for the Eq impementation to exist
            >It's super simple to impement
            >Doesn't exist, because if it were to exist, it would expose that IO a hid an impure function inside.

          • 1 month ago
            Anonymous

            >It makes sense for the Eq impementation to exist
            >It's super simple to implement
            totally wrong. The only sensible equivalence relation is functional equality, which is undecidable.

          • 1 month ago
            Anonymous

            Yes, in the general case, but not when the input domain of the function is finite, in this case, it's only one element as RealWorld only has one member.

            Of course, with impure functions that all changes which is why it's impure, but with pure functions it's trivial to decide the identicality of Eq a => RealWorld -> (Realworld, a). Just do:
            x == y = snd (x realWorld) == snd (y realWorld)

            And that's it.

    • 1 month ago
      Anonymous

      >distinction between pure and impure functions
      Congratulations for reinventing the color problem. Enjoy the hell you have created.

      • 1 month ago
        Anonymous

        What's the problem with it and why is it worse than monadic IO?

    • 1 month ago
      Anonymous

      Putstrln is not impure thoughever

      Calling it will never print a string and the IO is not a container around a tuple, the IO is more like a promise or future that will be fulfilled by the runtime (it is actually a closure that takes a Realworld dummy type and prints the string it closes over)

      Although what you said about monads being a hack is kind of true, and some languages do actually have a differentiation between the arrow type for impure and pure functions

  14. 2 months ago
    Anonymous

    Between these, I'd pick OCaml and get into the Jane Street ecosystem.
    If you want Haskell, then the purple book is better than LYAH. But I don't do Haskell anymore. The standard library is terrible, it doesn't even have a decent string type or a hashtable. And I'm not convinced that lazy evaluation is a good default. Monads are totally fine though, people who think they're difficult are just brainlets.

  15. 2 months ago
    Anonymous

    Any of you fooncbrains have experience with Futhark and Granule?

  16. 2 months ago
    Anonymous

    What's amazing about FP is you never know what they'll say.
    Today, monads are only about side-effects, apparently.

    • 2 months ago
      Anonymous

      Obviously not. I'm talking about abstracting effectful functions away in monads.

      The reality is that a language can never truly be “pure” and be useful outside of purely computing a value at the end based on input without user interaction so they come with different ways to claim being “pure” while still allowing it, all of them ridiculous hacks.

      I'm talking about the monad hack here, but the uniqueness type hack and the stream hack are hacks all the same.

      I'm saying drop the hacks and just admit that it's an overconvoluted way to partition the language into pure and impure functions and fool the type system so that even though it treats impure functions as pure, it still can't sequence them out of order.

      Simply on a type level discriminate between pure and impure functions and call it a day.

      >You don't have to use do-notation to use a monad
      You do if something you need to use is provided in a monad
      x <- returnsMonad y
      Were you projecting when you said we don't write anything more than hello world lol?

      Anon, you don't need do-notation for that either which is purely syntactic sugar around “>>=”, “return” and ”>>”.

      It will make your code more readable though.

      • 2 months ago
        Anonymous

        >">>=”, “return” and ”>>”
        I don't like those either because they look worse. Do notation forces you to not write point-free code. That's the main reason I dislike it

      • 2 months ago
        Anonymous

        The reality is that a language can never truly be “pure” and be useful outside of purely computing a value at the end based on input without user interaction so they come with different ways to claim being “pure” while still allowing it, all of them ridiculous hacks.
        >based on input without user interaction
        what if function's input is a result of user interaction ?
        recursion with a condition is functional too

  17. 2 months ago
    Anonymous

    elm. by the time you move onto haskell and learn what a monad is you'll realize you've already been using them

  18. 2 months ago
    Anonymous

    Learn Erlang

  19. 2 months ago
    Anonymous

    >not sure where to start
    anon, try https://haskell.mooc.fi

    best i found so far and it's free
    course uses a haskell build system that just works
    has assignments with auto-grading system. you clone their git repo and there's a framework to grade your answers automatically

    • 2 months ago
      Anonymous

      thank you anon, this actually looks very interesting.

  20. 2 months ago
    Anonymous

    >between Haskell, OCaml, Elixir which would you pick?
    Clojure

  21. 2 months ago
    ThugBuster9Million

    It's cringe. OOP is cringe too. Make code your focus and you're now a homosexual. Just get shit done until your employer gets in your way.

  22. 2 months ago
    Anonymous

    C is better

  23. 2 months ago
    Anonymous

    Scala is the only relevant FP language and since Scala 3 it's based af.

    If you want to do pure FP use ZIO and if you simply want to get shit done use Haoyis libraries which are now part of Scala Toolkit.

  24. 2 months ago
    Anonymous

    Lisp

  25. 2 months ago
    Anonymous

    None of the above. I suggest either Idris or Lean4.

  26. 2 months ago
    Anonymous

    Scala
    https://jobs.apple.com/en-us/search?search=Scala&sort=relevance&location=united-states-USA

    Haskell:
    https://jobs.apple.com/en-us/search?search=Haskell&sort=relevance&location=united-states-USA

    Bfffhahahahahahahahhaha

    • 2 months ago
      Anonymous

      Scala
      https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite?q=Scala

      Haskell
      https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite?q=Haskell

      Bfffhahahhahahahahahhaa

      DELETE this Odersky.

    • 2 months ago
      Anonymous

      Scala
      https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite?q=Scala

      Haskell
      https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite?q=Haskell

      Bfffhahahhahahahahahhaa

      [...]
      DELETE this Odersky.

      LMAO

    • 2 months ago
      Anonymous

      Scala
      https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite?q=Scala

      Haskell
      https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite?q=Haskell

      Bfffhahahhahahahahahhaa

      No ones arguing that Scala was for intellectuals who care about the future of our species.

    • 1 month ago
      Anonymous

      You know instead of cool scala they are doing the thing where they basically write full blown java inside a file that ends with .scala

  27. 2 months ago
    Anonymous

    Scala
    https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite?q=Scala

    Haskell
    https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite?q=Haskell

    Bfffhahahhahahahahahhaa

  28. 2 months ago
    Anonymous

    Jfc this thread.
    Erlang murders all these garbage pseudo functional languages. Erlang is a true functional language, all others are cheap imitations and fakes.

  29. 2 months ago
    Anonymous

    i have came to the conclusion FP is for autist and this thread proves it.

    • 2 months ago
      Anonymous

      F# and Clojure are the FP langs for non-autists

  30. 2 months ago
    Anonymous

    I like Elixir but IMO there is too much focus on webshit like Phoenix and LiveView, puts it in a high risk of getting "Ruby on Rails"-ed.
    Be nice if there were a bit more attention given to it as a more general purpose scripting language to replace Python.

  31. 2 months ago
    Anonymous

    Another way to flatten it, though it repeats "Name?" etc. strings too much
    {-# LANGUAGE LambdaCase #-}
    import Conduit
    import Control.Monad

    main = do
    putStrLn "Name?"
    runConduit $ void $ repeatMC getLine
    .| foldMC (curry $ case
    ("John", "Doe") -> do
    putStrLn "Hello, John Doe!"
    putStrLn "Name?"
    return ""
    ("John", _) -> do
    putStrLn "Wrong (nested)."
    putStrLn "Surname?"
    return "John"
    ("", "John") -> do
    putStrLn "Surname?"
    return "John"
    ("", _) -> do
    putStrLn "Wrong."
    putStrLn "Name?"
    return ""
    )
    ""

  32. 2 months ago
    Anonymous

    I think a really good argument as to why monadic IO is a terrible idea derives from actually looking up the internal definition of it. As in:

    newtype IO a = IO (RealWorld -> (RealWorld, a)

    This is actually what GHC uses so IO is nothing more than a wrapper around a function as far as the type system goes. Of course, the big wink is that the function inside of IO can be impure.

    On top of that, RealWorld is a unit type. A function of the type `() -> (a, ())` would of course be downright useless without impurities. So far so good, so IO is actually nothing more than a type constructor around functions that warns you that they can be impure.

    The issue is that for absolutely no reason it enforces an unwieldy programming style where the return value of one impure function must be used as the input value of the next. This is of course what guarantees sequencing, but it's also highly restrictive in how one can program. The system essentially enforces that one do:

    let rw, string = getLine rw;
    let rw = putStrLn string rw;
    let rw, fp = openFile string rw;

    And so forth instead of simpy:
    let string = getLine;
    putStrLn string;
    let fp = openFile string;

    Is there any advantage whatsoever to enforcing that practice opposed to simply making impure functions callable directly? Monad abstractions or not, you are constantly passing a “RealWorld” datum around in Haskell which is what leads to the code becoming unwieldly. From every branch, from every loop, this “RealWorld” datum that the first function is called with as the program starts has to be returned at the end as it passes through a giant human centipede being eaten and then pooped out again for the next function. This is simply unnecessarily unwieldly for no tangible benefit and this is why code constantly becomes unnecessarily verbose because this “RealWorld” value has to constantly be passed back to whenever the flow control goes.

    • 2 months ago
      Anonymous

      well if you have a programmatic mcguffin that forces you to traverse a data dependency graph in a certain order (i.e. the RealWorld token), then that means that the absence of such token implies that you can just order computations however you want.
      For example, if you call a function that relies on 3 arguments, and you know that one of those arguments is going to need a lot of heap space, you can decide as a compiler to explore that argument first, regardless of its location in the argument list. Then, after you've explored the argument that takes up a lot of heap space, you could use that allocated heap space for your other arguments without allocating any new memory. You then free that memory once you decide you don't need it anymore.

      • 2 months ago
        Anonymous

        >well if you have a programmatic mcguffin that forces you to traverse a data dependency graph in a certain order (i.e. the RealWorld token), then that means that the absence of such token implies that you can just order computations however you want.
        Which is why I suggested at the start the type system should simply discriminate between pure and impure functions and the optimizer should be aware that one can be done out of order and the other can't. This is I assume what Koka does. This is what optimizer already do in languages without the typological distinction if the compiler can simply proof that a function is pure.

        A simple solution of partitioning the language of into pure and impure functions where pure functions can only call other pure functions achieves the same, but cuts both the complexity and the restrictions of passing RealWorld around everywhere.
        >For example, if you call a function that relies on 3 arguments, and you know that one of those arguments is going to need a lot of heap space, you can decide as a compiler to explore that argument first, regardless of its location in the argument list. Then, after you've explored the argument that takes up a lot of heap space, you could use that allocated heap space for your other arguments without allocating any new memory. You then free that memory once you decide you don't need it anymore.
        To be fair, even many strict nonpure languages do not define evaluation order of arguments for this reason.

        In fact, any decent C compiler would in a case like
        small_type *y = malloc();
        big_type *x = malloc();
        small_function(x,y);
        free(x);
        free(y);

        First inline small_function, and then proof probably be able to simply re-use the same address space indeed if it can prove that this is possible without altering program semantics and actually call the allocation for the big type first which is bigger.

        Compilers do these things nowadays.

    • 2 months ago
      Anonymous

      The whole point of hiding RealWorld in IO is to make it a monad to force the user to do sequential operations resulting in one unique state because that's what CPUs do, even when running SIMD instructions.
      It's restrictive because the world is restrictive, I can't access memory I did not yet allocate without running into undefined behavior.
      Which is why you keep IO in main as much as possible and do all the out of order declarative backflips you want in pure world.

      • 2 months ago
        Anonymous

        This issue is that simply having a distinction between pure and impure function on a type level would do the same thing without being so unwieldy and ridiculous in to program.

        If a simpe a -!> b type constructorr exited for impure functions and a restiction that they could not be called inside of pure functions, though they could obviously still manipulate them, that would honestly be far cleaner, simpler and less unwieldy.

        But then one couldn't claim that it was a “purely functional language”, only that the type system discriminates between pure and impure functions.

        • 2 months ago
          Anonymous

          All the same opportunities and restrictions on how you can apply or compose pure and impure functions would apply under this system, so I don't see what this accomplishes.

          • 2 months ago
            Anonymous

            Those would, but in that system one doesn't have to constantly pass a RealWorld value around.
            Yes, it's abstracted by monads, which are further abstracted by do notation but that Haskell needed an abstraction on top of an abtraction to make it remotely work shows how unwieldy and silly it is.

            And even with all that, some of the example code is still verbose and ridiculous exactly because in some way that RealWorld datum needs to be passed around for every loop, every branch, every call. A unit type being passed through the entire program to simply be deleted by the optimizer at the end, all to stop it from ordering things out of sequence in earlier stages of optimization.

          • 2 months ago
            Anonymous

            I don't see how the monad abstraction would function any differently to an intrinsic impure function type constructor. If you could sketch out how basic use cases would look with your proposal it'd help to demonstrate how it would be less unwieldy, which I'm not currently seeing otherwise.

          • 2 months ago
            Anonymous

            The difference is not having to pass RealWorld around all the time, however abstracted, creating unnecessarily verbose code for no reason.

            My proposal would simply work like:

            main () = sequence
            let name = readLine ()
            putStrLn $ "Hello, " ++ name ++ "!"

            These are all simply effectful functions called with (). Of course they can't be called inside of pure functions on a type level but there is no need to rely on runCont madness to escape from a nested loop any more because there is no value RealWorld value that needs to leak.

            It essentially functions the same as any other pogramming language.

          • 2 months ago
            Anonymous

            >pogramming language

          • 2 months ago
            Anonymous

            It's ``po'', because it is free.

        • 2 months ago
          Anonymous

          a -!> b is a -> IO b which forces you to call this "impure" function from other "impure" functions because you can't unpack IO b to b (no, don't use unsafe or you make Simon cry) unlike other monads where you give a default b or pattern match over it and it's done. Besides IO you don't actually need to be verbose all over the place.

          The difference is not having to pass RealWorld around all the time, however abstracted, creating unnecessarily verbose code for no reason.

          My proposal would simply work like:

          main () = sequence
          let name = readLine ()
          putStrLn $ "Hello, " ++ name ++ "!"

          These are all simply effectful functions called with (). Of course they can't be called inside of pure functions on a type level but there is no need to rely on runCont madness to escape from a nested loop any more because there is no value RealWorld value that needs to leak.

          It essentially functions the same as any other pogramming language.

          I don't understand this example, this reads like using the IO monad, with do and binds and whatnot.

          Is the problem that the Cont monad is verbose? I don't even know how Cont could be an algebraic effect.

    • 2 months ago
      Anonymous

      >for no tangible benefit
      Proofs. One could provide their own RealWorld type. You can formally describe the effects of IO with pre and post conditions defined on your RealWorld type. With what you're proposing, these proofs become impossible. Plus, you completely lose equational reasoning for impure functions. It's a massive step backwards.

  33. 2 months ago
    Anonymous

    Scalachads, ww@?

  34. 2 months ago
    Anonymous

    Rule34 on haskell?

  35. 2 months ago
    Anonymous

    Should I use Clojure or Erlang if I want to make an open source server that handles different services, like serving pages made in a custom Markup language for a client to render (kinda like PlayOnlineViewer with .pml files), a chat service, a contact service, mail service, file downloading, authentication....
    Which of the two language would be best suited for the task?

    • 2 months ago
      Anonymous

      haskell. if you insist on choosing between clojure and erlang, I'd go with clojure because you get interop with java

    • 2 months ago
      Anonymous

      I'm Clojure's strongest soldier and I think you'd have a stupidly easy time making both server and client in a beam language, Erlang or Elixir. OTP makes it trivial.
      Choosing Clojure will give you access to the java ecosystem for libraries for all those things, but I assume elixir has a decent ecosystem.
      Mail is a different concern because it sucks. Unless you're not talking about email.
      For authentication and logins I'd use urbit +eauth

      • 2 months ago
        Anonymous

        Thanks anon, I'm also a Lisp enjoyer. I used to use autolisp (don't laugh) during my internship as a student and despite what I was using it for I really enjoyed the language. But Erlang really interests me too.

        >Mail is a different concern because it sucks. Unless you're not talking about email.
        I don't know if it's too ambitious but I had in mind to make up my own take on mailing, all contained within the ecosystem I'm building. Users would be able to mail each others pretty much, but it would be a closed garden.

        I'm only talking about the server mind you, for the client you'd be able to use anything as long as you respect the server implementation. But what I had in mind was to make a client that act as a front/renderer for the server, able to parse the markup language the server throws at it and render it like PlayOnlineViewer kinda does.

        I'll probably be using C++, but that comes later. I miss this kind of things, my aim is to make a system games who want their own live services would want to use, for free.

        >For authentication and logins I'd use urbit +eauth
        Nice I'm going to look into it.

        • 2 months ago
          Anonymous

          You can try having your cake and eating it by using LFE or Clojerl

        • 2 months ago
          Anonymous

          Btw, while I recommended elixir I'd probably use Electric Clojure for anything user facing I'd want to build, or HumbleUI for native DT applications

      • 2 months ago
        Anonymous

        Fricking Clojure doesn't even work on Windows

        • 2 months ago
          Anonymous

          Yes it does are you moronic?

        • 2 months ago
          Anonymous

          I've only run a few Babashka scripts on Windows, but I know that regular Clojure obviously does work on Windows too since some 10% or so of Clojure devs use it as their dev environment

      • 2 months ago
        Anonymous

        Elixir has an incredibly overpowered ecosystem (ie relative to its size), we just got an alternative to numpy that can compile to cuda and run llms efficiently lmao. We also have pretty good embedded support and imo a superior (albeit young) data science ecosystem on top of that. The creator is basically trying to eat python and he's succeeding.

        But there are some areas where the lack of thousands of autists shows: Like the only guid library currently supported. I forget the name of it but it's maintained by literally one older guy and written in erlang. A bit of spaghetti inside it too, but overall it works.

        Tldr elixir is great and I am moving heaven and earth to try and get a job in it but research your use case first to make sure you won't have to reimplement parts of the jvm ecosystem or something.

        • 2 months ago
          Anonymous

          https://github.com/elixir-circuits/circuits_uart looks better than https://hackage.haskell.org/package/serialport. But then I look at https://hexdocs.pm/lens/readme.html and there's a "Lens." in front of most names. Also they have a "&Integer.is_odd/1", which seems to be making distinctions that only come up when using the Haskell FFI.

      • 2 months ago
        Anonymous

        >OTP makes it trivial
        That obviously requires the person to know OTP, if he wants to do his project in erlang/otp but has little programming in it then it's just not going to work. OTP itself is not trivial and has much higher entry bar than many languages.

        • 2 months ago
          Anonymous

          I haven't programmed with OTP but I read Armstrong's Thesis it it seems to be wholly integrated with BEAM languages such that you don't have to think hard about it

  36. 2 months ago
    Anonymous

    Haskell every time.
    The other ones are just dumbed down versions of FP.

  37. 2 months ago
    Anonymous

    meme

  38. 2 months ago
    Anonymous

    https://www.youtube.com/playlist?list=PL04PGV4cTuIVP50-B_1scXUUMn8qEBbSs

    If the language is good enough, you could even do GPU programming on it. Nothing imperative languages can do; functional languages can't do better.

  39. 2 months ago
    Anonymous

    Monadic IO is actually even worse than passing a RealWorld uniqueness type around.
    It's using a RealWorld Uniqueness type to create continuation passing style to force a defined evaluation order.
    Monadic IO is essentially just programming in CPS which has always eliminated the distinction between lazy and strict languages and exposed an explicit evaluation order.

    • 2 months ago
      Anonymous

      >Monadic IO is essentially just programming in CPS which has always eliminated the distinction between lazy and strict languages and exposed an explicit evaluation order.
      That's not just monadic IO that does that. Everything that involves passing around a uniqueness type practically wrangles the programs into CPS. In fact, this is also the reason some haskellers call Cont
      newtype Cont = Cont ((a -> r) -> r

      the "mother of all monads", as it puts all computations in a continuation passing style, just like the bind operator does to every other monad instance

      • 2 months ago
        Anonymous

        I don't really agree it has much to do with Uniqueness types. Functions with uniqueness types can still return and don't really take as argument anything that can be called a continuation.

      • 1 month ago
        Anonymous

        >newtype Cont = Cont ((a -> r) -> r
        should be
        newtype Cont r a = Cont ((a -> r) -> r)

    • 2 months ago
      Anonymous

      Composing uniqueness with anything else devolves into monad transformers with State and Cont.
      Just keep uniques and IO in main and avoid uniques/IO propagating.

  40. 2 months ago
    Anonymous

    abomination of a language, use
    Racket
    Scheme
    Julia
    Clojure

    • 1 month ago
      Anonymous

      these are all good languages but they can't do what haskell does (have a good type system)

      • 1 month ago
        Anonymous

        Why are you so obsessed with it?

        • 1 month ago
          Anonymous

          it's a generally well-designed language that has a good selection of libraries. that's about it

  41. 1 month ago
    Anonymous

    Anyone use functional programming for robotics?

    • 1 month ago
      Anonymous

      I use serialport to send gcode. Galois uses it for code generation (copilot, ivory) because it's not realtime.

  42. 1 month ago
    Anonymous

    Did someone say catgirls? No? Well too bad.

    • 1 month ago
      Anonymous

      thread is just a bunch of morons arguing about monads, good job IQfy.

      uwu

      • 1 month ago
        Anonymous

        you vill contain ze IO in ze main with ze monad and have ze pure program instead of spreading unique aids all over functions with asterisks in the type and you vill like it

  43. 1 month ago
    Anonymous

    Does Haskell have namespaces?

    • 1 month ago
      Anonymous

      No, it has modules. You can't have different packages of functions in the same file, you have to put them in separate files and import them qualified (import foo, bar, baz as module.foo, module.bar, module.baz).

    • 1 month ago
      Anonymous

      You could use OverloadedRecordDot and put most of your code in the HasField instances. Then each type has it's own namespace. I don't like that HasField's functional dependency prevents 'instance Num x => HasField "x" X x", type errors are worse, HLS doesn't give completions, and when I write the instance I have to write out the type. In spite of those complaints, I'm on the fence about this style:
      data Elephant
      data Car
      instance HasField "trunk" Elephant Int
      instance HasField "trunk" Car Char
      main=do print dumbo.trunk; print vehicle.trunk

  44. 1 month ago
    Anonymous

    every single fp thread derails into morons arguing about monads.

    • 1 month ago
      Anonymous

      a simple concept you can teach children but not intermediate java developers, tainted as they are.

    • 1 month ago
      Anonymous

      There would be no such issue if Monad was just called FlatMappable.

      • 1 month ago
        Anonymous

        >FlatMappable
        Terminal Java brain cancer

        • 1 month ago
          Anonymous

          Works for Foldable and Traversable.

        • 1 month ago
          Anonymous

          Is that the only objection that you have for a name that reflects the usage?

          • 1 month ago
            Anonymous

            >yes of course, I love FlatMappabled error handling

          • 1 month ago
            Anonymous

            I don't say "Monadic error handling" either.

          • 1 month ago
            Anonymous

            Well, I do. Whatcha gonna do about it?

    • 1 month ago
      Anonymous

      That just shows people here have no real knowledge or interest in FP

      • 1 month ago
        Anonymous

        I already have LINQ. The rest of FP is bloat.

        • 1 month ago
          Anonymous

          >I already have LINQ
          lmao. .NET gays are hopeless.

  45. 1 month ago
    Anonymous

    haskell is a meme

  46. 1 month ago
    Anonymous

    flatmappable doesn't really describe the bind part though does it?

    • 1 month ago
      Anonymous

      The map part literally does?

      • 1 month ago
        Anonymous

        ?

    • 1 month ago
      Anonymous

      bind and flatMap are the same function

  47. 1 month ago
    Anonymous

    C, C++, and Haskell are the the only white heterosexual male programming languages. The others are for troons and Hindus.

    • 1 month ago
      Anonymous

      Haskell is literally full of troons

      • 1 month ago
        Anonymous

        They all moved to Rust. Unironically.

        • 1 month ago
          Anonymous

          They still recommend to learn Haskell too.

          • 1 month ago
            Anonymous

            Maybe as a curiosity but now it's time to Rewrite It In Rust (tm) (c) (r) (sponsored by the Rust Foundation).

          • 1 month ago
            Anonymous

            Straight white male here, frick trannies, they'll never be women, sneed.

            Rust is an excellent language. The tooling is awesome. I don't miss C/C++ clusterfrick of ideologies and styles. Still use it for some stuff because Rust tooling doesn't support some exotic shit I work in, but otherwise link to Rust libs and all UI is in rust. Unironically started learning rust to hate it on it more effectively.

            Its no bad at all. Kind of the "next step" in systems languages.

          • 1 month ago
            Anonymous

            Rust is a good language but you have to deal with a community that superimposes the language’s symbol on the homosexualtroonBlack person flag and makes that their discord’s icon.

          • 1 month ago
            Anonymous

            I have so far survived without ever joining that discord. No one I know who writes Rust is on that discord. Maybe just forget it exists and try writing rust with existing documentation and github examples. I think all the gender shock troops are contained at this point to their own club.

            I don't know am I off base here? Who makes design decisions for the language? Everything seems more or less reasonable to me. If you disagree with something usually reading the history of why the decision was made clarifies the situation and makes sense. Whatever it is, its so much better than C/C++ cacophony of boomer design patterns.

          • 1 month ago
            Anonymous

            >all UI is in rust
            Wait really? What are you using?

          • 1 month ago
            Anonymous

            slint (like a sane person)

          • 1 month ago
            Anonymous

            Thanks, any rec for TUIs?

      • 1 month ago
        Anonymous

        It isn’t from what I can tell. The only troonery I found is a Ukrainian flag on the GHCup homepage.

        • 1 month ago
          Anonymous

          Are you a zigger or something?

          • 1 month ago
            Anonymous
          • 1 month ago
            Anonymous

            Functional programming just isn't for you, Kolya, go back to php

          • 1 month ago
            Anonymous

            No.

          • 1 month ago
            Anonymous

            wtf i love haskell even more now

          • 1 month ago
            Anonymous
          • 1 month ago
            Anonymous

            Slava ukraini is basically blm and pride-tier virtue signaling homosexualry as far as I care

          • 1 month ago
            Anonymous

            Sounds like something a shitskin would say

          • 1 month ago
            Anonymous

            It gets real old seeing a bunch of morons that can't find Ukraine on a map spouting slava ukraini every chance they get so they can show off what a good goy they are.

          • 1 month ago
            Anonymous

            >if you hate my virtue signaling eyesore you're a <bigot | transphobe | shitskin>
            you're just as insufferable as they are

            It gets real old seeing a bunch of morons that can't find Ukraine on a map spouting slava ukraini every chance they get so they can show off what a good goy they are.

            it's just as insufferable when they can find ukraine on a map.

    • 1 month ago
      Anonymous

      c-nile boomer contributes to the thread, thx boomer

      >I already have LINQ
      lmao. .NET gays are hopeless.

      oh look a israelite troony, someone tell zher about rust

  48. 1 month ago
    Anonymous

    >is haskell based?
    it's ok
    >what are some usecases?
    those leetcode like websites, contributing to calibre
    >where do I start?
    I tried haskell first, got along in some exercises and textbooks.
    I tried ocaml next, and I ended up liking that one more
    I've never tried elixer but I did try the erlang based lisp
    Just try the ones you want to use, and see what you like.

  49. 1 month ago
    Anonymous

    read your land of lisp™

Your email address will not be published. Required fields are marked *