3 ms·
> Functional languages are composed of functions that take some input and produce some output. Every time a function is executed with a given input, it will ret
by JonathanBeuys 5y ago
> Functional languages are composed of functions that take some input and produce some output. Every time a function is executed with a given input, it will return the same output.
I think this is not true. If it was this way, there would be no way to read data from an API. read('https://news.ycombinator.com https://news.ycombinator.com') will not return the same output everytime.
And it would not be possible to keep track of anything. No counting, no transformation of data, nothing.
Googling a bit indicates that people use a mental trick and define the state part of the input of the function. So in terms of getUrl() the current state of the internet is part of the input of the function. And when counting something, the function gets the old sum as the input and outputs the new sum which gets stored in a different place than the old sum so the old sum "did not change".
I see a lot of overhead coming from these mental gymnastics with no benefit. Any short example that shows a benefit?
- piperswe 5y agoWith Nix, any network I/O is done through "fixed-output derivations." Fixed-output derivations define the expected hash of their outputs, so if they don't produce the expected output they throw an error.
- JonathanBeuys 5y agoThis seems like another mental trick to me. "Yeah, the function did not produce a different output. It just behaved different by throwing an exception." Still, some other code will read (or "interpret") this behavior and then behave accordingly etc. So what is won here?
- ghostwriter 5y agoNix doesn't allow for recovering from errors
- garethrowlands 5y agoIt's a good trick. The function didn't return a value, so its caller cannot interpret that value and cannot change it behaviour.
- ebingdom 5y ago> I think this is not true. If it was this way, there would be no way to read data from an API. Why do you think the only way to read from an API is with a function call? Have you not heard of monads?
- JonathanBeuys 5y agoNope. I have not heard of any of this. I only read this sentence in the article: > Functional languages are composed of functions that take some input and produce some output. Every time a function is executed with a given input, it will return the same output. It does not mention "monads".
- ghostwriter 5y agoin pure FP languages there are functions and IO actions, functions are pure, IO actions are side-effectful.
- soraminazuki 5y agoThe needs of the Nix language differs from that of a general purpose programming language. Its sole purpose is to output a self-contained and deterministic package build script. As such, it doesn't need persistent state. Every external input, such as source tarballs has their hashes verified so it should wield the exact same result every time it's evaluated. If any external input doesn't match expectations, evaluation would be aborted immediately. > And it would not be possible to keep track of anything. No counting, no transformation of data, nothing. All of this is possible without state. Counting could be done with, say, 'builtins.length'. As for transforming data, that's what programming languages literally do. The Nix language isn't an exception here. In fact, the Nix language has everything to do with transforming data. It transforms high level package definitions to lower level build instructions. > I see a lot of overhead coming from these mental gymnastics with no benefit At least with the Nix language, there's no mental gymnastics going on. Defining a package is as simple as it gets, as can be seen here[1]. The benefits are reproducible package builds and composability. Since Nix functions don't contain state, it's really easy to combine abstractions and make modifications to existing packages compared to conventional package managers. See the Chrome example in the NixOS Wiki[2]. [1]: https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/misc/hello/default.nix https://github.com/NixOS/nixpkgs/blob/master/pkgs/applicatio... [2]: https://nixos.wiki/wiki/Overlays https://nixos.wiki/wiki/Overlays
- rgoulter 5y agoA function which returns the same output (and has no side effects) if given the same input is a "pure function". Things like network requests, or reading from files, or keeping track of state like a counter, are effectful. So, yes, a function which does these things couldn't be pure. It's still nice to be able to have a pure function over an impure function. (Sortof the same "nice" as in "it's nice to not use global variables for everything in your code"). An impure function might be more difficult to think about than a pure one. In languages like Haskell, all the functions are pure. But useful programs are effectful. There are different ways Haskell can still have useful programs while only allowing pure functions. (The most common way this gets done is using monads). -- One trick is "algebraic effects", this blogpost is an accessible intro: https://overreacted.io/algebraic-effects-for-the-rest-of-us/ https://overreacted.io/algebraic-effects-for-the-rest-of-us/ Functional languages themselves are about a bit more than pure functions. It's about being able to pass functions around.. languages like JavaScript or Python have functions like map/filter/flatMap. Functions which take functions as parameters. They're a neat way of writing code. The JSON program JQ's language is comparable to Nix. -- You could write your JSON-processing programs with Python (or whatever), or you can use some JQ expressions to do the processing.
- garethrowlands 5y agoYour absolutely right: it's not true. Well, not entirely true. There are two ways functional languages get around this: Most functional language don't force functions to be pure. So, while they tend to be composed of functions that produce the same output for a given input, they aren't entirely. That is, they're just like any other language in this respect. Nonetheless, functional programs tend to separate the impure parts using patterns such as https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell https://www.destroyallsoftware.com/screencasts/catalog/funct... Then there are the languages where functions actually are necessarily pure - mostly Haskell. But this just means that the imperative actions aren't functions, not that they don't exist. The big impact is that, since a pure function can't invoke an impure action - or it wouldn't be pure - you have to use function-code-imperative-shell or your program won't compile.