Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> 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



> 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.


> 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.


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.


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.


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.


https://en.wikipedia.org/wiki/Rule_of_least_power is why we don't do everything with "if/goto". Being able to write "switch" or "while" or "throw" names the behavior intended (and especially what's not intended) more clearly than one construct that could do anything and appears everywhere.


Here is a completely pure function in any imperative language:

  int add(int a, int b) {
    return a + b;
  }


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.


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.


It's not at all difficult (https://pandoc.org/). However, I'd hazard a guess that pandoc written in Rust or C (with idioms appropriate to those languages) would be much more performant.


I’m not as sure, several optimizations are only possible if we know that they can’t/won’t have side effects, and while the compiler can see it after inlining, having it part of the signature does help. Haskell is quite impressive on the performance front.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: