https://clojuredocs.org/clojure.core/-%3E
It does the same thing, but it's much more awkward to use.
You're correct and I think that's kinda the parent's point. I think what the OP is saying is that the much of the syntax ergonomics are orthogonal to FP, which means they don't have to be as weird/frustrating/unusual/insert preference/unergonomic as they are.
A good example is how piping vs nesting are different syntaxes for function composition: x|A|B|C vs C(B(A(x)))
The former might feel more comfortable, familiar, and left-to-right readable for someone new to FP. That said I think a few language do use piping. F# has |> and I think Clojure used >>> maybe? -- signed, humble java programmer.
> The former might feel more comfortable, familiar, and left-to-right readable for someone new to FP.
C(B(A(x))) is the syntax introduced in school, but note that if you continue on in algebra the notation flips from C(B(A(x))) to x_{ABC}. Everyone agrees that it's easier to list the transformations in the order they happen.
They enable you to write pipe transformations and in my opinion make the code much more readable.
https://stackoverflow.com/questions/2177110/in-f-what-does-p...
See e.g. https://shuangrimu.com/posts/language-agnostic-intro-to-depe...
It's more that the utility of dependent types is generally restricted to functions that are pure and deal with immutable values, which means one possibility is to specially mark which of your functions are allowed to be used in a dependent type and which aren't. But the fragment of your program that can be used in dependent types is generally going to be a pure FP fragment.
Yeah, dependent types would be nonsensical for code that isn't functional. Marking which parts are and aren't is a good idea. Idris did something similar for totality checking. I think it'd be nice to have a system which differentiated between functions and procedures though.
That's essentially what 'IO' types are for (or finer-grained alternatives like 'Eff', etc.). At the value level, we have things like 'do notation', 'for/yield', etc.
h(x).f().g()
Is also very common and I would say it counts, especially if the language support something like extension methods.Extension methods are a bit of a hack (although useful!); a cleaner approach is https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax although I've not personally used a language which supports it :(
https://tour.dlang.org/tour/en/gems/uniform-function-call-sy...
2. Yes that's what I mean by dependent types, where types depend on values, like f(0): string and f(1): int. And yes, they totally are orthogonal. However, pure functional programming tends to lean on its type system more than other styles, in my experience. But then without dependent types, something as simple as loading a CSV gets hairy relative to something like pandas's pd.read_csv. Maybe others can go into why pure FP and static typing go so much together, but I gotta get back to work.
The example you gave of Python doesn't have tagged union. I really don't know much at all about Python so maybe the type checker can tell you that you're handling all the cases, but with tagged union types you can have to handle every possible output of `str_if_zero` when calling it. That doesn't have to be an FP thing but I only find it when doing Elm and Haskell in my experience.
[0] https://elm-lang.org/docs/syntax#operators
(-> x f g h ...)
[0] https://www.cs.cornell.edu/courses/cs3110/2019sp/textbook/ho...
[1] https://tour.dlang.org/tour/en/gems/uniform-function-call-sy...
1. I've never seen the "pipe" notation you talk about in any lang except bash, which is not an FP right? In which languages does "|" denote function application?
2. Aren't dependent types orthogonal to whether a language is functional? Just to make sure we're on the same page on what dependent types mean, I wanna give a example (a contrived one, sorry) of dependent types in Python.