In [ ]:
#
# 나는 julia 를 사랑하는가
#
In [ ]:
# Scope
# 범위
In [ ]:
# julia 는 lexical scope 이다.
# 이것은 Scheme 과 같다.
In [1]:
module ns_A
a = 1
end
module ns_B
module ns_C
c= 2
end
b = ns_C.c
import ns_A
d = ns_A.a
end
Out[1]:
In [2]:
# Local scope
# z 는 scope 밖에서는 보이지 않는다.
for i=1:10
z = i
end
z
In [3]:
# local 변수를 명시적으로 표현.
# 밖에 있는 x 는 영향받지 않는다.
x = 0
for i=1:10
local x
x = i + 1
end
x
Out[3]:
In [4]:
# scope 에서 global 변수를
# 만들고, 참조하는 방법
for i = 1:10
global z
z = i
end
z
Out[4]:
In [5]:
# local, global 을 표시하는 위치는
# 아무데나 상관없다.
for i=1:7
xxx = i
global xxx
end
xxx
Out[5]:
In [9]:
# 한줄에 쓸수있다.
for i=1:10
global x=i, y=1, z=2
local a=4, b, c=1
end
(x,y,z)
Out[9]:
In [10]:
# Soft local scope
x, y = 0, 1
for i = 1:10
x = i + y +1
end
x
Out[10]:
In [11]:
let
local x = 2
let
global x = 3
end
end
In [12]:
# 이것이 내가 원하는것이다.
# 완전한 scope 을 제공하여,
# 밖에서는 보이지 않는다.
let
yyy = 0
end
yyy
In [13]:
let
local yyy = 0
end
yyy
In [14]:
# global 을 쓰면,
# 밖에서도 볼수있다.
let
global yyy = 0
end
yyy
Out[14]:
In [15]:
# Hard local scope
x, y = 1, 2
function foo()
x = 2 # 할당이 새로운 변수를 만든다.
return x + y
end
Out[15]:
In [16]:
foo()
Out[16]:
In [17]:
# global x 는 변하지 않는다.
x
Out[17]:
In [18]:
# global x 를 바꾸려면
# global 을 써준다.
x = 1
function foo()
global x = 2
end
foo()
x
Out[18]:
In [19]:
# 함수안의 함수는
x,y = 1,2
function foo()
x = 2
function bar()
x = 10 # 부모의 x 를 바꾼다.
return x+y
end수
return bar() + x
end
foo()
Out[19]:
In [21]:
# global x 는 변함이 없다.
x
Out[21]:
In [27]:
# closure
let
state = 0
global counter
counter() = state += 1 # 부모의 state 를 바꾼다.
end
# 밖에서 state 는 보이지 않는다.
# 오직 counter() 만 보인다.
# 이것이 closure 이다.
# 이 코드는 아름답다.
Out[27]:
In [28]:
counter()
Out[28]:
In [29]:
counter()
Out[29]:
In [30]:
state
In [31]:
counter()
Out[31]:
In [32]:
Fs = Array(Any,2)
Out[32]:
In [33]:
i = 1
Out[33]:
In [34]:
while i <= 2
Fs[i] = ()->i
i += 1
end
In [35]:
Fs[1]()
Out[35]:
In [36]:
Fs[2]()
Out[36]:
In [38]:
# let 의 필요성
Fs = Array(Any,2)
i = 1
while i <= 2
let i = i
Fs[i] = ()->i
end
i += 1
end
In [39]:
Fs[1]()
Out[39]:
In [40]:
Fs[2]()
Out[40]:
In [41]:
# let 은 새로운 scope 을 만드는 용도로 쓴다.
# local 변수를 철저히 보호하여,
# 밖에서는 볼수없게하는 역할을 한다.
let
local x = 1
let
local x = 2
end
x
end
Out[41]:
In [42]:
# begin 은 scope 을 만들어내지 못한다.
# ttt 가 밖에서 사용가능하다.
# 이것은 좋지 않다.
begin
ttt = 1
end
ttt
Out[42]:
In [43]:
# let 은 scope 을 만들어낸다.
# 따라서, namespace 가 오염되는것을 막을수있다.
# namespace 가 더러워지는것을 막을수있다.
# namespace 의 위생을 지킬수있다.
let
sss = 1
end
sss
In [64]:
Fs2 = Array(Any, 2)
for i = 1:2
local i
Fs2[i] = ()->i
end
In [65]:
Fs2[1]()
Out[65]:
In [66]:
Fs2[2]()
Out[66]:
In [67]:
# for 는 이미존재하는 변수를 재사용한다.
# 이것은 좋지 않다.
# 이것은 아름답지 않다.
i=0
for i = 1:3
end
i
Out[67]:
In [69]:
# 그러나,
# comprehensions 는 그러지 않는다.
# iteration variable 을 언제나, 항상 새로 생성한다.
# 밖에 있는 x 는 변하지 않는다.
# 이 코드는 아름답다.
x = 0
[ x for x=1:3 ]
x
Out[69]:
In [81]:
# 배열을 생성하는 comprehension 도
# 강한 scope 을 제공한다.
# i 는 local 이다.
# 따라서, 이 코드도 아름답다.
Fs3 = [ ()->i for i=1:2 ]
Out[81]:
In [82]:
Fs3[1]()
Out[82]:
In [83]:
Fs3[2]()
Out[83]:
In [84]:
# Constant
# 상수
# global variable 에 const 를 쓰면
# 컴파일러 최적화가 작동할 수 있다.
# local variable 은
# const 를 안써줘도
# 컴파일러가 알아서 최적화를 수행할 수 있다.
# 따라서, local 에서 쓰는것은 의미없다.
let
const e = 2.71828182845904523536
const pi = 3.14159265358979323846
end
Out[84]:
In [90]:
# const 인 변수를 변경하면
# 경고가 발생한다.
const my_const3 = 1.3216549679865
my_const3 = 0.0
Out[90]: