Sejauh ini kita baru saja menyentuh sintaksis Hyperlambda. Untuk memahami sintaksnya, Anda harus memahami hubungan antara objek Hyperlambda dan lambda, di mana objek lambda bagi Hyperlambda setara dengan DOM bagi HTML. Untuk memahami objek lambda lagi, ada gunanya membayangkan beberapa kode semu C#/Java tradisional.

class Node
{
   string Name;
   object Value;
   List<Node> Children;
}

Di atas adalah deklarasi tipe "objek lambda" atau "pohon eksekusi", dan secara harfiah adalah "format kode mesin yang dapat dieksekusi" yang dijalankan Magic . Namun, karena semua fungsi dapat direduksi menjadi objek grafik atau struktur pohon, yang sifatnya hierarkis, ini menyiratkan bahwa setidaknya secara teori, Anda dapat membuat fungsi apa pun yang dapat dieksekusi yang dapat Anda buat dengan bahasa pemrograman lain hanya dengan menggunakan tipe di atas.

Saat Anda menulis Hyperlambda, apa yang Anda lakukan sebenarnya adalah mendeklarasikan objek secara dinamis yang menyerupai tipe di atas. Perhatikan contoh perulangan [sementara] yang kita mulai dengan beberapa artikel lalu.

.no:int:0
while
   lt
      get-value:x:@.no
      .:int:20
   .lambda
      log.info:Howdy from while
      math.increment:x:@.no

Objek lambda di atas memiliki satu akar implisit Node, yang juga memiliki dua turunan yang disebut [.no] dan [sementara]. Node while kita lagi-lagi memiliki dua turunan lagi yang disebut [lt] dan [.lambda], dan seterusnya. Tanda titik dua : memisahkan nama simpul dari nilainya, dan 3 spasi membuka koleksi turunan, sehingga Anda dapat mendeklarasikan simpul turunan dari simpul di atas.

Detailnya yang mengerikan

Pengurai Hyperlambda sekali lagi, cukup mem-parsing Hyperlambda sebagai teks terstruktur, dan secara dinamis membuat struktur Node dengan Hyperlambda yang ditentukan sesuai dengan kumpulan aturan di atas. Kemudian ketika parser Hyperlambda telah membuat objek lambda, ia meneruskan objek lambda tersebut sebagai satu-satunya argumennya ke dalam slot [eval] (pikirkan 'fungsi' di sini). Slot [eval]sekali lagi, mematuhi kumpulan aturan rekursif yang sangat sederhana yaitu sebagai berikut.

void eval(Node node)
{
   foreach(var idx in node.Children)
   {
      if (!idx.Name.StartsWith("."))
         signal(idx.Name, idx);
   }
}

Hal di atas sampai batas tertentu merupakan penyederhanaan yang berlebihan, namun sebenarnya, itulah keseluruhan “bahasa pemrograman” yang diringkas. Metode signal di atas sekali lagi, cukup memanggil metode antarmuka pada suatu kelas, di mana tipenya diambil dari string ==› ketik Dictionary, dan buat instance tipe tersebut menggunakan wadah IoC internal, memungkinkan Anda untuk mendeklarasikan tipe dalam bahasa pemrograman hosting yang dibuat menggunakan injeksi ketergantungan.

Jika kepala Anda sedikit sakit sekarang, abaikan saja dua paragraf terakhir, ini sebagian besar dimaksudkan sebagai penjelasan bagi mereka yang mencari detail lebih mengerikan. Namun, sadarilah bahwa Hyperlambda adalah bahasa pemrograman yang paling sederhana dan termudah di dunia untuk diimplementasikan, jika tidak ada alasan lain selain itu tidak ada kompilasi dan tidak ada interpretasi yang terjadi saat "dieksekusi", hanya sebuah operasi parse sederhana, membuat objek grafik, yang kemudian dieksekusi lagi secara rekursif sebagai “pohon eksekusi”. Oleh karena itu, objek lambda adalah Magic yang merupakan kode mesin untuk CPU Anda.

