Setiap programmer memiliki impian - untuk membuat bahasa pemrograman sendiri. Yang terbaik dan paling nyaman, tentu saja - tidak seperti yang sudah ada. Bagi saya pribadi, ide untuk memperbaikinya adalah menciptakan sebuah bahasa yang sama sekali tidak akan ada boilerplate, yang akan sesingkat mungkin, tetapi sangat fasih. Selama dua tahun saya telah berusaha untuk mencapai hasil yang diinginkan, tetapi di mana pun saya memulai, pada akhirnya, setelah memotong semua yang berlebihan, saya selalu mendapat Lisp. Dan kemudian sebuah pemikiran cerdik muncul pada saya - untuk mengambil Lisp, dan memperbaikinya sesuai dengan ide-ide saya. Untuk menghormati hal pertama yang menarik perhatian saya, proyek itu bernama Sova.
Untuk membuat bahasa di luar kotak berfungsi di server, di web, dan pada platform seluler, saya memutuskan untuk mengompilasinya dalam Javascript, yang, menurut pendapat saya, hanya salah satu bahasa yang dirancang terbaik saat ini, dan yang lebih penting, memiliki ekosistem npm yang kuat, Node.js, Bereaksi dan Bereaksi Asli.
Dan sebelum memulai perjalanan kami, untuk segera membangkitkan minat untuk membaca lebih lanjut artikel ini, berikut adalah contoh dari satu file aplikasi Express di Sova:
=-> './database' database =-> 'express' express = application express () application.get '/' -> (request response) (response.sendStatus 200) application.get '/user/:id' -> (request response) (response.send (database.getUserById request.params.id)) application.listen 8080 -> () (console.log 'Application is listening on port 8080')
Baiklah, mari kita mulai ...
Langkah 1: Menarik keluar tanda kurung dari Lisp menggunakan indentasi Python

