Saltar al contenido

¿Cuál es la diferencia entre programación procedimental y programación funcional?

[*]Al fin luego de mucho luchar ya dimos con la contestación de esta preocupación que ciertos usuarios de este sitio web han tenido. Si deseas compartir alguna información no dejes de dejar tu comentario.

Solución:

[*]Un lenguaje funcional (idealmente) le permite escribir una función matemática, es decir, una función que toma norte argumentos y devuelve un valor. Si se ejecuta el programa, esta función se evalúa lógicamente según sea necesario.1

[*]Un lenguaje procedimental, por otro lado, realiza una serie de secuencial pasos. (Hay una forma de transformar la lógica secuencial en lógica funcional llamada estilo de paso de continuación).

[*]Como consecuencia, un programa puramente funcional siempre produce el mismo valor para una entrada, y el orden de evaluación no está bien definido; lo que significa que los valores inciertos como la entrada del usuario o los valores aleatorios son difíciles de modelar en lenguajes puramente funcionales.


[*]1 Como todo lo demás en esta respuesta, eso es una generalización. Esta propiedad, que evalúa un cálculo cuando se necesita su resultado en lugar de secuencialmente donde se llama, se conoce como “pereza”. En realidad, no todos los lenguajes funcionales son universalmente perezosos, ni la pereza se restringe a la programación funcional. Más bien, la descripción dada aquí proporciona un “marco mental” para pensar en diferentes estilos de programación que no son categorías distintas y opuestas, sino ideas fluidas.

[*]Básicamente, los dos estilos son como Yin y Yang. Uno está organizado, mientras que el otro es caótico. Hay situaciones en las que la programación funcional es la opción obvia y otras situaciones en las que la programación procedimental es la mejor opción. Es por eso que hay al menos dos lenguajes que han salido recientemente con una nueva versión, que abarca ambos estilos de programación. (Perl 6 y D 2)

[*]#Procesal:#

  • La salida de una rutina no siempre tiene una correlación directa con la entrada.
  • Todo se hace en un orden específico.
  • La ejecución de una rutina puede tener efectos secundarios.
  • Tiende a enfatizar la implementación de soluciones de manera lineal.

[*]## Perl 6

##

sub factorial ( UInt:D $n is copy ) returns UInt 

  # modify "outside" state
  state $call-count++;
  # in this case it is rather pointless as
  # it can't even be accessed from outside

  my $result = 1;

  loop ( ; $n > 0 ; $n-- )

    $result *= $n;

  

  return $result;

[*]## D 2 ##

int factorial( int n )

  int result = 1;

  for( ; n > 0 ; n-- )
    result *= n;
  

  return result;


[*]#Funcional:#

  • A menudo recursivo.
  • Siempre devuelve la misma salida para una entrada determinada.
  • El orden de evaluación suele ser indefinido.
  • Debe ser apátrida. es decir, ninguna operación puede tener efectos secundarios.
  • Buen ajuste para ejecución paralela
  • Tiende a enfatizar un enfoque de divide y vencerás.
  • Puede tener la función de evaluación diferida.

[*]## Haskell ## (copiado de Wikipedia);

fac :: Integer -> Integer

fac 0 = 1
fac n | n > 0 = n * fac (n-1)

[*]o en una línea:

fac n = if n > 0 then n * fac (n-1) else 1

[*]## Perl 6 ##

proto sub factorial ( UInt:D $n ) returns UInt *

multi sub factorial (  0 )  1 
multi sub factorial ( $n )  $n * samewith $n-1  #  $n * factorial $n-1 

[*]## D 2 ##

pure int factorial( invariant int n )
  if( n <= 1 )
    return 1;
  else
    return n * factorial( n-1 );
  


[*]#Nota al margen: #

[*]Factorial es en realidad un ejemplo común para mostrar lo fácil que es crear nuevos operadores en Perl 6 de la misma manera que crearía una subrutina. Esta característica está tan arraigada en Perl 6 que la mayoría de los operadores en la implementación de Rakudo se definen de esta manera. También le permite agregar sus propios candidatos múltiples a los operadores existentes.

sub postfix:< ! > ( UInt:D $n --> UInt )
  is tighter(&infix:<*>)
   [*] 2 .. $n 

say 5!; # 120␤

[*]Este ejemplo también muestra la creación de rango (2..$n) y el metaoperador de reducción de lista ([ OPERATOR ] LIST) combinado con el operador de multiplicación infijo numérico. (*)
También muestra que puedes poner --> UInt en la firma en lugar de returns UInt después de.

[*](Puede salirse con la suya iniciando el rango con 2 ya que el "operador" de multiplicar volverá 1 cuando se llama sin ningún argumento)

[*]Nunca he visto esta definición dada en otro lugar, pero creo que esto resume bastante bien las diferencias dadas aquí:

[*]Funcional la programación se centra en expresiones

[*]Procesal la programación se centra en declaraciones

[*]Las expresiones tienen valores. Un programa funcional es una expresión cuyo valor es una secuencia de instrucciones que debe llevar a cabo la computadora.

[*]Las declaraciones no tienen valores y en cambio modifican el estado de alguna máquina conceptual.

[*]En un lenguaje puramente funcional no habría declaraciones, en el sentido de que no hay forma de manipular el estado (es posible que todavía tengan una construcción sintáctica llamada "declaración", pero a menos que manipule el estado, no lo llamaría una declaración en este sentido. ). En un lenguaje puramente procedimental no habría expresiones, todo sería una instrucción que manipula el estado de la máquina.

[*]Haskell sería un ejemplo de lenguaje puramente funcional porque no hay forma de manipular el estado. El código máquina sería un ejemplo de un lenguaje puramente procedimental porque todo en un programa es una declaración que manipula el estado de los registros y la memoria de la máquina.

[*]La parte confusa es que la gran mayoría de lenguajes de programación contienen ambos expresiones y declaraciones, lo que le permite mezclar paradigmas. Los lenguajes pueden clasificarse como más funcionales o más procedimentales en función de cuánto fomentan el uso de declaraciones frente a expresiones.

[*]Por ejemplo, C sería más funcional que COBOL porque una llamada a función es una expresión, mientras que llamar a un subprograma en COBOL es una declaración (que manipula el estado de las variables compartidas y no devuelve un valor). Python sería más funcional que C porque le permite expresar la lógica condicional como una expresión usando evaluación de cortocircuito (prueba && ruta1 || ruta2 en lugar de declaraciones if). Scheme sería más funcional que Python porque todo en el esquema es una expresión.

[*]Todavía puede escribir con un estilo funcional en un lenguaje que fomente el paradigma procedimental y viceversa. Es más difícil y / o más incómodo escribir en un paradigma que el idioma no fomenta.

Sección de Reseñas y Valoraciones

[*]Nos encantaría que puedieras dar visibilidad a este tutorial si te valió la pena.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *