Так я и сделал в новогоднюю ночь...

Я только что приехал к другу, и мне стало скучно за узкий отрезок времени. Я решил вернуться к себе, взять свой ноутбук и вернуться. Мне потребовалось около 40 минут, чтобы добраться из одного места в другое и обратно.

Вернувшись, я надел шумоподавляющие наушники и взял то, что давно хотел, Элм. Следующие час или два я потратил на его настройку (я использовал npm, но есть и другие методы, перечисленные здесь) и изучение базового синтаксиса. Это оказалось довольно весело, и позвольте мне показать вам, почему:

Если у вас есть Elm, вы можете попробовать продолжить или просто просмотреть краткий обзор. Я сделаю все возможное, чтобы сравнить его с JS, просто чтобы лучше понять его :D

Ценности

Довольно прямолинейно.

Строки всегда заключаются в двойные кавычки, а конкатенация выполняется с помощью двух знаков плюс (++).

-- Elm, also this is a single line comment
> "Hello" ++ " World!"
"Hello World!
// JS
> "Hello" + " World!"
"Hello World"
// Extra tip - you can start a code block with ```

Числа

В отличие от JS, Elm различает целое число (4) и число с плавающей запятой (4.0). Отсюда два типа деления: деление с плавающей запятой (/) и целочисленное деление (//).

-- Floating point division
> 9 / 2
4.5

-- Integer division
> 9 // 2
4

Функции

Теперь я согласен, функции выглядят немного странно, но позвольте мне объяснить, как они работают на этом примере:

-- Elm
> isNegative n = n < 0
> isNegative 4
False

// JS equivalent
function isNegative(n){return n < 0}
isNegative(4)
false

Elm в основном заменяет скобки пробелами.

Позвольте мне показать вам пример с аргументами 1‹

{- Elm, from now on assume everything starting with "<" is an elm statement or whatever; this is a multi-line comment -}
> combine a b = a + b
> combine 3 9
12
// JS
function combine(a, b){return a + b}
combine(3,9)
12

Условия

Теперь давайте подключим условное выражение к функции:

-- I'll skip else if, same syntax as if
>seenGoT answer = \
  if answer == "yes" then "okay" else "Well why not???"
>seenGoT "yes"
"okay"
>seenGoT "nope"
"Well why not???"
// JS
function seenGoT(answer){
  if (answer == "yes") return "okay"
  else return "Well why not???"
}
seenGot("yes")
"okay"

Списки

Аналогичен массивам JS, номожет содержать только 1 тип данных.

> names = ["Alice", "Bob", "Chloe"]
["Alice", "Bob", "Chloe"]
// JS
let names = ["Alice", "Bob", "Chloe"]

Мы можем рассмотреть некоторые примеры методов в следующий раз.

Кортежи

Кортежи могут содержать фиксированное количество значений, где каждое значение может быть любого типа (обычно используется при возврате более 1 значения из функции)

> barEntry age = \
  if age >= 18 then \
    (True, "Access Granted") \
  else \
    (False, "Access Denied")
>barEntry 19
(True, "Access Granted") : ( Bool, String )
// JS
/* There are better examples, but both of these can return multiple values */
function barEntry(age) {
  if (age >= 18) return [true, 'Access Granted'];
  else return [false, 'Access Denied']
}

Кортежи — это не то же самое, что массивы. Чтобы этот разглагольствование было коротким, я пропущу их и вместо этого дам ссылку на это.

Записи

Подобно объектам JS, с парой отличий, а именно:

  1. Вы не можете запросить поле, которого не существует
  2. Ни одно поле никогда не будет неопределенным или нулевым
  3. Вы не можете создавать рекурсивные записи с ключевыми словами this или self.
> person = { name = "Elon Musk", age = 46 }
> person.name
"Elon Musk"
{- there is also this weird way of accessing a record that works like a function -}
> .age person
46
// JS
person = {name: 'Elon Musk', age: 46}
person.name
"Elon Musk"

Вы также можете использовать записи с такими функциями:

over18 {age} = age > 18
over18 person
True : Bool

Обновить значения в записи

> { person | name = "Richard Stallman" }
{ name = "Richard Stallman", age = 46 }
> { person | age = 64 }
{ name = "Elon Musk", age = 64 }

Я думаю, что этого достаточно для первого дня.

До встречи в следующий раз :)