nim.md

Личный сайт Go-разработчика из Казани

Nim (ранее известный, как Nimrod) — язык программирования со статической типизацией, поддерживающий процедурный, объектно-ориентированный, функциональный и обобщённый стили программирования.

Nim эффективный, выразительный и элегантный.

1var # Объявление (и присваивание) переменных, 2 буква: char = 'n' # с указанием типа или без 3 язык = "N" & "im" 4 nLength : int = len(язык) 5 boat: float 6 правда: bool = false 7 8let # Используйте let *сразу* для объявления и связывания переменных. 9 ноги = 400 # ноги неизменяемый. 10 руки = 2_000 # Символ _ игнорируется и удобен для длинных чисел. 11 почтиПи = 3.15 12 13const # Константы вычисляются во время компиляции. Это обеспечивает 14 debug = true # производительность и полезно в выражениях этапа компиляции. 15 компилироватьПлохойКод = false 16 17when компилироватьПлохойКод: # `when` это `if` этапа компиляции. 18 ноги = ноги + 1 # Эта ошибка никогда не будет скомпилирована. 19 const ввод = readline(stdin) # Значения констант должны быть известны во 20 # время компиляции. 21 22discard 1 > 2 # Примечание. Компилятор будет жаловаться, если результат 23 # выражения не используется. `discard` обходит это. 24 25discard """ 26Это может использоваться как многострочный комментарий. 27Или для не поддающегося синтаксическому анализу, сломанного кода 28""" 29 30# 31# Структуры данных 32# 33 34# Кортежи 35 36var 37 дитя: tuple[имя: string, возраст: int] # Кортежи определяют *как* имя поля 38 сегодня: tuple[солнце: string, температура: float] # так *и* порядок полей. 39 40дитя = (имя: "Rudiger", возраст: 2) # Присвоить все сразу литералом () 41сегодня.солнце = "Пасмурно" # или отдельно по полям. 42сегодня.температура = 20.1 43 44# Последовательности 45 46var 47 напитки: seq[string] 48 49напитки = @["Вода", "Сок", "Какао"] # @[V1,..,Vn] является литералом 50 # последовательности 51 52напитки.add("Молоко") 53 54if "Молоко" in напитки: 55 echo "У нас тут Молоко и ещё", напитки.len - 1, " напиток(ов)" 56 57let мойНапиток = напитки[2] 58 59# 60# Определение типов 61# 62 63# Определение собственных типов позволяет компилятору работать на вас. 64# Это то, что делает статическую типизацию мощной и полезной. 65 66type 67 Имя = string # Псевдоним типа дает вам новый тип, который равнозначен 68 Возраст = int # старому типу, но более нагляден. 69 Человек = tuple[имя: Имя, возраст: Возраст] # Определение структур данных. 70 АльтернативныйСинтаксис = tuple 71 fieldOne: string 72 secondField: int 73 74var 75 джон: Человек = (имя: "John B.", возраст: 17) 76 новыйВозраст: int = 18 # Было бы лучше использовать Возраст, чем int 77 78джон.возраст = новыйВозраст # Но это все же работает, потому что int и Возраст синонимы. 79 80type 81 Нал = distinct int # `distinct` делает новый тип несовместимым с его 82 Описание = distinct string # базовым типом. 83 84var 85 money: Нал = 100.Нал # `.Нал` преобразует int в наш тип 86 описание: Описание = "Interesting".Описание 87 88when компилироватьПлохойКод: 89 джон.возраст = money # Error! возраст is of type int and money is Нал 90 джон.имя = описание # Компилятор говорит: "Нельзя!" 91 92# 93# Дополнительные типы и структуры данных 94# 95 96# Перечисления позволяют типу иметь одно из ограниченного числа значений 97 98type 99 Цвет = enum цКрасный, цГолубой, цЗеленый 100 Направление = enum # Альтернативный формат 101 нСевер 102 нЗапад 103 нВосток 104 нЮг 105var 106 напр = нСевер # `напр` имеет тип Направление, со значением `нСевер` 107 точка = цЗеленый # `точка` имеет тип Цвет, со значением `цЗеленый` 108 109discard нСевер > нВосток # Перечисления обычно являются "порядковыми" типами 110 111# Поддиапазоны определяют ограниченный допустимый диапазон 112 113type 114 Кости = range[1..20] # 🎲 Допустимым значением являются только int от 1 до 20 115var 116 мой_бросок: Кости = 13 117 118when компилироватьПлохойКод: 119 мой_бросок = 23 # Error! 120 121# Массивы 122 123type 124 СчетчикБросков = array[Кости, int] # Массивы фиксированной длины и 125 ИменаНаправлений = array[Направление, string] # индексируются любым порядковым типом. 126 Истины = array[42..44, bool] 127var 128 счетчик: СчетчикБросков 129 направления: ИменаНаправлений 130 возможны: Истины 131 132возможны = [false, false, false] # Массивы создаются литералом [V1,..,Vn] 133возможны[42] = true 134 135направления[нСевер] = "ОО. Великий белый Север!" 136направления[нЗапад] = "Нет, не иди туда." 137 138мой_бросок = 13 139счетчик[мой_бросок] += 1 140счетчик[мой_бросок] += 1 141 142var ещеМассив = ["Идекс по умолчанию", "начинается с", "0"] 143 144# Доступны другие структуры данных, в том числе таблицы, множества, 145# списки, очереди и crit-bit деревья. 146# http://nim-lang.org/docs/lib.html#collections-and-algorithms (EN) 147 148# 149# IO и поток управления выполнением 150# 151 152# `case`, `readLine()` 153 154echo "Читали какие-нибудь хорошие книги в последнее время?" 155 156case readLine(stdin) 157of "нет", "Нет": 158 echo "Пойдите в свою местную библиотеку." 159of "да", "Да": 160 echo "Тогда продолжим" 161else: 162 echo "Здорово!" 163 164# `while`, `if`, `continue`, `break` 165 166import strutils as str # http://nim-lang.org/docs/strutils.html (EN) 167echo "Я загадало число между 41 и 43. Отгадай!" 168let число: int = 42 169var 170 ввод_догадка: string 171 догадка: int 172 173while догадка != число: 174 ввод_догадка = readLine(stdin) 175 176 if ввод_догадка == "": continue # Пропустить эту итерацию 177 178 догадка = str.parseInt(ввод_догадка) 179 180 if догадка == 1001: 181 echo("AAAAAAGGG!") 182 break 183 elif догадка > число: 184 echo("Неа. Слишком большое.") 185 elif догадка < число: 186 echo(догадка, " это слишком мало") 187 else: 188 echo("Точнооооо!") 189 190# 191# Итерации (циклы) 192# 193 194for i, элем in ["Да", "Нет", "Может быть"]: # Или просто `for элем in` 195 echo(элем, " по индексу: ", i) 196 197for ключ, значение in items(@[(человек: "You", сила: 100), (человек: "Me", сила: 9000)]): 198 echo значение 199 200let мояСтрока = """ 201<пример> 202`строки` для 203тренировки 204""" # Многострочная "сырая" строка 205 206for строка in splitLines(мояСтрока): 207 echo(строка) 208 209for i, симв in мояСтрока: # Индекс и символ. Или `for j in` только для символов 210 if i mod 2 == 0: continue # Компактная форма `if` 211 elif симв == 'X': break 212 else: echo(симв) 213 214# 215# Процедуры 216# 217 218type Ответ = enum оДа, оНет 219 220proc спрос(вопрос: string): Ответ = 221 echo(вопрос, " (д/н)") 222 while true: 223 case readLine(stdin) 224 of "д", "Д", "да", "Да": 225 return Ответ.оДа # Перечисления могут быть квалифицированы 226 of "н", "Н", "нет", "Нет": 227 return Ответ.оНет 228 else: echo("Поточнее, да или нет") 229 230proc добавьСахар(количество: int = 2) = # Значение по умолчанию 2, ничего не возвращает 231 assert(количество > 0 and количество < 9000, "Диабет ☠") 232 for a in 1..количество: 233 echo(a, " кубик...") 234 235case спрос("Сахарку?") 236of оДа: 237 добавьСахар(3) 238of оНет: 239 echo "Ну немнооожко!" 240 добавьСахар() 241# Здесь нет необходимости в `else`. Возможны только `да` и `нет`. 242 243# 244# FFI (интерфейс внешних функций) 245# 246 247# Так как Nim компилируется в C, то FFI делается очень просто: 248 249proc strcmp(a, b: cstring): cint {.importc: "strcmp", nodecl.} 250 251let cmp = strcmp("C?", "Легко!")

Кроме того, Nim выделяется среди себе подобных метапрограммированием, производительностью, функциями этапа компиляции.

Дальнейшее чтение (EN)