Noteworthy Differences from other Languages
Noteworthy differences from MATLAB
MATLAB 사용자는 Julia의 문법이 친숙하다고 느낄 수 있지만, Julia는 MATLAB 클론이 아닙니다. 주요 문법적 및 기능적 차이가 있습니다. 다음은 MATLAB에 익숙한 Julia 사용자에게 혼란을 줄 수 있는 몇 가지 주목할 만한 차이점입니다:
- 줄리아 배열은 대괄호로 인덱싱됩니다,
A[i,j]
. - 줄리아 배열은 다른 변수에 할당할 때 복사되지 않습니다.
A = B
후에B
의 요소를 변경하면A
도 수정됩니다. 이를 피하려면A = copy(B)
를 사용하세요. - 줄리아 값은 함수에 전달될 때 복사되지 않습니다. 함수가 배열을 수정하면 변경 사항이 호출자에게 표시됩니다.
- 줄리아는 할당문에서 배열을 자동으로 확장하지 않습니다. MATLAB에서는
a(4) = 3.2
가 배열a = [0 0 0 3.2]
를 생성할 수 있고,a(5) = 7
이 이를a = [0 0 0 3.2 7]
로 확장할 수 있지만, 해당하는 줄리아 문장a[5] = 7
은a
의 길이가 5보다 작거나 이 문장이a
식별자의 첫 번째 사용인 경우 오류를 발생시킵니다. 줄리아는push!
와append!
를 가지고 있으며, 이는 MATLAB의a(end+1) = val
보다 훨씬 더 효율적으로Vector
를 확장합니다. - 허구 단위
sqrt(-1)
는 Julia에서im
로 표현되며, MATLAB에서와 같이i
또는j
로 표현되지 않습니다. - 줄리아에서 소수점이 없는 리터럴 숫자(예:
42
)는 부동 소수점 숫자 대신 정수를 생성합니다. 그 결과, 일부 연산은 부동 소수점을 기대할 경우 도메인 오류를 발생시킬 수 있습니다. 예를 들어,julia> a = -1; 2^a
는 결과가 정수가 아니기 때문에 도메인 오류를 발생시킵니다(자세한 내용은 the FAQ entry on domain errors를 참조하십시오). - 줄리아에서는 여러 값을 튜플로 반환하고 할당할 수 있습니다. 예를 들어,
(a, b) = (1, 2)
또는a, b = 1, 2
와 같이 사용할 수 있습니다. MATLAB의nargout
은 반환된 값의 수에 따라 선택적 작업을 수행하는 데 자주 사용되지만, 줄리아에는 존재하지 않습니다. 대신, 사용자는 선택적 인수와 키워드 인수를 사용하여 유사한 기능을 구현할 수 있습니다. - 줄리아는 진정한 1차원 배열을 가지고 있습니다. 열 벡터는
N
크기이며,Nx1
이 아닙니다. 예를 들어,rand(N)
는 1차원 배열을 만듭니다. - 줄리아에서
[x,y,z]
는 항상x
,y
및z
를 포함하는 3요소 배열을 생성합니다.- 첫 번째("수직") 차원에서 연결하려면
vcat(x,y,z)
를 사용하거나 세미콜론([x; y; z]
)으로 구분하십시오. - 두 번째("수평") 차원에서 연결하려면
hcat(x,y,z)
를 사용하거나 공백으로 구분하여([x y z]
) 사용할 수 있습니다. - 블록 행렬을 구성하려면 (첫 두 차원에서 연결),
hvcat
를 사용하거나 공백과 세미콜론을 결합하여 ([a b; c d]
) 사용하세요.
- 첫 번째("수직") 차원에서 연결하려면
- 줄리아에서
a:b
와a:b:c
는AbstractRange
객체를 생성합니다. MATLAB처럼 전체 벡터를 생성하려면collect(a:b)
를 사용하세요. 일반적으로collect
를 호출할 필요는 없습니다.AbstractRange
객체는 대부분의 경우 일반 배열처럼 작동하지만, 값을 지연 계산하기 때문에 더 효율적입니다. 전체 배열 대신 특수화된 객체를 생성하는 이 패턴은 자주 사용되며,range
와 같은 함수나enumerate
,zip
과 같은 반복자에서도 볼 수 있습니다. 이러한 특수 객체는 대부분 일반 배열처럼 사용할 수 있습니다. - 줄리아의 함수는 함수 정의에서 반환할 변수의 이름을 나열하는 대신 마지막 표현식이나
return
키워드에서 값을 반환합니다 (자세한 내용은 The return Keyword를 참조하세요). - 줄리아 스크립트는 임의의 수의 함수를 포함할 수 있으며, 모든 정의는 파일이 로드될 때 외부에서 볼 수 있습니다. 함수 정의는 현재 작업 디렉토리 외부의 파일에서 로드될 수 있습니다.
- 줄리아에서
sum(A)
와 같이 단일 인수로 호출될 때,sum
,prod
, 및maximum
와 같은 축소는 배열의 모든 요소에 대해 수행됩니다. 이는A
가 다차원 배열인 경우에도 마찬가지입니다. - 줄리아에서는 인수가 없는 함수를 호출할 때 괄호를 사용해야 합니다. 예:
rand()
. - 줄리아는 문장을 끝내기 위해 세미콜론을 사용하는 것을 권장하지 않습니다. 문장의 결과는 자동으로 출력되지 않으며(대화형 프롬프트를 제외하고), 코드의 줄은 세미콜론으로 끝날 필요가 없습니다.
println
또는@printf
를 사용하여 특정 출력을 인쇄할 수 있습니다. - In Julia, if
A
andB
are arrays, logical comparison operations likeA == B
do not return an array of booleans. Instead, useA .== B
, and similarly for the other boolean operators like<
,>
. - 줄리아에서 연산자
&
,|
, 및⊻
(xor
)는 MATLAB에서 각각and
,or
,xor
에 해당하는 비트 연산을 수행하며, C와는 달리 파이썬의 비트 연산자와 유사한 우선 순위를 가집니다. 이들은 스칼라 또는 배열에 대해 요소별로 작동할 수 있으며, 논리 배열을 결합하는 데 사용할 수 있지만, 연산 순서의 차이에 유의해야 합니다: 예를 들어,A
의 요소 중 1 또는 2와 같은 요소를 선택하려면(A .== 1) .| (A .== 2)
와 같이 괄호가 필요할 수 있습니다. - 줄리아에서 컬렉션의 요소는 스플랫 연산자
...
를 사용하여 함수에 인수로 전달될 수 있습니다. 예:xs=[1,2]; f(xs...)
. - 줄리아의
svd
는 특이값을 밀집 대각 행렬이 아닌 벡터로 반환합니다. - 줄리아에서
...
는 코드의 줄을 계속하는 데 사용되지 않습니다. 대신, 불완전한 표현식은 자동으로 다음 줄로 이어집니다. - Julia와 MATLAB 모두에서 변수
ans
는 대화형 세션에서 마지막으로 입력된 표현식의 값으로 설정됩니다. MATLAB과 달리 Julia에서는 비대화형 모드에서 Julia 코드가 실행될 때ans
가 설정되지 않습니다. - 줄리아의
struct
는 MATLAB의class
와 달리 런타임에 필드를 동적으로 추가하는 것을 지원하지 않습니다. 대신,Dict
를 사용하세요. 줄리아의 Dict는 순서가 없습니다. - 줄리아에서는 각 모듈이 고유한 전역 범위/네임스페이스를 가지지만, MATLAB에서는 단 하나의 전역 범위만 존재합니다.
- MATLAB에서는 원하지 않는 값을 제거하는 관용적인 방법으로 논리적 인덱싱을 사용하는데, 예를 들어
x(x>3)
와 같은 표현이나x(x>3) = []
와 같은 문장을 사용하여x
를 제자리에서 수정할 수 있습니다. 반면, Julia는filter
및filter!
와 같은 고차 함수를 제공하여 사용자가filter(z->z>3, x)
및filter!(z->z>3, x)
를 사용할 수 있게 하여 해당 변환에 대한 대안으로x[x.>3]
및x = x[x.>3]
를 제공합니다.4d61726b646f776e2e436f64652822222c202266696c746572212229_40726566
를 사용하면 임시 배열의 사용이 줄어듭니다. - 셀 배열의 모든 요소를 추출(또는 "역참조")하는 것의 유사체는 MATLAB에서
vertcat(A{:})
와 같이 작성되며, Julia에서는vcat(A...)
와 같이 스플랫 연산자를 사용하여 작성됩니다. - 줄리아에서
adjoint
함수는 켤레 전치를 수행합니다. MATLAB에서는adjoint
가 "여인수 행렬" 또는 고전적 여인수를 제공하며, 이는 여인수 행렬의 전치입니다. - 줄리아에서는 a^b^c가 a^(b^c)로 평가되는 반면, MATLAB에서는 (a^b)^c로 평가됩니다.
Noteworthy differences from R
줄리아의 목표 중 하나는 데이터 분석 및 통계 프로그래밍을 위한 효과적인 언어를 제공하는 것입니다. R에서 줄리아로 오는 사용자들에게는 다음과 같은 주목할 만한 차이점이 있습니다:
줄리아의 작은따옴표는 문자열이 아닌 문자들을 감쌉니다.
줄리아는 문자열에 인덱싱하여 부분 문자열을 생성할 수 있습니다. R에서는 부분 문자열을 생성하기 전에 문자열을 문자 벡터로 변환해야 합니다.
줄리아에서는 파이썬과 비슷하지만 R과는 달리, 문자열을 세 개의 따옴표
""" ... """
로 생성할 수 있습니다. 이 구문은 줄 바꿈이 포함된 문자열을 구성하는 데 편리합니다.줄리아에서 가변 인자는 스플랫 연산자
...
를 사용하여 지정되며, 이는 항상 특정 변수의 이름 뒤에 옵니다. 이는 R과 달리...
가 독립적으로 발생할 수 있습니다.줄리아에서 모듈러스는
mod(a, b)
이며,a %% b
가 아닙니다. 줄리아에서%
는 나머지 연산자입니다.줄리아는 대괄호를 사용하여 벡터를 생성합니다. 줄리아의
[1, 2, 3]
는 R의c(1, 2, 3)
와 동일합니다.줄리아에서는 모든 데이터 구조가 논리적 인덱싱을 지원하지 않습니다. 또한, 줄리아에서 논리적 인덱싱은 인덱싱되는 객체의 길이와 동일한 길이의 벡터에 대해서만 지원됩니다. 예를 들어:
- R에서
c(1, 2, 3, 4)[c(TRUE, FALSE)]
는c(1, 3)
과 같습니다. - R에서
c(1, 2, 3, 4)[c(TRUE, FALSE, TRUE, FALSE)]
는c(1, 3)
과 같습니다. - In Julia,
[1, 2, 3, 4][[true, false]]
는BoundsError
오류를 발생시킵니다. - 줄리아에서
[1, 2, 3, 4][[true, false, true, false]]
는[1, 3]
을 생성합니다.
- R에서
많은 언어와 마찬가지로, Julia는 R과 달리 서로 다른 길이의 벡터에 대한 연산을 항상 허용하지 않습니다. R에서는 벡터가 공통 인덱스 범위만 공유하면 됩니다. 예를 들어,
c(1, 2, 3, 4) + c(1, 2)
는 유효한 R 코드이지만, 이에 해당하는[1, 2, 3, 4] + [1, 2]
는 Julia에서 오류를 발생시킵니다.줄리아는 코드의 의미를 변경하지 않을 때 선택적 후행 쉼표를 허용합니다. 이는 배열에 인덱싱할 때 R 사용자에게 혼란을 줄 수 있습니다. 예를 들어, R에서
x[1,]
는 행렬의 첫 번째 행을 반환하지만, 줄리아에서는 쉼표가 무시되므로x[1,] == x[1]
이 되어 첫 번째 요소를 반환합니다. 행을 추출하려면:
를 사용해야 하며, 예를 들어x[1,:]
와 같이 사용합니다.줄리아의
map
는 함수가 먼저 오고 그 다음에 인수가 오는 방식으로, R의lapply(<structure>, function, ...)
와는 다릅니다. 유사하게, 줄리아의 R에서apply(X, MARGIN, FUN, ...)
에 해당하는 것은mapslices
로, 여기서 함수가 첫 번째 인수입니다.R에서의 다변량 적용 예시인
mapply(choose, 11:13, 1:3)
는 Julia에서broadcast(binomial, 11:13, 1:3)
로 작성할 수 있습니다. 동등하게 Julia는 함수의 벡터화를 위한 더 짧은 점 구문을 제공합니다:binomial.(11:13, 1:3)
.줄리아는
end
를 사용하여 조건 블록(예:if
), 루프 블록(예:while
/for
), 그리고 함수의 끝을 나타냅니다. 한 줄짜리if ( cond ) statement
대신, 줄리아는if cond; statement; end
,cond && statement
, 그리고!cond || statement
형태의 문장을 허용합니다. 후자의 두 구문에서의 할당 문장은 명시적으로 괄호로 감싸야 합니다. 예를 들어,cond && (x = value)
와 같이 작성해야 합니다.줄리아에서
<-
,<<-
및->
는 할당 연산자가 아닙니다.줄리아의
->
는 익명 함수를 생성합니다.줄리아의
*
연산자는 R과 달리 행렬 곱셈을 수행할 수 있습니다. 만약A
와B
가 행렬이라면,A * B
는 줄리아에서 행렬 곱셈을 나타내며, 이는 R의A %*% B
와 동일합니다. R에서는 이와 같은 표기법이 요소별(Hadamard) 곱셈을 수행합니다. 요소별 곱셈 연산을 얻으려면 줄리아에서A .* B
라고 작성해야 합니다.줄리아는
transpose
함수를 사용하여 행렬 전치를 수행하고,'
연산자 또는adjoint
함수를 사용하여 켤레 전치를 수행합니다. 줄리아의transpose(A)
는 따라서 R의t(A)
와 동일합니다. 또한 줄리아에서는 비재귀 전치를permutedims
함수를 통해 제공합니다.줄리아에서는
if
문이나for
/while
루프를 작성할 때 괄호가 필요하지 않습니다:for i in [1, 2, 3]
대신for (i in c(1, 2, 3))
를 사용하고,if i == 1
대신if (i == 1)
를 사용하세요.줄리아는 숫자
0
과1
을 불리언으로 취급하지 않습니다. 줄리아에서는if (1)
을 쓸 수 없으며,if
문은 오직 불리언만을 허용합니다. 대신if true
,if Bool(1)
, 또는if 1==1
을 쓸 수 있습니다.줄리아는
nrow
와ncol
을 제공하지 않습니다. 대신nrow(M)
에는size(M, 1)
을,ncol(M)
에는size(M, 2)
를 사용하세요.줄리아는 스칼라, 벡터 및 행렬을 구분하는 데 주의합니다. R에서는
1
과c(1)
이 동일하지만, 줄리아에서는 서로 바꿔 사용할 수 없습니다.줄리아에서는 할당 연산의 왼쪽에 함수 호출 결과를 할당할 수 없습니다:
diag(M) = fill(1, n)
와 같이 쓸 수 없습니다.줄리아는 주요 네임스페이스에 함수를 채우는 것을 권장하지 않습니다. 줄리아의 대부분의 통계 기능은 packages에서 JuliaStats organization 아래에서 찾을 수 있습니다. 예를 들어:
- 확률 분포와 관련된 함수는 Distributions package에 의해 제공됩니다.
- DataFrames package는 데이터 프레임을 제공합니다.
- 일반화 선형 모델은 GLM package에 의해 제공됩니다.
줄리아는 튜플과 실제 해시 테이블을 제공하지만 R 스타일의 리스트는 제공하지 않습니다. 여러 항목을 반환할 때는 일반적으로 튜플이나 명명된 튜플을 사용해야 합니다:
list(a = 1, b = 2)
대신(1, 2)
또는(a=1, b=2)
를 사용하세요.줄리아는 사용자들이 S3 또는 S4 객체보다 사용하기 쉬운 자신만의 타입을 작성하도록 권장합니다. 줄리아의 다중 분기 시스템 덕분에
table(x::TypeA)
와table(x::TypeB)
는 R의table.TypeA(x)
와table.TypeB(x)
처럼 작동합니다.줄리아에서는 값을 할당하거나 함수에 전달할 때 복사되지 않습니다. 함수가 배열을 수정하면 변경 사항이 호출자에게 표시됩니다. 이는 R과 매우 다르며, 새로운 함수가 대규모 데이터 구조에서 훨씬 더 효율적으로 작동할 수 있게 합니다.
줄리아에서는 벡터와 행렬이
hcat
,vcat
및hvcat
를 사용하여 연결되며, R에서처럼c
,rbind
및cbind
를 사용하지 않습니다.줄리아에서
a:b
와 같은 범위는 R에서 벡터의 약어가 아니라 반복에 사용되는 특수한AbstractRange
객체입니다. 범위를 벡터로 변환하려면collect(a:b)
를 사용하세요.:
연산자는 R과 Julia에서 다른 우선 순위를 가집니다. 특히, Julia에서는 산술 연산자가:
연산자보다 높은 우선 순위를 가지며, R에서는 그 반대입니다. 예를 들어, Julia에서1:n-1
은 R에서1:(n-1)
과 동일합니다.줄리아의
max
와min
는 R에서 각각pmax
와pmin
의 동등한 기능을 하지만, 두 인수는 동일한 차원을 가져야 합니다. 반면에maximum
와minimum
는 R에서max
와min
을 대체하지만, 중요한 차이점이 있습니다.줄리아의
sum
,prod
,maximum
, 및minimum
는 R의 대응물과 다릅니다. 이들은 모두 선택적 키워드 인수dims
를 받아들이며, 이는 연산이 수행되는 차원을 나타냅니다. 예를 들어, 줄리아에서A = [1 2; 3 4]
이고 R에서B <- rbind(c(1,2),c(3,4))
가 동일한 행렬이라고 가정해 보겠습니다. 그러면sum(A)
는sum(B)
와 동일한 결과를 제공하지만,sum(A, dims=1)
은 각 열의 합을 포함하는 행 벡터이고,sum(A, dims=2)
는 각 행의 합을 포함하는 열 벡터입니다. 이는 R의 동작과 대조적이며, R에서는 별도의colSums(B)
및rowSums(B)
함수가 이러한 기능을 제공합니다.dims
키워드 인수가 벡터인 경우, 이는 합계가 수행되는 모든 차원을 지정하며, 합산된 배열의 차원을 유지합니다. 예를 들어,sum(A, dims=(1,2)) == hcat(10)
입니다. 두 번째 인수에 대한 오류 검사는 없다는 점에 유의해야 합니다.줄리아는 인수를 변형할 수 있는 여러 함수를 가지고 있습니다. 예를 들어,
sort
와sort!
가 있습니다.R에서는 성능을 위해 벡터화가 필요합니다. Julia에서는 거의 반대의 경우가 사실입니다: 가장 높은 성능을 내는 코드는 종종 비벡터화된 루프를 사용하여 달성됩니다.
줄리아는 즉시 평가되며 R 스타일의 지연 평가를 지원하지 않습니다. 대부분의 사용자에게 이는 인용되지 않은 표현식이나 열 이름이 거의 없다는 것을 의미합니다.
줄리아는
NULL
타입을 지원하지 않습니다. 가장 가까운 동등물은nothing
이지만, 리스트처럼 동작하는 것이 아니라 스칼라 값처럼 동작합니다.is.null(x)
대신x === nothing
을 사용하세요.줄리아에서 결측값은
missing
객체로 표현되며,NA
로 표현되지 않습니다.ismissing(x)
(또는 벡터에 대한 요소별 연산을 위해ismissing.(x)
)를 사용하세요.skipmissing
함수는 일반적으로na.rm=TRUE
대신 사용됩니다 (특정 경우에는 함수가skipmissing
인수를 받을 수 있습니다).줄리아는 R의
assign
또는get
에 해당하는 기능이 부족하다.줄리아에서는
return
이 괄호를 필요로 하지 않습니다.R에서 원하지 않는 값을 제거하는 관용적인 방법은 논리적 인덱싱을 사용하는 것입니다. 예를 들어
x[x>3]
와 같은 표현식이나x = x[x>3]
와 같은 문장을 사용하여x
를 제자리에서 수정할 수 있습니다. 반면, Julia는 사용자가filter(z->z>3, x)
및filter!(z->z>3, x)
를 작성할 수 있도록 하는 고차 함수filter
및filter!
를 제공합니다. 이는 각각의 변환에 해당하는x[x.>3]
및x = x[x.>3]
의 대안입니다.4d61726b646f776e2e436f64652822222c202266696c746572212229_40726566
를 사용하면 임시 배열의 사용이 줄어듭니다.
Noteworthy differences from Python
- 줄리아의
for
,if
,while
등 블록은end
키워드로 종료됩니다. 들여쓰기 수준은 파이썬처럼 중요하지 않습니다. 파이썬과 달리 줄리아에는pass
키워드가 없습니다. - 문자열은 줄리아에서 큰따옴표(
"text"
)로 표시되며(여러 줄 문자열의 경우 세 개의 큰따옴표 사용), 파이썬에서는 작은따옴표('text'
) 또는 큰따옴표("text"
)로 표시될 수 있습니다. 줄리아에서는 문자에 대해 작은따옴표('c'
)를 사용합니다. - 문자열 연결은 Julia에서
*
를 사용하여 수행되며, Python의+
와는 다릅니다. 유사하게, 문자열 반복은^
를 사용하여 수행되며,*
는 아닙니다. Python과 같은 문자열 리터럴의 암시적 문자열 연결(예:'ab' 'cd' == 'abcd'
)은 Julia에서 수행되지 않습니다. - Python 리스트는 유연하지만 느리며, Julia의
Vector{Any}
타입 또는 더 일반적으로Vector{T}
에 해당합니다. 여기서T
는 비구조적 요소 타입입니다. NumPy 배열과 같이 요소를 제자리에서 저장하는 "빠른" 배열(즉,dtype
가np.float64
,[('f1', np.uint64), ('f2', np.int32)]
등)은Array{T}
로 표현될 수 있으며, 여기서T
는 구체적이고 불변의 요소 타입입니다. 여기에는Float64
,Int32
,Int64
와 같은 내장 타입뿐만 아니라Tuple{UInt64,Float64}
와 같은 더 복잡한 타입 및 많은 사용자 정의 타입도 포함됩니다. - 줄리아에서는 배열, 문자열 등의 인덱싱이 0이 아닌 1부터 시작합니다.
- 줄리아의 슬라이스 인덱싱은 마지막 요소를 포함합니다. 파이썬에서는
a[2:3]
가 줄리아에서는a[1:3]
입니다. - 파이썬과 달리 줄리아는 AbstractArrays with arbitrary indexes를 허용합니다. 파이썬의 음수 인덱싱에 대한 특별한 해석인
a[-1]
및a[-2]
는 줄리아에서a[end]
및a[end-1]
로 작성해야 합니다. - 줄리아는 마지막 요소까지 인덱싱하기 위해
end
를 필요로 합니다. 파이썬의x[1:]
는 줄리아에서x[2:end]
와 같습니다. - 줄리아에서
:
는 어떤 객체 앞에 사용될 때Symbol
또는 표현식을 인용합니다. 따라서x[:5]
는x[5]
와 동일합니다. 배열의 첫 번째n
요소를 가져오고 싶다면 범위 인덱싱을 사용하세요. - 줄리아의 범위 인덱싱은
x[start:step:stop]
형식을 가지며, 파이썬의 형식은x[start:(stop+1):step]
입니다. 따라서, 파이썬의x[0:10:2]
는 줄리아의x[1:2:10]
와 같습니다. 마찬가지로, 파이썬의x[::-1]
는 역 배열을 참조하며, 줄리아에서는x[end:-1:1]
와 같습니다. - 줄리아에서 범위는
start:step:stop
으로 독립적으로 구성할 수 있으며, 이는 배열 인덱싱에서 사용하는 것과 동일한 구문입니다.range
함수도 지원됩니다. - 줄리아에서
X[[1,2], [1,3]]
로 행렬을 인덱싱하면 첫 번째 및 두 번째 행과 첫 번째 및 세 번째 열의 교차점이 포함된 부분 행렬을 참조합니다. 파이썬에서X[[1,2], [1,3]]
는 행렬에서 셀[1,1]
과[2,3]
의 값을 포함하는 벡터를 참조합니다. 줄리아의X[[1,2], [1,3]]
는 파이썬의X[np.ix_([0,1],[0,2])]
와 동일합니다. 파이썬의X[[0,1], [0,2]]
는 줄리아의X[[CartesianIndex(1,1), CartesianIndex(2,3)]]
와 동일합니다. - 줄리아는 줄 계속 구문이 없습니다: 만약 한 줄의 끝에서까지 입력이 완전한 표현식이라면, 그것은 완료된 것으로 간주됩니다; 그렇지 않으면 입력이 계속됩니다. 표현식이 계속되도록 강제하는 한 가지 방법은 괄호로 감싸는 것입니다.
- 줄리아 배열은 열 우선(포트란 순서)인 반면, NumPy 배열은 기본적으로 행 우선(C 순서)입니다. 배열을 반복할 때 최적의 성능을 얻으려면, 줄리아에서 루프의 순서를 NumPy에 비해 반대로 해야 합니다 (자세한 내용은 relevant section of Performance Tips를 참조하세요).
- 줄리아의 업데이트 연산자(예:
+=
,-=
, ...)는 제자리에서 작동하지 않지만, NumPy의 연산자는 그렇습니다. 이는A = [1, 1]; B = A; B += [3, 3]
가A
의 값을 변경하지 않고, 오히려B
라는 이름을 오른쪽의 결과인B = B + 3
에 재바인딩하여 새로운 배열을 생성한다는 것을 의미합니다. 제자리 연산을 원할 경우B .+= 3
을 사용하거나(자세한 내용은 dot operators 참조), 명시적 루프 또는InplaceOps.jl
을 사용하세요. - 줄리아는 메서드가 호출될 때마다 함수 인수의 기본값을 평가하는 반면, 파이썬에서는 함수가 정의될 때 한 번만 기본값이 평가됩니다. 예를 들어, 함수
f(x=rand()) = x
는 인수 없이 호출될 때마다 새로운 랜덤 숫자를 반환합니다. 반면에, 함수g(x=[1,2]) = push!(x,3)
는g()
로 호출될 때마다[1,2,3]
을 반환합니다. - 줄리아에서는 키워드 인수를 키워드를 사용하여 전달해야 하며, 파이썬에서는 일반적으로 위치적으로 전달하는 것이 가능합니다. 키워드 인수를 위치적으로 전달하려고 하면 메서드 시그니처가 변경되어
MethodError
가 발생하거나 잘못된 메서드가 호출됩니다. - 줄리아에서
%
는 나머지 연산자이고, 파이썬에서는 모듈로 연산자입니다. - 줄리아에서 일반적으로 사용되는
Int
타입은 기계 정수 타입(Int32
또는Int64
)에 해당하며, 파이썬의int
는 임의 길이 정수와는 다릅니다. 이는 줄리아에서Int
타입이 오버플로우가 발생할 수 있음을 의미하며, 예를 들어2^64 == 0
이 됩니다. 더 큰 값을 필요로 하는 경우Int128
,BigInt
또는Float64
와 같은 부동 소수점 타입을 사용해야 합니다. - 허수 단위
sqrt(-1)
는 파이썬의j
가 아닌 줄리아에서im
으로 표현됩니다. - 줄리아에서 거듭제곱 연산자는
^
이며, 파이썬의**
와는 다릅니다. - 줄리아는
Nothing
타입의nothing
을 사용하여 null 값을 나타내고, 파이썬은NoneType
타입의None
을 사용합니다. - 줄리아에서 행렬 유형에 대한 표준 연산자는 행렬 연산인 반면, 파이썬에서는 표준 연산자가 요소별 연산입니다.
A
와B
가 모두 행렬일 때, 줄리아에서A * B
는 행렬 곱셈을 수행하며, 파이썬에서와 같이 요소별 곱셈을 수행하지 않습니다. 줄리아에서A * B
는 파이썬에서A @ B
와 동일하며, 파이썬에서A * B
는 줄리아에서A .* B
와 동일합니다. - 줄리아에서의 수반 연산자
'
는 벡터의 수반을 반환하며(행 벡터의 지연 표현), 파이썬에서 벡터에 대한 전치 연산자.T
는 원래 벡터를 반환합니다(비작용). - 줄리아에서는 함수가 여러 개의 구체적인 구현(이를 메서드라고 함)을 포함할 수 있으며, 이는 호출의 모든 인수 유형에 따라 다중 분산을 통해 선택됩니다. 반면, 파이썬의 함수는 단일 구현만 가지고 있으며 다형성이 없습니다(파이썬의 메서드 호출은 다른 구문을 사용하고 메서드의 수신자에 따라 분산을 허용합니다).
- 줄리아에는 클래스가 없습니다. 대신 데이터는 포함하지만 메서드는 없는 구조체(가변 또는 불변)가 있습니다.
- 파이썬에서 클래스 인스턴스의 메서드를 호출하는 것(
x = MyClass(*args); x.f(y)
)은 줄리아에서 함수 호출에 해당합니다. 예를 들어,x = MyType(args...); f(x, y)
와 같습니다. 일반적으로 다중 분산은 파이썬 클래스 시스템보다 더 유연하고 강력합니다. - 줄리아 구조체는 정확히 하나의 추상 슈퍼타입을 가질 수 있는 반면, 파이썬 클래스는 하나 이상의 (추상 또는 구체적인) 슈퍼클래스로부터 상속받을 수 있습니다.
- 논리적인 줄리아 프로그램 구조(패키지 및 모듈)는 파일 구조와 독립적이지만, 파이썬 코드 구조는 디렉토리(패키지)와 파일(모듈)에 의해 정의됩니다.
- 줄리아에서는 큰 모듈의 텍스트를 여러 파일로 나누는 것이 관례적이며, 파일당 새로운 모듈을 도입하지 않습니다. 코드는
include
를 통해 메인 파일 내의 단일 모듈 안에서 재조합됩니다. 파이썬의 동등한 기능(exec
)은 이 용도로 일반적이지 않으며(이전 정의를 조용히 덮어씌우기 때문), 줄리아 프로그램은using
또는import
를 통해module
수준에서 단위로 정의되며, 이는 처음 필요할 때 한 번만 실행됩니다–파이썬의include
와 유사합니다. 이러한 모듈 내에서, 해당 모듈을 구성하는 개별 파일은 의도된 순서로 한 번 나열하여include
로 로드됩니다. - 줄리아의 삼항 연산자
x > 0 ? 1 : -1
은 파이썬의 조건부 표현식1 if x > 0 else -1
에 해당합니다. - 줄리아에서
@
기호는 매크로를 나타내고, 파이썬에서는 데코레이터를 나타냅니다. - 줄리아에서 예외 처리는
try
—catch
—finally
를 사용하여 수행되며,try
—except
—finally
를 사용하지 않습니다. 파이썬과 달리, 줄리아에서는 일반적인 작업 흐름의 일부로 예외 처리를 사용하는 것이 권장되지 않습니다(파이썬과 비교할 때, 줄리아는 일반적인 제어 흐름에서 더 빠르지만 예외 포착에서는 더 느립니다). - 줄리아에서 루프는 빠르므로 성능상의 이유로 "벡터화된" 코드를 작성할 필요가 없습니다.
- 줄리아에서 비상수 전역 변수에 주의하세요, 특히 빠른 루프에서. 줄리아에서는 (파이썬과는 달리) 거의 메탈에 가까운 코드를 작성할 수 있기 때문에 전역 변수의 영향이 극단적일 수 있습니다 (참조: Performance Tips).
- 줄리아에서는 반올림과 잘라내기가 명시적입니다. 파이썬의
int(3.7)
는floor(Int, 3.7)
또는Int(floor(3.7))
로 표현되어야 하며,round(Int, 3.7)
와 구별됩니다.floor(x)
와round(x)
는 각각x
와 동일한 유형의 정수 값을 반환하며 항상Int
를 반환하지는 않습니다. - 줄리아에서는 파싱이 명시적입니다. 파이썬의
float("3.7")
는 줄리아에서parse(Float64, "3.7")
로 표현됩니다. - 파이썬에서는 대부분의 값이 논리적 맥락에서 사용될 수 있습니다 (예:
if "a":
는 다음 블록이 실행됨을 의미하고,if "":
는 실행되지 않음을 의미합니다). 줄리아에서는Bool
로의 명시적 변환이 필요합니다 (예:if "a"
는 예외를 발생시킵니다). 줄리아에서 비어 있지 않은 문자열을 테스트하려면 명시적으로if !isempty("")
라고 작성해야 합니다. 아마 놀랍게도, 파이썬에서if "False"
와bool("False")
는 모두True
로 평가됩니다 (왜냐하면"False"
는 비어 있지 않은 문자열이기 때문입니다); 줄리아에서는parse(Bool, "false")
가false
를 반환합니다. - 줄리아에서는 대부분의 코드 블록, 즉 루프와
try
—catch
—finally
를 포함하여 새로운 로컬 스코프가 도입됩니다. 리스트, 제너레이터 등과 같은 컴프리헨션은 파이썬과 줄리아 모두에서 새로운 로컬 스코프를 도입하는 반면,if
블록은 두 언어 모두에서 새로운 로컬 스코프를 도입하지 않습니다.
Noteworthy differences from C/C++
- 줄리아 배열은 대괄호로 인덱싱되며, 여러 차원을 가질 수 있습니다
A[i,j]
. 이 구문은 C/C++에서 포인터나 주소에 대한 참조를 위한 문법적 설탕이 아닙니다. the manual entry about array construction를 참조하세요. - 줄리아에서는 배열, 문자열 등의 인덱스가 0이 아닌 1부터 시작합니다.
- 줄리아 배열은 다른 변수에 할당할 때 복사되지 않습니다.
A = B
후에B
의 요소를 변경하면A
도 수정됩니다.+=
와 같은 업데이트 연산자는 제자리에서 작동하지 않으며,A = A + B
와 동일하여 왼쪽 변수를 오른쪽 표현식의 결과에 다시 바인딩합니다. - 줄리아 배열은 열 우선(포트란 순서)인 반면, C/C++ 배열은 기본적으로 행 우선 순서입니다. 배열을 반복할 때 최적의 성능을 얻으려면, 줄리아에서 루프의 순서를 C/C++에 비해 반대로 해야 합니다 (참조: relevant section of Performance Tips).
- 줄리아 값은 할당되거나 함수에 전달될 때 복사되지 않습니다. 함수가 배열을 수정하면 변경 사항이 호출자에게 표시됩니다.
- 줄리아에서는 공백이 중요하므로 C/C++와는 달리 줄리아 프로그램에서 공백을 추가하거나 제거할 때 주의해야 합니다.
- 줄리아에서 소수점이 없는 리터럴 숫자(예:
42
)는 부호가 있는 정수인Int
유형을 생성하지만, 머신 워드 크기에 맞지 않는 너무 큰 리터럴은 자동으로 더 큰 크기 유형으로 승격됩니다. 예를 들어,Int
가Int32
인 경우Int64
,Int128
또는 임의로 큰BigInt
유형으로 승격됩니다. 부호가 없는 정수와 부호가 있는 정수를 나타내기 위한 숫자 리터럴 접미사(예:L
,LL
,U
,UL
,ULL
)는 없습니다. 십진수 리터럴은 항상 부호가 있으며, 16진수 리터럴(예: C/C++에서0x
로 시작)은 부호가 없지만, 128비트를 초과하는 경우에는BigInt
유형이 됩니다. 16진수 리터럴은 C/C++/Java와 다르게, 그리고 줄리아의 십진수 리터럴과 다르게, 리터럴의 길이(선행 0 포함)에 따라 유형이 결정됩니다. 예를 들어,0x0
과0x00
은UInt8
유형을 가지며,0x000
과0x0000
은UInt16
유형을 가집니다. 그 후 5에서 8개의 16진수 자릿수를 가진 리터럴은UInt32
유형을 가지며, 9에서 16개의 16진수 자릿수는UInt64
유형, 17에서 32개의 16진수 자릿수는UInt128
유형, 32개 이상의 16진수 자릿수는BigInt
유형을 가집니다. 이는 16진수 마스크를 정의할 때 고려해야 합니다. 예를 들어~0xf == 0xf0
은~0x000f == 0xfff0
와 매우 다릅니다. 64비트Float64
와 32비트Float32
비트 리터럴은 각각1.0
과1.0f0
으로 표현됩니다. 부동 소수점 리터럴은 정확하게 표현할 수 없는 경우 반올림되며(BigFloat
유형으로 승격되지 않음), 부동 소수점 리터럴은 C/C++의 동작과 더 가깝습니다. 8진수(접두사0o
) 및 이진수(접두사0b
) 리터럴도 부호가 없는 것으로 처리되며(128비트를 초과하는 경우BigInt
로 처리됨) 됩니다. - 줄리아에서 나눗셈 연산자
/
는 두 피연산자가 정수형일 때 부동 소수점 숫자를 반환합니다. 정수 나눗셈을 수행하려면div
또는÷
를 사용하세요. Array
를 부동 소수점 타입으로 인덱싱하는 것은 일반적으로 Julia에서 오류입니다. C 표현식a[i / 2]
의 Julia 동등물은a[i ÷ 2 + 1]
이며, 여기서i
는 정수 타입입니다.- 문자열 리터럴은
"
또는"""
로 구분할 수 있으며,"""
로 구분된 리터럴은"
문자를 따옴표 없이 포함할 수 있습니다. 문자열 리터럴은 다른 변수나 표현식의 값을 포함할 수 있으며, 이는$variablename
또는$(expression)
으로 표시되며, 함수의 맥락에서 변수 이름이나 표현식을 평가합니다. //
는 단일 행 주석(줄리아에서#
로 표시됨)이 아니라Rational
숫자를 나타냅니다.#=
는 멀티라인 주석의 시작을 나타내고,=#
는 그것을 끝냅니다.- 줄리아의 함수는 마지막 표현식 또는
return
키워드에서 값을 반환합니다. 여러 값을 함수에서 반환하고 튜플로 할당할 수 있습니다. 예를 들어,(a, b) = myfunction()
또는a, b = myfunction()
와 같이 사용할 수 있으며, C/C++에서처럼 값을 가리키는 포인터를 전달할 필요가 없습니다 (즉,a = myfunction(&b)
와 같은 방식). - 줄리아는 문장을 끝내기 위해 세미콜론을 사용할 필요가 없습니다. 표현식의 결과는 자동으로 출력되지 않으며(대화형 프롬프트, 즉 REPL을 제외하고), 코드의 줄은 세미콜론으로 끝날 필요가 없습니다.
println
또는@printf
를 사용하여 특정 출력을 인쇄할 수 있습니다. REPL에서는;
를 사용하여 출력을 억제할 수 있습니다.;
는 또한[ ]
내에서 다른 의미를 가지므로 주의해야 합니다.;
는 한 줄에서 표현식을 구분하는 데 사용할 수 있지만, 많은 경우에 엄격히 필요하지 않으며 가독성을 돕는 역할을 합니다. - 줄리아에서 연산자
⊻
(xor
)는 비트wise XOR 연산을 수행합니다. 즉, C/C++에서^
와 같습니다. 또한, 비트wise 연산자의 우선순위는 C/C++와 동일하지 않으므로 괄호가 필요할 수 있습니다. - 줄리아의
^
는 C/C++에서의 비트wise XOR가 아닌 거듭제곱(pow)입니다 (줄리아에서는⊻
또는xor
를 사용하세요) - 줄리아에는 두 개의 오른쪽 시프트 연산자
>>
와>>>
가 있습니다.>>
는 산술 시프트를 수행하고,>>>
는 항상 논리 시프트를 수행합니다. C/C++와는 달리, C/C++에서는>>
의 의미가 시프트되는 값의 유형에 따라 달라집니다. - 줄리아의
->
는 익명 함수를 생성하며, 포인터를 통해 멤버에 접근하지 않습니다. - 줄리아는
if
문이나for
/while
루프를 작성할 때 괄호를 필요로 하지 않습니다:for i in [1, 2, 3]
대신for (int i=1; i <= 3; i++)
를 사용하고,if i == 1
대신if (i == 1)
를 사용하세요. - 줄리아는 숫자
0
과1
을 불리언으로 취급하지 않습니다. 줄리아에서는if (1)
을 쓸 수 없으며,if
문은 오직 불리언만을 허용합니다. 대신if true
,if Bool(1)
, 또는if 1==1
을 쓸 수 있습니다. - 줄리아는
end
를 사용하여if
와 같은 조건 블록,while
/for
와 같은 루프 블록, 그리고 함수의 끝을 나타냅니다. 한 줄짜리if ( cond ) statement
대신, 줄리아는if cond; statement; end
,cond && statement
및!cond || statement
형태의 문장을 허용합니다. 후자의 두 구문에서의 할당 문장은 연산자 우선순위 때문에 명시적으로 괄호로 감싸야 합니다. 예를 들어,cond && (x = value)
와 같이 작성해야 합니다. - 줄리아는 줄 계속 구문이 없습니다: 만약 한 줄의 끝에서까지 입력이 완전한 표현식이라면, 그것은 완료된 것으로 간주됩니다; 그렇지 않으면 입력이 계속됩니다. 표현식이 계속되도록 강제하는 한 가지 방법은 괄호로 감싸는 것입니다.
- 줄리아 매크로는 프로그램의 텍스트가 아니라 구문 분석된 표현식에서 작동하므로, 줄리아 코드의 정교한 변환을 수행할 수 있습니다. 매크로 이름은
@
문자로 시작하며, 함수와 유사한 구문@mymacro(arg1, arg2, arg3)
과 문장과 유사한 구문@mymacro arg1 arg2 arg3
을 모두 가집니다. 두 형태는 서로 교환 가능하며, 함수와 유사한 형태는 매크로가 다른 표현식 내에 나타날 때 특히 유용하고 종종 가장 명확합니다. 문장과 유사한 형태는 분산for
구조와 같이 블록을 주석 처리하는 데 자주 사용됩니다:@distributed for i in 1:n; #= body =#; end
. 매크로 구조의 끝이 불명확할 경우, 함수와 유사한 형태를 사용하는 것이 좋습니다. - 줄리아에는 매크로
@enum(name, value1, value2, ...)
를 사용하여 표현된 열거형 타입이 있습니다. 예를 들어:@enum(Fruit, banana=1, apple, pear)
- 관례적으로, 인수를 수정하는 함수는 이름 끝에
!
가 붙습니다. 예를 들어push!
입니다. - C++에서는 기본적으로 정적 디스패치가 적용됩니다. 즉, 동적 디스패치를 사용하려면 함수에 virtual로 주석을 달아야 합니다. 반면, Julia에서는 모든 메서드가 "가상"입니다(메서드는
this
뿐만 아니라 모든 인수 유형에 대해 디스패치되므로 더 일반적입니다. 가장 구체적인 선언 규칙을 사용합니다).
Julia ⇔ C/C++: Namespaces
- C/C++
namespace
s는 대략적으로 Juliamodule
s에 해당합니다. - 줄리아에는 개인 전역 변수나 필드가 없습니다. 모든 것은 완전한 경로(또는 원하는 경우 상대 경로)를 통해 공개적으로 접근할 수 있습니다.
using MyNamespace::myfun
(C++)는 대략import MyModule: myfun
(Julia)에 해당합니다.using namespace MyNamespace
(C++)는 대략using MyModule
(Julia)에 해당합니다.- 줄리아에서는
export
된 기호만 호출 모듈에 사용 가능합니다. - C++에서는 포함된 (공용) 헤더 파일에 있는 요소만 사용할 수 있습니다.
- 줄리아에서는
- 경고:
import
/using
키워드 (줄리아)는 모듈도 로드합니다 (아래 참조). - 경고:
import
/using
(줄리아)는 전역 범위 수준(module
)에서만 작동합니다.- C++에서
using namespace X
는 임의의 범위(예: 함수 범위) 내에서 작동합니다.
- C++에서
Julia ⇔ C/C++: Module loading
- C/C++ "라이브러리"를 생각할 때, 당신은 아마도 Julia "패키지"를 찾고 있을 것입니다.
- 경고: C/C++ 라이브러리는 종종 여러 개의 "소프트웨어 모듈"을 포함하는 반면, Julia "패키지"는 일반적으로 하나를 포함합니다.
- 알림: Julia
module
은 전역 범위입니다(반드시 "소프트웨어 모듈"은 아닙니다).
- 대신 build/
make
스크립트를 사용하는 대신, Julia는 "프로젝트 환경" (때때로 "프로젝트" 또는 "환경"이라고도 불림)을 사용합니다.- 빌드 스크립트는 더 복잡한 애플리케이션(예: C/C++ 실행 파일을 컴파일하거나 다운로드해야 하는 애플리케이션)에만 필요합니다.
- Julia에서 애플리케이션이나 프로젝트를 개발하려면 루트 디렉토리를 "프로젝트 환경"으로 초기화하고 애플리케이션 전용 코드/패키지를 그곳에 두면 됩니다. 이렇게 하면 프로젝트 종속성에 대한 좋은 제어가 가능하고, 향후 재현성을 보장할 수 있습니다.
- 사용 가능한 패키지는
Pkg.add()
함수 또는 Pkg REPL 모드를 사용하여 "프로젝트 환경"에 추가됩니다. (그러나 이는 해당 패키지를 로드하지는 않습니다). - "프로젝트 환경"에 대한 사용 가능한 패키지(직접 종속성) 목록은
Project.toml
파일에 저장됩니다. - "프로젝트 환경"에 대한 전체 의존성 정보는
Pkg.resolve()
에 의해 자동 생성되어Manifest.toml
파일에 저장됩니다.
- "프로젝트 환경"에서 사용할 수 있는 패키지("소프트웨어 모듈")는
import
또는using
으로 로드됩니다.- C/C++에서는
#include <moduleheader>
를 사용하여 객체/함수 선언을 가져오고, 실행 파일을 빌드할 때 라이브러리를 링크합니다. - 줄리아에서
using
/import
를 다시 호출하면 기존 모듈이 범위로 가져와지지만, 다시 로드되지는 않습니다(이는 C/C++에서 비표준#pragma once
를 추가하는 것과 유사합니다).
- C/C++에서는
- 디렉토리 기반 패키지 저장소 (줄리아)는
Base.LOAD_PATH
배열에 저장소 경로를 추가하여 사용할 수 있습니다.- 디렉토리 기반 저장소의 패키지는
import
또는using
으로 로드되기 전에Pkg.add()
도구가 필요하지 않습니다. 이들은 프로젝트에 간단히 사용 가능합니다. - 디렉토리 기반 패키지 저장소는 "소프트웨어 모듈"의 로컬 라이브러리를 개발하는 가장 빠른 솔루션입니다.
- 디렉토리 기반 저장소의 패키지는
Julia ⇔ C/C++: Assembling modules
- C/C++에서
.c
/.cpp
파일은 빌드/make
스크립트를 사용하여 컴파일되고 라이브러리에 추가됩니다.- 줄리아에서
import [PkgName]
/using [PkgName]
문은 패키지의[PkgName]/src/
하위 디렉토리에 위치한[PkgName].jl
파일을 로드합니다. - 그에 따라,
[PkgName].jl
은 일반적으로include "[someotherfile].jl"
호출을 통해 관련 소스 파일을 로드합니다.
- 줄리아에서
include "./path/to/somefile.jl"
(줄리아)은#include "./path/to/somefile.jl"
(C/C++)와 매우 유사합니다.- 그러나
include "..."
(줄리아)는 헤더 파일을 포함하는 데 사용되지 않습니다 (필요하지 않음). - 사용하지 마세요
include "..."
(Julia) 다른 "소프트웨어 모듈"에서 코드를 로드하기 위해 (대신import
/using
을 사용하세요). include "path/to/some/module.jl"
(줄리아)은 서로 다른 모듈에서 동일한 코드의 여러 버전을 인스턴스화하여 동일한 이름을 가진 구별되는 유형(등)을 생성합니다.include "somefile.jl"
는 일반적으로 같은 Julia 패키지("소프트웨어 모듈") 내에서 여러 파일을 조합하는 데 사용됩니다. 따라서 파일이 한 번만include
되도록 보장하는 것이 상대적으로 간단합니다(혼란을 피하기 위한#ifdef
없음).
- 그러나
Julia ⇔ C/C++: Module interface
- C++는 "public"
.h
/.hpp
파일을 사용하여 인터페이스를 노출하는 반면, Juliamodule
은 사용자에게 의도된 특정 기호를public
또는export
로 표시합니다.- 종종, Julia
module
은 기존 함수에 새로운 "메서드"를 생성하여 기능을 추가합니다 (예:Base.push!
). - Julia 패키지의 개발자들은 따라서 인터페이스 문서화를 위해 헤더 파일에 의존할 수 없습니다.
- Julia 패키지의 인터페이스는 일반적으로 docstring, README.md, 정적 웹 페이지 등을 사용하여 설명됩니다.
- 종종, Julia
- 일부 개발자는 패키지/모듈을 사용하기 위해 필요한 모든 기호를
export
하지 않기로 선택하지만, 여전히 비공식 사용자 기호를public
으로 표시해야 합니다.- 사용자는 이러한 구성 요소에 패키지/모듈 이름으로 함수/구조체/...를 한정하여 접근할 것으로 예상될 수 있습니다 (예:
MyModule.run_this_task(...)
).
- 사용자는 이러한 구성 요소에 패키지/모듈 이름으로 함수/구조체/...를 한정하여 접근할 것으로 예상될 수 있습니다 (예:
Julia ⇔ C/C++: Quick reference
Software Concept | Julia | C/C++ |
---|---|---|
unnamed scope | begin ... end | { ... } |
function scope | function x() ... end | int x() { ... } |
global scope | module MyMod ... end | namespace MyNS { ... } |
software module | A Julia "package" | .h /.hpp files<br>+compiled somelib.a |
assembling<br>software modules | SomePkg.jl : ...<br>import("subfile1.jl") <br>import("subfile2.jl") <br>... | $(AR) *.o ⇒ somelib.a |
import<br>software module | import SomePkg | #include <somelib> <br>+link in somelib.a |
module library | LOAD_PATH[] , *Git repository,<br>**custom package registry | more .h /.hpp files<br>+bigger compiled somebiglib.a |
* The Julia package manager supports registering multiple packages from a single Git repository.<br> * This allows users to house a library of related packages in a single repository.<br> ** Julia registries are primarily designed to provide versioning \& distribution of packages.<br> ** Custom package registries can be used to create a type of module library.
Noteworthy differences from Common Lisp
줄리아는 기본적으로 배열에 대해 1 기반 인덱싱을 사용하며, 임의의 index offsets도 처리할 수 있습니다.
함수와 변수는 동일한 네임스페이스(“Lisp-1”)를 공유합니다.
Pair
유형이 있지만, 이는COMMON-LISP:CONS
로 사용될 의도가 아닙니다. 대부분의 언어 부분에서 다양한 iterable 컬렉션을 서로 교환하여 사용할 수 있습니다(예: splatting, 튜플 등).Tuple
은 이질적인 요소의 짧은 컬렉션에 대해 Common Lisp 리스트와 가장 가깝습니다. alist 대신NamedTuple
을 사용하세요. 동질적인 유형의 더 큰 컬렉션에는Array
와Dict
를 사용해야 합니다.전형적인 Julia 프로토타입 작업 흐름은 Revise.jl 패키지를 사용하여 이미지의 지속적인 조작을 포함합니다.
성능을 위해, Julia는 연산이 type stability를 갖기를 선호합니다. Common Lisp가 기본 기계 연산에서 추상화하는 반면, Julia는 그에 더 가까이 다가갑니다. 예를 들어:
- 정수 나눗셈은
/
를 사용하면 항상 부동 소수점 결과를 반환합니다. 계산이 정확하더라도 마찬가지입니다.//
는 항상 유리한 결과를 반환합니다.÷
는 항상 (잘린) 정수 결과를 반환합니다.
- Bignums는 지원되지만 변환은 자동이 아닙니다; 일반 정수 overflow.
- 복소수는 지원되지만, 복소 결과를 얻으려면 you need complex inputs를 사용해야 합니다.
- 여러 가지 복소수 및 유리수 유형이 있으며, 서로 다른 구성 요소 유형이 있습니다.
- 정수 나눗셈은
모듈(네임스페이스)은 계층적일 수 있습니다.
import
와using
는 이중 역할을 합니다: 코드를 로드하고 네임스페이스에서 사용할 수 있도록 만듭니다. 모듈 이름만을 위한import
는 가능하며(대략ASDF:LOAD-OP
와 동등합니다). 슬롯 이름은 별도로 내보낼 필요가 없습니다. 전역 변수는 모듈 외부에서 할당할 수 없습니다(탈출구로eval(mod, :(var = val))
를 제외하고).매크로는
@
로 시작하며, Common Lisp만큼 언어에 매끄럽게 통합되어 있지 않기 때문에 매크로 사용이 후자만큼 널리 퍼져 있지 않습니다. macros에 대한 위생의 한 형태가 언어에 의해 지원됩니다. 서로 다른 표면 구문 때문에COMMON-LISP:&BODY
에 해당하는 것이 없습니다.모든 함수는 제네릭이며 다중 디스패치를 사용합니다. 인수 목록은 동일한 템플릿을 따를 필요가 없으며, 이는 강력한 관용구로 이어집니다(참조:
do
). 선택적 및 키워드 인수는 다르게 처리됩니다. 메서드 모호성은 공통 리스프 객체 시스템(Common Lisp Object System)처럼 해결되지 않으며, 교차점에 대해 더 구체적인 메서드를 정의해야 합니다.기호는 어떤 패키지에도 속하지 않으며, 그 자체로 어떤 값도 포함하지 않습니다.
M.var
는 모듈M
에서 기호var
를 평가합니다.언어는 클로저를 포함하여 함수형 프로그래밍 스타일을 완전히 지원하지만, 항상 줄리아의 관용적인 솔루션은 아닙니다. 캡처된 변수를 수정할 때 성능을 위해 일부 workarounds가 필요할 수 있습니다.