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] = 7a의 길이가 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, yz를 포함하는 3요소 배열을 생성합니다.
    • 첫 번째("수직") 차원에서 연결하려면 vcat(x,y,z)를 사용하거나 세미콜론([x; y; z])으로 구분하십시오.
    • 두 번째("수평") 차원에서 연결하려면 hcat(x,y,z)를 사용하거나 공백으로 구분하여([x y z]) 사용할 수 있습니다.
    • 블록 행렬을 구성하려면 (첫 두 차원에서 연결), hvcat를 사용하거나 공백과 세미콜론을 결합하여 ([a b; c d]) 사용하세요.
  • 줄리아에서 a:ba:b:cAbstractRange 객체를 생성합니다. 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 and B are arrays, logical comparison operations like A == B do not return an array of booleans. Instead, use A .== 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는 filterfilter!와 같은 고차 함수를 제공하여 사용자가 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]을 생성합니다.
  • 많은 언어와 마찬가지로, 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과 달리 행렬 곱셈을 수행할 수 있습니다. 만약 AB가 행렬이라면, 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)를 사용하세요.

  • 줄리아는 숫자 01을 불리언으로 취급하지 않습니다. 줄리아에서는 if (1)을 쓸 수 없으며, if 문은 오직 불리언만을 허용합니다. 대신 if true, if Bool(1), 또는 if 1==1을 쓸 수 있습니다.

  • 줄리아는 nrowncol을 제공하지 않습니다. 대신 nrow(M)에는 size(M, 1)을, ncol(M)에는 size(M, 2)를 사용하세요.

  • 줄리아는 스칼라, 벡터 및 행렬을 구분하는 데 주의합니다. R에서는 1c(1)이 동일하지만, 줄리아에서는 서로 바꿔 사용할 수 없습니다.

  • 줄리아의 diagdiagm는 R의 것과 다릅니다.

  • 줄리아에서는 할당 연산의 왼쪽에 함수 호출 결과를 할당할 수 없습니다: diag(M) = fill(1, n)와 같이 쓸 수 없습니다.

  • 줄리아는 주요 네임스페이스에 함수를 채우는 것을 권장하지 않습니다. 줄리아의 대부분의 통계 기능은 packages에서 JuliaStats organization 아래에서 찾을 수 있습니다. 예를 들어:

  • 줄리아는 튜플과 실제 해시 테이블을 제공하지만 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, vcathvcat를 사용하여 연결되며, R에서처럼 c, rbindcbind를 사용하지 않습니다.

  • 줄리아에서 a:b와 같은 범위는 R에서 벡터의 약어가 아니라 반복에 사용되는 특수한 AbstractRange 객체입니다. 범위를 벡터로 변환하려면 collect(a:b)를 사용하세요.

  • : 연산자는 R과 Julia에서 다른 우선 순위를 가집니다. 특히, Julia에서는 산술 연산자가 : 연산자보다 높은 우선 순위를 가지며, R에서는 그 반대입니다. 예를 들어, Julia에서 1:n-1은 R에서 1:(n-1)과 동일합니다.

  • 줄리아의 maxmin는 R에서 각각 pmaxpmin의 동등한 기능을 하지만, 두 인수는 동일한 차원을 가져야 합니다. 반면에 maximumminimum는 R에서 maxmin을 대체하지만, 중요한 차이점이 있습니다.

  • 줄리아의 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)입니다. 두 번째 인수에 대한 오류 검사는 없다는 점에 유의해야 합니다.

  • 줄리아는 인수를 변형할 수 있는 여러 함수를 가지고 있습니다. 예를 들어, sortsort!가 있습니다.

  • 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)를 작성할 수 있도록 하는 고차 함수 filterfilter!를 제공합니다. 이는 각각의 변환에 해당하는 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 배열과 같이 요소를 제자리에서 저장하는 "빠른" 배열(즉, dtypenp.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을 사용합니다.
  • 줄리아에서 행렬 유형에 대한 표준 연산자는 행렬 연산인 반면, 파이썬에서는 표준 연산자가 요소별 연산입니다. AB가 모두 행렬일 때, 줄리아에서 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에 해당합니다.
  • 줄리아에서 @ 기호는 매크로를 나타내고, 파이썬에서는 데코레이터를 나타냅니다.
  • 줄리아에서 예외 처리는 trycatchfinally를 사용하여 수행되며, tryexceptfinally를 사용하지 않습니다. 파이썬과 달리, 줄리아에서는 일반적인 작업 흐름의 일부로 예외 처리를 사용하는 것이 권장되지 않습니다(파이썬과 비교할 때, 줄리아는 일반적인 제어 흐름에서 더 빠르지만 예외 포착에서는 더 느립니다).
  • 줄리아에서 루프는 빠르므로 성능상의 이유로 "벡터화된" 코드를 작성할 필요가 없습니다.
  • 줄리아에서 비상수 전역 변수에 주의하세요, 특히 빠른 루프에서. 줄리아에서는 (파이썬과는 달리) 거의 메탈에 가까운 코드를 작성할 수 있기 때문에 전역 변수의 영향이 극단적일 수 있습니다 (참조: 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를 반환합니다.
  • 줄리아에서는 대부분의 코드 블록, 즉 루프와 trycatchfinally를 포함하여 새로운 로컬 스코프가 도입됩니다. 리스트, 제너레이터 등과 같은 컴프리헨션은 파이썬과 줄리아 모두에서 새로운 로컬 스코프를 도입하는 반면, 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 유형을 생성하지만, 머신 워드 크기에 맞지 않는 너무 큰 리터럴은 자동으로 더 큰 크기 유형으로 승격됩니다. 예를 들어, IntInt32인 경우 Int64, Int128 또는 임의로 큰 BigInt 유형으로 승격됩니다. 부호가 없는 정수와 부호가 있는 정수를 나타내기 위한 숫자 리터럴 접미사(예: L, LL, U, UL, ULL)는 없습니다. 십진수 리터럴은 항상 부호가 있으며, 16진수 리터럴(예: C/C++에서 0x로 시작)은 부호가 없지만, 128비트를 초과하는 경우에는 BigInt 유형이 됩니다. 16진수 리터럴은 C/C++/Java와 다르게, 그리고 줄리아의 십진수 리터럴과 다르게, 리터럴의 길이(선행 0 포함)에 따라 유형이 결정됩니다. 예를 들어, 0x00x00UInt8 유형을 가지며, 0x0000x0000UInt16 유형을 가집니다. 그 후 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.01.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)를 사용하세요.
  • 줄리아는 숫자 01을 불리언으로 취급하지 않습니다. 줄리아에서는 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++ namespaces는 대략적으로 Julia modules에 해당합니다.
  • 줄리아에는 개인 전역 변수나 필드가 없습니다. 모든 것은 완전한 경로(또는 원하는 경우 상대 경로)를 통해 공개적으로 접근할 수 있습니다.
  • 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는 임의의 범위(예: 함수 범위) 내에서 작동합니다.

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를 추가하는 것과 유사합니다).
  • 디렉토리 기반 패키지 저장소 (줄리아)는 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 파일을 사용하여 인터페이스를 노출하는 반면, Julia module은 사용자에게 의도된 특정 기호를 public 또는 export로 표시합니다.
    • 종종, Julia module은 기존 함수에 새로운 "메서드"를 생성하여 기능을 추가합니다 (예: Base.push!).
    • Julia 패키지의 개발자들은 따라서 인터페이스 문서화를 위해 헤더 파일에 의존할 수 없습니다.
    • Julia 패키지의 인터페이스는 일반적으로 docstring, README.md, 정적 웹 페이지 등을 사용하여 설명됩니다.
  • 일부 개발자는 패키지/모듈을 사용하기 위해 필요한 모든 기호를 export하지 않기로 선택하지만, 여전히 비공식 사용자 기호를 public으로 표시해야 합니다.
    • 사용자는 이러한 구성 요소에 패키지/모듈 이름으로 함수/구조체/...를 한정하여 접근할 것으로 예상될 수 있습니다 (예: MyModule.run_this_task(...)).

