2

This older question tells us that in functional programming "true" randomness cannot be achieved since in FP functions are pure/idempotent and return the same value irrespective of number of invocations without any side effects.

But if that is true, how is FP applicable for problems like picking randomly a Captcha or some puzzle to question the user before entering the system?

I considered taking system time as a seed inside the function. But that is depending on external state.

Could anyone please demonstrate it with a code snippet in Haskell/Clojure etc?

Vicky
  • 399
  • 3
  • 6

3 Answers3

4

Your question in a bit unclear in that you don't specify whether you are talking about true random numbers or pseudo-random numbers, so I will answer both.

True Random Numbers

You are correct that functional programs can't produce true random numbers. But neither can imperative programs. Computers are still deterministic machines, regardless of whether they are running a C program or a Haskell program.

Pseudo-Random Numbers

Pseudo-Random Numbers are generated by a Pseudo-Random Number Generator (aka PRNG). PRNGs are just algorithms like any other algorithm. They can be expressed in a functional language just as well as they can be expressed in an imperative language.

So, there is really no difference between functional languages and imperative languages when it comes to random numbers. Both can compute pseudo-random numbers and neither can compute true random numbers (since they can't be computed at all).

in functional programming "true" randomness cannot be achieved since in FP functions are pure/idempotent and return the same value irrespective of number of invocations without any side effects.

Again, the same thing is true for imperative programming. If you call srand with the same seed number, you will deterministically get the same pseudo-random number sequence from rand, every time.

The only way to get true randomness is through I/O. But, functional languages can model I/O just fine, whether that be with an I/O Monad (or something more specialized like a Random monad), linear types, world types, effect types, an effect system, or like Scala, ML, Clojure, and F♯ do it, by simply allowing them and trusting the programmer to not make mistakes.

So, in other words, it makes no sense to be asking about Random Numbers specifically. A PRNG is just a function, so if you are asking how functional programming can be used to deal with pseudo-random numbers, then you should rather ask how functional programming can be used to deal with functions, because there is nothing special about a PRNG, it's just a function. And True Randomness is just I/O, so again, it doesn't make sense to ask about them specifically.

If you accept that you can write functions in FP, then you must also accept that you can write PRNGs in FP. And if you accept that you can read the clock, read input from the user, read a file, access a database, access the web, etc., then you must also accept that you can read True Random Numbers. (In fact, on Unix, for example, device drivers are typically exposed as files, and a true random number device would typically be exposed as a file you read from. And there is a web service that serves true random numbers.)

Jörg W Mittag
  • 104,619
3

The whole point of a random number generator is to return a value that is not a deterministic function of its input.

A "random number function" is therefore a contradiction in terms. It is not even on par with I/O, which can still be modelled purely as a function as part of a deterministic system.

What we do in a functional language is simply implement a non-functional, non-deterministic method call - it may look like a function, have the garb of functional syntax, and assemble together as a function (and be called or evaluated, and its results used, in a deterministic order relative to other functions), but it is clearly not actually a function (because its outputs do not relate to its inputs) - and the whole program that depends on it ceases to be a function anymore (because the program does not execute deterministically according to its inputs).

Steve
  • 12,325
  • 2
  • 19
  • 35
1

Short Answer


Randomness is handled just like other kinds of input.

Long Answer


Random is Input

Random is like reading the state of the hardware clock. And that is like reading the state of the camera to take a profile picture about the computer user, or like reading the content of a certain file. Random is just a special kind of input.

Handling Random Differently than Other Input

In theory some need exists to handle randomness differently from other kinds of input. For example : for security. And the theory of purely functional programming can answer that need. But in practice this direction happens to be not pursued. Even more important security needs are not addressed yet in practice simply because of deficit in software engineering capacity.

How Input is Handled by Purely Functional Programming ?

This topic is discussed in much material over the web. If it to be discussed here on StackExchange then it deserves its own question.

Some Concrete Help to your question Anyway

A pure function returns not the final, concrete result that depends on random, but a [possibly composite] action, like a little algorithm, that says : get a random value; compute some other action with it and perform that other action. A pure function returns just a deterministic value that represents, describes what the program is to do. It forwards the "dirty" problems of non-determinism, IO to the runtime system. A pure function does not do anything, it just computes [and returns] what to do.

libeako
  • 159