scala - ¿Cómo puede existir una función de tiempo en la programación funcional?



6 Answers

Si y no.

Diferentes lenguajes de programación funcionales los resuelven de manera diferente.

En Haskell (uno muy puro) todo esto tiene que suceder en algo que se llama la Mónada de E / S , consulte here .

Puede pensar que es obtener otra entrada (y salida) en su función (el estado del mundo) o más fácil como un lugar donde ocurre la "impureza", como el cambio de tiempo.

Otros lenguajes como F # solo tienen algo de impureza incorporado, por lo que puede tener una función que devuelve diferentes valores para la misma entrada, al igual que los lenguajes imperativos normales .

Como Jeffrey Burka mencionó en su comentario: Aquí está la buena introducción a la E / S Monad directamente desde el wiki de Haskell.

scala haskell f# functional-programming clean-language

Tengo que admitir que no sé mucho sobre programación funcional. Lo leí de aquí y de allí, y así llegué a saber que en la programación funcional, una función devuelve la misma salida, para la misma entrada, sin importar cuántas veces se llame la función. Es exactamente como una función matemática que evalúa la misma salida para el mismo valor de los parámetros de entrada que implica la expresión de la función.

Por ejemplo, considera esto:

f(x,y) = x*x + y; // It is a mathematical function

No importa cuántas veces uses f(10,4) , su valor siempre será 104 . Como tal, siempre que hayas escrito f(10,4) , puedes reemplazarlo por 104 , sin alterar el valor de la expresión completa. Esta propiedad se conoce como transparencia referencial de una expresión.

Como dice la Wikipedia ( link ),

A la inversa, en el código funcional, el valor de salida de una función depende solo de los argumentos que se ingresan a la función, por lo que llamar a una función f dos veces con el mismo valor para un argumento x producirá el mismo resultado f (x) en ambas ocasiones.

¿Puede existir una función de tiempo (que devuelve el tiempo actual ) en la programación funcional?

  • Si es así, ¿cómo puede existir? ¿No viola el principio de programación funcional? Viola particularmente la transparencia referencial, que es una de las propiedades de la programación funcional (si la comprendo correctamente).

  • O si no, entonces ¿cómo se puede saber la hora actual en la programación funcional?




La mayoría de los lenguajes de programación funcionales no son puros, es decir, permiten que las funciones no solo dependan de sus valores. En esos idiomas es perfectamente posible tener una función que devuelva la hora actual. De los idiomas con los que marcó esta pregunta, esto se aplica a Scala y F# (así como a la mayoría de las otras variantes de ML ).

En lenguajes como Haskell y Clean , que son puros, la situación es diferente. En Haskell, la hora actual no estaría disponible a través de una función, sino de una acción llamada IO, que es la forma en que Haskell encapsula los efectos secundarios.

En Limpiar sería una función, pero la función tomaría un valor mundial como argumento y devolvería un valor mundial nuevo (además del tiempo actual) como su resultado. El sistema de tipos se aseguraría de que cada valor mundial se pueda usar una sola vez (y cada función que consuma un valor mundial produciría una nueva). De esta manera, la función de tiempo tendría que llamarse con un argumento diferente cada vez y, por lo tanto, se le permitiría devolver un tiempo diferente cada vez.




Absolutamente se puede hacer de una manera puramente funcional. Hay varias formas de hacerlo, pero la más simple es hacer que la función de tiempo devuelva no solo el tiempo, sino también la función a la que debe llamar para obtener la siguiente medición de tiempo .

En C # podrías implementarlo así:

// Exposes mutable time as immutable time (poorly, to illustrate by example)
// Although the insides are mutable, the exposed surface is immutable.
public class ClockStamp {
    public static readonly ClockStamp ProgramStartTime = new ClockStamp();
    public readonly DateTime Time;
    private ClockStamp _next;

    private ClockStamp() {
        this.Time = DateTime.Now;
    }
    public ClockStamp NextMeasurement() {
        if (this._next == null) this._next = new ClockStamp();
        return this._next;
    }
}

(Tenga en cuenta que este es un ejemplo destinado a ser simple, no práctico. En particular, los nodos de la lista no pueden recogerse como basura porque están arraigados por ProgramStartTime).

