Paren - это диалект языка Лисп. Он спроектирован как встроенный язык.
1;;; Комментарии
2# комментарии
3
4;; Однострочные комментарии начинаются с точки с запятой или символа решетки
5
6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7;; 1. Примитивные типы данных и операторы
8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9
10;;; Числа
11123 ; int
123.14 ; double
136.02e+23 ; double
14(int 3.14) ; => 3 : int
15(double 123) ; => 123 : double
16
17;; Обращение к функции записывается так: (f x y z ...),
18;; где f - функция, а x, y, z, ... - операнды
19;; Если вы хотите создать буквальный список данных, используйте (quote), чтобы
20;; предотвратить ненужные вычисления
21(quote (+ 1 2)) ; => (+ 1 2)
22;; Итак, некоторые арифметические операции
23(+ 1 1) ; => 2
24(- 8 1) ; => 7
25(* 10 2) ; => 20
26(^ 2 3) ; => 8
27(/ 5 2) ; => 2
28(% 5 2) ; => 1
29(/ 5.0 2) ; => 2.5
30
31;;; Логический тип
32true ; обозначает истину
33false ; обозначает ложь
34(! true) ; => false
35(&& true false (prn "досюда не доходим")) ; => false
36(|| false true (prn "досюда не доходим")) ; => true
37
38;;; Символы - это числа (int).
39(char-at "A" 0) ; => 65
40(chr 65) ; => "A"
41
42;;; Строки - это массив символов с фиксированной длиной.
43"Привет, мир!"
44"Benjamin \"Bugsy\" Siegel" ; обратная косая черта экранирует символ
45"Foo\tbar\r\n" ; включает управляющие символы в стиле Cи: \t \r \n
46
47;; Строки тоже могут объединяться!
48(strcat "Привет " "мир!") ; => "Привет мир!"
49
50;; Строка может трактоваться подобно списку символов
51(char-at "Apple" 0) ; => 65
52
53;; Выводить информацию достаточно легко
54(pr "Я" "Paren. ") (prn "Приятно познакомиться!")
55
56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
57;; 2. Переменные
58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
59;; Вы можете создать или инициализировать переменную, используя (set)
60;; имя переменной может содержать любой символ, исключая: ();#"
61(set some-var 5) ; => 5
62some-var ; => 5
63
64;; Обращение к переменной, прежде не определенной, вызовет исключение
65; x ; => Неизвестная переменная: x : nil
66
67;; Локальное связывание: Используйте лямбда-вычисление! `a' и `b' связывается
68;; с `1' и `2' только в пределах (fn ...)
69((fn (a b) (+ a b)) 1 2) ; => 3
70
71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
72;; 3. Коллекции
73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
74
75;;; Списки
76
77;; Списки подобны динамическому массиву (vector). (произвольный доступ равен O(1).)
78(cons 1 (cons 2 (cons 3 (list)))) ; => (1 2 3)
79;; `list' - это удобный конструктор списков с переменным числом элементов
80(list 1 2 3) ; => (1 2 3)
81;; и quote может также использоваться для литеральных значений списка
82(quote (+ 1 2)) ; => (+ 1 2)
83
84;; Можно еще использовать `cons', чтобы добавить элемент в начало списка
85(cons 0 (list 1 2 3)) ; => (0 1 2 3)
86
87;; Списки являются основным типом, поэтому для них предусмотрено *много* функций
88;; немного примеров из них:
89(map inc (list 1 2 3)) ; => (2 3 4)
90(filter (fn (x) (== 0 (% x 2))) (list 1 2 3 4)) ; => (2 4)
91(length (list 1 2 3 4)) ; => 4
92
93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
94;; 3. Функции
95;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
96
97;; Используйте `fn' для создания функций.
98;; Функция всегда возвращает значение своего последнего выражения
99(fn () "Привет Мир") ; => (fn () Привет Мир) : fn
100
101;; Используйте скобки, чтобы вызвать все функции, в том числе лямбда-выражение
102((fn () "Привет Мир")) ; => "Привет Мир"
103
104;; Назначить функцию переменной
105(set hello-world (fn () "Привет Мир"))
106(hello-world) ; => "Привет Мир"
107
108;; Вы можете сократить это, используя синтаксический сахар определения функции:
109(defn hello-world2 () "Привет Мир")
110
111;; Как и выше, () - это список аргументов для функции
112(set hello
113 (fn (name)
114 (strcat "Привет " name)))
115(hello "Стив") ; => "Привет Стив"
116
117;; ... или, что эквивалентно, используйте синтаксический сахар определения:
118(defn hello2 (name)
119 (strcat "Привет " name))
120
121;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
122;; 4. Равенство
123;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
124
125;; для чисел используйте `=='
126(== 3 3.0) ; => true
127(== 2 1) ; => false
128
129;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
130;; 5. Поток управления
131;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
132
133;;; Условный оператор
134
135(if true ; проверка выражения
136 "это - истина" ; тогда это выражение
137 "это - ложь") ; иначе другое выражение
138; => "это - истина"
139
140;;; Циклы
141
142;; Цикл for для чисел
143;; (for ИДЕНТИФИКАТОР НАЧАЛО КОНЕЦ ШАГ ВЫРАЖЕНИЕ ..)
144(for i 0 10 2 (pr i "")) ; => печатает 0 2 4 6 8 10
145(for i 0.0 10 2.5 (pr i "")) ; => печатает 0 2.5 5 7.5 10
146
147;; Цикл while
148((fn (i)
149 (while (< i 10)
150 (pr i)
151 (++ i))) 0) ; => печатает 0123456789
152
153;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
154;; 6. Изменение
155;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
156
157;; Используйте `set', чтобы назначить новое значение переменной или памяти
158(set n 5) ; => 5
159(set n (inc n)) ; => 6
160n ; => 6
161(set a (list 1 2)) ; => (1 2)
162(set (nth 0 a) 3) ; => 3
163a ; => (3 2)
164
165;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
166;; 7. Макросы
167;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
168
169;; Макросы позволяют вам расширять синтаксис языка.
170;; Paren-макросы легкие.
171;; Фактически, (defn) - это макрос.
172(defmacro setfn (name ...) (set name (fn ...)))
173(defmacro defn (name ...) (def name (fn ...)))
174
175;; Давайте добавим инфиксную нотацию
176(defmacro infix (a op ...) (op a ...))
177(infix 1 + 2 (infix 3 * 4)) ; => 15
178
179;; Макросы приводят к неясному коду, т.е. вы можете затереть существующие переменные!
180;; Они являются кодопреобразующей конструкцией.