5차시(9.15)에 해당하는 내용 .... 까마득하다 .... 2주전이네 ....
오늘 수업 들어가기 전에 A4 용지에 간단히 복습했다.
뿌듯하니까 복습한 사진 첨부
block을 쓰기 시작하면 local variable / global variable 의 의미가 중요해진다.
그리고 혼동하기 쉬운데 이를 잘 보여주는 코드가 있다
val t=0
def f(x:Int) = t + g(x+1)
def g(y:Int) = y*y
val x = f(5) //cbv니까 바로 x=36 저장
val s = {
val t = 10
f(5)}
위의 코드에서 x와 s는 모두 f(5)인데 쓰인 블럭이 다르고 블럭에서의 t값이 다르다.
Q. x와 s는 같을까 ?
정답은 같다. 이는 name의 정의와 관련된 개념인데 f가 정의될 당시의 t로 항상 쓰이게 된다.
즉, 한 번 정의한 name의 의미는 바뀌지 않는다!!!
s는 블럭에서 t = 10이라고 로컬변수를 선언해주긴 했지만 f(5)를 연산할 때에는 f(5) = 0 + g(6) 으로 계산된다.
아래 두 문장은 항상 기억해두자
너무너무너무 중요함
!!! The same name cannot be defined twice in the same block.
!!! A function is evaluated under the environment where it is defined, not the environment where it is invoked.
.
.
.
.
다음은 전설의 .. 그 한 시간 내내 한 슬라이드에서만 설명하셨던 지옥의 슬라이드이다....
필기가 너어어어무 많고 이해도 하나도 안됐던 기억이 난다.
필기를 봐도 뭐가 뭔지 알 수 없음 ^__^
일단 미래의 나는 알아볼거라고 믿고 첨부
하하 ^^....
음 다시 깨끗한 슬라이드도 첨부하겠다
어쩌면 그게 더 이해하기 좋을 것 같다
어차피 이해해야되니까 일단 지금 정리....
저 슬라이드가 불친절한 이유는 칸이 부족하다는 이유로 .... 으로 너무 많이 생략됐기 때문이다
val t=0 //1
def f(x:Int)=t+g(x+1) //2
def g(y:Int)=y*y //3
val x = f(5) //4
val r = { //5
def t = 10 //6
def s = f(5) //7
s-t } //8
t+r //9
[ ],1 ~
[t=0],2 ~
[t=0, f=(x)t+g(x)],3 ~
[t=0, f=(x)t+g(x), g=(y)y*y],4 ~
[t=0, f=(x)t+g(x), g=(y)y*y, x=36],5 ~
[t=0, f=(x)t+g(x), g=(y)y*y, x=36] : [ ] ,6 ~
[t=0, f=(x)t+g(x), g=(y)y*y, x=36] : [t=10 ] ,7 ~
[t=0, f=(x)t+g(x), g=(y)y*y, x=36] : [t=10 , s = 36] ,8 ~
[t=0, f=(x)t+g(x), g=(y)y*y, x=36, r = 26] ,9 ~
[t=0, f=(x)t+g(x), g=(y)y*y, x=36, r = 26] ,26
*[ ] : 자식환경
1. val x = f(5)가 선언될 때의 상황
[t=0, f=(x)t+g(x), g=(y)y*y] : [x=5], t + g(x+1) ~ 0+g(6) ~ 36
2. val s = f(5)가 선언될 때의 상황
[t=0, f=(x)t+g(x), g=(y)y*y, x =36] : [x=5], t + g(x+1) ~ 0+g(6) ~ 36
--> 환경에 x=36이라는 변수가 생겼지만 f body 안에선 바깥 x를 사용하지 않으므로 x = 36이 있나없나 결과는 같다.
▶ Example : def with no arguments
val t = 0 //1
def x = t+t //2 essentially treated same as def x() = t+t
val r = { //3
val t = 10 //4
x+t } //5
위에서 변수를 선언하는 것처럼 def x = t+t 라는 코드가 있는데 이는 인자가 없는 함수처럼 움직인다.
def x() = t+t 랑 동일한 취급하면 됨. 따라서 위에서 함수와 같이 정의될 때의 t 값을 따르므로 x는 항상 0이다.
여기서 r의 괄호 블럭 안에서 소환됐다고 def는 cbn 이니까 이제 계산해야지 ~ x = 20 !! 하면 틀린다는 말임.
위의 코드의 결과는 어떻게 나올까?
x 는 항상 0 이므로 그냥 r = 10이다.
자세한 메커니즘을 알아보자
[ ], 1
[t=0],2
[t=0, x=t+t],3
[t=0, x=t+t]:[ ],4
[t=0, x=t+t]:[t=10 ],5
[t=0, x=t+t,r=10], 6
5번 라인 실행환경을 살펴보면
[t=0, x=t+t], t+t ~ 0 이다.
▶ Semi-colons and Parenthesis
block 안에서는 두 개의 정의나, 익스프레션을 한 줄로 이어서 적을 수도 있다. 대신 한 줄로 이어서 적을거라면 사이사이에 세미클론을 써주면 된다. 만약 쓰다가 다음 줄로 넘어갈 경우 괄호를 사용하면 되는데, 만약 의미가 분명한 경우라면 괄호를 생략할 수 있다.
1. 괄호 생략해도 되는 경우
val r = {
val t=10; val s=square(5) ; t+
s }
위의 경우처럼 binary operator에서 끊긴 경우는 컴파일러가 알아서 한 줄로 인식해준다.
2. 생략하면 안되는 경우
val r = {
val t=10; val s=square(5); t
+s }
이런 경우는 안됨 !!!!
val r = {
val t=10; val s=square(5); (t
+s) }
이렇게 binary operator로 시작하게 되면 괄호를 써줘야 한다. 괄호를 추가해주면 에러가 나지 않는다.
'프로그래밍 > Scala' 카테고리의 다른 글
HW 1. Exercise 3 (0) | 2022.10.02 |
---|---|
Recursion / Tail Recursion (0) | 2022.10.01 |
HW1. Exercise 2 (1) | 2022.09.30 |
PART 1 - Functional Programming with Function Applications (3) (0) | 2022.09.29 |
Scala 란 (0) | 2022.09.28 |