company_banner

Google представил новый язык программирования Logica


    Корпорация Google довольно часто удивляет новыми проектами. То операционная система Fuchsia, теперь — новый декларативный язык логического программирования Logica. По словам разработчиков, он предназначен для манипулирования данными и транслирования программ в язык SQL.

    Нужна Logica разработчикам, планирующим использовать синтаксис логического программирования для написания запросов к БД. Сейчас уже есть экспериментальная поддержка выполнения результирующего SQL-кода в хранилище Google BigQuery или в СУБД PostgreSQL и SQLite. Чем еще может порадовать новый язык?

    На самом деле, Logica — продолжение развития еще одного языка обработки данных, который называется Yedalog. Разработан он еще и для того, чтобы предоставить уровень абстракции, недоступный в штатном SQL. Логическим же язык назван потому, что запросы в Logica программируются в форме набора логических утверждений.

    В нем поддерживаются модули, операции импорта и возможность работы Logica прямо из интерактивной оболочки Jupyter Notebook. Практический пример — формирование выборки персон и названий, которые чаще других упоминались в 2020 году. Программа на Logica для обращения к БД GDELT будет выглядеть так:

    @OrderBy(Mentions, «mentions desc»);
    Limit(Mentions, 10);
    Mentions(person:, mentions? += 1) distinct :-
    gdelt-bq.gdeltv2.gkg(persons:, date:),
    Substr(ToString(date), 0, 4) == «2020»,
    the_persons == Split(persons, ";"),
    person in the_persons;

    $ logica mentions.l run Mentions
    +----------------+----------------+
    | person | mentions_count |
    +----------------+----------------+
    | donald trump | 3077130 |
    | los angeles | 1078412 |
    | joe biden | 1054827 |
    | george floyd | 872919 |
    | boris johnson | 674786 |
    | barack obama | 438181 |
    | vladimir putin | 410587 |
    | bernie sanders | 387383 |
    | andrew cuomo | 345462 |
    | las vegas | 325487 |
    +----------------+----------------+


    Разработчики языка говорят, что решились на его создание для облегчения жизни всем, кто работает с SQL. Проблема в том, что сложные запросы для SQL могут быть очень длинными и многострочными. При этом содержимое таких запросов неочевидно для восприятия.

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

    А вот Logica предоставляет возможность компоновки программ из небольших, понятных и доступных для повторного использования логических блоков. Они могут быть протестированы и связаны с определенными именами, после чего сгруппированы в пакеты, доступные для использования в составе прочих проектов.

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

    Selectel
    IT-инфраструктура для бизнеса

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

      +9

      Еще один…

        +16
        Как должен был выглядеть заголовок:
        Два русских парня Konstantin Tretyakov и Evgeny Skvortsov за выходные написали язык который как бы «not an officially supported Google product»
          +1
          Это вообще нормально?
          Когда хабр успел скатиться до уровня пикабу и нецензурщины в комментариях?
        +8

        16 standards.

          +8
          Чую, будет, как с ORM, где по итогу всё равно смотришь sql-запросы и почему они такие неоптимальные.
            –11
            Ну если разработчики начнут внедрять его нативную поддержку вместо SQL, то почему бы и нет?
            SQL уже явный анахронизм
              +10
              а почему вы так считаете? Просто от того, что ему чуть менее 50 лет? Не стильно-модно-молодежно?
                +4
                SQL с одной стороны не дает выбрать оптимальный план запроса (даже если вы переписали свой SQL запрос чтобы он работал быстрее, не факт, что это — оптимальное решение для конкретной СУБД, может она может и лучше) — недостаточно низкоуровневости.
                А с другой стороны — слишком низкоуровневый язык, чтобы запросы выглядели легко и в них можно было легко и быстро разобраться (сложные запросы).
                и тестировать SQL сложно.
                  0
                  Простите, но если с пунктом номер два еще можно согласиться (действительно, полотна на 2-3 «страницы» бывает читать сложно, однако их надобность — тема отдельного разговора), то п.1 — а причем тут собственно язык? Оптимизация запроса (всмысле выбора плана и «ниже») — целиком и полностью ответственность СУБД, вы можете ей лишь «подсказать» уточнив вопрос до более адекватного. Я например был бы очень против внедрения в запрос каких-то ключей/аттрибутов для управления оптимизацией запросов. Ну это выглядит как ужасный костыль. Неужели вам и правда такое требуется? Может тогда дело не в языке, а к примеру в архитектуре приложения?

                  насчет тестирования наверное нужен пример. я не очень понял суть проблемы.

                  ПС: Если честно, полотно в 2 страницы того, что приведено в статье — еще хуже читалось бы.
                    +1
                    А посмотрите сколько хинтов запросов придумала Oracle.
                    docs.oracle.com/cd/B13789_01/server.101/b10752/hintsref.htm
                    Все это для достижения максимальной эффективности.
                      0
                      ну впринцепе я и говорил, что это выглядит уродливо, а не что этого не существует :)
                    0
                    1. Оптимизация плана запроса, все зависит от субд и вообще не задача SQL — это язык для аналитики а не оптимизации.
                    2. Во многих базах можно написать от нативного кода до специальных процедур которые будут работать более оптимальную
                    3. Легко/трудно это субъективная оценка. На мой взгляд SQL более простой(менее сложный) чем большинство ЯП.
                    4. Тестировать элементарно — просто выполнить запрос на реальной или тестовой таблице(если это оп. модификации.)
                      +1
                      SQL — это язык для аналитики а не оптимизации
                      Именно. Это язык для аналитики, а не разработки.
                    +2

                    — Условие джойна. У нас в таблицах описаны внешние ключи, и в 90% случаев джойн делается для получения данных связанной сущности, логичнее делать джойн по названию связи. FOREIGN KEY fk_user(user_id, table_user.id); table_a JOIN table_user USING(fk_user)
                    — Джойн для получения данных связанной сущности это вообще неоптимальная вещь. У нас есть одна статья и много комментариев, и чтобы получить статью с комментариями, надо сделать джойн с таблицей комментариев, и в результате будет куча копий строки из таблицы статей.
                    — Одна таблица на структуру данных. Нельзя сделать таблицу deleted_users и перемещать туда удаленных пользователей с сохранением всех связей по id с другими таблицами, надо делать поле is_deleted и учитывать его во всех запросах.

                      +1
                      — Одна таблица на структуру данных. Нельзя сделать таблицу deleted_users и перемещать туда удаленных пользователей с сохранением всех связей по id с другими таблицами, надо делать поле is_deleted и учитывать его во всех запросах.


                      вот прям сейчас смотрю на проекте именно на реализацию с deleted users… и если честно, лучше б это было поле is_deleted. А зачем его учитывать? Сделайте view ActiveUsers по условию not deleted да и все? Любой из этих вариантов жизнеспособен. Какой — выбирать вам :-) Еще раз. Язык запросов тут не причем.

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

                      Можно делать и не так. Оптимально ли? Зависит от приложения.

                      table_a JOIN table_user USING(fk_user)

                      Согласен, выглядит «стильно» — но зачем? Не читаемо абсолютно. Кто его знает что там за фк у вас. а если он составной… и его название выглядит как FK_scheme_table_field1_scheme_table_field2_on_scheme_table2_field1_scheme_table2_field2 (утрировано конечно) то назвать это более читаемым что то я не могу. А сокращенное название никак не даст представление о том, что там. Откуда привычка экономить буквы? Вы же не стели бы читать статью в которой все слова написаны сокращениями? Зачем?
                        0
                        вот прям сейчас смотрю на проекте именно на реализацию с deleted users… и если честно, лучше б это было поле is_deleted.

                        Так с ограничениями SQL конечно лучше делать is_deleted. Но вот конкретные примеры недостатков было бы интересно узнать.


                        Можно делать и не так. Оптимально ли?

                        Так, как надо делать, в SQL сделать нельзя, пример далее.


                        Согласен, выглядит «стильно» — но зачем?

                        Затем же, зачем объявляются классы, выделяются функции, именуются переменные. Для семантики. В ORM например так и делают, джойн по названию связи, это выражает то, что мы хотим сделать.


                        Кто его знает что там за фк у вас. а если он составной
                        и его название выглядит как FK_scheme_table_field1_scheme_table_field2_on_scheme_table2_field1_scheme_table2_field2

                        Если он составной, в JOIN все равно будут эти поля.
                        Так не надо такие названия давать, название fk это название соответствующей связанной сущности.


                        А сокращенное название никак не даст представление о том, что там.

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


                        Откуда привычка экономить буквы?

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


                        SELECT id, title, text,
                            author(id, nickname),
                            comments(id, text, author(id, nickname) WHERE moderated = true)
                        FROM article
                        WHERE article.id = 123
                        0
                        ну если комментариев действительно куча, то кто мешает сделать второй запрос с IN, отсортировать по user_id и в коде соединить их? Некоторые библиотеки так умеют, например SqlAlchemy ORM версия для python
                          0

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

                          0
                          — Условие джойна
                          Условия джойна бывают не только по FK, не только по равенству и тд. Кроме того, дата сатанисты не указывают FK в 95% проектов. В частности по той причине, что FK в аналитических базах не работают и не вырезаны от туда совсем только для документации.
                          — Джойн для получения данных связанной сущности это вообще неоптимальная вещь.
                          Это решается довольно просто при помощи агрегатных функций

                          — Одна таблица на структуру данных.
                          «Оба хуже».
                          Смотря что здесь хочется оптимизировать. Если не хочется писать условия на is_deleted в запросах, но при этом удаленные нужно сохранять — то это совсем непонятно. Либо можно удалять данные, либо нельзя. Лучше второе :)

                          Если оптимизируется скорость:

                          — (в зависимости от базы) можно сделать, например, партиционирование. И тогда deleted будут физически лежать в физически отдельной таблице.

                          — сделать условные индексы для is_deleted = true и is_deleted = false.

                          Но лучше не делать булевых полей совсем, а вместо них делать даты, когда этот deleted произошел. Очень поможет в будущем :)

                          А есть еще такая архитектура как anchor modeling…

                          +1
                          а почему вы так считаете? Просто от того, что ему чуть менее 50 лет? Не стильно-модно-молодежно?
                          Просто от того, что SQL создавался не как язык для программистов, а как язык для менеджеров. Мол, обычный человек сможет извлекать нужные ему данные по нужным критериям, без участия программистов. В итоге получился язык, сильно похожий на естественный. Манипулировать им — довольно сложно. Для машин нужен нормальный машинный или полу-машинный формат, типа json или что-то подобное.

                          Представьте, если бы по http-апи приходили параметры запроса не в таком виде: {id: 1, name: «Joe», ...}, а в виде обычного текста «user with id 12, name Joe, ...» и вам надо было сначала его парсить, потом что-то с ним делать, потом обратно превращать в обычный текст и отдавать обратно. Да вы бы первый сказали «вы тут что, больные все собрались?» и уволились бы оттуда.

                          Или разметка сайта не тегами "\<html\>...\<body\>....\</body\>\<html\>" бы делалась, а текстом типа: «Документ с заголовком: название заголовка. Содержимое документа: блок такой-то с содержимым таким-то».

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

                          Огромное количество ОРМ придумано потому, что люди не хотят напрямую работать с чистым sql. Но эта практика изначально порочна, потому что в конечном счете надо трансформировать запрос обратно в «человеческий» язык, перед отправкой в базу данных, со всеми его ограничениями.
                            0

                            ОРМ всё же придумали не из-за SQL, а из-за реляционной модели, которая плохо ложится на объектную. Есть объектные базы данных с поддержкой SQL и без ОРМ.

                              +1
                              Чтобы не спорить из-за терминов, давайте представим, что вместо ORM я привел в пример query builder. Суть моего сообщения от этого не изменится — писать в проекте на чистом sql обычно считается плохим тоном.
                                0

                                Так этому билдеру не всё ли равно генерить json, xml или sql?

                                  0
                                  Билдеру — всё равно. У него же нет своей воли.
                                  0
                                  Билдер используют чтоб ошибок в запросе не допускать, как синтаксических, так и семантических, а не потому что sql — «плохой тон».
                                    0
                                    С чего это вдруг плохим тоном? При database first подходе как раз таки стараются использовать чистый SQL, а при code first различные ORM. Это просто разные способы управления данными, со своими преимуществами недостатками, так что не стоит так категорично утверждать.
                                    0

                                    Точнее её плохо кладут. Реляционная модель построена на множествах. Объекты это те же множества.

                                      0

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

                            +9
                            Хипстеры никак не угомонятся
                              +9

                              Вот смотрел я на го, когда впервые увидел — все понятно.
                              В этом примере я не понял ничего из синтаксиса. Может, конечно, дело привычки, но на вид — это не упрощение

                                –9

                                Я когда текст на украинском увидел — тоже почти всё понял. А в немецком не понял ничего.

                                +18

                                И что, эта белиберда понятнее SQL?

                                  +5
                                  При этом содержимое таких запросов неочевидно для восприятия.

                                  Угу, а вот из этого


                                  Limit(Mentions, 10);
                                  Mentions(person:, mentions? += 1) distinct :-
                                  gdelt-bq.gdeltv2.gkg(persons:, date:),
                                  Substr(ToString(date), 0, 4) == «2020»,
                                  the_persons == Split(persons, ";"),
                                  person in the_persons;

                                  очевидно что будет колонка mentions_count

                                    0
                                    Интересно, умеет ли язык работать с рекурсивными логическими определениями, умеет ли он эффективно выполнять запросы или просто транслирует логический код в SQL, и чем он отличается от Datalog.
                                      +1
                                      Миллениалы изобрели SQL.
                                      +5
                                      Substr(ToString(date), 0, 4) == «2020»

                                      И шанс получить по лбу сразу 2мя граблями!
                                      1) преобразование даты в строку вычеркнет любые индексы. не думаю, что в новой системе как-то по другому это отработает.
                                      2) преобразование даты в строку различается для разных локалей и временных зон. Попробуйте угадать результат, когда на клиенте и сервере локали будут различаться.
                                        0

                                        А зачем в субд вообще поддержка локализованной сериализации дат?


                                        Касательно индексов, если они строятся автоматически по коду запросов, то даже такой код может их задействовать.

                                          0
                                          А зачем в субд вообще поддержка локализованной сериализации дат?

                                          Сложилось так, она там есть. Теперь с этим придётся жить, в том числе разработчикам модных языков.

                                            0
                                            Да ладно бы только локализованная сериализация…

                                            image
                                              0
                                              `valid_since` = CONVERT_TZ(FROM_UNIXTIME(LEAST(%s + 0, 2145916800)), '+3:00', '+0:00'),
                                              `valid_till` = CONVERT_TZ(FROM_UNIXTIME(LEAST(%s + 0, 2145916800)), '+3:00', '+0:00')
                                              Иногда даже так. Потому что MySQL шибко умный и дату при вставке самостоятельно сдвигает на текущую таймзону.
                                          +6
                                          В вашем примере кода поехали отсутпы от начала строки. Этот язык, похоже, как Питон, где отступы заменяют операторные скобки.
                                          Код должен выглядеть примерно так:
                                          @OrderBy(Mentions, "mentions desc");
                                          @Limit(Mentions, 10);
                                          Mentions(person:, mentions? += 1) distinct :-
                                              gdelt-bq.gdeltv2.gkg(persons:, date:),
                                              Substr(ToString(date), 0, 4) == "2020",
                                              the_persons == Split(persons, ";"),
                                              person in the_persons;
                                            +1
                                            Да нет, ПМСМ, там разделение операций через запятую идет и до точки с запятой. Форматирование не должно никак влиять.
                                            ":-" — это определяет тело функции (предиката), операции в ней разделены запятой.
                                            В целом, всё понятно. Документация, кстати, тут: colab.research.google.com/github/EvgSkv/logica/blob/main/tutorial/Logica_tutorial.ipynb#scrollTo=DznTm114TvD7

                                            tzlom
                                            я думаю, в примере описка — должно было быть, наверно
                                            Mentions(person:, mentions_count? += 1) distinct :-

                                            Да, точно. У них есть такой пример в документации:
                                            AnonymizedCodeContribution(cl_lengths: [110, 220, 405], org: "ads");
                                            AnonymizedCodeContribution(cl_lengths: [30, 51, 95], org: "ads");
                                            AnonymizedCodeContribution(cl_lengths: [10, 20, 1000], org: "games");

                                            HarmonicMean(x) = Sum(1) / Sum(1 / x);

                                            OrgStats(
                                            org:,
                                            mean_cl_size? Avg= cl_size,
                                            harmonic_mean_cl_size? HarmonicMean= cl_size) distinct :-
                                            AnonymizedCodeContribution(cl_lengths:, org:),
                                            cl_size in cl_lengths;

                                            The following table is stored at OrgStats variable.

                                            org mean_cl_size harmonic_mean_cl_size
                                            0 ads 151.833333 75.402468
                                            1 games 343.333333 19.867550


                                            Вопросительный знак — это агрегированное поле.

                                            В общем, это фантазия на тему Пролога.
                                            0
                                            срочно внедрить в 1С.
                                              0
                                              лучше наоборот. хватит писать латиницей.
                                              0
                                              А главное — это не язык, а расширение в рамках Google Cloud BigQuery API — не знаю, будет ли оно работать за пределами Colab, но это точно облако со всеми вытекающими. Ну по крайней мере в приведенном «туториале» (который блокнот Colab) — оно так работает.
                                                +2
                                                Ну направление ИМХО правильное.

                                                Теперь бы еще поддержать рекурсии, наследование с полиморфизмом, сессии изменений, события, ограничения, логику представлений, и еще много чего и получится lsFusion.
                                                  +1
                                                  Потом нужно будет учить как этот язык транслируется в SQL и все равно разбираться на уровне SQL. Потому что полюбому он порой будет генерировать дичь.
                                                    0

                                                    При условии, что на нём будет удобно писать в большинстве случаев (мне пока это не очевидно, но вдруг) — популярность свою он всё равно найдёт. Есть множество аналогичных примеров языков, которые транслируются в C/С++ или в итоге выполняются виртуальной машиной на С/С++ — здесь принцип для меня тот же самый, и проблемы по факту того же класса.

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

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