The most common template for using a functional language database, given the lack of side effects?

I am trying to understand the basic concept of functional languages:

"The central concept in functional languages ​​is that the result of a function is determined by its input and only by its input. No side effects!"

http://www.haskell.org/haskellwiki/Why_Haskell_matters#Functions_and_side-effects_in_functional_languages

My question is: if a function only makes changes to the local environment and returns a result, how can it interact with a database or file system? By definition, will there be access to what is actually a global variable or global state?

What is the most common pattern used to bypass or address?

+8
functional-programming side-effects
source share
3 answers

The most common scheme for dealing with side effects and impurities in functional languages:

  • be pragmatic, not purist
  • provide built-in modules that allow unclean code and side effects.
  • use them as little as possible!

Examples:

  • Lisp / Schema: set!
  • Clojure: refs and using mutating methods for Java objects
  • Scala: creating variables with var
  • ML: not sure about the specifics, but Wikipedia says it admits some impurities

Haskell is a little cheating - its solution is that for functions that access the file system or database, the state of the entire universe at that moment , including the state of the / db file system, will be passed to the function. (1) Thus, if you can replicate the state of the entire universe at that moment , then you can get the same results twice from such a function. Of course, you cannot replicate the state of the entire universe at this moment , and therefore functions return different values ​​...

But the Haskell solution, IMHO, is not the most common.


(1) Not sure about the specifics here. Thanks to CAMcCann, pointing out that this metaphor is over-used and maybe not as accurate.

+4
source share

Just because a functional language is functional (perhaps even completely clean like Haskell!) Doesn’t mean that programs written in that language should be clean at startup.

The Haskell approach, for example, when dealing with side effects, can be explained quite simply: let the whole program be clean by itself (this means that functions always return the same values ​​for the same arguments and have no side effect), but let the return value of the main function be an action that can be triggered.

Trying to explain this with pseudo-code, here is some kind of program in an imperative , non-functional language:

 main: read contents of abc.txt into mystring write contents of mystring to def.txt 

The main procedure above is this: a series of steps that describe how to perform a series of actions.

Contrast this with a purely functional language such as Haskell. In functional languages, everything is an expression, including the main function. Thus, one can read the equivalent of the above program as follows:

 main = the reading of abc.txt into mystring followed by the writing of mystring to def.txt 

So, main is an expression that, when evaluated, returns an action that describes what to do to execute the program. The actual execution of this action takes place outside the world of programmers. And it really is how it works; The following is a real Haskell program that can be compiled and run:

 main = readFile "abc.txt" >>= \ mystring -> writeFile "def.txt" mystring 

a >>= b we can say that this means “action a , followed by the result a given to action b ” in this situation, and the result of the operator is the combined actions a and b. The above program, of course, is not idiomatic by Haskell; it can be rewritten as follows (removing the redundant variable):

 main = readFile "abc.txt" >>= writeFile "def.txt" 

... or using syntactic sugar and the notation:

 main = do mystring <- readFile "abc.txt" writeFile "def.txt" mystring 

All of the above programs are not only equivalent, but also identical for the compiler.

So files, databases and web servers can be written as purely functional programs: by streaming the action values ​​through the program so that they are combined and, finally, end up in the main function. This gives the programmer tremendous control over the program, and therefore purely functional programming languages ​​are so attractive in some situations.

+10
source share

Recognizing the database is no different from other I / O cases, such as print(17) .

In non-terminally evaluated languages ​​such as LISP and ML, the usual approach to effective programming is simply to use side effects, as in most other programming languages.

At Haskell, the solution to the IO problem uses monads. For example, if you check HDBC , the haskell database library, you will see that there are many functions that return I / O.

Some languages, such as Clean, use unique types to provide the same type of sequence as Haskell with monads, but these languages ​​are more difficult to find at present.

+4
source share

All Articles