MyLang adalah bahasa pemrograman pendidikan sederhana yang terinspirasi oleh Python
, JavaScript
, dan C
, ditulis sebagai tantangan pribadi, dalam waktu singkat, sebagian besar untuk bersenang-senang menulis parser keturunan rekursif dan menjelajahi dunia interpreter. Jangan mengharapkan bahasa skrip lengkap dengan perpustakaan dan kerangka kerja yang siap untuk penggunaan produksi. Namun, MyLang
memiliki seperangkat bawaan minimal dan dapat digunakan untuk tujuan praktis juga.
MyLang ditulis dalam C++17 portabel : saat ini, proyek tidak memiliki dependensi selain pustaka C++ standar. Untuk membangunnya, jika Anda sudah menginstal GNU make
, jalankan saja:
$ make -j
Jika tidak, teruskan saja semua file .cpp ke kompiler Anda dan tambahkan direktori src/
ke jalur pencarian include. Salah satu hal terbaik tentang tidak memiliki ketergantungan adalah tidak diperlukannya sistem pembangunan untuk pembangunan satu kali.
Cukup berikan opsi BUILD_DIR
untuk make
:
$ make -j BUILD_DIR=other_build_directory
Jika Anda ingin menjalankan tes MyLang juga, Anda hanya perlu mengkompilasi dengan TESTS=1 dan menonaktifkan optimasi dengan OPT=0, untuk pengalaman debugging yang lebih baik:
$ make -j TESTS=1 OPT=0
Kemudian, jalankan semua tes dengan:
$ ./build/mylang -rt
Perlu diperhatikan bahwa, meskipun kerangka pengujian seperti GoogleTest dan Boost.Test jauh lebih kuat dan fleksibel dibandingkan mesin pengujian sepele yang kita miliki di src/tests.cpp
, keduanya merupakan dependensi eksternal . Semakin sedikit ketergantungan, semakin baik, bukan? :-)
Cara terpendek untuk mendeskripsikan MyLang
adalah: bahasa python-ish dinamis yang tampak seperti C. Mungkin, cara tercepat untuk mempelajari bahasa ini adalah dengan memeriksa skrip di direktori samples/
sambil melihat dokumentasi singkat di bawah.
MyLang
adalah bahasa pengetikan bebek yang dinamis, seperti Python
. Jika Anda paham Python
dan ingin menggunakan kurung kurawal { }
, Anda otomatis bisa menggunakannya. Tidak ada kejutan. String tidak dapat diubah seperti di Python
, array dapat didefinisikan menggunakan [ ]
seperti di Python
, dan kamus juga dapat didefinisikan menggunakan { }
. Bahasa ini juga mendukung irisan array menggunakan sintaks [start:end]
yang sama dengan yang digunakan oleh Python
.
Meskipun demikian, MyLang
berbeda dari Python
dan bahasa skrip lainnya dalam beberapa aspek:
Ada dukungan untuk konstanta waktu parse yang dideklarasikan menggunakan const
.
Semua variabel harus dideklarasikan menggunakan var
.
Variabel memiliki cakupan seperti di C
. Shadowing didukung ketika variabel dideklarasikan ulang secara eksplisit menggunakan var
, dalam blok bertingkat.
Semua pernyataan ekspresi harus diakhiri dengan ;
seperti di C
, C++
, dan Java
.
Kata kunci true
dan false
ada, tetapi tidak ada tipe boolean
. Seperti di C, 0
salah, yang lainnya true
. Namun, string, array, dan kamus memiliki nilai boolean, persis seperti di Python
(misalnya array kosong dianggap false
). Bawaan true
hanyalah alias untuk bilangan bulat 1
.
Operator penugasan =
dapat digunakan seperti dalam C
, di dalam ekspresi, tetapi tidak ada yang namanya operator koma, karena fitur perluasan array.
MyLang mendukung perulangan for
klasik dan perulangan foreach
eksplisit.
MyLang tidak mendukung tipe khusus saat ini. Namun, kamus mendukung gula sintaksis yang bagus: selain sintaksis utama d["key"]
, untuk kunci string, sintaksis d.key
juga didukung.
Variabel selalu dideklarasikan dengan var
dan berada dalam cakupan yang telah dideklarasikannya (sementara terlihat dalam cakupan bersarang). Misalnya:
# Variable declared in the global scope
var a = 42 ;
{
var b = 12 ;
# Here we can see both `a` and `b`
print ( a , b ) ;
}
# But here we cannot see `b` .
Dimungkinkan untuk mendeklarasikan beberapa variabel menggunakan sintaks yang sudah dikenal berikut ini:
var a , b , c ;
Namun ada peringatan, mungkin satu-satunya fitur "mengejutkan" dari MyLang
: menginisialisasi variabel tidak berfungsi seperti di C. Pertimbangkan pernyataan berikut:
var a , b , c = 42 ;
Dalam hal ini, daripada hanya mendeklarasikan a
dan b
dan menginisialisasi ke c
hingga 42, kita menginisialisasi ketiga variabel ke nilai 42. Untuk menginisialisasi setiap variabel ke nilai yang berbeda, gunakan sintaks ekspansi array:
var a , b , c = [ 1 , 2 , 3 ] ;
Konstanta dideklarasikan dengan cara yang sama seperti variabel tetapi tidak dapat dibayangi dalam cakupan yang disarangkan. Misalnya:
const c = 42 ;
{
# That's not allowed
const c = 1 ;
# That's not allowed as well
var c = 99 ;
}
Dalam MyLang
konstanta dievaluasi pada parse-time , dengan cara yang mirip dengan deklarasi constexpr C++
(tetapi di sini kita berbicara tentang waktu kompilasi ). Saat menginisialisasi const
, literal apa pun dapat digunakan selain seluruh rangkaian const bawaan. Misalnya:
const val = sum ( [ 1 , 2 , 3 ] ) ;
const x = " hello " + " world " + " " + join ( [ " a " , " b " , " c " ] , " , " ) ;
Untuk memahami bagaimana tepatnya sebuah konstanta dievaluasi, jalankan interpreter dengan opsi -s
, untuk membuang pohon sintaksis abstrak sebelum menjalankan skrip. Untuk contoh di atas:
$ cat > t
const val = sum([1,2,3]);
const x = "hello" + " world" + " " + join(["a","b","c"], ",");
$ ./build/mylang t
$ ./build/mylang -s t
Syntax tree
--------------------------
Block(
)
--------------------------
Terkejut? Ya, konstanta selain array dan kamus bahkan tidak dipakai sebagai variabel. Mereka tidak ada saat runtime . Mari tambahkan pernyataan menggunakan x
:
$ cat >> t
print(x);
$ cat t
const val = sum([1,2,3]);
const x = "hello" + " world" + " " + join(["a","b","c"], ",");
print(x);
$ ./build/mylang -s t
Syntax tree
--------------------------
Block(
CallExpr(
Id("print")
ExprList(
"hello world a,b,c"
)
)
)
--------------------------
hello world a,b,c
Sekarang, semuanya harusnya masuk akal. Hal yang hampir sama terjadi dengan array dan kamus dengan pengecualian bahwa array dan kamus juga dibuat instan seperti pada saat runtime, untuk menghindari potensi literal yang besar di mana-mana. Perhatikan contoh berikut:
$ ./build/mylang -s -e 'const ar=range(4); const s=ar[2:]; print(ar, s, s[0]);'
Syntax tree
--------------------------
Block(
ConstDecl(
Id("ar")
Op '='
LiteralArray(
Int(0)
Int(1)
Int(2)
Int(3)
)
)
ConstDecl(
Id("s")
Op '='
LiteralArray(
Int(2)
Int(3)
)
)
CallExpr(
Id("print")
ExprList(
Id("ar")
Id("s")
Int(2)
)
)
)
--------------------------
[0, 1, 2, 3] [2, 3] 2
Seperti yang Anda lihat, operasi irisan telah dievaluasi pada waktu penguraian saat menginisialisasi konstanta s
, tetapi kedua array juga ada pada waktu proses. Operasi subskrip pada ekspresi const, sebaliknya, diubah menjadi literal. Tampaknya ini merupakan trade-off yang baik untuk kinerja: nilai-nilai kecil seperti bilangan bulat, float, dan string dikonversi menjadi literal selama evaluasi const , sementara array dan kamus (berpotensi besar) dibiarkan sebagai simbol baca-saja pada saat runtime, namun tetap mengizinkan beberapa operasi pada mereka (seperti [index]
dan len(arr)
) untuk dievaluasi secara konstituen.
MyLang
, saat ini, hanya mendukung tipe (bawaan) berikut:
None Tipe none
, setara dengan None
milik Python. Variabel yang baru saja dideklarasikan tanpa diberi nilai, tidak memiliki nilai none
(misalnya var x;
). Hal yang sama berlaku untuk fungsi yang tidak memiliki nilai kembalian. Selain itu, ini digunakan sebagai nilai khusus oleh bawaan seperti find()
, jika terjadi kegagalan.
Integer Integer ukuran penunjuk yang ditandatangani (misalnya 3
).
Float Angka floating-point (misalnya 1.23
). Secara internal, ini adalah double yang panjang.
String Sebuah string seperti "halo". String tidak dapat diubah dan mendukung irisan (misalnya s[3:5]
atau s[3:]
atau s[-2:]
, memiliki arti yang sama seperti dalam Python
).
Array Tipe yang bisa berubah untuk array dan tupel (misalnya [1,2,3]
). Itu dapat berisi item dari jenis yang berbeda dan mendukung irisan yang dapat ditulis. Irisan array berperilaku seperti salinan, sedangkan irisan array menggunakan teknik copy-on-write.
Kamus Kamus adalah peta hash yang didefinisikan menggunakan sintaksis Python
: {"a": 3, "b": 4}
. Elemen diakses dengan sintaksis familiar d["key-string"]
atau d[23]
, dapat dicari dengan find()
dan dihapus dengan erase()
. Saat ini, hanya string, integer, dan float yang dapat digunakan sebagai kunci kamus. Keuntungan : kunci string seperti pengidentifikasi dapat diakses juga dengan sintaks "anggota": d.key
.
Fungsi Baik fungsi mandiri maupun lambda memiliki tipe objek yang sama dan dapat diteruskan seperti objek lainnya (lihat di bawah). Namun, hanya lambda yang dapat memiliki daftar tangkapan. Fungsi reguler tidak dapat dijalankan selama evaluasi const, sedangkan fungsi pure
bisa. Fungsi murni hanya dapat melihat konstanta dan argumennya.
Pengecualian Satu-satunya jenis benda yang bisa dilempar. Untuk membuatnya, gunakan exception()
bawaan atau pintasannya ex()
.
Pernyataan kondisional bekerja persis seperti di C
Sintaksnya adalah:
if ( conditionExpr ) {
# Then block
} else {
# Else block
}
Dan kurung kurawal { }
dapat dihilangkan seperti pada C
, pada kasus blok pernyataan tunggal. conditionExpr
dapat berupa ekspresi apa pun, misalnya: (a=3)+b >= c && !d
.
Ketika conditionExpr
adalah ekspresi yang dapat dievaluasi secara konstituen, seluruh pernyataan if diganti dengan cabang yang benar, sedangkan cabang yang salah dibuang. Misalnya, perhatikan skrip berikut:
const a = 3 ;
const b = 4 ;
if ( a < b ) {
print ( " yes " ) ;
} else {
print ( " no " ) ;
}
Tidak hanya selalu mencetak "ya", bahkan tidak perlu memeriksa apa pun sebelum melakukan itu. Periksa pohon sintaksis abstrak:
$ ./build/mylang -s t
Syntax tree
--------------------------
Block(
Block(
CallExpr(
Id("print")
ExprList(
"yes"
)
)
)
)
--------------------------
yes
MyLang
mendukung perulangan while
dan for
klasik.
while ( condition ) {
# body
if ( something )
break ;
if ( something_else )
continue ;
}
for ( var i = 0 ; i < 10 ; i += 1 ) {
# body
if ( something )
break ;
if ( something_else )
continue ;
}
Di sini, kurung kurawal { }
dapat dihilangkan seperti pada kasus di atas. Hanya ada beberapa perbedaan dari C
yang perlu diperhatikan:
Operator ++
dan --
tidak ada di MyLang
saat ini.
Untuk mendeklarasikan banyak variabel, gunakan sintaksis: var a, b = [3,4];
atau hanya var a,b,c,d = 0;
jika Anda ingin semua variabel memiliki nilai awal yang sama.
Untuk meningkatkan nilai beberapa variabel gunakan sintaksis: a, b += [1, 2]
. Dalam kasus yang sangat jarang dan kompleks ketika dalam pernyataan kenaikan pada perulangan for, kita perlu menetapkan variabel baru ke setiap variabel menggunakan ekspresi yang berbeda, manfaatkan sintaks perluasan dalam penugasan: i, j = [i+2, my_next(i, j*3)]
.
MyLang
mendukung loop foreach
menggunakan sintaks yang cukup familiar:
var arr = [ 1 , 2 , 3 ] ;
foreach ( var e in arr ) {
print ( " elem: " , e ) ;
}
Loop foreach dapat digunakan untuk array, string, dan kamus. Misalnya, melakukan iterasi setiap pasangan <key, value>
dalam kamus semudah:
var d = { " a " : 3 , " b " : 10 , " c " : 42 } ;
foreach ( var k , v in d ) {
print ( k + " => " + str ( v ) ) ;
}
Untuk melakukan iterasi hanya melalui setiap kunci, cukup gunakan var k in d
saja.
MyLang
juga mendukung enumerasi di loop foreach. Periksa contoh berikut:
var arr = [ " a " , " b " , " c " ] ;
foreach ( var i , elem in indexed arr ) {
print ( " elem[ " + str ( i ) + " ] = " + elem ) ;
}
Dengan kata lain, ketika nama container diawali dengan kata kunci indexed
, variabel pertama akan diberi nomor progresif pada setiap iterasi.
Saat melakukan iterasi melalui array array kecil berukuran tetap (pikirkan tentang tupel), dimungkinkan untuk secara langsung memperluas "tupel" tersebut di loop foreach:
var arr = [
[ " hello " , 42 ] ,
[ " world " , 11 ]
] ;
foreach ( var name , value in arr ) {
print ( name , value ) ;
}
# This is a shortcut for :
foreach ( var elem in arr ) {
# regular array expansion
var name , value = elem ;
print ( name , value ) ;
}
# Which is a shortcut for :
foreach ( var elem in arr ) {
var name = elem [ 0 ] ;
var value = elem [ 1 ] ;
print ( name , value ) ;
}
Mendeklarasikan suatu fungsi sederhana seperti:
func add ( x , y ) {
return x + y ;
}
Namun beberapa pintasan juga didukung. Misalnya, dalam kasus fungsi pernyataan tunggal seperti di atas, sintaks berikut dapat digunakan:
func add ( x , y ) => x + y ;
Selain itu, meskipun merupakan praktik yang baik untuk selalu menulis ()
untuk fungsi tanpa parameter, fungsi tersebut sebenarnya opsional dalam bahasa ini:
func do_something { print ( " hello " ) ; }
Fungsi diperlakukan sebagai simbol biasa di MyLang
dan tidak ada perbedaan substansial antara fungsi mandiri dan lambda dalam bahasa ini. Misalnya, kita bisa mendeklarasikan fungsi add
(di atas) sebagai lambda dengan cara ini:
var add = func ( x , y ) => x + y ;
Catatan: saat membuat objek fungsi dalam ekspresi, kami tidak diperbolehkan memberi nama pada objek tersebut.
Lambdas juga mendukung daftar tangkapan, namun tangkapan implisit tidak didukung, untuk menegakkan kejelasan. Tentu saja, lambda dapat dikembalikan seperti objek lainnya. Misalnya:
func create_adder_func ( val ) =>
func [ val ] ( x ) => x + val ;
var f = create_adder_func ( 5 ) ;
print ( f ( 1 ) ) ; # Will print 6
print ( f ( 10 ) ) ; # Will print 15
Lambda dengan tangkapan memiliki status , seperti yang diharapkan siapa pun. Perhatikan skrip berikut:
func gen_counter ( val ) => func [ val ] {
val += 1 ;
return val ;
} ;
var c1 = gen_counter ( 5 ) ;
for ( var i = 0 ; i < 3 ; i += 1 )
print ( " c1: " , c1 ( ) ) ;
# Clone the `c1` lambda object as `c2` : now it will have
# its own state , indipendent from `c1` .
var c2 = clone ( c1 ) ;
print ( ) ;
for ( var i = 0 ; i < 3 ; i += 1 )
print ( " c2: " , c2 ( ) ) ;
print ( ) ;
for ( var i = 0 ; i < 3 ; i += 1 )
print ( " c1: " , c1 ( ) ) ;
Ini menghasilkan output:
c1: 6
c1: 7
c1: 8
c2: 9
c2: 10
c2: 11
c1: 9
c1: 10
c1: 11
Objek fungsi reguler yang ditentukan pengguna (termasuk lambda) tidak dianggap const
dan, oleh karena itu, tidak dapat dijalankan selama evaluasi const. Itu adalah batasan yang cukup kuat. Perhatikan contoh berikut:
const people = [
[ " jack " , 3 ] ,
[ " alice " , 11 ] ,
[ " mario " , 42 ] ,
[ " bob " , 38 ]
] ;
const sorted_people = sort ( people , func ( a , y ) => a [ 0 ] < b [ 0 ] ) ;
Dalam hal ini, skrip tidak dapat membuat array const sorted_people
. Karena kita meneruskan objek fungsi ke const sort()
bawaan, kita akan mendapatkan kesalahan ExpressionIsNotConstEx
. Tentu saja, jika sorted_people
dideklarasikan sebagai var
, skrip akan berjalan, tetapi arraynya tidak akan menjadi const lagi dan, kita tidak akan bisa mendapatkan keuntungan dari pengoptimalan waktu parse apa pun. Oleh karena itu, meskipun sort()
bawaan dapat dipanggil selama evaluasi const, jika ia memiliki parameter compare func
khusus, hal itu tidak mungkin lagi.
Untuk mengatasi batasan yang baru saja dijelaskan, MyLang
memiliki sintaks khusus untuk fungsi murni . Ketika sebuah fungsi dideklarasikan dengan kata kunci pure
sebelum func
, interpreter memperlakukannya dengan cara khusus: fungsi tersebut dapat dipanggil kapan saja, baik selama evaluasi const maupun saat runtime tetapi fungsi tersebut tidak dapat melihat variabel global, atau menangkap apa pun: ia hanya dapat menggunakan konstanta dan nilai parameternya: itulah yang kita perlukan selama evaluasi const. Misalnya, untuk menghasilkan sorted_people
selama evaluasi const, cukup menulis:
const sorted_people = sort ( people , pure func ( a , b ) => a [ 0 ] < b [ 0 ] ) ;
Fungsi murni dapat didefinisikan sebagai fungsi mandiri dan juga dapat digunakan dengan parameter non-const. Oleh karena itu, jika suatu fungsi dapat dideklarasikan sebagai pure
, maka harus selalu dideklarasikan seperti itu. Misalnya, perhatikan skrip berikut:
pure func add2 ( x ) => x + 2 ;
var non_const = 25 ;
print ( add2 ( non_const ) ) ;
print ( add2 ( 5 ) ) ;
Pohon sintaksis abstrak yang akan digunakan mesin bahasa saat runtime adalah:
$ ./build/mylang -s t
Syntax tree
--------------------------
Block(
FuncDeclStmt(
Id("add2")
<NoCaptures>
IdList(
Id("x")
)
Expr04(
Id("x")
Op '+'
Int(2)
)
)
VarDecl(
Id("non_const")
Op '='
Int(25)
)
CallExpr(
Id("print")
ExprList(
CallExpr(
Id("add2")
ExprList(
Id("non_const")
)
)
)
)
CallExpr(
Id("print")
ExprList(
Int(7)
)
)
)
--------------------------
27
7
Seperti yang Anda lihat, dalam kasus pertama pemanggilan fungsi sebenarnya terjadi karena non_const
bukan sebuah konstanta, sedangkan dalam kasus kedua AS JIKA kita meneruskan bilangan bulat literal ke print()
.
Seperti konstruksi lainnya, MyLang
memiliki penanganan pengecualian yang mirip dengan Python
, tetapi menggunakan sintaksis yang mirip dengan C++
. Konstruksi dasarnya adalah pernyataan try-catch
. Mari kita lihat contohnya:
try {
var input_str = " blah " ;
var a = int ( input_str ) ;
} catch ( TypeErrorEx ) {
print ( " Cannot convert the string to integer " ) ;
}
Catatan: jika pengecualian dihasilkan oleh ekspresi konstan (misalnya int("blah")
), selama evaluasi const, kesalahan akan dilaporkan secara langsung, melewati logika penanganan pengecualian apa pun. Alasannya adalah untuk menegakkan kegagalan dini .
Beberapa pernyataan catch
juga diperbolehkan:
try {
# body
} catch ( TypeErrorEx ) {
# error handling
} catch ( DivisionByZeroEx ) {
# error handling
}
Dan, jika beberapa pengecualian dapat ditangani dengan kode yang sama, sintaksis yang lebih pendek juga dapat digunakan:
try {
# body
} catch ( TypeErrorEx , DivisionByZeroEx as e ) {
# error handling
print ( e ) ;
} catch ( OutOfBoundsEx ) {
# error handling
}
Pengecualian mungkin berisi data, namun saat ini tidak ada pengecualian bawaan yang berisi data. Daftar pengecualian runtime bawaan yang dapat ditangkap dengan blok try-catch
adalah:
Pengecualian lain seperti SyntaxErrorEx
tidak dapat ditangkap. Di MyLang
juga dimungkinkan untuk menangkap pengecualian APAPUN menggunakan blok catch-anything:
try {
# body
} catch {
# Something went wrong .
}
Bahasa ini tidak mendukung tipe khusus saat ini. Oleh karena itu, tidak mungkin melempar benda apa pun seperti dalam beberapa bahasa lain. Untuk memunculkan pengecualian, Anda perlu menggunakan fungsi bawaan khusus exception()
atau pintasannya, ex()
. Perhatikan contoh berikut:
try {
throw ex ( " MyError " , 1234 ) ;
} catch ( MyError as e ) {
print ( " Got MyError, data: " , exdata ( e ) ) ;
}
Seperti yang disarankan oleh intuisi, dengan ex()
kita telah membuat dan kemudian melemparkan objek pengecualian bernama MyError
, yang memiliki 1234
sebagai data payload. Kemudian, di blok catch
, kami menangkap pengecualian dan, kami mengekstrak data payload menggunakan exdata()
bawaan.
Jika pengecualian tertentu tidak perlu memiliki payload, Anda dapat menyimpan hasil ex()
dalam sebuah variabel dan membuangnya nanti menggunakan sintaksis yang mungkin lebih menyenangkan:
var MyError = ex ( " MyError " ) ;
throw MyError ;
MyLang
mendukung pelemparan ulang pengecualian di badan pernyataan catch menggunakan kata kunci rethrow
khusus:
try {
do_something ( ) ;
} catch {
print ( " Something went wrong!! " ) ;
rethrow ;
}
Dalam beberapa kasus, mungkin perlu dilakukan pembersihan, setelah mengeksekusi blok kode yang mungkin memunculkan pengecualian. Untuk kasus ini, MyLang
mendukung klausa finally
yang terkenal, yang berfungsi persis seperti di C#
:
try {
step1_might_throw ( ) ;
step2_might_throw ( ) ;
step3_might_throw ( ) ;
step4_might_throw ( ) ;
} catch ( TypeErrorEx ) {
# some error handling
} finally {
# clean - up
}
Perlu diperhatikan bahwa konstruksi try-finally
(tanpa klausa catch
) juga diperbolehkan.
Fungsi bawaan berikut akan dievaluasi selama waktu parse ketika argumen const diteruskan ke fungsi tersebut.
defined(symbol)
Periksa apakah symbol
didefinisikan. Mengembalikan 1 jika simbol ditentukan, 0 jika tidak.
len(container)
Kembalikan jumlah elemen dalam wadah yang diberikan.
str(value, [decimal_digits])
Ubah nilai yang diberikan menjadi string. Jika value
adalah float, parameter ke-2 menunjukkan jumlah digit desimal yang diinginkan dalam string keluaran.
int(value)
Ubah string yang diberikan menjadi bilangan bulat. Jika nilainya float, maka akan terpotong. Jika nilainya berupa string, maka akan diurai dan dikonversi menjadi bilangan bulat, jika memungkinkan. Jika nilainya sudah berupa bilangan bulat, maka akan dikembalikan apa adanya.
float(value)
Ubah nilai yang diberikan menjadi float. Jika nilainya berupa bilangan bulat, maka akan diubah menjadi bilangan floating-point. Jika nilainya berupa string, maka akan diurai dan diubah menjadi float, jika memungkinkan. Jika nilainya sudah berupa float, maka akan dikembalikan apa adanya.
clone(obj)
Kloning objek yang diberikan. Berguna untuk objek non-sepele seperti array, kamus, dan lambda dengan tangkapan.
type(value)
Kembalikan nama tipe nilai yang diberikan dalam bentuk string. Berguna untuk debugging.
hash(value)
Mengembalikan nilai hash yang digunakan oleh kamus secara internal ketika value
digunakan sebagai kunci. Saat ini, hanya bilangan bulat, float, dan string yang mendukung hash()
.
array(N)
Kembalikan array yang none