Julia ⇔ C/C++: Quick reference

Software ConceptJuliaC/C++
unnamed scopebegin ... end{ ... }
function scopefunction x() ... endint x() { ... }
global scopemodule MyMod ... endnamespace MyNS { ... }
software moduleA Julia "package".h/.hpp files<br>+compiled somelib.a
assembling<br>software modulesSomePkg.jl: ...<br>import("subfile1.jl")<br>import("subfile2.jl")<br>...$(AR) *.o &rArr; somelib.a
import<br>software moduleimport SomePkg#include <somelib><br>+link in somelib.a
module libraryLOAD_PATH[], *Git repository,<br>**custom package registrymore .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을 사용하세요. 동질적인 유형의 더 큰 컬렉션에는 ArrayDict를 사용해야 합니다.

  • 전형적인 Julia 프로토타입 작업 흐름은 Revise.jl 패키지를 사용하여 이미지의 지속적인 조작을 포함합니다.

  • 성능을 위해, Julia는 연산이 type stability를 갖기를 선호합니다. Common Lisp가 기본 기계 연산에서 추상화하는 반면, Julia는 그에 더 가까이 다가갑니다. 예를 들어:

    • 정수 나눗셈은 /를 사용하면 항상 부동 소수점 결과를 반환합니다. 계산이 정확하더라도 마찬가지입니다.
      • //는 항상 유리한 결과를 반환합니다.
      • ÷는 항상 (잘린) 정수 결과를 반환합니다.
    • Bignums는 지원되지만 변환은 자동이 아닙니다; 일반 정수 overflow.
    • 복소수는 지원되지만, 복소 결과를 얻으려면 you need complex inputs를 사용해야 합니다.
    • 여러 가지 복소수 및 유리수 유형이 있으며, 서로 다른 구성 요소 유형이 있습니다.
  • 모듈(네임스페이스)은 계층적일 수 있습니다. importusing는 이중 역할을 합니다: 코드를 로드하고 네임스페이스에서 사용할 수 있도록 만듭니다. 모듈 이름만을 위한 import는 가능하며(대략 ASDF:LOAD-OP와 동등합니다). 슬롯 이름은 별도로 내보낼 필요가 없습니다. 전역 변수는 모듈 외부에서 할당할 수 없습니다(탈출구로 eval(mod, :(var = val))를 제외하고).

  • 매크로는 @로 시작하며, Common Lisp만큼 언어에 매끄럽게 통합되어 있지 않기 때문에 매크로 사용이 후자만큼 널리 퍼져 있지 않습니다. macros에 대한 위생의 한 형태가 언어에 의해 지원됩니다. 서로 다른 표면 구문 때문에 COMMON-LISP:&BODY에 해당하는 것이 없습니다.

  • 모든 함수는 제네릭이며 다중 디스패치를 사용합니다. 인수 목록은 동일한 템플릿을 따를 필요가 없으며, 이는 강력한 관용구로 이어집니다(참조: do). 선택적 및 키워드 인수는 다르게 처리됩니다. 메서드 모호성은 공통 리스프 객체 시스템(Common Lisp Object System)처럼 해결되지 않으며, 교차점에 대해 더 구체적인 메서드를 정의해야 합니다.

  • 기호는 어떤 패키지에도 속하지 않으며, 그 자체로 어떤 값도 포함하지 않습니다. M.var는 모듈 M에서 기호 var를 평가합니다.

  • 언어는 클로저를 포함하여 함수형 프로그래밍 스타일을 완전히 지원하지만, 항상 줄리아의 관용적인 솔루션은 아닙니다. 캡처된 변수를 수정할 때 성능을 위해 일부 workarounds가 필요할 수 있습니다.