본문 바로가기

프로그래밍/Scala

PART 1 - Blocks and Name Scoping (1)

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