[HN Gopher] Building a new functional programming language
       ___________________________________________________________________
        
       Building a new functional programming language
        
       Author : signa11
       Score  : 79 points
       Date   : 2023-03-05 15:08 UTC (7 hours ago)
        
 (HTM) web link (www.onebigfluke.com)
 (TXT) w3m dump (www.onebigfluke.com)
        
       | cde-v wrote:
       | Seems like the correct answer here is that Brett Slatkin likes
       | the smell of his own farts. Typical fart sniffer behavior.
        
       | Max_Limelihood wrote:
       | Because 14 wasn't enough. https://xkcd.com/927/
        
       | juancn wrote:
       | The problem is that those are f**king difficult problems to
       | solve. Regardless of how you approach them. No tool or paradigm
       | will make them easy, it may make a part of them easier (at some
       | other cost somewhere else), but by no means will make it easy.
       | 
       | Building large scale, low latency systems is really hard.
       | Handling concurrency and shared state is hard.
       | 
       | Heck, even functional programming is hard to grok for most
       | people. The evidence is in its popularity (or lack of it).
       | 
       | There's no large mystery why we all are not using functional
       | programming exclusively: because it's hard. Imperative, with all
       | it's drawbacks it's easier to grasp and closer to how hardware
       | works. Most people find it more natural, there's no big
       | conspiracy.
       | 
       | But (there's always a "but"), the functional paradigm is
       | essential to solve all those hard problems. It provides many
       | tools where many common pitfalls are essentially avoided, but
       | gaining a comfortable grasp of those tools takes work and it's
       | not easy as many claim.
       | 
       | They seem easy _after_ you 've had the "aha!" moment, but it's
       | like advanced math, getting there takes time and a certain
       | proclivity to it. Once you develop some sort of intuition, you
       | tend to forget the effort it took to gain it.
       | 
       | In any case, I love languages and new ideas, so I hope he
       | succeeds (or fails in an interesting way where we learn something
       | new).
        
       | rurban wrote:
       | He has set, not functional. See his Twitter
        
         | bslatkin wrote:
         | It's SSA. If you use (define) in Racket is it no longer
         | functional?
        
       | alexisread wrote:
       | I'll drop this here: https://github.com/manuel/wat-js
       | 
       | If you have delimited continuations then you can construct
       | coroutines/threads/await/async, promises etc.
       | 
       | I guess that this might be suitable for many scenarios thanks to
       | nodejs, but the runtimes it relies on are not exactly small.
        
       | PaulDavisThe1st wrote:
       | I've been programming for 35 years or more, and I've yet to come
       | across situations where the hard problem was _the language_.
       | 
       | Sure, there are situations where I've been grateful for the
       | ability to use Python (because everything is so easy), or Perl
       | (because sometimes its the right tool for the job) or Lisp
       | (because its slippery fluidity just feels right) rather than the
       | C/C++ that I've generally used during that time.
       | 
       | But the hard problems I've faced writing code would (almost?)
       | never be made easier by using functional programming, or Rust, or
       | Go or Swift or Brainfuck. The problems are hard because the
       | problems are hard, and typically for me over the last 23+ years,
       | it has been the combination of generically tough programming
       | problems with performance requirements that ultimately make the
       | choice of language mostly irrelevant.
       | 
       | Sure, someone could offer me a thread-safe sparse integer-to-
       | integer mapping container in another language, but then I have to
       | wonder about what design assumptions were made and how performant
       | it is, and if the language was clearly created to prevent me from
       | ever doing such things myself, then I'm going to be deeply
       | suspicious from the outset that it could possibly have my
       | (coding) interests at heart.
       | 
       | I understand that I'm not the typical programmer these days, and
       | I don't work on entirely typical problems, but I can't help but
       | feel that sometimes the focus on "languages to help programmers"
       | comes from programmers who just don't enjoy their work enough
       | and/or don't have enough to do.
        
         | bslatkin wrote:
         | I love to swing a hammer as much as the next programmer. But if
         | you offer me a nail gun, even with slightly lower precision, I
         | will happily use it the majority of the time and revert to my
         | hand tools when it's most appropriate. This is about developing
         | force multipliers and producing leverage, not avoiding the
         | craft.
        
           | PaulDavisThe1st wrote:
           | I would say that a better analogy is that you've already got
           | an experienced crew, some swinging hammers, some lugging nail
           | guns and everyone's really quite good at what they do. But
           | the plans from the architect are just _really hard to build_.
           | You and the crew can do it, for sure, but the issues are not
           | going to better or worse if the guys use the table saw to
           | crosscut some of the framing elements or someone gets one of
           | those new german tool widgets. I mean, sure, the tools might
           | make a small difference to the process, but the overall
           | experience will be dominated by the fact that the thing is
           | just hard to build.
        
         | not_the_fda wrote:
         | I've also been doing this for over 30 years and agree with you
         | 100%. Never has the language been the impediment, or the thing
         | keeping me awake at night.
         | 
         | We don't need more programming languages. All languages are
         | either hated or not used. The language isn't the problem and it
         | a poor craftsman that always blames the tool.
         | 
         | I've never been on a retrospective of a failed project and the
         | reason being the language.
        
         | anonuser123456 wrote:
         | As a developer I would agree. As a maintainer I would disagree.
         | 
         | Some problems require paradigms to solve, and developing
         | bespoke implementations makes maintenance extremely painful.
        
         | sakras wrote:
         | I definitely agree. I think somewhere along the way we went
         | from solving problems to bickering about _how_ to solve
         | problems. I feel there are now plenty of languages now that
         | exist purely for aesthetic reasons (C++, Swift, etc) rather
         | than having some deep technical reason for existing (C, Rust).
         | 
         | I guess I get it though, designing your own language is great
         | fun and I've definitely made a couple myself in my spare time.
        
         | Chris_Newton wrote:
         | _I 've been programming for 35 years or more, and I've yet to
         | come across situations where the hard problem was_ the
         | language.
         | 
         | The hardest problem is usually something else, but IME some
         | languages make it much easier to solve a given hard problem
         | than others. Some languages are qualitatively safer. Some
         | languages are much more expressive, in the sense that I can
         | implement my solution with far less code/time/cost without
         | compromising anywhere else.
         | 
         | There is a difference between whether I can solve a problem and
         | how efficiently and pleasantly I can solve a problem. I find
         | choice of language rarely affects the former but often
         | profoundly affects the latter.
        
           | PaulDavisThe1st wrote:
           | 100%. But that's why I mentioned performance. I work with
           | realtime audio, and this puts most of the "pleasantly solve
           | the problem" options off the table.
        
       | iLoveOncall wrote:
       | As always for those niche languages, if the answer is not
       | personal entertainment, then the reality is that it's just poor
       | judgement.
        
       | century19 wrote:
       | I'm surprised he doesn't mention Scala and Spark.
        
         | bslatkin wrote:
         | I think Spark is a good example of where the functional
         | paradigm has done well in a niche.
        
       | karmakurtisaani wrote:
       | > The hypothesis I aim to test with a new programming language
       | is: By making different tradeoffs, these issues can be mitigated
       | and a more broadly-appealing functional language can be built.
       | With such a language, I hope that the true promise of functional
       | programming for parallel computing can be widely realized.
       | 
       | Proceeds to give zero indication how to achieve this.
        
         | karmakaze wrote:
         | Very disappointed by the non-announcement. If it were a corp,
         | it would be FUD.
         | 
         | I'm curious as to what these different trade-offs are.
         | 
         | > My conclusion is that there are major, well-justified reasons
         | for why people strongly dislike functional languages.
         | 
         | My conclusion is because most everyone is taught to think
         | empirically and 'play computer' that functional doesn't fit in
         | their preconceived brains. I once had someone say SQL didn't
         | make sense because it's SELECTing fields (i.e. vars) before
         | they're defined/assigned later in the (binding) expressions.
         | 
         | People having trouble with FP is like how people who learn
         | databases using ORM's don't deal well with SQL as expressions
         | of set operations.
         | 
         | There are varying limits to how much people like and handle
         | abstract constructs before applying the construction to the
         | data at hand but you can do a whole lot of effective and
         | unsurprising development before getting to such esoteric
         | levels.
         | 
         | Edit: I was super-excited to open the link, and now on re-
         | reading expect this new FP language to be as much an
         | advancement as Go was to 'systems' programming. I hope I'm
         | mistaken. Also odd that only Haskell and Lisp were mentioned
         | when there are so many others. On the plus-side if Google were
         | to make F# and back it as well as they have Go, that would be a
         | win-win.
        
           | lolinder wrote:
           | > it would be FUD
           | 
           | I thought FUD stood for Fear Uncertainty Doubt--it's usually
           | used to indicate that something is designed to sow fear for
           | clicks or for some ulterior motive, not for insubstantial
           | non-announcements.
           | 
           | Did something in this post evoke fear?
        
             | karmakaze wrote:
             | The point of FUD is usually to carve out a space where
             | existing products/solutions can't compete with idealized
             | vapourware. I updated my opinion to NIH (though could be
             | both)--and still hope to be mistaken.
        
           | karmakaze wrote:
           | After reading their other post "The case for dynamic,
           | functional programming", I would classify this as FUD, or
           | rather NIH. Go got support by being touted as "Not Java". I
           | can't say that this would gain much by being declared as "Not
           | Elixir".
        
         | jalk wrote:
         | > My conclusion is that there are major, well-justified reasons
         | for why people strongly dislike functional languages.
         | 
         | I'm sure there are a multitude of different reason and likely
         | require different conflicting tradeoffs to address
        
           | bslatkin wrote:
           | It's true and that is one of the largest challenges.
           | Producing something that feels familiar (but not error prone)
           | has been the way I've solved such conflicts so far.
        
         | lolinder wrote:
         | It's a four paragraph blog post answering the question "why?".
         | I'm not sure why you expect him to delve into the how at this
         | stage: he probably doesn't have anything fully formed yet.
        
           | bslatkin wrote:
           | Thanks! Right now the language's codebase is about 50KLOC.
           | There's an interpreter for fast iteration and a compiler
           | built on LLVM for producing native binaries. I'd like to make
           | more progress on the parallel computing functionality before
           | sharing it more widely.
        
           | iampims wrote:
           | https://twitter.com/haxor/status/1582878447134572544?s=20
           | 
           | Looks like the syntax is taking shape at least.
        
             | noelwelsh wrote:
             | No language syntax needs return in 2023.
        
               | bslatkin wrote:
               | How should an early return if statement work instead?
        
               | noelwelsh wrote:
               | When if is an expression early returns aren't really a
               | problem.
        
               | bslatkin wrote:
               | I understand what you mean. But I expect most potential
               | users want explicit returns because they're familiar and
               | more approachable for beginners.
        
               | noelwelsh wrote:
               | I disagree. You make two claims: familiarity, and
               | beginner friendliness.
               | 
               | For the first, I think it's a mistake to perpetuate the
               | mistakes of the past. I don't think JS developers have
               | had problems adjusting to the lack of return in arrow
               | functions.
               | 
               | Beginners have no preconceived notions of how a
               | programming language should operate, and return makes the
               | language model more complex.
               | 
               | 1 + 1 evaluates to 2, but (in a language that requires
               | return)
               | 
               | def foo = 1 + 1
               | 
               | foo
               | 
               | doesn't for no good reason. This breaks the simple
               | substitution model of evaluation.
               | 
               | These claims could be addressed emperically, but I guess
               | neither of us are going to do the research. :-)
        
           | tsegratis wrote:
           | He's going for apple/iphone style of drip feed product
           | announcements to build excitement
           | 
           | Look at us salivating for his big unveil -- we've probably
           | already written more than he did
        
         | User23 wrote:
         | It basically comes down to nondeterminism. Pure functional
         | languages supposedly make it easier to exploit associativity,
         | commutativity, and distributivity to allow many expressions to
         | have nondeterministic semantics that are amenable to concurrent
         | execution. Argument evaluation also can be specified
         | nondeterministic so the runtime is free to execute something
         | like the following with two or more CPU threads:
         | f(g(), h())
         | 
         | Of course a well designed imperative language could also avoid
         | overspecifying deterministic semantics and open itself up to
         | similar optimizations, but for various reasons that hasn't
         | caught on. One example would be specifying the conditional to
         | select a branch with a true guard nondeterministically rather
         | than deterministically in the order of appearance in the
         | program text. Dijkstra's EWDs give many practical examples of
         | why one might want such a thing.
         | 
         | Another example would be deducing when statement composition is
         | symmetric and allowing nondeterminism when it is. For example
         | if f and g don't have access to each other's data then the
         | following can be executed in two threads even with mutation:
         | f(); g()
         | 
         | Side effects will appear nondeterministically though which may
         | or may not be a problem. As always an algorithm needs to be
         | designed for the semantics the language has not those the
         | programmer wishes it does.
        
           | alexisread wrote:
           | This makes a good case for effect systems in conjunction with
           | FP, so they can be reasoned about as well. Something like
           | https://koka-lang.github.io/koka/doc/index.html
           | 
           | Having said that, having something like Daedelus in there as
           | well would give a handle on temporal-based determinism, and
           | then some allowance for delimited continuations would top
           | things off nicely.
        
         | worksonmine wrote:
         | In his defense the title is "why" not "how". I guess you'll
         | have to spend some sleepless nights waiting for the follow-up.
        
           | bslatkin wrote:
           | I'm sorry to make you wait.
        
       | evanwang0 wrote:
       | While certainly true that functional programming provides an
       | intrinsic advantage to programming parallelism, parallelism is
       | limited by hardware constraints. To best take advantage of CPU
       | architectures,"function" execution needs to optimize usage of
       | caching layers and execution threads. This naturally lends itself
       | to the development of event loops/schedulers in functional
       | runtimes like node and erlang.
        
       | mark_l_watson wrote:
       | The article is light on details, but as a polyglot programmer, I
       | encourage him.
       | 
       | I am an enthusiastic, but far from expert, Haskell programmer. I
       | wonder if Brett is thinking of a more Python-like interpreted
       | functional language?
        
         | bslatkin wrote:
         | Thank you! Imagine everything we like about Python, remove some
         | warts, make it functional. It should feel familiar and
         | appealing to a Python programmer.
        
           | eternalban wrote:
           | Based on above it seems you want to test the hypothesis that
           | 'there is a python-like functional language in the space of
           | FP'.
           | 
           | Is there anything ~technical you can share beyond desires and
           | disappointments that leads you to believe this is a
           | reasonable hypothesis?
        
             | bslatkin wrote:
             | I've got a working interpreter and compiler for the initial
             | language. I've had a few people take it for a spin and they
             | were able to rapidly learn it and start contributing,
             | despite having expressed frustration in trying FP languages
             | in the past. All anecdotes for now!
        
               | eternalban wrote:
               | Ah, you already have it. Now we're all intrigued! Looking
               | forward to the public release.
        
       | dimitar wrote:
       | So why would Clojure or Erlang or Elixir fail to satisfy the need
       | for a functional language capable of taking advantage of the
       | available cores?
        
         | davidw wrote:
         | Seems like he's talking about parallelism rather than
         | concurrency? Erlang does the latter pretty well, but I'm not
         | sure it's that great for "I have a lot of processing to do and
         | I want the language to help parallelize it", especially since
         | it's also not the fastest thing out there.
        
         | lolinder wrote:
         | I don't think he's arguing that the existing functional
         | languages can't take advantage of all cores, it sounds like he
         | believes that the existing functional languages cannot reach
         | mainstream adoption because of fundamental flaws that he hopes
         | to address:
         | 
         | > My conclusion is that there are major, well-justified reasons
         | for why people strongly dislike functional languages. The
         | hypothesis I aim to test with a new programming language is: By
         | making different tradeoffs, these issues can be mitigated and a
         | more broadly-appealing functional language can be built. With
         | such a language, I hope that the true promise of functional
         | programming for parallel computing can be widely realized.
        
           | bslatkin wrote:
           | Exactly.
        
             | darkmarmot wrote:
             | So what advantages to comprehension or usability would you
             | like to offer over Elixir? (as it doesn't really focus on
             | type/category theory like most other FP languages)
        
               | bslatkin wrote:
               | I'm not an Elixir expert at all, but one important
               | feature I believe is missing: explicit returns.
        
       | Hizonner wrote:
       | > once asked Guido van Rossum (the creator of Python [...]) [...]
       | 
       | Uh-oh...
       | 
       | You know, I was just programming in Python yesterday, and I was
       | once again reminded of how ANNOYING a language it is... how
       | annoying it is that it's so _popular_ that I 'm essentially
       | forced to code in it.
       | 
       | Especially now that a bunch of (probably needed) changes have
       | been made in half-assed ways that interact clunkily with its
       | original rather, um, idiosyncratic structure, syntax, and
       | philosophy, which for a long time were determined almost entirely
       | by one person's idea of what was intuitive.
       | 
       | I mean, it's not JavaScript-level annoying or Perl-level chaotic,
       | but it's a pretty damned annoying language.
       | 
       | > Although our tools have continued to improve (such as golang),
       | 
       | Uh-oh...
       | 
       | Another language that grabbed some popularity by fixing some
       | things, but still fails to systematically Do Things Right, even
       | though we're now like 50 or 75 years into this whole computer
       | thing, and are at a point where we ought to have a mature
       | understanding of what Right is and the time to act with
       | deliberation.
       | 
       | One of the ways it grabbed that popularity was, of course, by
       | looking familiar and unintimidating to people who don't like
       | "weird languages".
       | 
       | > By making different tradeoffs, these issues can be mitigated
       | and a more broadly-appealing functional language can be built.
       | 
       | Uh-oh...
        
       | nextaccountic wrote:
       | > He spoke of the potential for functional languages to provide a
       | significant, intrinsic advantage when it comes to parallel
       | computing.
       | 
       | > (...)
       | 
       | > If that were true, you'd expect that the many existing
       | functional programming languages would have already satisfied
       | this need. But in my opinion, they haven't
       | 
       | Well there is https://futhark-lang.org/ - it runs on the GPU, and
       | is awesome.
       | 
       | On the CPU side, I think that Rust plus https://github.com/rayon-
       | rs/rayon was a huge breakthrough on writing parallel programs
       | using both functional and imperative programming, and future
       | languages should learn from its successes. The ownership system &
       | the borrow checker, plus other type-level features like the Send
       | and Sync traits, were essential to enable sharing read-only data
       | between threads without synchronization, or sharing read-write
       | data with synchronization, all checked at compile time for data
       | races (which is a huge problem to solve, and is something that
       | neither Go nor Java protects against at compile time)
       | 
       | Indeed Futhark shares a key feature with Rust: it uses uniqueness
       | types to enable in-place updates, which is kind like a limited
       | form of Rust ownership: if you are the sole user of some memory,
       | you can update it and other code will be none the wiser. This
       | kind of thing is very important to build functional programs that
       | are performant in practice.
        
         | tsegratis wrote:
         | Fair point
         | 
         | It may be better to see rust as sitting between functional and
         | imperative paradigms
        
         | klavinski wrote:
         | See also the Higher-Order Virtual Machine for a functional,
         | non-garbage-collected, and parallel runtime:
         | https://github.com/HigherOrderCO/HVM
        
           | nextaccountic wrote:
           | Hey, that's pretty cool! The lang that targets this runtime
           | is https://github.com/HigherOrderCO/Kind
        
       | lolinder wrote:
       | > Why is the gap between these two perspectives so large? My
       | conclusion is that there are major, well-justified reasons for
       | why people strongly dislike functional languages.
       | 
       | Now that (nearly) every mainstream language has lambda
       | expressions, there are very few patterns in functional
       | programming that cannot be replicated in mainstream languages,
       | which means that moving to a pure functional language now
       | provides strictly fewer choices when problem solving. In order
       | for a programmer to accept a language with strictly _less_
       | expressive power, those new restrictions must solve problems that
       | the programmer actually cares about.
       | 
       | Rust reached adoption because mainstream systems programmers
       | recognized that memory errors are a huge problem and dealing with
       | the borrow checker is worth it to solve them. Static typing
       | reached mainstream adoption because it made coordinating work in
       | a large team dramatically easier and solved refactoring.
       | 
       | Functional-style programming has hit the mainstream--embedded
       | within imperative and OO code--but purely functional languages
       | have yet to make a good case for their additional restrictions,
       | and I'm not convinced that multiprocessing is that case. Golang
       | mainstreamed a very effective model for multiprocessing in an
       | imperative environment that solves most of the problems without
       | asking programmers to completely change the way they write code,
       | and that model is increasingly being adopted in other languages
       | (Java's project loom, for example).
        
         | noelwelsh wrote:
         | > Now that (nearly) every mainstream language has lambda
         | expressions, there are very few patterns in functional
         | programming that cannot be replicated in mainstream languages
         | 
         | I don't think this is true. Algebraic data types and exhaustive
         | pattern matching, which implies a type system, are the things I
         | use most in my adventures in functional programming. Mainstream
         | languages (for some definition of mainstream) don't yet have
         | these features.
         | 
         | The original post doesn't mention _pure_ FP. I don 't think
         | purity is that interesting when you can have a type system that
         | can reason about mutation (i.e. linear or affine types, similar
         | to Rust.)
        
           | lolinder wrote:
           | Kotlin and Java now have sealed classes/interfaces, which can
           | provide exhaustive pattern matching and as far as I can tell
           | can be used to model any ADT.
           | 
           | EDIT: In fact, both languages are now listed as having ADTs
           | on the Wikipedia page:
           | https://en.m.wikipedia.org/wiki/Algebraic_data_type
           | 
           | Also, TypeScript's union types can express ADTs, and Rust's
           | enums. I don't think it will be very long before the rest of
           | the mainstream languages catch up.
        
             | noelwelsh wrote:
             | Agreed, but that's why I hedged with "some definition of
             | mainstream". I don't think Kotlin or Rust are mainstream
             | yet, most Java places are still on Java 8 or 11, and ADTs
             | in Typescript are a PITA.
        
               | kaba0 wrote:
               | I wouldn't be surprised if there would be more people on
               | Java 19 than on Haskell, for what it's worth.
        
               | wk_end wrote:
               | ADT's in TypeScript aren't as nice as in a language that
               | supports them natively in many respects, but "PITA" is
               | really overselling it. We use them pervasively at my
               | shop. In fact, the ability to synthesize them without
               | naming them (because TypeScript is structurally-typed
               | instead of nominally) sometimes makes them even more
               | convenient than in most FP languages (OCaml excepted) -
               | the ability to, say, return an ad-hoc ADT from a lambda
               | without giving it some meaningless name like
               | "HelperFunctionResult" can occasionally be really handy.
        
           | nerdponx wrote:
           | It's also a matter of performance. Functional non-mutating
           | patterns in JavaScript and Python can be substantially,
           | sometimes catastrophically, less performant than the
           | procedural/imperative mutating equivalents. All functional
           | programming languages that I know of which have decent
           | performance rely on an optimizing compiler to some extent,
           | and/or core data structures that have been optimized for
           | immutability.
        
             | smitty1e wrote:
             | Python bogs down where there is excess use of the dynamic
             | aspects, e.g., a large list comprehension.
             | 
             | Go with a generator, and watch that list be more kind to
             | the resources.
        
               | nerdponx wrote:
               | > Python bogs down where there is excess use of the
               | dynamic aspects, e.g., a large list comprehension. Go
               | with a generator, and watch that list be more kind to the
               | resources.
               | 
               | This is a micro-optimization and it's not always true.
               | Generators usually use less memory, but list
               | comprehensions can actually be _faster_ because the
               | memory gets allocated all at once and the loop is
               | performed internally inside the interpreter, instead of
               | the generator possibly being consumed as a slow top-level
               | loop.
               | 
               | I was talking about examples like making a copy of a
               | list/dict/object instead of replacing elements in-place,
               | or using a stack of map/filter operations instead of a
               | single-pass for-loop with dynamic programming.
        
               | smitty1e wrote:
               | Fair point, especially in the case of network-bound or
               | disk-IO intensive work.
        
           | adastra22 wrote:
           | Algebraic data types and exhaustive pattern matching Are a
           | core part of Rust.
        
           | bryanlarsen wrote:
           | ADT's and exhaustive pattern matching are in Rust. The way
           | you wrote your comment makes it clear that you know that, but
           | might as well make it explicit.
           | 
           | IMO, people come to Rust because of memory safety, but they
           | stay because of ADT's and similar features.
        
         | amitport wrote:
         | I would credit this model for multiprocessing to LISP family
         | (Scheme/Rackt/Clojure) before golang. (Probably someone else
         | would mention an earlier references :)
        
           | lolinder wrote:
           | Yep, there's a reason why I credited Golang with
           | mainstreaming the concept, not inventing it. The model goes
           | back quite a ways, but Golang brought it into the mainstream.
        
         | initplus wrote:
         | Any programming language represents limitations placed on the
         | underlying expressiveness of the hardware. By this argument raw
         | x86 asm is "more expressive" than any higher level language.
         | 
         | The whole point of a programming language is to provide you
         | with common patterns/designs to simplify reasoning about your
         | program. Even base concepts like a "function" or "struct" is
         | really a limitation on the underlying expressive power.
         | 
         | Immutability/purity does solve real problems for programmers:
         | it means that you only have to reason about mutability at the
         | margins of your application. I think people who don't have
         | experience with functional style don't realise how helpful this
         | is. I choose to use functional languages because it makes me a
         | better developer - I am able to write code that I am not
         | diligent/smart/disciplined enough to write in an imperative
         | style.
        
           | lolinder wrote:
           | I agree completely about immutability and purity--for my own
           | code I strongly lean that way and try to outsource as much of
           | my thinking to the compiler as possible.
           | 
           | However, there are times where impurity and mutability are
           | beneficial--whether within a single function or at the
           | margins. Functional programming languages do not tend to have
           | good support for these cases, because their _whole thing_ is
           | representing everything in a functional style.
           | 
           | I think this is why functional languages don't tend to get
           | traction while the multi-paradigm languages do. Given a
           | choice between purity and pragmatism, most engineers will
           | pick pragmatism. The alternative is to intentionally remove
           | tools from your toolbox, and unless those tools are
           | demonstrably more dangerous than they are helpful that's a
           | tough sell.
           | 
           | My ideal language is a multi paradigm language which has
           | robust, statically analyzable support for objects, imperative
           | code, and functional code.
        
         | tikhonj wrote:
         | > _In order for a programmer to accept a language with strictly
         | less expressive power_
         | 
         | Sort of hard to reconcile this view with just how much more
         | expressive the Haskells and Lisps of the world are compared to
         | Go and Python! I've used all of these extensively and
         | functional languages have consistently let me define more
         | general and flexible abstractions, do a better job of
         | reflecting my conceptual model of the domain in my code... all
         | in substantially less code and less boilerplate (excessive
         | imports aside :P) than primarily imperative languages.
         | 
         | Functional languages don't _stop_ you from writing imperative
         | code, they _allow_ you to write code that isn 't--and, either
         | way, that's just one small aspect of what makes a language
         | adaptable and flexible.
        
           | lolinder wrote:
           | LISP isn't a pure functional language, it's a multi-paradigm
           | language that is as dynamic as they come. Its problem isn't
           | lack of expressivity, it's probably that it's _too_ flexible
           | (and of course the syntax throws people off).
           | 
           | As for Haskell, I guess that gets into the question of how
           | you define expressivity, which is admittedly a very fuzzy
           | term. Here I meant it to mean capable of fluently expressing
           | many different kinds of algorithms without having to resort
           | to circumlocution.
           | 
           | Functional programming is natively supported in almost all
           | modern languages. You call a function which calls a function
           | which calls a function which calls a function, return the
           | result. There's no syntactic sugar, just function calls.
           | 
           | In Haskell, while I've seen people argue that do notation may
           | as well be imperative code, it _isn 't_. It's an
           | approximation of imperative code using Church--Turing and a
           | liberal dose of syntactic sugar, and using it effectively
           | still requires you to understand the underlying monadic
           | model.
        
             | coldtea wrote:
             | > _LISP isn 't a pure functional language_
             | 
             | In the modern history-rewritten sense of the term to mean
             | Haskell and purity.
             | 
             | In the past LISP was the 100% canonical idea of what a
             | functional language is, including on HN before 2010 or so.
        
             | CrimsonCape wrote:
             | This seems like an easy fix, re-release LISP with cleaner
             | syntax. Lexers have come so far this seems like an easy
             | fix.
             | 
             | I can't say i've ever read the opinion that LISP's syntax
             | allows more expressive programming; rather LISP itself
             | allows more expressive programming at the tradeoff of the
             | syntax.
        
               | Kamq wrote:
               | > re-release LISP with cleaner syntax.
               | 
               | A lot of the flexibility of lisp relies on there being no
               | difference between a list of symbols and code (for,
               | example, this is how the entire macro system works).
               | 
               | Function calls being inside the parentheses (and, really,
               | all language constructs just being lists of symbols) is
               | generally what people mean when they say the syntax
               | throws people.
               | 
               | These two things are at odds.
               | 
               | You could go with Racket's method of letting people use
               | alternate delimiters, but that's a fairly trivial reader
               | macro in common lisp and probably not worth releasing a
               | language over.
        
               | coldtea wrote:
               | > _I can 't say i've ever read the opinion that LISP's
               | syntax allows more expressive programming; rather LISP
               | itself allows more expressive programming at the tradeoff
               | of the syntax._
               | 
               | The conventional idea from LISPers is the other way
               | around: LISP's syntax allows for more expressive
               | programming, because code and data are isomorphic (so,
               | macros and rewriting, etc.), and any function you make
               | looks as "first class" as any native one.
               | 
               | LISP's syntax is also said to be a better and more
               | concise way than JSON (and or course XML) to describe
               | arbitrary hierarchical structures.
        
               | patrickmay wrote:
               | There is no cleaner syntax than Lisp's. It is essential
               | to Lisp's expressivity.
        
             | physPop wrote:
             | If you truly think "functional programming is natively
             | supported in almost all modern languages" then you really
             | don't know what modern FP is about.
             | 
             | For instance implementations of monadic control flow,
             | effect systems, higher kinded types, algebraic data types,
             | exhaustive pattern matching etc are all laughably
             | unergonomic or entireley missing in most
             | "popular"/"enterprise" languages. Just having a labmda
             | doesn't FP make.
             | 
             | To me, FP in modern functional languages provides
             | abstractions that enable much more straightforward problem
             | solving and understandable code with fearless refactoring.
             | Haskell and Ocaml are the pragmatic leaders here I think,
             | with honorable mentions for things like Scala3, F#, and
             | (kindof?) clojure.
             | 
             | (edit spelling)
        
         | karmakaze wrote:
         | > strictly _less_ expressive power
         | 
         | We have a difference in what we consider expressive. How in
         | this more expressive language would you represent pure
         | functions or deeply immutable datastructures if it only offered
         | flexible/mutable ones? More flexible does not mean more
         | expressive.
         | 
         | If by expressive you mean conciseness, "Comparing the Same
         | Project in Rust, Haskell, C++, Python, Scala and OCaml"[0] is
         | of interest.
         | 
         | [0] https://news.ycombinator.com/item?id=20192645
        
           | lolinder wrote:
           | > How in this more expressive language would you represent
           | pure functions or deeply immutable datastructures if it only
           | offered flexible/mutable ones
           | 
           | With a function that doesn't cause any mutations and a set of
           | classes/interfaces that offer no mutator methods.
           | 
           | My point is that you don't _need_ to be able to have the
           | compiler enforce constraints in order to express an algorithm
           | --you just write the code. Having the compiler enforce
           | constraints is often helpful but comes with decreased ability
           | to express _other_ types of algorithms that rely on breaking
           | those constraints, so the language as a whole is less
           | expressive. In order for a programmer to accept those
           | limitations there need to be clear advantages, and the
           | advantages that functional programming proponents have put
           | forward so far haven 't been persuasive to most developers.
           | 
           | By the definition I'm working with, the most expressive
           | languages are the ones that offer the fewest constraints to
           | what the code can do--LISP would be a top contender.
           | Expressivity isn't the highest virtue, but it is valuable and
           | programmers don't give it up unless they can be persuaded it
           | will be worth it.
        
             | karmakaze wrote:
             | > you don't need to be able to have the compiler enforce
             | constraints
             | 
             | Expressing such constraints and having the
             | language/compiler enforce them is part of what I want from
             | an expressive language. That way once I've expressed them,
             | I don't have to ensure those things repeatedly for the
             | entire lifecycle of the program. We each have our
             | definitions and values.
        
               | lolinder wrote:
               | I should be clear that I personally agree with you
               | 100%--I prefer to outsource as much as I can to the
               | compiler. It's just that I also recognize that that means
               | being unable to express some things that are otherwise
               | possible, and that most developers don't like that trade-
               | off.
        
               | karmakaze wrote:
               | I don't know what you mean. Just because C++ has "const",
               | you can still make a method that doesn't mutate without
               | the keyword. Seems like a "No True Scotsman" definition
               | of expressiveness.
        
               | initplus wrote:
               | I feel like this doesn't make sense because mainstream
               | functional languages all provide a way to express
               | imperative code.
               | 
               | In Haskell you can write an entire application using
               | IO/do blocks and it will be completely imperative. In f#
               | you can declare every variable mut.
               | 
               | Functional languages don't prevent you from writing
               | imperative code. They give you the opportunity to choose
               | not to, and enforce it at compile time. The opposite is
               | not true of imperative languages, there the type system
               | cannot help you to enforce that some code is purely
               | functional.
        
           | kaba0 wrote:
           | Here is a completely pure function in any imperative
           | language:                 int add(int a, int b) {
           | return a + b;       }
        
             | CrimsonCape wrote:
             | Yes, this is a great example of a pillar of functional
             | programming, pure functions. What is concerning is that
             | your code example, like other pure function examples out
             | there, implements a math operation a first grader can
             | perform.
             | 
             | It's exceedingly difficult to find a pure functional
             | example that operates on tangible domain-specific data of
             | objects full of state.
        
             | initplus wrote:
             | But the purity is implicit. Nothing will stop you from
             | refactoring add into an impure function. As a programmer
             | you have to maintain this mentally by remembering which
             | types are pass by value and which are pass by reference.
        
         | kaba0 wrote:
         | Go solves no correctness problem regarding parallelism, it is
         | as chock full of foot guns as any other multithreaded largely
         | imperative language.
        
         | [deleted]
        
         | bcrosby95 wrote:
         | I'm a bit confused, because I don't see the commonality between
         | Go and Project Loom other than lightweight threading. Go's
         | whole concurrency model is still fundamentally different from
         | Java as it went all in on CSP, and Project Loom isn't.
         | 
         | Beyond that, nothing about Project Loom fundamentally changes
         | the design of all but the most performance sensitive concurrent
         | programs in Java.
         | 
         | For most of us plain programmers that Go was targeted at
         | anyways, a bucket of OS threads is just fine. Now they will be
         | a bucket of virtual threads, which will be nicer, but not
         | exactly game changing.
        
         | [deleted]
        
       | karmakaze wrote:
       | This other "The case for dynamic, functional programming"[0] post
       | may offer hints. So I suppose it will be more like Elixir/BEAM.
       | 
       | > Theoretically, functional programs should: have fewer bugs, be
       | easier to optimize for performance, allow you to add features
       | more quickly, achieve the same outcome with less effort, require
       | less time to get familiarized with a new codebase, etc. With a
       | dynamic, functional language you could enjoy all of this
       | simplicity.
       | 
       | In my experience use of static typing has fewer bugs and better
       | performance than my usages of dynamic languages on all but small
       | or short-lived projects.
       | 
       | I suppose this will round-out Google languages: Go, Dart, and _,
       | until they make their own scripting or an actual systems
       | language.
       | 
       | [0] https://www.onebigfluke.com/2022/11/the-case-for-dynamic-
       | fun...
        
       | throwway23432 wrote:
       | There are a lot of people that have no interest in FP and hate
       | reading functional code which involves reading and understanding
       | recursion, fix-point style, partial application, currying, lazy
       | evaluation, immutable data structures, lambdas, and combinators.
       | 
       | Then you have to think of performance characteristics, and
       | debugging, onboarding new engineers, and code reviews.
       | 
       | I think it's easy to see why the industry doesn't use FP
       | languages, and because of this people see no reason to even
       | bother with it.
       | 
       | I myself would rather use ML family languages or Clojure or BEAM
       | but it will never happen. The majority want to use Python or Go
       | since they are slim on abstraction and easy to pickup. There's no
       | bullshit involved.
        
       | twen_ty wrote:
       | This must be a troll post because F# already exists and used
       | extensively in production in Azure.
        
       | moring wrote:
       | > My conclusion is that there are major, well-justified reasons
       | for why people strongly dislike functional languages.
       | 
       | I hope he is also questioning the premise that functional
       | programming is the reason why functional languages are unpopular.
       | Every time I wanted to dive into functional programming I was
       | very quickly frustrated with the abysmal tooling around them and
       | while that didn't really _prevent_ me from trying, I simply found
       | a better use for my time.
       | 
       | Most recent example: Clojure wanting me to choose one of multiple
       | package managers before starting my first project. Before that it
       | was package management nonsense in Haskell, and before that some
       | Scheme interpreter not being able to even give a stack trace on
       | errors.
       | 
       | IMHO a really underrated feature of Rust is how friendly its
       | tooling is towards its users. I'd really like to see something
       | like that for functional programming.
        
         | bslatkin wrote:
         | Great examples. Another question that leads to frustration is
         | "can I use my existing code editor for this"? People are turned
         | off when the answer is "no"
        
           | taeric wrote:
           | What examples force not using an editor? Many have a "natives
           | use this" choice, but few lock you to it.
        
             | bslatkin wrote:
             | Some parentheses languages are much easier to use if you're
             | familiar with a structural editor, for example.
        
               | taeric wrote:
               | All languages are easier that way, though? My kids
               | learning python are best with a ton of hand holding.
               | Affordances that show the structure are huge.
        
               | bslatkin wrote:
               | Agreed that seeing structure is important. I mean
               | operating on it at a higher level like
               | https://calva.io/paredit/
        
         | munch117 wrote:
         | The question "functional programming is great, why isn't it
         | more popular?" predates package managers by decades. That
         | question is older than Linux, older than Haskell.
         | 
         | Best of luck with improving tooling, but it's not the answer.
        
         | pyjarrett wrote:
         | > IMHO a really underrated feature of Rust is how friendly its
         | tooling is towards its users. I'd really like to see something
         | like that for functional programming.
         | 
         | > abysmal tooling around them
         | 
         | F# has amazing tooling.
         | 
         | Debugging works out of the box in Visual Studio and Rider, and
         | it's impure enough I was able to get comfortable quickly and
         | .NET core has a crazy amount built in (e.g. no fuss JSON
         | serialization). I ported a project from C# to F# and the old
         | bash/powershell scripts to publish a standalone executable are
         | now just F# scripts you run with `dotnet fsi`.
        
         | taeric wrote:
         | While I do think an opinionated template would be good; I do
         | also hate how some languages pretend you don't need a package
         | manager.
         | 
         | Back when code was shared more in ideas than implementations,
         | this was truer. All too often today, first thing you need to do
         | is import a package.
        
         | xiaq wrote:
         | As someone who's dabbled in Clojure: the project manager scene
         | (lein vs boot vs deps CLI) is not nearly as bad it is may seem.
         | They are different _project workflow runners_ , not completely
         | different ways to write code and use dependencies. They are not
         | radically different in their core job of taking your code,
         | downloading dependencies and running it.
         | 
         | If you're a beginner, you can choose any one and there's very
         | little you're missing out or getting locked into. You only need
         | to worry about the choice when you start having complex
         | development workflows.
         | 
         | In comparison, the JavaScript ecosystem is much, much more
         | divided. There are different ways to write modules, different
         | ways to build them, different package repositories, etc..
        
           | moring wrote:
           | > If you're a beginner, you can choose any one
           | 
           | I found this to be false in practice: I did choose any one
           | (lein actually, because my IDE suggested that it's the one
           | you'll want to use when you don't know better). The
           | consequence was that the examples from the Clojure page
           | didn't work and/or printed totally different output, because
           | they made a different choice.
           | 
           | It's the kind of thing where a Clojure expert would say: they
           | are different tools, of course their output is different, but
           | it doesn't matter because that's only the tool output and the
           | net effect is the same. But in practice, a newbie will
           | struggle solving very simple problems because the tutorial
           | doesn't match reality.
           | 
           | Contrast that with the "rust book" (more or less the official
           | tutorial) in which every single example behaves 100% exactly
           | as described in the tutorial, from installing the toolchain
           | to very complex, language-specific issues (yes, of course I'm
           | referring to the borrow checker).
        
         | slifin wrote:
         | Just choose Clojure deps
         | 
         | I kind of agree some more clarity would be helpful but we don't
         | have a lot of enthusiastic young programmers in Clojure land
         | who like making super accessible stuff
         | 
         | It's just kind of assumed you'll put the work in because
         | Clojure is different enough that you probably have a good
         | reason to be here
         | 
         | Btw if you want anything Clojure Google Clojure Slack and
         | they'll help you there
        
       | klysm wrote:
       | The biggest thing I find myself missing from functional languages
       | isn't the purity or functions - it's the clean expression of
       | immutable data types combined with exhaustive pattern matching.
       | All I want is algebraic data types and the ability to use the
       | compiler to check my work.
        
         | adastra22 wrote:
         | Most new systems languages have this now.
        
       | nothrowaways wrote:
       | Short answer, because I am bored.
        
         | robertlagrant wrote:
         | "I want to be paid a fortune for making a programming language,
         | so I need a reason."
         | 
         | Of course, I would do the same in their position.
        
           | bslatkin wrote:
           | It's an unpaid personal open source project.
        
       | fjfaase wrote:
       | Functional is a good way to 'specify' how a certain
       | calculation/change has to be performed. When working with
       | distributed systems with multiple actors making changes, you have
       | to treat the whole system (distribute database) as a single value
       | on which your functions operate. Then you can use the commutative
       | properties of function to implement transactions. (If two
       | operations on the system commute, they can be applied in either
       | order on the system, to result in the same state.)
       | 
       | But from such a specifying approach to a working system, is a
       | long way.
        
       | andsoitis wrote:
       | Without articulating what particular tradeoffs the author is
       | balancing and sounding like they only recently
       | realized/discovered the parallelism advantage possible to
       | functional programming languages and paradigms, it is hard to
       | know for sure, but I might venture a guess that Julia will be
       | superior to what they are building: https://julialang.org
        
         | bslatkin wrote:
         | The conversation happened in ~2008.
         | 
         | Julia has a lot of great ideas in it for sure. Why hasn't it
         | gotten more popular?
        
           | lenkite wrote:
           | When it gets out of its data-science pedigree and can be used
           | for standard apps. When it gets good tooling. When its stack-
           | traces stop being arcane gobbledygook. When it can be
           | compiled to a single binary at the command line without going
           | through arcane hoops. When it gets
           | interfaces/protocols/traits.
           | 
           | At the moment, Julia is a nice language at v1alpha1 for
           | scripts and data exploration.
        
         | mrkeen wrote:
         | Parallelism is concurrency (+maybe a little SIMD) done for
         | _speed 's sake_.
         | 
         | Haskell is by far the best programming experience I've ever had
         | (all aspects included), and it's damn fast. It's just not
         | C/C++/Rust fast _in nearly all cases_.
         | 
         | Having said that, going functional for 'parallelism advantage'
         | (speed) is a fool's errand (for now).
         | 
         | The same thing is said about how incredibly fast JIT has
         | become. (But AOT is faster!)
         | 
         | Want speed? C/C++/Rust.
        
       | xutopia wrote:
       | What language is he working on though? Can we see the initial
       | ideas in the syntax?
        
       ___________________________________________________________________
       (page generated 2023-03-05 23:01 UTC)