Лучший в мире язык программирования

    У каждого программиста есть мечта — создать свой язык программирования. Самый лучший и самый удобный, конечно же — не то что существующие. Лично для меня идеей-фикс было создание языка, в котором совершенно не будет бойлерплейта, который будет максимально краток, но при этом чрезвычайно красноречив. В течение двух лет я делал попытки добиться желаемого результата, но с чего бы я не начинал, в конце концов после отсечения всего лишнего у меня всегда получался Lisp. И тогда мне в голову пришла гениальная мысль — взять Lisp, и усовершенствовать его в соответствие с моими идеями. В честь первой попавшейся мне на глаза вещи, проект был назван Sova.


    Чтобы язык из коробки работал и на сервере, и в вебе, и на мобильных платформах я решил сделать компиляцию в Javascript, который по-моему мнению без шуток является одним из лучше всего спроектированных языков нашего времени и что гораздо более важно обладает мощнейшей экосистемой npm, Node.js, React и React Native.


    И перед началом нашего путешествия, чтобы сразу вызвать интерес к дальнейшему прочтению статьи, вот вам пример одного файла Express-приложения на 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')

    Ну что ж, начнем...


    Шаг 1: Вырываем с корнем скобочки из Lisp с помощью индентации Python


    image
    Хоть этот комикс и вызывает у меня улыбку каждый раз, как я на него смотрю, я совершенно не согласен с основным его утверждением. Скобочки — это не элегантно, скобочки — это бойлерплейт.


    Поэтому первым делом в своем чудесном языке я решил избавится от скобочек. Лучшим решением стала имеющая значение индентация, прямо как в Python. Возьмем, к примеру, такой кусок кода на lisp:


    (* 2 (+ 1 2) (- 4 (/ 2 1)))

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


    (* 2
      (+ 1 2)
      (- 4 (/ 2 1)))

    А теперь посмотрим, как элегантно и воздушно можно написать это же выражение на Sova с помощью имеющей значение индентации:


    * 2
      + 1 2
      - 4 (/ 2 1)

    То есть в Sova выражение a (b c) (d (e f)) равнозначно выражению:


    a
      b c
      d
        e f

    Шаг 2: Делаем язык лаконичным


    Что мне не нравилось в большинстве языков программирования, так это засоренность синтаксиса ничего не значащим, но занимающим место на экране бойлерплейтом — лишними ключевыми словами, бессмысленными знаками препинания и многим другим. Даже в common lisp вместо простых и всем понятных символов часто используются слова для обозначения простейших операций, вроде того же defn.


    Объявление констант


    Возьмем к примеру объявление константы в Javascript:


    const a = 1

    Sova — язык исключительно функциональный и в нем все переменные иммутабельны, поэтому не нужно указывать дополнительное ключевое слово const, а пишется все просто:


    = a 1

    Функции


    Основным элементом любого языка являются функции. Вот так минималистично они выглядят в Sova:


    = addOne -> number
      + number 1
    
    = doubleAndAddOne -> number
      = doubled (* number 2)
      addOne doubled
    
    console.log (doubleAndAddOne 2) 

    Как и в любых функциональных языках последнее выражение в теле функции является возвращаемым. То есть код выше в скомпилированном JavaScript будет выглядеть как:


    const addOne = number => {
      return number + 1
    }
    const doubleAndAddOne = number => {
      const doubled = number * 2
      return addOne(doubled)
    }
    console.log(doubleAndAddOne(2))

    Сравнения и условия


    У условного выражения в Sova может быть как два так и один аргумент.
    Вот примеры условий, имеющих два аргумента:


    console.log
      ? true 1 0
    
    console.log
      ? (> 2 1) 'Greater' 'Less'
    
    console.log
      ? (> 2 1)
        ? (> 1 2) 'x' 'y'
        'z'

    А вот тут например в функции checkNumber мы возвращаем значения по условию:


    = 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)

    В скомпилированном JavaScipt это выглядит как:


    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))
    

    Коллекции


    Array


    Основной коллекцией любого языка является массив. Вот так объявление и деконструкция массива выглядят в 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

    В скомпилированном JavaScript это будет выглядеть как:


    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)

    Object


    Второй самой важной коллекцией является хешмапа. В Sova объявление и деконструкция мапы выглядит так:


    = map :
      a 1
      b 2
      c :
        d 3
        e 4
      f 'Hello'
    
    console.log map
    
    = (: a (c (: d e))) map
    
    console.log a
    console.log d
    console.log e

    В скомпилированном JavaScript это выглядит так:


    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)

    Если мы хотим вызвать у объекта метод, то есть два способа это сделать. Мы можем вызвать его как object.method parameter1 parameter2 либо как .method object parameter1 parameter2. Второй способ позволяет нам создавать цепь вызовов методов.


    Импорт и экспорт модулей


    Импорт


    Импортировать в Sova код можно модули как из других .sv файлов, так и из .js файлов. Например, в данном примере, импортируются два модуля — data/index.js и handler/index.sv:


    =-> './data' (: greeting name)
    =-> './handler' handle
    
    handle greeting name

    В скомпилированном JavaScript это выглядит так:


    const { greeting, name } = require('./data')
    const handle = require('./handler')
    handle(greeting, name)

    Импорт как JavaScript, так и Sova модулей дает возможность по чуть-чуть внедрять Sova в существующий Javascript проект.


    Экспорт


    В данном примере, из модуля экспортируется функция:


    <-= -> (greeting name)
      console.log greeting
      console.log name

    В скомпилированном JavaScript это выглядит так:


    module.exports = (greeting, name) => {
        console.log(greeting)
        console.log(name)
    }

    Примеры использования


    Чтобы увидеть всю красоту, воздушность и лаконичность Sova, нужно посмотреть на более менее крупную программу. Например, вот программа вычисляющая средний возраст людей и находящая имя человека, чей возраст наиболее близок к среднему возрасту.


    =-> '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))
        -> (x y) (+ x y)
        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

    Благодаря тому что язык компилируется в JavaScript, становится возможной разработка под любые платформы. Например, вот небольшой пример React-приложения под веб-браузеры:


    =-> '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')

    Так же в репозитории есть примеры Express-сервера и React Native приложения под мобильные платформы.


    Заключение


    Таким образом, язык Sova вобрал в себя лучшее из нескольких других языков:


    • простота и мощь Lisp
    • чистота индентации Python
    • рантайм и экосистема JavaScript

    Код компилятора с примерами использования языка лежит тут https://github.com/sergeyshpadyrev/sova. Буду рад увидеть звезды на репозитории от всех тех, кому понравилась концепция языка и кто хотел бы, чтобы работа над ним продолжилась. Но сразу предупрежу, что пока что это исключительно proof of concept, и даже поиграться с языком из-за отсутствия документации и некоторых возможностей крайне трудно. Например, в языке пока что отсутствует обработка исключений, классы и другие необходимые вещи. И под Windows запустить его вряд ли получится.


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

    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 108

      +14
      *Автор*
      Хочу сделать лаконичный, простой, красноречивый язык
      *Тоже автор*
      ? (=== number 1) (< — 'One')
      <-= -> (greeting name)
      (-> x (+ x 1))


      Ну правда, я чего-то не понимаю, или в какой-то вселенной
      ? (=== number 2) (< — 'Two')
      читается действительно проще и удобнее чем
      if (number === 2) return 'Two'
      ?
        +1
        Есть ещё более читаемые варианты в языках типа ruby
        return 'Two' if number == 2
        return 'Two' if number.eql? 2

        hakell
        fn :: Int -> String -- необязательно
        fn 2 = 'Two'
        fn _ = 'Others'
          +2
          Чем перевёрнутое с ног на голову условие удобнее?
          Если A то B — естественный порядок.
          B если A — странный.
            +1

            Да оба они, на самом деле, "естественны".

              0
              Может буть чуть чуть. Но если развернуть целиком, то такая запись совсем обычная.
              B только если A
                0
                Естественно сначала понять ситуацию, а уже потом действие в ней.
              0

              clojure


              (cond
                  (= n 1) 'One'
                  (= n 2) 'Two'
                  (<= n 9) 'From three to nine'
                  :else 'Ten or more'))</source>
                0

                Заменить :else на T и будет просто Лисп.

                  +1
                  clojure
                  (cond
                      (= n 1) 'One'
                      (= n 2) 'Two'
                      (<= n 9) 'From three to nine'
                      :else 'Ten or more'))
                  


                  В Clojure одиночных кавычек у строк нет (JVM).

                  Good:
                  (cond
                      (= n 1) "One"
                      (= n 2) "Two"
                      (<= n 9) "From three to nine"
                      :else 'Ten or more'))
                  

                  Better:
                  ;; binary predicate
                  ;; для каждого выражения исполняется предикат, тестовое выражение и выражение результат
                  (condp = value
                        1 "one"
                        2 "two"
                        3 "three"
                        (str "unexpected value, \"" value \"))
                  

                  Pro:
                  ;; тестовые константы не исполняются, константы времени компиляции 
                  ;;(compile-time constants - строки, числа, символы, keywords и их композиции)
                  ;; (case 'y
                  ;;      (x y z) "x, y, or z"
                  ;;      "default")
                  ;;=> "x, y, or z"
                  
                  (case n
                    1 "One"
                    2 "Two"
                    "Ten or more")
                  
                    +1

                    А почему у вариантов Better и Pro поведение другое? :)

                      0

                      Прошу прощения, можете уточнить о каком поведении речь? Возможно я где-то ошибся.


                      Поведение этих трех примеров, будет отличаться при других операторах/предикатах, но в случае с "равно" поведение одинаковое.


                      В первом случае выполняются все тестовые выражения целиком, во втором случае принимается бинарный предикат, коим является =, в третьем выполняется constant-time dispatch значения и сравнивается с тестовыми константами.


                      (cond
                          (= n 1) "One"
                          (= n 2) "Two"
                          (= n 9) "From three to nine"
                          :else "Ten or more"))
                      
                      (condp = n
                          1 "One"
                          2 "Two"
                          9 "From three to nine"
                          "Ten or more"))
                      
                      (case n
                          1 "One"
                          2 "Two"
                          9 "From three to nine"
                          "Ten or more"))
                        0

                        Обычно при сравнении разных языковых конструкций хорошим тоном считается, чтобы все они работали одинаково. И да, судя по всему


                        (cond
                            (= n 1) "One"
                            (= n 2) "Two"
                            (<= n 9) "From three to nine"
                            :else "Ten or more"))

                        из первого вашего примера выдаст "One" при n=1, "Two" при n=2, "From three to nine" при n=3...9 и "Ten or more" при n >= 10 (и n < 1 :)
                        Но вот варианты Better и Pro из комментария #20216220 будут работать по-другому. И также у меня есть мнение, что при n=5 все ваши примеры из комментария #20221542 выдадут "Ten or more".

                          0
                          Но вот варианты Better и Pro из комментария #20216220 будут работать по-другому.

                          Признаю свою ошибку в комментарии #20216220, соответственно там эти примеры не работают одинаково.
                          Из-за того что я был невнимателен и принял (<= n 9) за (= n 9). Поэтому и дают другой результат при n=3...9.


                          Поведение этих трех примеров, будет отличаться при других операторах/предикатах, но в случае с "равно" поведение одинаковое.

                          Поэтому я уточнил этот момент в #20221542


                          что при n=5 все ваши примеры из комментария #20221542 выдадут "Ten or more".

                          Да. Так и должно быть. Все три примера дадут одинаковый результат в #20221542. Поскольку ни один из тестов не проходит и результатом будет дефолтное значение.

                0
                Для лисперов обратная польская/префиксная запись проще и очевиднее класической. Это стоит учитывать.
                  0
                  Это обычная запись, если воспринимать оператор как имя функции.
                  const c = +(1, 2);
                  const c = sum(1, 2);

                  То, что там скобки по другому устроены — особенность языка. В Haskell это
                  sum :: Int -> Int -> Int
                  sum a b = (+) a b

                  т.е. целиком фишка языка
                +14
                Работа интересная, придумывать свой ЯП — это всегда здорово и хороший опыт для программиста. Без сарказма.

                Но. Использовать обратную польскую нотацию и утвержать, что язык простой и чистый — попахивает издевательством.

                К тому же на том же Котлине задачу «найти средний возраст записей из списка и найти наиболее близкую к среднему запись» можно решить в три строки, после чего код компилируется хоть под JS, хоть под Джаву, хоть ещё куда.
                  +4
                  Использовать обратную польскую нотацию

                  Это не обратная нотация. Это вполне себе префиксная, как и в Лиспе. В обратной нотации было бы ещё больше ада :)

                    +7
                    Да, точно. Почему-то всегда так получается когда хочется понтануться умным словом в разговоре и забываю перепроверить, что точно помню о чем говорю :(
                  +1
                  = App -> ((: name))
                    e 'div' (: (style styles.container))
                      e 'div' (: (style styles.hello)) 'Hello'
                      e 'div' (: (style styles.name)) name

                  И то же самое в CoffeeScript:


                  App = ({ name }) ->
                    e 'div', style: styles.container, [
                      e 'div', style: styles.hello, 'Hello'
                      e 'div', style: styles.name, name
                    ]
                    +4
                    Если лучший язык в какой-то определённой нише ещё можно найти/создать, то лучший язык в вакууме — нет.
                      +3
                      SergioShpadi, с почином!

                      Но есть несколько замечаний :)

                      Скобки же в Лиспе не от балды. Их смысл как раз таки в том, что любое валидное выражение в Лиспе можно прочесть как программу, а можно как список. Таким образом мы получаем обалденную систему макросов.

                      По-поводу иммутабельности — имеется ввиду иммутабельность значений? Или всего лишь иммутабельность связки символ-значение?
                        0
                        Ссылки. Это `= a 1` компилируется в `const a = 1` Javascript-а.
                          +1

                          А еще скобки легко читать редактору кода, чтобы выполнять текущий блок из любого места, или там скакать к концу-началу. Насколько легко это с индентацией — не понятно.
                          Надеюсь автор сделал скобки опциональными, а не вообще от них отказался.

                          +4
                          У каждого программиста есть мечта — создать свой язык программирования.

                          Ойвей, не надо так за всех.
                          Посмотрел ваши примеры — очень вкусовая наркомания. Не отрицаю, возможно кому-то такое заходит, но с точки зрения длительной разроботки в команде, пожалуй, я выберу что-то более очевидное в плане понимания.
                            0
                            Про JS иногда говорят что это Лисп в шкуре Си

                            JS — это и есть лучший в мире ЯП

                            И я не понимаю, зачем усложнять си-подобный синтаксис?
                            +2
                            Поздравляю с реализацией мечты :)
                            Но язык должен быть читаемым легко и всеми «с ходу», тогда его ждет успех, а не мизерная маргинальная ниша внутри академического сообщества, имхо.
                            Таки возможность самодокументации кода — это супер фишка.
                              0
                              Но язык должен быть читаемым легко и всеми «с ходу»

                              Чудес не бывает.
                                0

                                Прежде всего цель должна быть, которую на этом яп можно достичь проще, быстрее, более понятным способом. Тогда язык займет нишу. Вот, например, скрипты в браузере — js: интерпретируемый с динамической типизацией, прототипный ООП и элементы функциональных языков. Или параллельное программирование на серверной стороне — Go (не люблю его, но т к его все знают — привожу в качестве примера): компилируемый, строгая типизация, поддержка из коробки таких сложных абстракций как CSP. Ну очевидно, что можно писать на js на сервере и наоборот — на go в браузере. Вот только так делают отдельные извращенцы. И в обратную сторону справедливо — если язык "слишком универсален" — в нем есть все и куча лишнего одновременно. И со временем эти фичи ещё и расширяются и вступают в конфликт в конечном итоге. Учитывая количество ЯП сейчас, нет смысла делать новый, если он не решает какую то специфическую задачу, которую его предшественники решают не идеально. Ну только для обучения если.

                                  –2
                                  ну JS сначала таки занял нишу и только потом появились вкусные плюшки, псевдо ООП и функциональщина прочая. А сначала же он был простой, с простым синтаксисом и ява-подобный. То есть читабельный.
                                    +2
                                    ява-подобный

                                    Не смешите меня, где вы там ява-подобность увидели? Вы Java то хоть раз видели?
                                    Разработчики JavaScript просто примазались к популярному в то время бренду.
                                      0
                                      Я на 1.1-1.3 начинал писать и на JS во времена нетскейпа. Уж позвольте не согласиться с Вами :)
                                        0
                                        Из схожего у них только основная часть синтаксиса выражений и управляющих конструкций, что унаследовано ими от C, как и у большинства современных языков, прямо или косвенно. Собственно, на этом сходства и заканчиваются. Конкретно чего-то от Java в JavaScript'е нет и не было.
                                          0
                                          А сначала же он был простой, с простым синтаксисом и ява-подобный. То есть читабельный.

                                          Я ровно тоже самое и написал. Синтаксис на старте был читаемым даже для неподготовленного человека (чего не скажешь например про С). Поэтому в начале нулевых, при поддержке развития интерактивного веба он и выстрелил так хорошо.
                                            +1
                                            Возможно мне не удалось правильно распарсить ваш коммент, слова о простоте не выглядят относящимися к словам о «ява-подобии» :).

                                            читаемым даже для неподготовленного человека

                                            Ну, скорее для тех, кто уже знаком с каким-либо си-подобным языком.
                                +10
                                У каждого программиста есть мечта — создать свой язык программирования.

                                Нет.
                                  0
                                  Пара замечаний.
                                  Lisp без скобочек существует. Называется Wsip.
                                  Кажется, что вы пожертвовали читаемостью ради лаконичности:
                                  <-= -> (greeting name)
                                  Что мешает вместо этого добавить ключевое слово export например?

                                    +1
                                    Мне кажется для этого проекта лучше подходит название Lipthon Script ;)
                                      0
                                      Нет же, LISI — Lots of Irriating Superfluous Indentations ;D
                                      +1
                                      так это засоренность синтаксиса ничего не значащим, но занимающим место на экране бойлерплейтом — лишними ключевыми словами
                                      [...]
                                      = checkNumber -> number
                                      ? (=== number 1) (<- 'One')
                                      ? (=== number 2) (<- 'Two')
                                      ? (<= number 9) (<- 'From three to nine')
                                      'Ten or more'

                                      Ну и зачем в этом примере слово number четыре раза?


                                      let checkNumber = function 
                                      | 1 -> "One"
                                      | 2 -> "Two"
                                      | x when x > 2 && x <= 9 -> "From three to nine"
                                      | _ -> "Ten or more"

                                      (и немедленно получаем warning "значения от нуля и вниз не покрыты")


                                      Ну и да, говорить о "лучшем в мире языке программирования" и вообще не упомянуть типизацию?

                                        –14
                                        Все верно. Типизация не делает код лучше, но сильно замедляет разработку. На языках с динамической типизацией разработка идет в разы быстрее.

                                        Я сам получил прививку от любви к типам поработав некоторое время со Scala. Сначала мне это нравилось, но в конце концов я понял, что большую часть времени занимаюсь не разработкой, а ублажением компилятора.
                                          +5
                                          Типизация не делает код лучше

                                          Пожалуйста, остановитесь. Такие заявления должны же строиться на чем-то большем, чем просто заявления.

                                          Замедляет разработку отсутствие прямоты рук у разработчика. А типизация, например, ускоряет отладку (аж на этапе компиляции) и упрощает дальнейшую поддержку. Но это все например, я не буду утверждать, что делает код лучше и или хуже — это все субъективщина.

                                          Я так понимаю, разработка идет быстрее, потому что компилятор даст вам по рукам за ошибки в коде. Это безусловно, влияет на скорость разработки.
                                          Только, я надеюсь, вам известно, зачем же все таки введены такие ограничения и чем типизация и компиляция полезна и отличается от динамических интерпретируемых языков?
                                            –10
                                            Никакой корреляции между статической типизацией и количеством багов нет. Вот советую почитать хороший пост на эту тему (https://ru.hexlet.io/blog/posts/the-broken-promise-of-static-typing)

                                            Про ускорение отладки это смешно, учитывая что в лиспоподобных языках, да и многих динамических есть REPL. Но большинство не используют его, потому что проще просто перезапустить код и сразу увидеть изменение без всякой перекомпиляции.
                                              –1
                                              Пожалуйста, остановитесь. Такие заявления должны же строиться на чем-то большем, чем просто заявления.

                                              Ну, вообще-то бремя доказательство тут, наоборот, лежит на доказывании утверждения пользы типизации. И — увы! — несмотря на десятки лет исследований надёжности ПО, польза типизации не доказана. Есть практики с доказанной пользой: такие как код-ревью и тесты. Типизация к ним не относится.


                                              А типизация, например, ускоряет отладку (аж на этапе компиляции) и упрощает дальнейшую поддержку.

                                              Вот это как раз и требуется доказать. Ещё никто не смог привести подтверждающие цифры. С учётом того, что всё это происходит после многих часов ублажения компилятора, польза весьма сомнительна и не превышает накладных расходов.

                                                +3
                                                Типизация есть во всех языках, вопрос про статическую и динамическую вариацию. Так что наброс не засчитан.
                                                Ублажения компилятора происходят у тех, кто не знаком со стандартом языка.
                                                  –6
                                                  1. Шланг засчитан.
                                                  2. Как только вы начнёте писать программу посложнее Hello World с динамическими структурами и рекурсией, вы быстро обнаружите, что типами это описать это очень сложно, если не невозможно. Известный факт, что некоторые подходы ФП не описываются статической типизацией.
                                                    +2
                                                    Как только вы начнёте писать программу посложнее Hello World с динамическими структурами и рекурсией, вы быстро обнаружите, что типами это описать это очень сложно

                                                    Ну писал я сложные программы с "динамическими структурами и рекурсией", на статически типизированном языке. Ну да, надо подумать иногда. Но ничего невозможного я не видел.


                                                    Известный факт, что некоторые подходы ФП не описываются статической типизацией.

                                                    А можно пример?

                                                      +3
                                                      Ой ой, как только Hello world закончился, сразу динамические структуры поперли во все щели и рекурсия, рекурсия, аж через край льется.
                                                      Как я только умудряюсь одни хелловорлды писать на работе, ума не приложу.
                                                      Я понял, что диалога нет. Вы видимо не видели, какие штуки на статически типизированых языках пишут.
                                                        +1

                                                        Диалога и вправду нет. Вы так и не привели обоснований утверждения о пользе типизации с цифрами. Типичное поведение слепо верующих фанатиков: отбрехаться, не предоставляя реальные факты.

                                                          0
                                                          Статическая типизация работает быстрее, т.к. операции приведения к типу происходит на этапе компиляции, а не в рантайме, присущие динамической типизации.
                                                          Польза очевидна — в производительности.
                                                          Ну и да, статическая типизация сама по себе убирает необходимость тестирования на приведение типов.
                                                          Жаль, что приходится ссылки на википедию прикреплять, но видимо, без этого никак.
                                                            0
                                                            А на мой вопрос сможете ответить?
                                                            Вот этот — habr.com/en/post/451422/#comment_20176348
                                                              0
                                                              Я — Понятия не имею. Но и вопрос динамической тиизации не в скорости, она тоже нужны для определенных задач, по любому придется чем то пожертвовать.
                                                          +1
                                                          Как только вы начнёте писать программу посложнее Hello World с динамическими структурами и рекурсией

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


                                                          Как вы это тестами докажете?

                                                        +2
                                                        Есть практики с доказанной пользой: такие как код-ревью и тесты. Типизация к ним не относится.

                                                        Типизация — это такой подвид тестов. От выразительной силы типизации зависит то, какие «тесты» с её помощью вы можете написать.


                                                        И типизация может гарантировать выполняемость утверждений с квантором всеобщности, в отличие от тестов.

                                                          –4

                                                          Типизация — это подвид хреновых тестов. Тех, которые проверяют детали реализации, а не ожидаемое поведение. Хорошие тесты позволяют вам переписать реализацию без переписывания тестов. Типизация же требует изменений на каждый чих. При этом ловит только тривиальные ошибки, которые при хороших тестах и так будут отловлены.

                                                            +2

                                                            Почему?


                                                            Если у меня есть функция sort с типом (xs : List a) -> (ys : List a ** Sorted xs ys) (или функция sort : List a -> List a и рядом sortTheorem : (xs : List a) -> Sorted xs (sort xs), это чуть более модульный подход), то она проверяет, что функция возвращает сортированный список. Без деталей реализации.


                                                            Если у меня есть функция с типом a -> b, и b не имеет вид IO b' (и ещё пару подобных вариантов), то функция не лезет в сеть и на диск, не майнит биткоины на вашем компьютере и не утягивает ключи от биткоин-кошельков. Успехов проверить это тестами.


                                                            И нет, на каждый чих ничего менять не надо. Зачем вам менять тип функции, если поменялась только её реализация? А внутри функции у вас никаких аннотаций типов нет, тайпчекер всё сам выводит.


                                                            А если я существенно меняю логику, то я наоборот хочу, чтобы тайпчекер мне указал на все места, на которые надо обратить внимание.

                                                              +1
                                                              Типизация же требует изменений на каждый чих.

                                                              Это утверждение настолько же обосновано, как и "тесты требуют изменений на каждый чих".

                                                                +2
                                                                Нормальная типизация позволяет вам тестировать бизнес логику, а не кастовать данные (причем здесь приложение, если проверяем данные) во что угодно, считать количество переданных параметров и убеждаться, что вам пришел не null — а потом называть это тестированием.
                                                          +9
                                                          Типизация не делает код лучше

                                                          А ничего, что у любого языка есть "типизация"? Но вы просто игнорируете этот факт, вы закрываете на его глаза — а потом немедленно вводите костыли в виде number в вашем коде.


                                                          сильно замедляет разработку.

                                                          … или нет. Я вот на языках со статической типизацией (типа C#) пишу быстрее, чем на языках с динамической (типа python), потому что мне проще увидеть, когда я запихиваю "не то не туда".


                                                          На языках с динамической типизацией разработка идет в разы быстрее.

                                                          Во-первых, это заявление неплохо бы подтвердить ссылкой на авторитетные источники. Во-вторых, после этого неплохо бы сравнить аналогичные источники по стоимости поддержки такого кода.

                                                            0
                                                            А ничего, что у любого языка есть "типизация"?

                                                            Смотря что называть типизацией.


                                                            Классическая задача типов — статически гарантировать, что программы удовлетворяют определённым требованиям. Смешивать это с наличием рантайм-меток и рантайм-проверок — можно, конечно, и это, увы, достаточно общепринятая точка зрения, но она неконструктивна и не имеет смысла.

                                                              0
                                                              Это вы про статическую типизацию. Само поняте типизации гораздо шире и в программировании присутствует всегда
                                                                0

                                                                То есть, если я буду рассуждать исключительно в терминах пары из void* и некоторого тега, описывающего семантику значения по этому указателю, и предварять любые операции проверками этого тега, то у меня получится типизация?


                                                                Не, ну можно так говорить, но как-то, ИМХО, неправильно называть настолько принципиально разные вещи одним термином, различая их лишь неприметным прилагательным.

                                                                  0
                                                                  Это прилагательное и несет в себе смысл. Сама типизация никуда не девается.
                                                                  Простой пример — для операции «1» + «1» вам все равно придется объяснить, складываете вы строки или числа. «Сам» язык программирования не выбирает, он либо приоритет имеет, либо ошибку вам выкинет. Самостоятельно «догадаться» он не в состоянии.
                                                                  Это как раз именно про типизацию в принципе.
                                                                    0

                                                                    Это потому что тут перегрузка операторов есть. Если у меня будет отдельно функция addInt и отдельно concatStr, то ничего никому выбирать не придётся.


                                                                    Чистое лямбда-исчисление (тьюринг-полное, кстати) вполне себе нетипизировано. Там даже нолик как false выглядит в Church encoding, и один можно использовать вместо другого вообще без всяких мыслей о типах.


                                                                    Собственно, да, хороший пример. Где типы в untyped lambda calculus?

                                                                      0
                                                                      Вопрос в том, что операция над статической типизацией имеет малое процессорное время выполнения и выдает ошибку в случае нарушения правил.
                                                                      Динамическая типизация (в 99% случаев) так же скатывается в стандартные процессорные инструкции, дополнительно проведя все касты в рантайме. Вы же не написали собственное сложение а используете предоставленное языком?
                                                                      Это занимает больше времени, но позволяет писать по парадигме динамической типизации.
                                                                      Я не берусь утверждать, что лучше. Методы имеют разное применение, да и юзайте, что вам подходит.
                                                                        0

                                                                        Не, я-то апологет статической типизации, причём, ну, очень ортодоксальный апологет.


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


                                                                        Ну да ладно, видимо, стоит уж мне прекратить пропагандировать различение этих двух разных ситуаций.


                                                                        Скрытый текст

                                                                        Хотя ко мне вчера на stackoverflow чувак справедливо придрался, что я использовал термин «доказательство от противного» в неправильном контексте, так что хз.

                                                            +1
                                                            Собеседование на должность секретаря. Директор спрашивает:
                                                            — Какая у вас скорость печати?
                                                            — 100 знаков в минуту!
                                                            — Спасибо, Вы нам не подходите! Следующая!
                                                            — Какая у вас скорость печати?
                                                            — 200 знаков в минуту!
                                                            — Спасибо, Вы нам не подходите! Следующая!
                                                            — Какая у вас скорость печати?
                                                            — 3000 знаков в минуту!!!
                                                            — Так много???!!!
                                                            — Ага! Правда все время какая-то ерунда получается...
                                                              +5
                                                              Типизация не делает код лучше


                                                              Расскажите, пожалуйста, как должен быть устроен эффективный по производительности и памяти рантайм с динамической типизацией (меня интересуют аллокации на стеке и хипе, data locality, расходы на сборку мусора, etc).

                                                              И, нет, компьютеры все еще недостаточно быстрые, чтобы все могли на это забить.
                                                                0
                                                                Разве что-то принципиально мешает проводить статический анализ такого кода? Примеры существуют: Stalin, ChezScheme, SBCL, V8. Применяются техники от поверхностных, например, мягкой типизации, до хардкорных, например, частичного исполнения кода. Это позволяет оптимизировать представления значений, в том числе, с учётом escape-анализа, и размещать всё и на стеке, и локально, и без сборки мусора. Это сложнее, конечно, сделать, чем для менее гибких языков, но вполне возможно.

                                                                Можно пойти другим путём, и делать, например, многостадийные компиляторы, как Petalisp, Terra или Julia.

                                                                Не всё так однозначно, в общем. Runtime может быть разным и достаточно эффективным. Node.js в некоторых cpu-bound нагрузках вполне себе на уровне Java работает. Java — статически типизированный. И раза в 4 медленней C++, но скорее всего, потому что в JavaScript нет поддержки sse intrinsic-ов. И что?

                                                                И надо не забывать 10-ое правило Гринспена: «Любая достаточно сложная программа на Си или Фортране содержит заново написанную, неспецифицированную, глючную и медленную реализацию половины языка Common Lisp.» В принципе, ничего с тех пор не изменилось, в список легко попадают и Си++, и Rust, и, не побоюсь этого слова, Haskell.

                                                                Потому что внешний мир, с которым необходимо работать, не типизирован (возможно, на фундаментальном уровне). Поэтому, если принимать в качестве основного языка нечто жёстко типизированное (Си++, например), приходится изобретать нетипизированные языки (Bash, JavaScript, Perl, etc), иначе всё будет слишком дорого, сложно, а потому и коряво, и глючно.
                                                                +2

                                                                Вот ведь забавно, я окончательную прививку от динамической типизации получил, поработав с хаскелем. Сначала мне это выворачивало мозги, но в конце концов я понял, что большую часть времени я занимаюсь не отладкой, а разработкой. И в разы быстрее, да.

                                                                  +1

                                                                  Сначала вам типизация мешает, потом компиляция, и в результате мы получаем очередной браузер размером под сто мегабайт в качестве текстового редактора. Нет, спасибо, оставьте себе.

                                                                    +1
                                                                    Про замедление разработки из-за наличия статической типизации смешно читать. Такое ощущение, что прям очередной гений стиля «херак-херак и в продакшн». Вспоминаются всякие чудики из интернета, по словам которых они каждую свободную минуту могут монетизировать и все из себя такие крутые, что, буквально, матери подать стакан воды уже убыток. Только не понятно что они на форумах интернета забыли. Это еще больше разработку замедляет ведь :)
                                                                    Ну вот никогда за мои 15 лет опыта никакая типизация никак не влияла на скорость. Зато на скорость влияет куча говнокода после таких вот кодеров за которыми приходится разгребать авгиевы конюшни.
                                                                    Статическая типизация учит порядку в мышлении и однозначно делает код лучше. И уж точно никогда и никак не мешала, разве что генерировать говнокод. Не стоит этим прикрывать свои недостатки.
                                                                    Динамическая же типизация возникла там, где это было необходимо.
                                                                      –1
                                                                      +1.
                                                                      Когда только начинаешь учить язык с нормальной типизацией, постоянно спотыкаешься о типы, и кажется, что это компилятор придирается на пустом месте, что можно было бы обойтись без всего этого, что это какой-то лишний бойлерплейт, который только мешает. Но достаточно быстро вырабатывается привычка, об этом уже не надо задумываться — мозг за всем на автомате следит.
                                                                      Но многие делают выводы о языке и забрасывают его ещё до этого.
                                                                    +1
                                                                    Вообще, поработав на достаточно большом количестве проектов, я понял, что никакими методологиями и техническими приблудами сделать код более легко изменяемым, надежным и чистым нельзя. Ни типизация, ни eslint, ни юнит тесты не помогают. Да полезный эффект от них есть и чаще всего он достаточно велик, но основной затык всегда — это прямота рук программистов. Если программисты оверинжинирят на ровном месте, не изучают мануалов до того, как использовать библиотеку и проектируют кривую архитектуру приложения, то ничего не поможет
                                                                      +2
                                                                      Ни типизация, ни eslint, ни юнит тесты не помогают.

                                                                      Кому не помогают? Вам не помогают? Ну да, верю. Мне — помогают.

                                                                        +1
                                                                        это все дураки придумали, наверно, или проклятые менеджеры, чтобы разводить заказчика на лишние траты. Я вот накодил и сразу в прод лью</sarkasm off>
                                                                          0

                                                                          Вот у вас точно самый лучший в мире язык программирования, раз такое позволяет.

                                                                            +1
                                                                            По моему если автор спорит о том, что лучше — статическая или динамическая типизация, дальше конструктивно можно даже не пытаться.
                                                                            В мире приняты несколько тем, запрещенных для обсуждения — политика, религия, сексуальная ориентация.
                                                                            Для разработчиков надо сюда внести еще «динамическая или статческая типизация», «фп или ооп», «множественное или одиночное наследование».
                                                                          +1
                                                                          Мне в наследство часто доставались репозитории с отборным еле-работающим говнокодом, прекрасно проходящим проверку линтером, с наличием кучи юнит-тестов и flow-типами.

                                                                          Эти инструменты могут сделать хороший код надежней, чище и лучше. Но плохой код плох не потому что не использует линтер или типы, а потому что криво написан. И можно хоть сколько угодно танцевать вокруг этого кода с линтером и чем угодно, добиться значимого улучшения без тотального переписывания не удастся.
                                                                            +3

                                                                            Ну я и говорю: вам не помогло. Это не значит, что другим не поможет.

                                                                      0
                                                                      Наброшу:
                                                                      Как же ЯП может быть «лучшим» без статической типизации?
                                                                        0
                                                                        Я правильно понимаю что у вас не предполагается полноценных объектов, а только хэшмапы?
                                                                          0
                                                                          Эти объекты компилируются в обычные объекты JavaScript.
                                                                            0

                                                                            В обычные хешмапы, то есть instanceof от них ждать не стоит?

                                                                          +1
                                                                          про кофескрипт уже шутили?
                                                                            0

                                                                            если переменные иммутабельны, то почему вы продолжаете называть их переменными, а не постоянными например?

                                                                              –1

                                                                              Автор, а вы ClojureScript смотрели?

                                                                                –1
                                                                                Автор, не смотрели при изобретении своего языка на целую группу конкатенативных языков

                                                                                и в частности Factor язык, который был изобретён разработчиком его при отказе от использования Java?
                                                                                  0
                                                                                  Настоящие программисты не пишут на лиспах и фортах. Их используют лишь сосунки.
                                                                                  Ни постфиксные ни префиксные языки не нужны, вы не понимаете, ни что не держит мозг в тонусе лучше, чем необходимость помнить 20 уровней приоритетов операторов и ассоциативность каждого.
                                                                                    0
                                                                                    Да, чем больше размышляешь, тем больше приходишь к выводу, что языки программирования разделяет вопрос об отношении к скобкам.
                                                                                    Forth на Лурк
                                                                                    , а мозг и без них может обойтись, что и подтвердил автор данного поста заменив их пробелами в Питон варианте. :)
                                                                                  +5
                                                                                  когда же это закончится. хайп драйвен девелопмент и борьба с ветряными мельницами.
                                                                                  Автор хочет красивый и выразительный язык, и предлагает следующее для описания вычислений:
                                                                                  А теперь посмотрим, как элегантно и воздушно можно написать это же выражение на Sova с помощью имеющей значение индентации:
                                                                                  * 2
                                                                                    + 1 2
                                                                                    - 4 (/ 2 1)
                                                                                  


                                                                                  Думаю нужно пойти дальше, и записывать в такой манере математические статьи, и литературу. Это же прекрасно, отлично читается.
                                                                                  Если честно, я надеюсь, что автор шутит. Просто после всех таких статей, и прочих, где рассказывают, например, как копипаста на go становится более изящным решением, чем generic в C#, например, я начинаю сомневаться в будущем программирования.

                                                                                  ПС: На самом деле имеющая значение индентация — это тоже бойлерплэйт, нажимать на таб или на пробелы — все тоже, что эти скобки кошмарные ставить. Надо писать код в одну строку, а scope сообщать силой мысли напрямую компилятору.
                                                                                  • НЛО прилетело и опубликовало эту надпись здесь
                                                                                      0
                                                                                      У каждого программиста есть мечта — создать свой язык программирования.

                                                                                      Нет
                                                                                        +2

                                                                                        Нормально так, для увеличения чсв сойдёт. Я тоже думал написать язык, но во время понял что я не самый умный в этом мире.

                                                                                          0
                                                                                          Теперь осталось на своём языке создать уникальное ПО или технологию для оправдания сего действия.
                                                                                            0
                                                                                            У меня знакомый работает в компании, которая так и сделала.
                                                                                            Написали свой язык толи для принтеров, толи еще для какой-то периферии и теперь продают его и курсы по нему в разных странах. (Как сам язык называется к сожалению не помню)
                                                                                          +1
                                                                                          Такой синтаксис называется I-expressions, придуман давно и даже в каком-то диалекте лиспа был реализован (вроде Scheme).

                                                                                          Почитайте ещё про M-expressions.
                                                                                            0

                                                                                            Что за чушь. Никогда даже не возникало такой мысли. Такое свойственно либо начинающему программисту в стадии зазнайства "все вокруг идиоты, один я весь в белом", либо идеалисту.

                                                                                              0

                                                                                              Нет, ну почему. Мне было бы интересно сделать свой язык программирования, хотя я вроде как не совсем зазнайка и не идеалист. Даже несколько языков программирования, с разными идеями:


                                                                                              1. Что, если отказаться от parametricity для зависимых типов-сумм, где первый элемент в зависимой паре — тип?
                                                                                              2. Можно ли попробовать интернализировать тотальность функций и как-то формализовать это понятие, а не выносить это на уровень метаязыка?
                                                                                              3. Можно ли работать с отношениями эквивалентности как-то изящнее, чем так?

                                                                                              Ну это так, сходу.

                                                                                              • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                  0

                                                                                                  Да.

                                                                                                  • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                      0

                                                                                                      Язык-то где, где это все уже готовое?


                                                                                                      Не кок плз, люблю видеть свои термы.

                                                                                                      • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                  0
                                                                                                  В принципе, если есть избыток свободного времени, то имея подобный интерес можно и поиграться. В академических целях. Но рассчитывать всерьез, что это панацея, да еще и удастся продвинуть — явно не стоит.
                                                                                                  Самому же реально такая мысль не разу не посещала, даже мимо не пробегала. Всегда было интересно решить задачу, а язык — всего лишь средство. Тех что напридумывали уже с избытком хватает для самых разных нужд.
                                                                                                    0

                                                                                                    Именно, исключительно академический интерес.


                                                                                                    Который, впрочем, можно сделать работой и решить проблему со свободным временем, если устроиться, наконец, в кокодемию.

                                                                                                    –2
                                                                                                    Было бы классно, если бы за этими вопросами стояли ещё и ответы например на то, как это мне поможет написать алгоритм решения Судоку быстрее :)
                                                                                                  0
                                                                                                  Статья интересная, и парсер у вас довольно мило написан.
                                                                                                  Но сам язык в текущем виде, особой пользы не представляет нa мой взгляд. Тот же пример с экспрессом почти ничем не отличается от такого же кода на js. Как уже выше написали, чтобы язык имел шанс на востребованность — у него должна быть своя ниша. Просто новым языком (особенно с весьма спорными фичами) пользоваться никто не будет.

                                                                                                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                                                  Самое читаемое