LINUX.ORG.RU

beef - новый системный ЯП

 , ,


1

8

https://www.beeflang.org/

Особенности:

  • По заявлению автора, представляет собой смесь C++ и C#, с небольшими вкраплениями Rust.
  • Без GC, JIT и тому подобного.
  • Развивается параллельно с IDE (написана на самом beef и собственном тулките). Дизайн языка развивается с учётом удобства разработки IDE.
  • Автор делает упор на удобную отладку с помощью дебаггера, а не print.
  • Умеет все модные фичи: ADT, pattern matching, лямбды, дженерики, миксины, кортежи, опциональные типы и тд. Но не гарантирует null-safety.
  • Поддерживает рантайм рефлексию.
  • Не использует исключения. Используется тот же подход что и в Rust: Result + panic.
  • Проверяет проблемы с памятью в рантайме в отладочной сборке. В релизной сборке всё как в C/C++.
  • Предоставляет лёгкое взаимодействие с C/C++ кодом (не уверен в каком виде).
  • Основан на ворованном LLVM. Как будто кто-то сомневался.
  • Автор пилит язык последние 5 лет full-time.

Простой пример:

static Result<uint> GetMinusOne(uint i)
{
    if (i == 0)
        return .Err;
    return .Ok(i - 1);  
}

void Use()
{
    /* Handle result via a switch */
    switch (GetMinusOne(i))
    {
        case .Ok(let newVal): Console.WriteLine("Val: {}", newVal);
        case .Err: Console.WriteLine("Failed");
    }

    /* This invokes an implicit conversion operator, which will be fatal at runtime if an error is returned */
    int newVal = GetMinusOne(i);

    /* Result<T> contains a special "ReturnValueDiscarded" method which is invoked to facilitate failing fatally on ignored returned errors here */
    GetMinusOne(i);
}

В целом ближе к D, чем к Rust, так как содержит намного меньше гарантий.

★★★★★

Последнее исправление: RazrFalcon (всего исправлений: 3)

Ответ на: комментарий от byko3y

А при чём тут предыдущий символ? Следующий ищется всё тем же алгоритмом. В Unicode «символ» многобайтный (больше 4-х, если что). Так что в любом случае нужно «парсить».

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

нового исключения?

Какого нового? Все исключения наследники от какого-то базовго в либе. А тот базовый от std::exception в 99% случаев. Это тот же Error, которого тебе, например, хватает.

anonymous
()
Ответ на: комментарий от byko3y

У C++ контекстно-зависимая грамматика, поэтому парсер работает в связке с семантическим анализатором. «Невозможно распарсить на машине тьюринга», «должен угадывать наобум» - чушь.

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

Может, хватит чуши в этом треде? Можно хотя бы нести ее менее безапелляционным тоном. Несколько страниц доказываешь общеизвестные вещи, но в таких кривых формулировках, что доходит до абсурда.

anonymous
()

Веганы уже высказались?

Nervous ★★★★★
()
Ответ на: комментарий от anonymous

У всех контекстно-зависимая. У C++ идиотическая :). Что касается единиц трансляции, то на практике все пишут и используют header-only-библиотеки со всеми вытекающими говном последствиями.

anonymous
()
Ответ на: комментарий от anonymous

средства вроде вышеуказанного по ссылке должны быть частью стандарта языка

Куда-куда валидатор вставить? Прям в язык? Нет, спасибо

Deleted
()
Ответ на: комментарий от RazrFalcon

А при чём тут предыдущий символ? Следующий ищется всё тем же алгоритмом. В Unicode «символ» многобайтный (больше 4-х, если что). Так что в любом случае нужно «парсить»

Если бы алгоритмы так работали, то UTF-8 славилс своей тормознутостью. Слава богу, создатели подумали про это, и сделали механизм перехода на следующий символ по единственному байту текущего.

byko3y ★★★★
()
Ответ на: комментарий от RazrFalcon

Интересно, есть ли реализации строк, в которых все «кластеры графем» проиндексированы, их позиции в строке сохранены в какой-то словарик. Чтобы случайный доступ к такому символу не влек за собой перепарсинг всей строки

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от anonymous

на практике все пишут и используют header-only-библиотеки

Qt нет, половина буста нет. Тенденция есть, да, и последствия есть. Но это далеко не отсутствие раздельной компиляции.

anonymous
()
Ответ на: комментарий от anonymous

У C++ контекстно-зависимая грамматика, поэтому парсер работает в связке с семантическим анализатором. «Невозможно распарсить на машине тьюринга», «должен угадывать наобум» - чушь.

Хорошо, давай я подтяну тяжелую артиллерию шаблонов:

struct SomeType {};

template <...> struct TuringMachine {
  // Insert implementation of a Turing machine here, which we know
  // is possible from previous proofs.
};

template <typename T> struct S {
  static int name;
};

template<> struct S<SomeType> {
  typedef int name;
};

int x;
int main() {
  S<TuringMachine<...>::output>::name * x;
}

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

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

Что значить «независимо»? Код у них почти одинаковый, а единицы - разные. Можно, конечно, говорить о том, что если я скомпилировал ту же программу с разными флагами в разные выходные каталоги - то у меня разные единицы компиляции и они компилируются отдельно. Но я бы все-таки был склонен говорить о том, что они тесно связаны. Я еще раз напоминаю, что ситуация более актуальна именно для C++, где абсолютно нормально для содержимого заголовков быть в сотню раз больше, чем весь размер полезного кода.

byko3y ★★★★
()
Ответ на: комментарий от RazrFalcon

Вы про code point, а я про графему

Графему в общем случае тяжело обрабатывать. Для простого текста code point = grapheme, и тогда обрабатывать их легко.

byko3y ★★★★
()
Ответ на: комментарий от RazrFalcon

Всегда можно посмотреть changes ;)

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

Если это unchecked exception, то с ними сложнее. Но в нормальных проектах всегда идёт глобальная обёртка для отлова непредсказуемых ошибок (а такое бывает, например, когда железо посыпалось), где можно такое отловить. Хотя в данном случае достаточно отлавливать RuntimeException, который будет ловить все unchecked exception.

ma1uta ★★★
()
Ответ на: комментарий от byko3y

Я могу много рассказывать про убогости языка

Только на поверку все рассказы оказываются ложью. Ну, может не все, но itt пока так было

anonymous
()
Ответ на: комментарий от byko3y

Я так понимаю, вот это для тебя тоже рокет саенсом покажется:

proc f {} { puts ururu }

namespace eval n {
  proc f {} { puts URURU }
  proc b {} { f }
}

n::b
Догадайся, что оно выведет ;)

anonymous
()
Ответ на: комментарий от anonymous

У C++ контекстно-зависимая грамматика

Да с кем ты разговариваешь… Он не признаёт существования раздельной компиляции, а ты ему про классы грамматик

anonymous
()
Ответ на: комментарий от anonymous

на практике все пишут и используют header-only-библиотеки

А вот и смайлодаун, покусанный «гурами» цэпэпэ

anonymous
()

Больше стоит не ЯП, а его стандартная либа и вообще либы в целом. Какой-то RFC ковырять, даже и плёвый типа syslog-а и импортнуть – фундаментально разные вещи.

(собственно Си с плюсами до сих пор не выкинули только из-за этого, флейма ради)

kostyarin_ ★★
()
Ответ на: комментарий от byko3y

что может оказаться невозможно

Компиляторы обычно в этом случае просто режут глубину вычисления шаблонов и выдают ошибку

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

Хорошо, давай я подтяну тяжелую артиллерию шаблонов

Хорошо, только ты опять ничего конкретного про «угадывание» не сказал

Код у них почти одинаковый

Так одинаковый или нет?

anonymous
()
Ответ на: комментарий от byko3y

Достаточно не объявить идентификатор или забыть включить заголовок

Или использовать еще один из миллионов способов написать некорректный исходный код. О чем разговор?

trex6 ★★★★★
()
Ответ на: комментарий от anonymous

Только на поверку все рассказы оказываются ложью

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

byko3y ★★★★
()
Ответ на: комментарий от anonymous

Я так понимаю, вот это для тебя тоже рокет саенсом покажется

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

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

byko3y ★★★★
()
Ответ на: комментарий от anonymous

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

На шаблонах? Гуглится же:

#include <iostream>

template <int N> struct Factorial
{
    enum { val = Factorial<N-1>::val * N };
};

template<>
struct Factorial<0>
{
    enum { val = 1 };
};

int main()
{
    // Note this value is generated at compile time.
    // Also note that most compilers have a limit on the depth of the recursion available.
    std::cout << Factorial<4>::val << "\n";
}

Но компиляторы режут глубину, как я уже писал.

Хорошо, только ты опять ничего конкретного про «угадывание» не сказал

Что непонятно в том примере? Компилятор не может определить смысл конструкции

S<TuringMachine<...>::output>::name * x;