Esta clase 'ClockStamp' actúa como una lista enlazada inmutable, pero en realidad los nodos se generan a pedido para que puedan contener el tiempo 'actual'. Cualquier función que quiera medir la hora debe tener un parámetro 'clockStamp' y también debe devolver su última medición de tiempo en su resultado (para que la persona que llama no vea las mediciones anteriores), como esto:

// Immutable. A result accompanied by a clockstamp
public struct TimeStampedValue<T> {
    public readonly ClockStamp Time;
    public readonly T Value;
    public TimeStampedValue(ClockStamp time, T value) {
        this.Time = time;
        this.Value = value;
    }
}

// Times an empty loop.
public static TimeStampedValue<TimeSpan> TimeALoop(ClockStamp lastMeasurement) {
    var start = lastMeasurement.NextMeasurement();
    for (var i = 0; i < 10000000; i++) {
    }
    var end = start.NextMeasurement();
    var duration = end.Time - start.Time;
    return new TimeStampedValue<TimeSpan>(end, duration);
}

public static void Main(String[] args) {
    var clock = ClockStamp.ProgramStartTime;
    var r = TimeALoop(clock);
    var duration = r.Value; //the result
    clock = r.Time; //must now use returned clock, to avoid seeing old measurements
}

Por supuesto, es un poco incómodo tener que pasar esa última medición dentro y fuera, dentro y fuera, dentro y fuera. Hay muchas formas de ocultar la placa, especialmente en el nivel de diseño del idioma. Creo que Haskell usa este tipo de truco y luego oculta las partes feas usando mónadas.




Sí, es posible que una función pura devuelva el tiempo, si se le da ese tiempo como parámetro. Argumento de tiempo diferente, resultado de tiempo diferente. Luego forme otras funciones del tiempo también y combínelas con un vocabulario simple de funciones de función (-t-time) -transforming (orden superior). Dado que el enfoque no tiene estado, el tiempo aquí puede ser continuo (independiente de la resolución) en lugar de discreto, lo que aumenta enormemente la modularidad . Esta intuición es la base de la Programación reactiva funcional (FRP).




Sí, puede existir una función de obtención de tiempo en la programación funcional utilizando una versión ligeramente modificada en la programación funcional conocida como programación funcional impura (la predeterminada o la principal es la programación funcional pura).

En caso de obtener el tiempo (o leer un archivo, o lanzar un misil), el código debe interactuar con el mundo exterior para realizar el trabajo y este mundo exterior no se basa en los fundamentos puros de la programación funcional. Para permitir que un mundo de programación funcional puro interactúe con este mundo exterior impuro, las personas han introducido programación funcional impura. Después de todo, el software que no interactúa con el mundo exterior no es más útil que hacer algunos cálculos matemáticos.

Pocos lenguajes de programación de programación funcional tienen incorporada esta característica de impureza, por lo que no es fácil separar qué código es impuro y cuál es puro (como F #, etc.) y algunos lenguajes de programación funcionales se aseguran de que al hacer algunas cosas impuras ese código es claramente destacado en comparación con el código puro, como Haskell.

Otra forma interesante de ver esto sería que su función de obtención de tiempo en la programación funcional tomaría un objeto de "mundo" que tiene el estado actual del mundo, como el tiempo, el número de personas que viven en el mundo, etc. El objeto siempre será puro, es decir, si pasa en el mismo estado mundial, siempre obtendrá el mismo tiempo.




Si es así, ¿cómo puede existir? ¿No viola el principio de programación funcional? Viola especialmente la transparencia referencial.

No existe en un sentido puramente funcional.

O si no, entonces ¿cómo se puede saber la hora actual en la programación funcional?

Primero puede ser útil saber cómo se recupera una hora en una computadora. Esencialmente, hay circuitos integrados que realizan un seguimiento del tiempo (razón por la cual una computadora usualmente necesita una batería de celda pequeña). Entonces podría haber algún proceso interno que establezca el valor del tiempo en un determinado registro de memoria. Lo que esencialmente se reduce a un valor que puede ser recuperado por la CPU.

Para Haskell, hay un concepto de 'acción de IO' que representa un tipo que se puede hacer para llevar a cabo algún proceso de IO. Entonces, en lugar de hacer referencia a un valor de time , hacemos referencia a un valor de IO Time Todo esto sería puramente funcional. No estamos haciendo referencia al time sino a algo como "leer el valor del registro de tiempo" .

Cuando realmente ejecutamos el programa Haskell, la acción IO realmente tendría lugar.




Related