2011-09-28 17 views
8

W ramach zadania domowego zlecono nam wykonanie zadania bez żadnych "efektów ubocznych". Sprawdziłem "efekty uboczne" w Wikipedii i choć teoretycznie rozumiem, że "modyfikuje stan lub ma zauważalną interakcję z funkcjami wywołującymi", mam problem z określeniem szczegółów.OCaml: Czy przechowywanie niektórych wartości do późniejszego wprowadzenia wprowadza "efekty uboczne"?

Na przykład, czy tworzenie wartości zawierającej wynik niezgodny z kompilacją może spowodować pojawienie się efektów ubocznych?

Say miałem (nie może być doskonały składniowo):

val myList = (someFunction x y);; 
if List.exists ((=) 7) myList then true else false;; 

Czy to przedstawić skutki uboczne? Sądzę, że może jestem zdezorientowany tym, co "modyfikuje stan" oznacza w definicji skutków ubocznych.

+3

Jedna wskazówka dla stylu: Wzorzec "if expression then true false" lub podobne wzory są bardzo popularne wśród początkujących. Jeśli się nad tym zastanowisz, dla części, która ma być wybrana, wyrażenie musi być prawdziwe, a dla części else musi być fałszywe. Tak więc ten wzór można upuścić i zredukować do "wyrażenia". – LiKao

+0

Czy możesz pokazać kod dla tego? Zdecydowanie jestem początkującym i mogę użyć wskazówek. –

+0

Oczywiście, jest to dość proste: zamiast "if List.istnieje ((=) 7) myList wtedy true else false ;;" możesz po prostu napisać "List.exists ((=) 7) myList ;;". Jeśli przestaniesz myśleć o powodach, dlaczego te dwa stwierdzenia mają tę samą semantykę, dowiesz się dużo o programowaniu funkcjonalnym (a także ogólnym). – LiKao

Odpowiedz

8

Nie; efekt uboczny odnosi się do np. zmutowanie komórki ref z operatorem przypisania := lub innymi rzeczami, w których wartość określona nazwą zmienia się w czasie. W tym przypadku myList jest wartością niezmienną, która nigdy nie zmienia się w trakcie programu, a zatem jest bez efektu.

Zobacz także

http://en.wikipedia.org/wiki/Referential_transparency_(computer_science)

+0

Dzięki, ten link jest bardzo użyteczny dla lepszego zrozumienia programowania funkcjonalnego i efektów ubocznych. –

5

Dobrym sposobem myślenia o to „mieć zmieniłem coś, co każdy później kod (łącznie z ponownym uruchomieniem tę samą funkcję później) może kiedykolwiek ewentualnie Zobacz inne niż wartość I wracam? Jeśli tak, to efekt uboczny. Jeśli nie, to możesz wiedzieć, że go nie ma.

Tak, coś takiego:

let inc_nosf v = v+1 

nie ma skutków ubocznych, ponieważ tylko zwraca nową wartość, która jest o jeden więcej niż w całkowitej v Więc jeśli uruchomić następujący kod w SML Toplevel, masz. odpowiednie wyniki:

# let x = 5;; 
val x : int = 5 
# inc_nosf x;; 
- : int = 6 
# x;; 
- : int = 5 

Jak widać, wartość x nie uległa zmianie. Ponieważ nie zapisaliśmy wartości zwracanej, nic tak naprawdę nie zostało zwiększone. Nasza funkcja jedynie modyfikuje wartość zwracaną, a nie samą x. Tak, aby zapisać go w X, to mamy do czynienia:

# let x = inc_nosf x;; 
val x : int = 6 
# x;; 
- : int = 6 

Ponieważ funkcja inc_nosf nie ma skutków ubocznych (to znaczy, że tylko komunikuje się ze światem zewnętrznym za pomocą jego wartości zwracanej, a nie jakichkolwiek innych zmiany).

Ale coś takiego:

let inc_sf r = r := !r+1 

ma skutki uboczne, ponieważ zmienia wartość przechowywaną w odniesieniu reprezentowana przez r. Więc jeśli uruchomić podobny kod na najwyższym poziomie, to masz, zamiast:

# let y = ref 5;; 
val y : int ref = {contents = 5} 
# inc_sf y;; 
- : unit =() 
# y;; 
- : int ref = {contents = 6} 

więc, w tym przypadku, chociaż wciąż nie zapisać zwracanej wartości, to i tak dostał zwiększany. Oznacza to, że musiały nastąpić zmiany w czymś innym niż wartość zwracana. W tym przypadku zmiana polegała na tym, że zmieniono zapisaną wartość ref.

Zgodnie z dobrą zasadą, w Ocaml, jeśli unikasz używania refingów, rekordów, klas, łańcuchów, tablic i tabel hash, unikniesz ryzyka wystąpienia efektów ubocznych. Chociaż można bezpiecznie używać literałów łańcuchowych, o ile unika się modyfikowania ciągu znaków za pomocą funkcji takich jak String.set lub String.fill. Zasadniczo każda funkcja, która może modyfikować typ danych w miejscu, wywoła efekt uboczny.

Powiązane problemy