他の言語との注目すべき違い
MATLAB との注目すべき違い
MATLAB ユーザーはジュリアの構文を親しみやすいと思うかもしれませんが、Juliaは MATLAB クローンではありません。構文や機能の違いは大きいです。MATLAB に慣れているJuliaユーザーがつまずきやすい注目すべき違いは次のとおりです:
- Julia の配列は角かっこで
A[i,j]
のようにインデックス付けされる。 - Juliaでは、配列は他の変数に代入してもコピーされません。
A = B
の後、B
の要素を変更するとA
も同様に変更されます。 - Juliaでは、値は関数に渡されてもコピーされません。関数が配列を変更すると、その変更は呼び出し元にも影響を与えます。
- Juliaでは、代入文の中で配列のサイズが自動的に拡張されません。 MATLABでは
a(4)= 3.2
でa = [0 0 0 3.2]
が生成され、その後a(5)= 7
とするとa = [0 0 0 3.2 7]
と配列のサイズが大きくなります。対して、Juliaでa [5] = 7
とすると、a
の長さが5より場合、もしくは、この代入式が識別子a
を初めて使用する式である場合には、エラーが発生します。Juliaには、push!
関数やappend!
関数があり、ベクトルのサイズを拡張する手段として、MATLABのa(end + 1)= val
よりもはるかに効率的です。 - 虚数単位
sqrt(-1)
は、MATLABではi
やj
が用いられますが、Juliaではim
と表記します。 - Juliaでは、小数点のない数値リテラル(
42
など)は浮動小数点ではなく整数を作成します。任意の大きな整数リテラルがサポートされています。その結果、一部の演算では 例えばjulia> a = -1; 2^a
のように 浮動小数点を想定している場合、「演算結果が整数ではない」というドメインエラーが発生します(詳細については、ドメインエラーに関するFAQを参照)。 - Juliaでは、複数の値が返され、タプルとして割り当てられます。例えば
(a,b) = (1,2)
やa, b = 1, 2
という具合です。MATLABのnargout
は、呼び出し側から期待される戻り値の数に基づいて選択的な処理をを行うもので、MATLABではよく使用されますが、Julia では使用できません。代わりに、ユーザーはオプション引数、キーワード引数の機能を使って、似たようなことをできます。 - Juliaは真の1次元配列を持っています。列ベクトルは、サイズが
N
で、Nx1
ではありません。例えば、rand(N)
は1次元配列を作成します。 - Juliaでは、
[x、y、z]
は常にx
、y
、z
を含む3要素の配列を構築します。- 最初の( "垂直方向の")次元で連結するには、
vcat(x, y, z)
を使うか、配列の要素をセミコロンで分割します([x; y; z]
)。 - 2番目の( "水平方向の")次元で連結するには、
hcat(x, y, z)
を使うか、配列の要素をスペースで分割します([x y z]
)。 - ブロック行列を構築する(最初の2つの次元で連結する)には、
hvcat
を使うか、スペースとセミコロンを組み合わせます([a b; c d]
)。
- 最初の( "垂直方向の")次元で連結するには、
- Juliaでは、
a:b
とa:b:c
はAbstractRange
オブジェクトを構成します。 MATLABのように完全なベクトルを作成するには、collect(a:b)
を使用してください。しかし、一般的にはcollect
を呼び出す必要はありません。 AbstractRangeオブジェクトはほとんどのケースで通常の配列のように振る舞いますが、その値を遅延計算するためより効率的です。完全な配列ではなく特殊化されたオブジェクトを作成するというこのパターンはよく使用されていて、range
のような関数や、enumerate
や、zip
のようなイテレータでも見られます。特殊オブジェクトは、通常の配列のように使用することができます。 - Juliaの関数は、最後の式または
return
キーワードから戻り値を返します。MATLABのように、関数定義で戻り値の名前を列挙するのではありません。(詳細はreturnキーワードを参照)。 - Juliaスクリプトには関数をいくつでも含めることができ、ファイルがロードされれば、すべての関数定義は外部から見えます。現在の作業ディレクトリの外にあるファイルからも関数定義はロードすることができます。
- Juliaでは、
sum
、prod
、max
のような簡約処理は、sum(A)
のように単一の引数で呼び出された場合、全ての要素に対して行われます。たとえA
が2次元以上だったとしても、です。 - Juliaでは、
rand()
のように、ゼロ引数で関数を呼び出すには括弧を使用する必要があります。 - Juliaは、文を終了するのにセミコロンを使用することを推奨していません。(対話式プロンプトでの実行を除き)式の結果が自動出力されませんので(出力を抑制したいのだとしても)コードの行末にセミコロンを使う必要はありません。
println
または@printf
を使ってプリント出力することができます。 - Juliaでは、
A
とB
が配列の場合、A == B
のような論理比較演算は真偽値の配列を返しません。(要素ごとの比較結果が欲しい場合には) 代わりにA.== B
を使用してください。<
や>
。のような他のブール演算子についても同様です。 - Juliaでは、演算子
&
、|
、および⊻
(xor
)で、それぞれMATLABにおけるand
、or
、およびxor
と等価なビット演算が行われます。演算の優先度は、Pythonのビット演算子に似ています(Cとは異なります)。それらはスカラーまたは要素ごとに操作でき、論理配列と組み合わせることもできますが、操作の順序の違いに注意してください: 括弧が必要な場合があります(例えば、1または2に等しいA
の要素を選択するには、(A。== 1)|(A。== 2)
を使用します)。 - Juliaでは、接合演算子
...
を使ってxs = [1,2]; f(xs...)
のようにして、コレクションの要素を引数として関数に渡すことができます。
* Juliaのsvd
は特異値を密な対角行列ではなくベクトルとして返します。 * Juliaでは、 ...
はコード行を継続するためには使用されません。代わりに、不完全な式は自動的に、次の行へと解釈が継続します。
- JuliaとMATLABの両方で、対話式セッションでは、変数
ans
は最後に発行された式の値に設定されますが、 Juliaでは、MATLABと異なり、Juliaコードが非インタラクティブモードで実行されるときには、ans
は設定されません。 - Juliaの
struct
は、MATLABのclass
とは異なり、実行時に動的なフィールドを追加をサポートしません。代わりに、Dict
を使ってください。 - Juliaでは各モジュールは独自のグローバルスコープ/名前空間を持ちますが、MATLABでは1つのグローバルスコープしかありません。
- MATLABでは、不要な値を削除するための慣用的な方法は、次のように論理インデックスを使用すること で、
x(x> 3)
としたりx(x> 3)= []
とx
を上書きしたりします。対してJuliaでは、より高次の関数filter
とfilter!
が利用できます。MATLABのコードをそのままJuliaに書き換えたx [x.> 3]
やx = x [x.> 3]
の代わりに、filter(z-> z> 3,x)
や、filter!(z-> z> 3,x)
と書くことができます。filter!
を使うと一時配列の使用を減らすことができます。 - セル配列のすべての要素を抽出する(つまり「間接参照する」)には、MATLABでは
vertcat(A {:})
が使われますが、Julia で同様のことを行うには、接合演算子を使ってvcat(A ...)
と書きます。
R との注目すべき違い
One of Julia's goals is to provide an effective language for data analysis and statistical programming. For users coming to Julia from R, these are some noteworthy differences:
Julia's single quotes enclose characters, not strings.
Julia can create substrings by indexing into strings. In R, strings must be converted into character vectors before creating substrings.
In Julia, like Python but unlike R, strings can be created with triple quotes
""" ... """
. This syntax is convenient for constructing strings that contain line breaks.In Julia, varargs are specified using the splat operator
...
, which always follows the name of a specific variable, unlike R, for which...
can occur in isolation.In Julia, modulus is
mod(a, b)
, nota %% b
.%
in Julia is the remainder operator.In Julia, not all data structures support logical indexing. Furthermore, logical indexing in Julia is supported only with vectors of length equal to the object being indexed. For example:
- In R,
c(1, 2, 3, 4)[c(TRUE, FALSE)]
is equivalent toc(1, 3)
. - In R,
c(1, 2, 3, 4)[c(TRUE, FALSE, TRUE, FALSE)]
is equivalent toc(1, 3)
. - In Julia,
[1, 2, 3, 4][[true, false]]
throws aBoundsError
. - In Julia,
[1, 2, 3, 4][[true, false, true, false]]
produces[1, 3]
.
- In R,
Like many languages, Julia does not always allow operations on vectors of different lengths, unlike R where the vectors only need to share a common index range. For example,
c(1, 2, 3, 4) + c(1, 2)
is valid R but the equivalent[1, 2, 3, 4] + [1, 2]
will throw an error in Julia.Julia allows an optional trailing comma when that comma does not change the meaning of code. This can cause confusion among R users when indexing into arrays. For example,
x[1,]
in R would return the first row of a matrix; in Julia, however, the comma is ignored, sox[1,] == x[1]
, and will return the first element. To extract a row, be sure to use:
, as inx[1,:]
.Julia's
map
takes the function first, then its arguments, unlikelapply(<structure>, function, ...)
in R. Similarly Julia's equivalent ofapply(X, MARGIN, FUN, ...)
in R ismapslices
where the function is the first argument.Multivariate apply in R, e.g.
mapply(choose, 11:13, 1:3)
, can be written asbroadcast(binomial, 11:13, 1:3)
in Julia. Equivalently Julia offers a shorter dot syntax for vectorizing functionsbinomial.(11:13, 1:3)
.Julia uses
end
to denote the end of conditional blocks, likeif
, loop blocks, likewhile
/for
, and functions. In lieu of the one-lineif ( cond ) statement
, Julia allows statements of the formif cond; statement; end
,cond && statement
and!cond || statement
. Assignment statements in the latter two syntaxes must be explicitly wrapped in parentheses, e.g.cond && (x = value)
.In Julia,
<-
,<<-
and->
are not assignment operators.Julia's
->
creates an anonymous function.Julia constructs vectors using brackets. Julia's
[1, 2, 3]
is the equivalent of R'sc(1, 2, 3)
.Julia's
*
operator can perform matrix multiplication, unlike in R. IfA
andB
are matrices, thenA * B
denotes a matrix multiplication in Julia, equivalent to R'sA %*% B
. In R, this same notation would perform an element-wise (Hadamard) product. To get the element-wise multiplication operation, you need to writeA .* B
in Julia.Julia performs matrix transposition using the
transpose
function and conjugated transposition using the'
operator or theadjoint
function. Julia'stranspose(A)
is therefore equivalent to R'st(A)
. Additionally a non-recursive transpose in Julia is provided by thepermutedims
function.Julia does not require parentheses when writing
if
statements orfor
/while
loops: usefor i in [1, 2, 3]
instead offor (i in c(1, 2, 3))
andif i == 1
instead ofif (i == 1)
.Julia does not treat the numbers
0
and1
as Booleans. You cannot writeif (1)
in Julia, becauseif
statements accept only booleans. Instead, you can writeif true
,if Bool(1)
, orif 1==1
.Julia does not provide
nrow
andncol
. Instead, usesize(M, 1)
fornrow(M)
andsize(M, 2)
forncol(M)
.Julia is careful to distinguish scalars, vectors and matrices. In R,
1
andc(1)
are the same. In Julia, they cannot be used interchangeably.Julia cannot assign to the results of function calls on the left hand side of an assignment operation: you cannot write
diag(M) = fill(1, n)
.Julia discourages populating the main namespace with functions. Most statistical functionality for Julia is found in packages under the JuliaStats organization. For example:
- Functions pertaining to probability distributions are provided by the Distributions package.
- The DataFrames package provides data frames.
- Generalized linear models are provided by the GLM package.
Julia provides tuples and real hash tables, but not R-style lists. When returning multiple items, you should typically use a tuple or a named tuple: instead of
list(a = 1, b = 2)
, use(1, 2)
or(a=1, b=2)
.Julia encourages users to write their own types, which are easier to use than S3 or S4 objects in R. Julia's multiple dispatch system means that
table(x::TypeA)
andtable(x::TypeB)
act like R'stable.TypeA(x)
andtable.TypeB(x)
.In Julia, values are not copied when assigned or passed to a function. If a function modifies an array, the changes will be visible in the caller. This is very different from R and allows new functions to operate on large data structures much more efficiently.
In Julia, vectors and matrices are concatenated using
hcat
,vcat
andhvcat
, notc
,rbind
andcbind
like in R.In Julia, a range like
a:b
is not shorthand for a vector like in R, but is a specializedAbstractRange
object that is used for iteration without high memory overhead. To convert a range into a vector, usecollect(a:b)
.Julia's
max
andmin
are the equivalent ofpmax
andpmin
respectively in R, but both arguments need to have the same dimensions. Whilemaximum
andminimum
replacemax
andmin
in R, there are important differences.Julia's
sum
,prod
,maximum
, andminimum
are different from their counterparts in R. They all accept an optional keyword argumentdims
, which indicates the dimensions, over which the operation is carried out. For instance, letA = [1 2; 3 4]
in Julia andB <- rbind(c(1,2),c(3,4))
be the same matrix in R. Thensum(A)
gives the same result assum(B)
, butsum(A, dims=1)
is a row vector containing the sum over each column andsum(A, dims=2)
is a column vector containing the sum over each row. This contrasts to the behavior of R, where separatecolSums(B)
androwSums(B)
functions provide these functionalities. If thedims
keyword argument is a vector, then it specifies all the dimensions over which the sum is performed, while retaining the dimensions of the summed array, e.g.sum(A, dims=(1,2)) == hcat(10)
. It should be noted that there is no error checking regarding the second argument.Julia has several functions that can mutate their arguments. For example, it has both
sort
andsort!
.In R, performance requires vectorization. In Julia, almost the opposite is true: the best performing code is often achieved by using devectorized loops.
Julia is eagerly evaluated and does not support R-style lazy evaluation. For most users, this means that there are very few unquoted expressions or column names.
Julia does not support the
NULL
type. The closest equivalent isnothing
, but it behaves like a scalar value rather than like a list. Usex === nothing
instead ofis.null(x)
.In Julia, missing values are represented by the
missing
object rather than byNA
. Useismissing(x)
(orismissing.(x)
for element-wise operation on vectors) instead ofis.na(x)
. Theskipmissing
function is generally used instead ofna.rm=TRUE
(though in some particular cases functions take askipmissing
argument).Julia lacks the equivalent of R's
assign
orget
.In Julia,
return
does not require parentheses.In R, an idiomatic way to remove unwanted values is to use logical indexing, like in the expression
x[x>3]
or in the statementx = x[x>3]
to modifyx
in-place. In contrast, Julia provides the higher order functionsfilter
andfilter!
, allowing users to writefilter(z->z>3, x)
andfilter!(z->z>3, x)
as alternatives to the corresponding transliterationsx[x.>3]
andx = x[x.>3]
. Usingfilter!
reduces the use of temporary arrays.
Python との注目すべき違い
- Julia は、コードブロックの終わりに
end
が必要です。Pythonとは違って Julia にはpass
キーワードがありません。 - Julia では、配列、文字列などのインデックスは 0 からではなく 1 から始まります。
- Julia のスライス インデックス作成には、Python とは異なり、最後の要素が含まれています。ジュリアの
a[2:3]
は Python のa[1:3]
です。 - Julia は負のインデックスをサポートしていません。特に、リストまたは配列の最後の要素は、Python では
-1
ですが、Julia ではend
でインデックス付けされます。 - Julia の
for
、if
、while
などのブロックはend
キーワードで終了します。インデントレベルはPythonほど重要ではありません。 - Julia には行継続構文がありません: 行末で、これまでの入力が完全な式である場合は、完了したと見なされますが、それ以外の場合は、入力が続行されます。式を括弧でくくると(そして行内で括弧を閉じなければ) 強制的に次の行に続行することができます。
- Julia 配列は列メジャー (Fortran オーダー) ですが、NumPy 配列はデフォルトで行メジャー (C オーダー) です。配列をループする際に最適なパフォーマンスを得るには、NumPy に対して Julia でループの順序を逆にする必要があります (パフォーマンス・ティップスの関連する節を参照)。
- Julia の更新演算子(例:
+=
、-=
、...)はインプレースではありません(NumPy の更新演算子は インプレースですが) 。どういうことかというと、A = [1, 1]; B = A; B += [3, 3]
はA
の値を変更せず、新しい配列である右側のB = B + 3
の結果にB
という名前を再バインドします。インプレース操作の場合は、B.+= 3
を使用してください。 ( ドット演算子、示的なループ、またはInplaceOps.jl
を参照) - Julia は、関数の定義時に既定値が 1 回だけ評価される Python とは異なり、メソッドが呼び出されるたびに関数引数の既定値を評価します。たとえば、関数
f(x=rand()= x
は、引数なしで呼び出されるたびに新しい乱数を返します。 一方、関数g(x=[1,2]) = push!(x,3)
はg()
と呼ばれるたびに[1,2,3]
を返します。 - Julia では、
%
は reminder 演算子ですが、Python ではモジュラスです。(訳者注: reminder は商に負の数を許した上での剰余) - The commonly used
Int
type corresponds to the machine integer type (Int32
orInt64
). This means it will overflow, such that2^64 == 0
. If you need larger values use another appropriate type, such asInt128
,BigInt
or a floating point type likeFloat64
.
C/C++ との注目すべき違い
- Julia 配列は角かっこでインデックス付けされ、複数次元の配列を扱えます
A[i,j]
のように。この構文は、C/C++ のようにポインタまたはアドレスへの参照のための単なる糖衣構文ではありません。配列構築の構文については、Julia のドキュメントを参照してください (バージョン間で構文が変更されています)。 - Julia では、配列、文字列などのインデックスは 0 からではなく 1 から始まります。
- Julia 配列は、別の変数に割り当てられた場合はコピーされません。
A = B
の後、B
の要素を変更するとA
も変更されます。+=
のような更新演算子は、インプレースでの動作はしませんが、左辺を右辺の式の結果に最バインドする、A = A + B
に相当します。 - Julia 配列は列メジャー (Fortran オーダー) ですが、C/C++ 配列はデフォルトで行メジャーです。配列をループする際に最適なパフォーマンスを得るには、C/C++ に対して Julia でループの順序を逆にする必要があります (パフォーマンス・ティップスの関連セクションを参照)。
- Julia では、値は、関数に割り当てられたり渡されたりしてもコピーされません。関数が配列を変更すると、その変更は呼び出し元にも影響を及ぼします。
- Julia では、空白は C/C++ とは異なり重要です。Julia プログラムから空白を追加/削除する場合は注意が必要です。
- Juliaでは、小数点のないリテラル数(
42
など)は、Int
型の符号付き整数を作成します。しかし機械語のサイズに収まらないほど大きいリテラルは自動的にInt64
(Int
がInt32
の場合)やInt128
、または任意の大きさのより大きなサイズの型のBigInt型に昇格されます。L
、LL
、U
、UL
、ULL
などの、符号なしおよび/または 符号付き と 符号なしの積などを示す、数値リテラルの接尾辞はありません。10進数リテラルは常に符号付き、16進数リテラル(C / C ++のように0x
で始まる)は符号なしです。また、16進リテラルは、 C / C ++ / Javaの16進数リテラルや、Juliaの10進数リテラルとは違い、リテラルの長さに基づいた型があります。先頭に0が複数が付くものも含みます。例えば、0x0
と0x00
は型UInt8
を持ち、0x000
と0x0000
は型UInt16
になります。5から8桁の16進数のリテラルは型UInt32
に、9から16桁の16進数リテラルは型UInt64
に、そして17から32桁の16進数リテラルは型UInt128
です。16進数マスクを定義するときには、このことを考慮する必要があります。例えば~0xf == 0xf0
は~0x000f == 0xfff0
と全く異なります。 64ビットのFloat64
や、32ビットのFloat32
のビットリテラルはそれぞれ1.0
と1.0f0
とひょうきします。浮動小数点リテラルが正確に表現できない場合は、丸められます(BigFloat
型には昇格されません)。浮動小数点リテラルの動作はC / C ++に近いです。 8進数(接頭辞0o
)とバイナリ(接頭辞0b
)リテラルも符号なしとして扱われます。
*文字列リテラルは "
または"""
で囲って表記することができます。 """
を使った文字列リテラルは、"\""
のようにクオートすることなく、文字 "
を内に含むことができます。文字列リテラルは他の変数や式の値を 展開して用いることができます。そこでは、$variablename
や $(expression)
と言った具合に書かれ、変数名や式をその文字列を用いたコンテキストの中で評価されます。
//
は有理数
を表し、単一行のコメントではありません (Juliaのコメントは#
です)#=
は複数行コメントの始まりを示し、=#
は終了を示します。- Juliaの関数は最後の式または
return
キーワードから値を返します。複数の値を関数から返すことができ、タプルとして割り当てられます。例えば、(a, b)= myfunction()
や、a, b = myfunction()
といった具合です。C / C ++のように(すなわちa=myfunction(&b)
というふうに)値へのポインタを渡す必要はありません。 - Juliaでは、文を終了するためにセミコロンを使用する必要はありません。(対話型プロンプト、すなわちREPLを除き)、式の結果は自動的に出力されませんので、コードの行末にセミコロンをつける必要はありません。特段プリント出力が必要なときには、
println
や@printf
を使います。REPLでは、;
を使って出力を抑制することができます。[]
内では;
は注目に値する、別の意味を持ちます。同じ行の中で、複数の式を区切るのに使うことができるのです。しかし、この機能は、多くの場合で必ず必要ということではなく、可読性向上のために役立つという意味合いが強いです。 - Juliaでは、演算子
⊻
(xor
)はXORビット演算を実行します。C / C ++でいうところの^
にあたります。また、ビット演算子はC / ++とは優先順位が異なるので、括弧が必要な場合があります。 - Juliaの
^
はべき乗(pow)であり、C / C ++の場合のようなビット演算のXORではありません(Julia では⊻
またはxor
を使ってください) - Juliaには2つの右シフト演算子、
>>
と>>>
があります。>>>
は算術シフトを実行します、>>
は C / C ++とは異なり、常に論理シフトを実行します。ここで、>>
の意味は、シフトされる値の型によって異なります。 - Juliaの
->
は無名関数を作成し、ポインタ経由のメンバへのアクセスではありません。 - Juliaは
if
ステートメントやfor
/while
ループを書くときに括弧を必要としません:for(int i = 1; i <= 3; i ++)
ではなくfor i in [1, 2, 3]
です。if(i == 1)
ではなくif i == 1
です。 - Juliaは数字の0と1をブール値として扱いません。 Juliaでは
if(1)
と書くことはできません。なぜなら、if文はブール値だけを受け入れるからです。代わりに、if true
、if Bool(1) 、
if 1 == 1`と書くことはできます。 - Juliaは、
if
などの条件付きブロックの終わりを示すのにend
を使います。同様に、while
やfor
などのループブロックのの終わりにもend
を使います。ワンラインで書くif ( cond ) statement
の代わりに、Juliaでは、if cond; statement; end
や、cond && statement
や、!cond || statement
のように書くことができます。終わり2つの構文で、代入式を書く場合には、括弧で明示的に囲う必要があります。例えば、cond &&(x = value)
といった具合で、これは演算子の優先順位のためです。 - Juliaには行継続構文はありません。行末で、これまでの入力が完全な式である場合、完了したとみなされますが、そうでなければ、入力が続行されます。式を括弧でくくることで、強制的に次の行に続行することができます。
- Juliaのマクロは、プログラムのテキストではなく、解析された式を操作します。これにより、Juliaコードの洗練された変換を実行することができます。マクロ名は
@
文字で始まり、mymacro(arg1, arg2,arg3)
という形の関数のような構文であったり、@mymacro arg1 arg2 arg3
という形の文のような構文を持ちます。書式は書き換え可能です。関数のような形式は特にマクロが別の式の中にある場合に便利で、多くの場合明確です。文のような形式は、ブロックに注釈を付けるためによく使われます。例えば、分散実行型のfor
構文のようでは、@distributed for i in 1:n; #= body =#;end
のように書きます。マクロの終わりがはっきりしないコードでは、関数のような形式を使用してください。 - Juliaは列挙型を持ち、
@enum(name, value1, value2, ...)
マクロを使って表現されます。例えば、@enum(Fruit, banana = 1, apple, pear)のように書きます。
*慣例により、引数を変更する関数は名前の最後に !
を持ちます。例えば、push!
などです。
- C ++では、デフォルトでは静的ディスパッチを利用可能です。つまり、動的なディスパッチを行うには、関数を仮想関数であるようにアノテーションする必要があります。一方、Juliaでは、すべてのメソッドは「仮想」です(ただし、より一般的です。メソッドは、最も具体的な宣言規則を使用するような、ディスパッチを、thisだけではなくすべての引数の型に対して行います)。
Common Lisp との注目すべき違い
- Julia uses 1-based indexing for arrays by default, and it can also handle
arbitrary index offsets.
Functions and variables share the same namespace (“Lisp-1”).
There is a
Pair
type, but it is not meant to be used as a
COMMON-LISP:CONS
. Various iterable collections can be used interchangeably in most parts of the language (eg splatting, tuples, etc). Tuple
s are the closest to Common Lisp lists for short collections of heterogeneous elements. Use NamedTuple
s in place of alists. For larger collections of homogeneous types, Array
s and Dict
s should be used.
- The typical Julia workflow for prototyping also uses continuous
manipulation of the image, implemented with the Revise.jl package.
- Bignums are supported, but conversion is not automatic; ordinary integers
- Modules (namespaces) can be hierarchical.
import
and
using
have a dual role: they load the code and make it available in the namespace. import
for only the module name is possible (roughly equivalent to ASDF:LOAD-OP
). Slot names don't need to be exported separately. Global variables can't be assigned to from outside the module (except with eval(mod, :(var = val))
as an escape hatch).
- Macros start with
@
, and are not as seamlessly integrated into the
language as Common Lisp; consequently, macro usage is not as widespread as in the latter. A form of hygiene for macros is supported by the language. Because of the different surface syntax, there is no equivalent to COMMON-LISP:&BODY
.
- All functions are generic and use multiple dispatch. Argument lists
don't have to follow the same template, which leads to a powerful idiom (see do
). Optional and keyword arguments are handled differently. Method ambiguities are not resolved like in the Common Lisp Object System, necessitating the definition of a more specific method for the intersection.
- Symbols do not belong to any package, and do not contain any values *per
se*. M.var
evaluates the symbol var
in the module M
.
- A functional programming style is fully supported by the language,
including closures, but isn't always the idiomatic solution for Julia. Some workarounds may be necessary for performance when modifying captured variables.