En programació d'ordinadors, avaluació tardana (en anglès: Lazy evaluation) és la tècnica de retardar un càlcul fins que se'n requereixi el resultat.

Els beneficis de l'avaluació tardana inclouen:

  • augment de rendiment en evitar el càlcul d'expressions no requerides, evitant a més els errors que s'hi puguin produir.
  • capacitat de construir estructures de dades de llargada infinita
  • capacitat de definir estructures de control com a abstraccions en comptes de comandes.

El contrari de l'avaluació tardana és l'avaluació primerenca (en anglès: eager evaluation), també anomenada avaluació estricta, on una expressió és avaluada tan bon punt és assignada a una variable o paràmetre. L'avaluació primerenca és el comportament utilitzat en la majoria de llenguatges.

L'avaluació tardana comprèn els següents tres conceptes:

  1. L'expressió només s'avalua quan és requerida per la funció que la requereix (avaluació retardada).
  2. L'expressió només s'avalua fins a l'extensió requerida (avaluació curtcircuitada)
  3. L'expressió mai no s'avalua més d'una vegada (avaluació en l'ordre aplicatiu)[1]

El llenguatge Haskell utilitza majoritàriament l'avaluació tardana.

Altres llenguatges com OCaml, Scheme[2] i altres la incorporen de manera opcional, mitjançant construccions explícites.

Exemples modifica

Llistes d'avaluació tardana en OCaml modifica

open Printf ;;

(* tipus de llista d'avaluació tardana (ang:lazy) *)

type 'a node_t =
 | Nil
 | Cons of 'a * 'a zlist_t
and 'a zlist_t = 'a node_t Lazy.t
;;

(** generador tardà de m elements; ''lazy'' deixa la generació en suspens *)

let rec genera_llista (m:int) :'a zlist_t =
 lazy (match m with
 | 0 -> Nil
 | n -> Cons(n, genera_llista (n-1))
) ;;

(** fold_left_tard: aplica una op. binària sobre un acumulador i els elem. d'una llista d'avaluació tardana *)

let rec fold_left_tard f acum (llista:'a zlist_t) =
 match (Lazy.force llista) with (* força l'avaluació del generador de la llista obtenint-ne 1 elem. *)
 | Nil -> acum
 | Cons(x, xs) -> fold_left_tard f (f acum x) xs
;;

let op_binaria = fun (a:float) (b:int) -> a +. sqrt (float_of_int b) ;; (* qualsevol que interessi *)

let _ =
 printf "resultat: %.2f\n" (fold_left_tard op_binaria 0. (genera_llista 100000)) 
;;

Referències modifica

  1. David A. Watt, "Programming Language concepts and Paradigms", p. 100
  2. IBM.com - Simple lazy programming in Scheme(anglès)