Hal ini menghasilkan lingkungan sandbox, dimana eksekusi terjadi secara virtual, melalui bahasa pemrograman host, menyediakan slot sebagai layanan, serupa dengan bagaimana virtualisasi terjadi di tempat lain dalam komputasi. Jika hypervisor adalah CPU atau sistem operasi virtual, maka Hyperlambda adalah "hyper-executor", yang logika dasarnya diimplementasikan dalam bahasa pemrograman host, yang untuk tujuan Magic adalah C# dan Waktu proses .Net 6. Namun, Anda tidak perlu repot dengan bahasa pemrograman host yang mendasarinya, C# atau .Net dengan cara apa pun. Dan Anda mungkin bisa membuat runtime eksekusi Hyperlambda di Java, PHP atau C++ jika Anda mau.

Sistem pengetikan Hyperlambda

Meskipun Hyperlambda tidak memiliki OOP, atau konstruksi kompleks apa pun yang ditemukan dalam bahasa pemrograman tradisional lainnya, Hyperlambda perlu menangani tipe asli pada suatu saat. Dengan Hyperlambda Anda dapat mendeklarasikan tipe dengan memasukkan deklarasi tipe di antara nama node dan nilainya, dan Anda sebenarnya sudah melihat sintaksis ini lebih lanjut di artikel ini pada contoh loop while kami. Mari kita ulangi bagian penting sekali lagi.

.no:int:0

Di atas mendeklarasikan node yang namanya [.no], nilainya 0, dan deklarasi tipenya adalah int, menyiratkan tipe int dari .Net 6. Ada berbagai macam tipe di Hyperlambda, dan Anda dapat melihat sebagian besar di bawah ini, dan bagaimana peta tersebut dipetakan ke tipe namespace .Net 6 System.

  • string = Sistem.String
  • pendek = System.Int16
  • ushort = Sistem.UInt16
  • int = Sistem.Int32
  • uint = Sistem.UInt32
  • panjang = System.Int64
  • ulong = Sistem.UInt64
  • desimal = Sistem.Desimal
  • ganda = Sistem.Ganda
  • tunggal = Sistem.Float
  • float = System.Float — Alias ​​untuk di atas
  • bool = Sistem.Boolean
  • tanggal = Sistem.TanggalWaktu
  • waktu = Sistem.Span Waktu
  • panduan = Sistem.Panduan
  • char = Sistem.Char
  • byte = Sistem.Byte
  • x = sihir.node.ekstensi.Ekspresi
  • simpul = sihir.node.Node

Hal ini memungkinkan Anda untuk misalnya mendeklarasikan boolean seperti yang diilustrasikan di bawah ini.

.source:bool:true
.result
if
   get-value:x:@.source
   .lambda
      set-value:x:@.result
         .:yup!
else
   set-value:x:@.result
      .:nope!

Di atas adalah pernyataan if/else sederhana yang mengatur nilai node [.result] sesuai dengan nilai node [.source]. Jika Anda menjalankannya di evaluator Magic, Anda akan melihat sesuatu seperti berikut.

Ekspresi Lambda

Bagian terakhir dari teka-teki yang sekarang tersisa untuk Anda pahami sebelum Anda mengetahui semua yang perlu Anda ketahui tentang Hyperlambda adalah “ekspresi lambda”. Ekspresi Lambda untuk objek lambda sama dengan penyeleksi jQuery atau DOM untuk JavaScript Anda. Mereka memungkinkan Anda untuk mereferensikan kumpulan simpul dalam kode DOM Anda, untuk kemudian menggunakan ekspresi seperti argumen ke slot, yang menggunakan ekspresi ini untuk mengubah kode DOM Anda. Ekspresi lambda sangat mudah dipahami, dan faktanya ini hanyalah daftar enumerable, yang dirangkai bersama, yang hasil gabungannya menghasilkan satu atau lebih node. Di bawah ini adalah contoh penggunaan slot [for-each] untuk melakukan iterasi pada beberapa kumpulan node dan mencatat nilainya.

.data
   item1:Hello from Item1
   item2:Hello from Item2
   item3:Hello from Item3
for-each:x:@.data/*
   log.info:x:@.dp/#

Ekspresi pertama di atas dapat ditemukan di node [untuk-setiap] kami, dan adalah sebagai berikut @.data/*. Ungkapan ini pada dasarnya mengatakan sebagai berikut.

Temukan node pertama ke atas yang bernama “.data”, lalu kembalikan semua node turunannya

Mungkin membantu untuk menyadari pada titik ini bahwa sebuah ekspresi memiliki “iterator”, dan setiap iterator dipisahkan dengan iterator sebelumnya dengan karakter /. Oleh karena itu ekspresi ini memiliki dua iterator, satu dimulai dengan karakter @, menyiratkan 'temukan node pertama yang bernama xxx', dengan 'xxx' adalah apa pun yang mengikuti karakter @. Iterator berikutnya adalah iterator * yang pada dasarnya mengatakan 'berikan saya semua node anak dari node yang dihasilkan oleh iterator sebelumnya'.

Bagian dalam dari loop [for-each] lagi, adalah bahwa ia akan memanggil anak-anaknya sebagai objek lambda, satu kali untuk setiap node yang dihasilkan dari ekspresinya — Dan ketika ia memanggil anak-anaknya, ia akan menyuntikkan sebuah simpul [.dp] yang menyiratkan “penunjuk data”, yang memungkinkan objek lambda di dalam perulangan for-each mengakses simpul yang sedang diiterasi dengan referensi.

Bagian terakhir sangat penting untuk dipahami, karena perulangan [for-each] memungkinkan objek lambdanya memodifikasi node yang diiterasi, karena node diteruskan dengan referensi, menyiratkan “ semantik penunjuk”. Inilah mengapa kita perlu menggunakan iterator # yang aneh di dalam loop [for-each] kita untuk mengambil nilai dari node yang sedang diiterasi dengan referensi, karena node yang kita iterasi di dalam kita [for-each] dapat ditemukan di nilai dari node [.dp] itu sendiri.

Terdapat berbagai macam iterator berbeda di Hyperlambda, dan Anda dapat menemukan sebagian besarnya di bawah.

  • * Mengambil semua anak dari hasil sebelumnya
  • # Mengambil nilai hasil sebelumnya sebagai node dengan referensi
  • - Mengambil "adik" kumpulan hasil sebelumnya (node ​​sebelumnya)
  • + Mengambil "saudara tertua" dari kumpulan hasil sebelumnya (node ​​berikutnya)
  • . Mengambil node induk kumpulan hasil sebelumnya
  • .. Mengambil simpul akar
  • ** Mengambil turunan kumpulan hasil sebelumnya, dengan algoritma “breadth first”.
  • {x} Ekspresi yang diekstrapolasi yang akan dievaluasi dengan asumsi menghasilkan satu hasil, menggantikan dirinya sendiri dengan nilai dari node mana pun yang ditunjuknya
  • =xxx Mengambil node dengan nilai “xxx”, mengubahnya menjadi string jika perlu
  • [n,n] Mengambil subset dari kumpulan hasil sebelumnya, menyiratkan arti “dari, ke” [n1,n2›
  • @xxx Mengembalikan node pertama “sebelum” dalam hierarkinya yang cocok dengan “xxx” yang diberikan dalam namanya
  • n (nomor berapa pun) Mengembalikan anak ke-n dari kumpulan hasil sebelumnya

Membungkus

Jika kepala Anda sakit sekarang, sadarilah bahwa hal itu akan menjadi lebih mudah mulai saat ini dan seterusnya. Ekspresi Lambda mungkin merupakan subjek paling kompleks yang ada di Hyperlambda, karena memerlukan keterampilan visualisasi yang hebat dalam pikiran Anda untuk berimajinasi. Namun, pada dasarnya, keduanya sama dengan penyeleksi DOM dari HTML atau ekspresi XPath dari XML.

Namun, apakah Anda memperhatikan bahwa kita sekarang telah membahas seluruh bahasa pemrograman yang disebut Hyperlambda, setidaknya bagian intinya, dan kita tidak pernah membicarakan variabel, bahkan sekali? Itulah intinya, karena semuanya adalah variabel di Hyperlambda, itulah alasan mengapa Hyperlambda dapat memperlakukan kode seperti data, dan memodifikasinya, sama seperti kode tradisional (hanya) dapat memanipulasi data.

Untuk kode Hyperlambda adalah sebuah variabel, yang secara semantik dapat dilintasi, diubah, dan dimutasi menjadi sesuatu yang lain, itulah inti dari Hyperlambda, dan mengapa komputer dapat membuat kode secara dinamis, dengan cara yang bahkan secara teori tidak dapat Anda capai dalam bahasa pemrograman lain. .

Hyperlambda tidak diciptakan untuk Anda pahami, ia diciptakan agar KOMPUTER Anda memahami …

"Baca selengkapnya"