Meskipun buku komik ini membuat saya tersenyum setiap kali saya melihatnya, saya sepenuhnya tidak setuju dengan pernyataan utamanya. Kurung tidak elegan, kurung adalah boilerplate.
Oleh karena itu, hal pertama dalam bahasa saya yang luar biasa, saya memutuskan untuk menyingkirkan tanda kurung. Solusi terbaik adalah lekukan yang relevan, seperti di Python. Ambil, misalnya, sepotong kode lisp:
(* 2 (+ 1 2) (- 4 (/ 2 1)))
Tentu saja, ungkapan ini dapat tersebar dalam garis yang berbeda, tetapi ini tidak membebaskan kita dari clowning dari mata yang menyumbat.
(* 2 (+ 1 2) (- 4 (/ 2 1)))
Sekarang mari kita lihat bagaimana elegan dan lapang mungkin untuk menulis ungkapan yang sama di Sova dengan bantuan lekukan yang signifikan:
* 2 + 1 2 - 4 (/ 2 1)
Artinya, dalam Sova, ekspresi a (bc) (d (ef))
setara dengan ungkapan:
a bc d ef
Langkah 2: buat bahasa ringkas
Apa yang saya tidak suka di sebagian besar bahasa pemrograman adalah penyumbatan sintaks dengan tidak ada yang berarti, tetapi mengambil tempat di layar dengan boilerplate - kata kunci tambahan, tanda baca yang tidak berarti dan banyak lainnya. Bahkan dalam bahasa umum, alih-alih karakter yang sederhana dan dapat dimengerti, kata-kata sering digunakan untuk menunjukkan operasi sederhana, seperti defn
sama.
Deklarasi Konstanta
Ambil contoh deklarasi konstanta dalam Javascript:
const a = 1
Sova adalah bahasa yang sangat fungsional dan semua variabel tidak berubah di dalamnya, jadi Anda tidak perlu menentukan kata kunci tambahan, tetapi semuanya ditulis sederhana:
= a 1
Fungsi
Elemen inti dari setiap bahasa adalah fungsi. Sangat minimalis mereka terlihat di Sova:
= addOne -> number + number 1 = doubleAndAddOne -> number = doubled (* number 2) addOne doubled console.log (doubleAndAddOne 2)
Seperti dalam bahasa fungsional apa pun, ekspresi terakhir di tubuh fungsi dapat dikembalikan. Artinya, kode di atas dalam JavaScript yang dikompilasi akan terlihat seperti:
const addOne = number => { return number + 1 } const doubleAndAddOne = number => { const doubled = number * 2 return addOne(doubled) } console.log(doubleAndAddOne(2))
Perbandingan dan kondisi
Ekspresi bersyarat dalam Sova dapat memiliki dua atau satu argumen.
Berikut adalah contoh kondisi yang memiliki dua argumen:
console.log ? true 1 0 console.log ? (> 2 1) 'Greater' 'Less' console.log ? (> 2 1) ? (> 1 2) 'x' 'y' 'z'
Dan di sini, misalnya, dalam fungsi checkNumber, kami mengembalikan nilai berdasarkan kondisi:
= checkNumber -> number ? (=== number 1) (<- 'One') ? (=== number 2) (<- 'Two') ? (<= number 9) (<- 'From three to nine') 'Ten or more' console.log (checkNumber 1) console.log (checkNumber 4) console.log (checkNumber 11)
Dalam JavaScipt yang dikompilasi, sepertinya:
const checkNumber = number => { if (number === 1) return 'One' if (number === 2) return 'Two' if (number <= 9) return 'From three to nine' return 'Ten or more' } console.log(checkNumber(1)) console.log(checkNumber(4)) console.log(checkNumber(11))
Koleksi
Array
Koleksi utama bahasa apa pun adalah array. Ini adalah bagaimana deklarasi dan dekonstruksi array terlihat di Sova:
= list | 1 2 3 4 console.log list console.log list.map (-> x (+ x 1)) = (| first second) list console.log first console.log second
Dalam JavaScript yang dikompilasi, akan terlihat seperti:
const list = [1, 2, 3, 4] console.log(list) console.log(list.map(x => x + 1)) const [first, second] = list console.log(first) console.log(second)
Obyek
Koleksi terpenting kedua adalah hashmap. Di Sova, pengumuman dan dekonstruksi peta terlihat seperti ini:
= map : a 1 b 2 c : d 3 e 4 f 'Hello' console.log map = (: a (c (: de))) map console.log a console.log d console.log e
Dalam JavaScript yang dikompilasi, tampilannya seperti ini:
const map = { a: 1, b: 2, c: { d: 3, e: 4 }, f: 'Hello' } console.log(map) const { a, c: { d, e }} = map console.log(a) console.log(d) console.log(e)
Jika kita ingin memanggil metode pada objek, maka ada dua cara untuk melakukan ini. Kita dapat menyebutnya sebagai object.method parameter1 parameter2
atau sebagai .method object parameter1 parameter2
. Metode kedua memungkinkan kita untuk membuat rantai panggilan metode.
Impor dan ekspor modul
Impor
Anda dapat mengimpor modul ke dalam kode Sova dari file .sv
lainnya dan juga dari file .js
. Sebagai contoh, dalam contoh ini, dua modul diimpor - data/index.js
dan handler/index.sv
:
=-> './data' (: greeting name) =-> './handler' handle handle greeting name
Dalam JavaScript yang dikompilasi, tampilannya seperti ini:
const { greeting, name } = require('./data') const handle = require('./handler') handle(greeting, name)
Mengimpor modul JavaScript dan Sova memungkinkan untuk sedikit mengintegrasikan Sova ke dalam proyek Javascript yang ada.
Ekspor
Dalam contoh ini, fungsi diekspor dari modul:
<-= -> (greeting name) console.log greeting console.log name
Dalam JavaScript yang dikompilasi, tampilannya seperti ini:
module.exports = (greeting, name) => { console.log(greeting) console.log(name) }
Contoh Penggunaan
Untuk melihat semua keindahan, kelapangan dan keringkasan Sova, Anda perlu melihat program yang kurang lebih besar. Sebagai contoh, berikut adalah program yang menghitung usia rata-rata orang dan menemukan nama orang yang usianya paling dekat dengan usia rata-rata.
=-> 'lodash' _ = people | : (name 'Alice') (age 24) : (name 'Bob') (age 15) : (name 'Chris') (age 46) : (name 'Daniel') (age 35) : (name 'Elisabeth') (age 29) : (name 'Fred') (age 52) = averageAge / .reduce (.map people (-> man man.age)) -> (xy) (+ xy) 0 .length people = manWithClosestToAverageAge _.minBy .map people (-> man (: (name man.name) (distance (Math.abs (- averageAge man.age))))) 'distance' console.log averageAge console.log manWithClosestToAverageAge.name
Karena fakta bahwa bahasa dikompilasi dalam JavaScript, pengembangan untuk platform apa pun menjadi mungkin. Misalnya, berikut adalah contoh kecil aplikasi Bereaksi untuk browser web:
=-> 'react' React =-> 'react-dom' ReactDOM =-> './styles' styles = (: createElement:e) React = App -> ((: name)) e 'div' (: (style styles.container)) e 'div' (: (style styles.hello)) 'Hello' e 'div' (: (style styles.name)) name ReactDOM.render (e App (: (name 'John'))) (document.getElementById 'root')
Juga di repositori ada contoh server Express dan Bereaksi aplikasi asli untuk platform mobile.
Kesimpulan
Dengan demikian, Sova menggabungkan yang terbaik dari beberapa bahasa lain:
- kesederhanaan dan kekuatan Lisp
- Lekukan python bersih
- runtime dan ekosistem JavaScript
Kode kompiler dengan contoh-contoh penggunaan bahasa terletak di sini https://github.com/sergeyshpadyrev/sova . Saya akan senang melihat bintang-bintang di repositori dari semua orang yang menyukai konsep bahasa dan yang ingin terus mengerjakannya. Tetapi saya akan segera memperingatkan Anda bahwa untuk sementara ini ini hanya bukti konsep, dan bahkan bermain dengan bahasa karena kurangnya dokumentasi dan beberapa fitur sangat sulit. Misalnya, bahasa belum memiliki penanganan penanganan, kelas, dan hal-hal lain yang diperlukan. Dan menjalankan Windows tidak mungkin berhasil.
Dalam langkah-langkah berikut, saya berencana untuk menambah dan menstabilkan sintaks, menulis ulang parser, menulis tes untuk parser dan penerjemah, menulis dokumentasi. Sementara itu, terima kasih atas perhatian Anda dan sampai jumpa lagi.