Czytam programowanie książek w scali i jest powiedziane:
... w tym przypadku jego efektem ubocznym jest drukowanie do standardowego strumienia wyjściowego.
i nie widzę, gdzie jest efekt uboczny, ponieważ dla tego samego wejścia println wydrukuje to samo wyjście (myślę)
UPDATE
na przykład za każdym razem, gdy wywołujemy:
println(5)
wypisze 5 , nie widzę przypadku, w którym wywołanie println(5)
wypisze wartość inną niż 5 !!
println
jest funkcją deterministyczną, ale aby być czystą, musi być również RT.Odpowiedzi:
Możesz stwierdzić, czy wyrażenie ma efekt uboczny, zastępując wyrażenie jego wynikiem. Jeśli program zmienia znaczenie , występuje efekt uboczny. Na przykład,
jest innym programem niż
Oznacza to, że efektem ubocznym jest każdy możliwy do zaobserwowania efekt, który nie jest zakodowany w wyniku oceny wyrażenia. Oto wynik
()
, ale w tej wartości nie ma nic, co by kodowało fakt, że 5 pojawiło się gdzieś na ekranie.źródło
val a = println("hello"); val b = (a, a)
powinno być takie samo jakval b = (pritnln("hello"), println("hello"))
.println(5)
a()
. A może miałeś na myśli ostatnie zdanie?x = 1
ix = 1; x = 1; x = 1
?Rozważ następującą analogię
Tutaj
myprintln
jest nieczysta, bo obok powrocie wartość()
it także mutuje zmienne non-localout
jako efekt uboczny. Teraz wyobraź sobie,out
że jestprintln
mutacją waniliową .źródło
()
mutuje również stan nielokalny wSystem.out
.Efektem ubocznym jest stan komputera. Każdorazowe wywołanie
println()
zmiany stanu pamięci w celu wyświetlenia danej wartości na terminalu. Lub bardziej ogólnie, stan standardowego strumienia wyjściowego ulega zmianie.źródło
Odpowiedzi na to pytanie zostały już udzielone, ale dodam dwa grosze.
Jeśli zajrzysz do
println
funkcji, zasadniczo jest to to samo cojava.lang.System.out.println()
- więc kiedy wywołujesz standardowąprintln
metodę biblioteczną Scali pod maską, wywołuje ona metodęprintln
naPrintStream
instancji obiektu, która jest zadeklarowana jako poleout
wSystem
klasie (a ściślejoutVar
wConsole
obiekcie), co zmienia jej stan wewnętrzny . Można to uznać za kolejne wyjaśnienie, dlaczegoprintln
funkcja nieczysta jest.Mam nadzieję że to pomoże!
źródło
Ma to związek z koncepcją przejrzystości referencyjnej . Wyrażenie jest referencyjnie przezroczyste, jeśli możesz go zastąpić ocenionym wynikiem bez zmiany programu .
Kiedy wyrażenie nie jest względnie przejrzyste, mówimy, że ma skutki uboczne .
podczas
Bardziej szczegółowe wyjaśnienie można znaleźć tutaj: https://typelevel.org/blog/2017/05/02/io-monad-for-cats.html
źródło
f(println("effect"), println("effect"))
wydrukuje dwa razy w „efekcie” konsoli, podczas gdyval x = println("effect");f(x,x)
wydrukuje raz.