I am learning Clojure and functional programming in general (coming from python). In Clojure it is possible to make impure functions, since you can use slurp and other means of input. Is there a way to easily identify impure functions in Clojure, or is it practice to just keep those functions in a separate section of the code?
Theoretically, there is no way to identify whether a function produces side effects or not (due to Rice's Theorem). So, it is probably impossible to distinguish pure functions from impure functions. Of course, there might be a way to check whether a function is definitely impure at a syntactic level, but I doubt this would actually help in practice.
There is quite a common convention to end a function name with a bang (eg. swap!) where that function is not safe for use inside an STM transaction. This includes IO and many types of side-effect, so there is some overlap here with impurity, however, many impure functions are also entirely safe.
Related
I think I know what refertially transparent and pure mean. However here's a question about the two properties and how they differ.
As regards how referential transparency and/or purity are enforced in a language, I don't know much. (Not even this helped me understand.) I mean, I might know (kind of) how Haskell can deal with IO though being purely functional (see this), and I understand that I can't write impure functions because the type system just doesn't let me (or, better, it does let me in a controlled way, as I have to write unsafe explicitly).
But in C++, like in many other languages, functions are normally non pure nor referentially transparent.
So on the one hand I have Haskell which is constructed as a pure language, where every function is pure. On the other hand I have C++ which has no way to enforce purity (or does it?¹).²
But would it be possible, in the future, for the C++ language to provide a pure/whatever attribute that one could attach to a function so that the compiler would have to verify that the function is indeed pure (or compile-time fail otherwise)?
(¹) This question popped up in my mind when I first knew of [[gnu:pure]] and [[gnu:const]]. My understanding is that those (non-portable) attributes are for giving more guarantees to the compiler, so that it can optimize more stuff, not for telling it to check if the function is truly pure. After all this example seems to compile and run just fine.
(²) But I also remember another, very old language, which is not pure like Haskell, but gives you a PURE attribute to tell that a functions must be pure, and the compiler checked it: Fortran.
I'm currently delving into Fortran and I've come across the pure keyword specifying functions/subroutines that have no side effects.
I have a book, Fortran 90/95 by S Chapman which introduces the pure keyword but strangely provides no "good coding practice" uses.
I'm wondering how liberally one should use this keyword in their procedures. Just by looking around it's obvious to me that most procedures without side effects don't find it necessary to include the pure keyword.
So where is it best used? Only in procedures one wants to completely guarantee have no side effects? Or perhaps in procedures one plans to convert to elemental procedures later? (As elemental procedures must first be pure.)
PURE is required in some cases - for example, procedures called within specification expressions or from FORALL or DO CONCURRENT constructs. PURE is required in these case to give the Fortran processor flexibility in the ordering of procedure invocations while still having a reasonably deterministic outcome from a particular stretch of code.
Beyond those required cases, whether to use PURE or not is basically a question of style, which is somewhat subjective.
There are costs to use of PURE (inability to do IO within the procedure, inability to call procedures that are not PURE) and benefits (a pure procedure written today can be called from a context written tomorrow that requires a pure procedure, because PURE procedures have no side effects the implications of an invocation of such a procedure may be clearer to a reader of the code), the trade-off between the two depends on specifics.
The standard may give Fortran processors considerable lee-way in how they evaluate expressions and function references within expressions. It definitely constrains programs in some ways around side effects of function execution and modification of function arguments. The requirements on a pure function are consistent with that lee-way and those constraints, consequently some people use a style where most functions are pure. Again, it may still depend on specifics, and exceptions may have to exist for things like C interoperability or interaction with external API's.
As suggested by chw21, the primary motivation of PURE is to allow the compiler to better optimize. In particular, the lack of PURE for a function will prevent parallelization due to unknown side effects. Note that PURE subroutines, unlike functions, may have INTENT(INOUT) arguments, but there is still the restriction on side effects (and that a PURE procedure can call only other PURE procedures.)
Up through Fortran 2003, ELEMENTAL procedures are implicitly PURE. Fortran 2008 adds an IMPURE prefix that can be used with ELEMENTAL procedures to disable that aspect.
This might be a stupid question, but since OCaml is not pure and has side effects built-in, what is the use of monads in OCaml?
Monads have nothing to do with purity, except that a pure language without Monads would be almost entirely useless.
In layman's terms, a Monad is just a set of rules that describe how a sequence of steps can be executed. Having a Monad abstraction gives you the ability to define a DSL for executing stuff. A Monad can be built to intelligently handle things like exceptions, ATOMIC rollbacks/commits, retry logic, sleeping between each step, or whatever.
Here are some examples of Monads:
https://wiki.haskell.org/Monad#Interesting_monads
I realize that this list is for Haskell, which is a pure language, but don't let that confuse you.
You don't need to understand category theory to understand what a Monad is, contrary to popular belief. A monad basically has 2 things: (paraphrased from this wikipedia article)
A unit function, defined as (a -> M a), called "return" in Haskell, used to put a value into the context of a Monad.
A binding operation, defined as (M t -> (t -> M u) -> M u), which looks scary but if you look carefully, this is a function that gets invoked between each step of the process, this is where you inject the good stuff.
Depending on the language, there may be more things, but this is the heart of it.
Whilst OCaml supports the standard side-effects provided by most languages, this does not include all possible side-effects. There are a number of effects which OCaml does not provide native support for. Many of these effects can be encoded using Monads. For example,
Concurrency (see Lwt and Async libraries)
Non-deterministic choice
First-class continuations
Ambivalent choice and backtracking
Using more sophisticated representations of computation, such as parameterised monads, even more exotic effects can be encoded. For example,
Polymorphic state
Linear resources
While OCaml allows one to write imperative code it is still functional by its nature, it is used by functional programmers. And we prefer to use persistent data structures and algorithms whenever possible.
What concerning your question, then in particular monads are usefull, for asynchronous computations, e.g., Lwt, Async, where they're used to bind computations (instead of usual way of setting callbacks). Also, monads are used for error handling, instead of exceptions. Also, monads are very helpful in writing parsers, see mparser library. There're also other uses, I enumerated only the most popular.
In general monads just allow you to hide a complex control flow under simple sequential syntax.
This may be a lot more naive than the answer you want but a monad is just a simple abstraction that's useful for structuring computation. It's a little math thing like an equivalence relation (or for people smarter than I am, like a group). Once you learn what they are, you see them everywhere, and they help organize your thinking.
I have been trying to think more about what abstraction actually means in functional programming. The very best post I have found that talks the type of language I can understand is the following 4 abstractions. However since I'm a wannabe Clojure programmer I'm wondering what sort of abstractions macros provide. It seems that they fit in stage 2 together with HOF but at the same time they are more then a HOF. I find stage 3 to be related to the Expression problem and would be protocol and multi methods in Clojure. So my question is:
When implementing a macro in a Lisp language what would you say you are abstracting over?
What would stage 3 and 4 be in a Lisp language?
I don't really view macros as an abstraction, but more as a compiler hook.
Most languages implement what is known as an Abstract Syntax Tree (or AST). This is a representation of the code of a program in a sort of data structure. Lisp macros expose parts of this AST as data that can be transformed via a macro function. But since lisp programs are themselves data structures, macros tend to be a bit cleaner in lisp programs then they would be in Rust or Scala.
So one could say that macros are simply abstractions of language semantics...but I don't know that I agree with that. One could say that macros are extensions of the lisp compiler, but that's not exactly true either.
As it turns out, macros are quite limited. They can only see a small subsection of the code being compiled. In other words, a macro can't see up the tree, only down. In addition while macros that perform deep inspection of children in the AST are possible (known as deep walking macros) these macros tend to be complex and error prone (just look at the guts of core.async's go or the contents of midje to see how complex these can get). So I hesitate to call them abstractions, perhaps they are, perhaps they are just very limited abstractions.
So I see macros as a weird mix between the more powerful Fexprs (http://en.wikipedia.org/wiki/Fexpr) and the more complete compiler code transforms found in projects like LLVM. They provide a very limited controlled way to transform code at compile time, that's about it.
And in the end it all comes down to the lisp mantra that "code is data is code". If your code is data it makes sense to provide ways to transform it at compile time.
At the moment I'm aware of the following methods to integrate side-effects into purely functional programming languages:
effect systems
continuations
unique types
monads
Monads are often cited to be the most effective and most general way to do this.
Which other methods exist? How do they compare?
Arrows, which are more general than monads.
The very simplest method is to simply pass around the environment between the functions. This is often used to teach scheme.
To me a more general way is via a monad/comonad pair. This generalizes the common "monad" approach which should correctly be called the "strong monad" approach, since it only works with strong monads.
Moving to a monad/comonad pair allows effects to be modeled that result in some variables no longer being available. An example where this is useful is the effect of migrating a thread to another host in a distributed setting.
An additional method of historical interest is to make the whole program a function mapping a stream/list of input events to a stream/list of output events. See: "How to Declare an Imperative" by Phil Wadler: http://www.cs.bell-labs.com/~wadler/topics/monads.html#monadsdeclare