пока не интерпретирует шаблон - а сложность интерпретации шаблона может быть бесконечна. А задача конечности алгоритма нерешаема на машине тьюринга.

Код у них почти одинаковый

Так одинаковый или нет?

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

byko3y ★★★★
()
Последнее исправление: byko3y (всего исправлений: 1)
Ответ на: комментарий от byko3y

к чему тут эта программа

Ну и ладно

anonymous
()
Ответ на: комментарий от byko3y

реализации машины тьюринга(с бесконечной памятью) Гуглится же Но компиляторы режут глубину, как я уже писал

Да, режут. Её даже стандарт режет(утанавливает минимально необходимое значение). К чему бы это, интересно?

да, в крестовых проектах зачастую компилируют одинаковые модули тысячи

Почему бы тогда не вынести «одинаковый код» из заголовков и компилировать единожды на проект?

anonymous
()
Ответ на: комментарий от anonymous

Её даже стандарт режет(утанавливает минимально необходимое значение)

Под словом «режет» обычно подразумевается максимальное, а не минимальное значение:

жарг. комп. ограничивать доступ к чему-либо

Почему бы тогда не вынести «одинаковый код» из заголовков и компилировать единожды на проект?

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

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Под словом «режет» обычно подразумевается максимальное, а не минимальное значение

Ограничивать можно, ВНЕЗАПНО, и снизу

У меня такой же вопрос к разработчикам крестов и крестовых библиотек

Приведи пример исправления. Полный, разумеется, не надо. Простейший контейнер типа vector

anonymous
()
Ответ на: комментарий от fsb4000

extern template

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

anonymous
()
Ответ на: комментарий от anonymous

вы хотите уменьшить время компиляции

Почему бы тогда не вынести «одинаковый код» из заголовков и компилировать единожды на проект?

У меня такой же вопрос к разработчикам крестов и крестовых библиотек.

Я говорю, что вы можете в ручную указать extern templates и компиляция будет идти один раз. Но мало кто указывает, значит время компиляции не является настоящей проблемой. Значит нечего и исправлять, так как проблемы нет. Если бы была, то пользовались бы активно extern templates…

fsb4000 ★★★★★
()
Ответ на: комментарий от fsb4000

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

extern template class allocator; extern template class basic_string;

gcc-8

anonymous
()
Ответ на: комментарий от fsb4000

можете в ручную указать extern templates и компиляция будет идти один раз

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

Значит нечего и исправлять

Проблема есть. Инстанцировать можно на клиенте. Иногда и в библиотеке(basic_string<> очевидный пример). Но только _иногда_. Вот в этом суть. Ну а byko3y просто поговорить хочет/бомбит/ещё что-то

anonymous
()
Ответ на: комментарий от anonymous

Ограничивать можно, ВНЕЗАПНО, и снизу

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

Приведи пример исправления. Полный, разумеется, не надо. Простейший контейнер типа vector

Это почти любой высокоуровневый язык. Даже жаба эту фичу по большей части на интерфейсах реализует - а ведь она переняла худшие черты крестов. Не все, видимо.

byko3y ★★★★
()
Ответ на: комментарий от anonymous

extern template class allocator<char>;
extern template class basic_string<char>;

markdown скобки потерял

anonymous
()
Ответ на: комментарий от fsb4000

Только мало кому это действительно нужно

Все остальные просто привыкли ко вкусу колючек. Я не верю, что людям, которые по 10-20 минут компилируют проект на тридцатиядерном сервере, не нужно этой фичи.

byko3y ★★★★
()
Последнее исправление: byko3y (всего исправлений: 1)
Ответ на: комментарий от byko3y

Ага, расскажи мне, что «резать людям водку» может значить «потреблять не меньше стакана в день на рыло»

Щас бы алконавтов в wg-21…

Приведи пример исправления Это почти любой высокоуровневый язык

Речь была про код на крестах(у тебя э к разработчикам библиотек претензии). Пока мимо

anonymous
()
Ответ на: комментарий от anonymous

Всё-таки markdown редкостное говно. Lorcode и тот херню подчас выдавал, но до markdown-а ему как до луны

anonymous
()
Ответ на: комментарий от anonymous

Речь была про код на крестах(у тебя э к разработчикам библиотек претензии). Пока мимо

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

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Да ради бога. Приведи пример на языках с _мономорфизируемыми_ шаблонами/генериками/как их ещё называют. Java, если что, не подойдёт

anonymous
()
Ответ на: комментарий от byko3y

Ты отвратительно перевираешь мои слова

Кстати, да - это не я, это долбанный markdown

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.