LINUX.ORG.RU

Вышла новая версия языка программирования D (2.091.0)

 ,


2

7

Изменения в компиляторе:

  • Окончательно убран деаллокатор классов.
  • Возможность сообщать о номерах строк в стиле GNU.
  • Добавлена экспериментальная генерация заголовочников C++ из внешних (extern) объявлений C|C++: DMD теперь умеет писать заголовочные файлы C++, содержащие биндинги на объявления в существующих файлах D, помеченных как extern(C) или extern(C++).

Изменения в рантайме:

  • Добавлен пропущенный в некоторых местах pthread_attr_destroy.
  • Расширенные биндинги в core.sys.windows.security.
  • Добавлен core.stdcpp.memory.unique_ptr.
  • Добавлен TFD_TIMER_CANCEL_ON_SET.

Изменения в библиотеке:

  • std.bigint теперь @safe.
  • Замена approxEqual на isClose в std.math.
  • Удалён устаревший std.format.Mangle.
  • Удалены устаревшие структуры ByLine, ByChunk, ByRecord из std.stdio.
  • std.algorithm.sorting.schwartzSort теперь поддерживает и бинарные функции трансформации.
  • Добавлена curry в std.functional.

Изменения в инсталляторе:

  • Скрипт инсталляции теперь может исполняться на Windows.

Изменения в Dub:

  • Добавлена переменная окружения SOURCE_FILES.
  • У DUB теперь стиль дополнения zsh.

>>> Подробности

★★★★★

Проверено: shell-script ()
Последнее исправление: Virtuos86 (всего исправлений: 2)
Ответ на: комментарий от q0tw4

Ты генерируешь какие потоки шизофазии. В принципе невозможно понять, что ты хочешь этим сказать. Скорее всего ты просто не знаешь что написать и генерируешь это.

Ну концепт же проверяет какие методы доступны.

Нет, никакой концепт ничего не проверяет.

Нельзя же с помощью концепта сделать так, что class A { int f(); } и class B { int f(); }

Какая-то шиза. Чего реализовано, куда реализовано?

но при этом сама реализация не будет знать конкретных имен A и B (так как реализация находится в либе, а классы у узера).

Никакие шаблоны в принципе не завязаны на какие-то типы. У тебя опять же проблема с методичкой.

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

Почему у вас постоянно какие-то проблемы с этим. Ну не можешь объяснить чего хочешь - роди ты 5 строк кода и покажи их.

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

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

Но и в целом:

over 50 lines of output

Потуги родила явно бездарная обезьяна, которая даже не осознаёт, что 50 строк - это фича нормального языка, а одна строка - это строка дерьма. Потому как в этих 50 строках строка с ошибкой одна, а остальные строки - это контекст/трейс, чего нету в мусорных недоязычках.

К тому же концепты вообще не покажут ошибку сектунту, потому как они не триггерят ошибку, а исключают функцию из кандидатов, как sfinae и ошибка там будет всегда «функция не найдена». Это основная их фича.

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

Конечно requires поможет и тут, но это просто свойство адекватного дизайна.

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

Ах да.

Близко к тайпклассам, поправь уже ты если ошибаюсь.

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

В С++ ненужно затирать типы сводя их к подтипам. В статическом языке со статической же семантикой это в принципе невозможно. Это возможно в скриптухе лишь потому(и это является костылём), что там снизу есть рантайм-типизация. От того это и бездарная скриптуха.

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

Концепты это более читаемые enable_if.

Как-то так:

https://gcc.godbolt.org/z/NmhEkS

То есть все enable_if могут быть заменены на концепты. Будет немного читаемее код, и другие сообщения об ошибках. Если знать про ошибки С++, то не так важно какое сообщение выдадут…

Вместо

<source>:17:6: note:   template argument deduction/substitution failed:

<source>:15:66: error: no type named 'type' in 'struct std::enable_if<false, void>'

15 |     typename std::enable_if<constructible_to_string<T>>::type* = nullptr

будет

constraints not satisfied

<source>: In instantiation of 'void f(T&&) [with T = int]':

<source>:35:8:   required from here

<source>:11:9:   required for the satisfaction of 'ConstructibleToString<T>' [with T = int]

<source>:11:38: note: the expression 'is_constructible_v<std::__cxx11::string, T> [with T = int]' evaluated to 'false'

   11 | concept ConstructibleToString = std::is_constructible_v<std::string, T>;
fsb4000 ★★★★★
()
Ответ на: комментарий от fsb4000

Концепты это более читаемые enable_if.

Нет, «более читаемый enable_if» - это requires.

template<typename T> void f(T && x) requires constructible_to_string<T> {}

К тому же проблема не в читаемости. Проблема в том, что в enable_if множество дыр. Не засирая шаблоны лишними параметрами. Можно его использовать только для определения типа возврата, но тогда не работает вывод типа возврата. Слева недоступны параметры функции. И много чего.

Но основная проблема - это работоспособность только в sfinae-контексте. Т.е. результат enable_if должен зависеть от какого-либо шаблонного параметра функции. Таким образом невозможна глобальная конфигурация.

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

Сами же концепты - это прежде всего вывод из тени sfinae-семантики. Ранее она выводилась через костыли, нам нужно было преобразовать собирается/не собирается в конкретное значение true/false requires {} реализует это явно. Тоже самое касается и отключения кандидатов. Это так же выведено из тени, но об этом уже написано выше.

Поэтому на самом деле идиоматичной реализацией будет:

template<typename T> concept constructible_to_string = requires(T x) {
  std::string{x};
};

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

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

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

Если я не ошибаюсь, аналог этого:

template<typename T> void f(T && x) requires constructible_to_string<T> {}

существует в D можно уже много лет:

void f(T)(auto ref T x) if (is(T : string)) {}
yetanother ★★
()
Ответ на: комментарий от yetanother

Ты не понял как это работает: в D, как и в остальных языках, нет и не может быть аналога никаким фичам C++, потому что всё это бездарная скриптуха, а ты адепт.

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

void f(T)(auto ref T x) if (is(T : string)) {}

Сомнительно, что это: T : string аналог. Но в любом случае заход уровня «много лет» не состоятелен. Повторюсь - вас сильно потрепала пропаганда. В крестах этому requires так же много лет и это ничего не значит. Абсолютно неважно сколько чему лет. Эти сравнения несостоятельны, ведь кресты и какой-то там недоязычок с помойки находятся совершенно в разных условиях.

Да и выглядит это как дерьмо. К тому же оно не может в auto f(auto x), а auto|T && в крестах - это не ref даже близко.

Оно не может даже в auto f(auto) - но в целом это и не удивительно. Дизайн 90х годов типа помойка. Что же вас так тянет на всякий мусор.

Вы настолько удивительные люди, что у вашего недоязычка до сих пор пропаганда протухшая 15 лет назад весит. Состоящая из вранья на 99%. Скорее всего и ваши знания о C++ берутся из неё же.

Такое чувство, что у людей попросту нет вкуса. В противном случае я не могу объяснить как возможно метапрограммирование на строках, f(T)(auto ref T x) - этот мусор, f!string(x) - этот мусор. Да и вообще весь недоязычок.

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

Ну где-то выпилили odr - это основная проблема С++. Да, но а толку. Если это в паре мест, а во всех остальных всё осталось как было. Это ничего не дело - лишь поломало согласованность логики.

auto f(T)(auto ref T x) { string _ = x;}
auto f(T)(auto ref T x) { int _ = x;}

Это не работает. Причём оно работает настолько топорно и примитивно.

Ладно в C++ есть этот костыль с отдельным инстанцированием сигнатур. От части даже понятно почему так сделано, но почему у тебя в языке это так же сделано?

Ну и сообщения об ошибках достойны самой убогий скриптухи. Вроде серьёзный язык, кукарекаку. А решения и реализация не далеко ушла от раста.

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

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

в D, как и в остальных языках, нет и не может быть аналога никаким фичам C++, потому что всё это бездарная скриптуха

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

Если система типов C++ не приемлет затирание типов, а скриптухи на этом живёт, то о каких фичах можно говорить? Это банальная проблема всех колхозников. Т.к. колхозник не может отличить жопу от пальца - его поиметь не составляет труда. Колхозник мыслит на уровне «это красненькое и это - значит оно одинаковое». А уж если оно и называется одинаково, то это 100% одно и тоже.

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

Т.к. колхозник не может отличить жопу от пальца

Правильное понимание C++.

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

Я не знаю в чем глубокий смысл этого кода, но все работает ЧЯДНТ?

И в этом весь лор. Уровень адептов просто поражает воображение. Я пишу код, адепт пастит из него кусок и рассказывает мне о том, что «всё работает».

А если нормально спастить мой пример и запустить, то бам:

onlineapp.d(7): Error: onlineapp.f called with argument types (string) matches both:
onlineapp.d(3):     onlineapp.f!string.f(string x)
and:
onlineapp.d(4):     onlineapp.f!string.f(string x)

Ой, не работает. Кстати, заметим ахренительные сообщения об ошибках. Более бездарного мусора я в жизни не видел. Где-то на уровне раста, а может даже выше.

По поводу «не знаю». Для понимания смысла кода нужно понимать C++. Причём я даже дал пояснения, но адепт их не прочитал. Если проще, то в нормальном зыке этот код должен работать. А не работает он из-за костыля в С++. Неизвестно почему так сделано, скорее всего для упрощения реализации/оптимизации. Правда это уже давно не актуально.

И вот твой супер-недоязычок, который должен спасти нас от убогости C++ - не починил его основную проблему.

Если её починить, никакие enable_if и прочая чушь в принципе не нужна будет. Сейчас же в 95% случаев enable_if латает именно эту дыру, а не делает что-то полезное.

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

И хотя при передачи в функцию строки - функции int _ = x существовать не может - нам сообщают о наличии двух функций. Соответственно, все sfinae-хаки и существуют для того, что-бы вынести эти ограничения из тел в сигнатуру. Но зачем их вообще выносить?

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

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

Слушайте, что Вы такой нервный? И что Вам так не нравится в скриптоподобии? Ну да, D нифига не замена ++ 1:1. Зато по скорости написания попробуйте, посоревнуйтесь.

И да, зачем передёргивать? Ваш пример всем прекрасно знаком и известно, что это прямое следствие упрощений. Никому не влом точно специфицировать тип аргументов шаблона. Зато плюсовый аналог собирается gcc ровно в 2 (два!) раза дольше, чем аналог на ди собирается тормозным ldc2. Никто не спорит, что на ++ иногда можно изрядно выразиться. Ну и что, если упрощения позволяют резко повысить скорость сборки практически без потери выразительной силы? Короче, спокойнее надо быть, ну правда.

f(T)(auto ref T x) - этот мусор, f!string(x)

почему? первое — точная спецификация, не нужно, не используйте. Как Вы хотите выразить то же самое без «мусора»? Второе — а что Вам не нравится? стринг в этом примере вообще можно не писать в большинстве случаев.

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

Слушайте, что Вы такой нервный? И что Вам так не нравится в скриптоподобии? Ну да, D нифига не замена ++ 1:1. Зато по скорости написания попробуйте, посоревнуйтесь.

О какой скорости написания может идти речь, если язык попросту не обладает какой-либо инфраструктурой и даже вменяемыми сообщениями об ошибках?

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

Подходы скриптухи работают в скриптухе и должны в ней и оставаться.

И да, зачем передёргивать? Ваш пример всем прекрасно знаком и известно, что это прямое следствие упрощений.

Это прямое следствие дыры в дизайне, упрощения уже давно никакого нет. Это решение времён C++98, когда сигнатура была чисто сишной. Сейчас это давно не актуально и сигнатуры не особо легче тел, если не тяжелее. И в языке, который претендует на современный дизайн и «С++ такой, каким он должен быть» - таких решений быть не должно.

Никому не влом

Я даже не знаю как комментировать эти заходы уровня начальной школы. Каждый адепт начинает с этой ахренительной истории, что то, чего нет - ненужно и что всегда можно пожрать дерьма. Только вот дерьма я жрать не хочу. И основной критерий хорошего дизайна - не сбрасывать бойлерплейт на пользователя. Человек должен делать то, что может делать он. Всё, что может быть автоматизировано - должно быть автоматизировано.

точно специфицировать тип аргументов шаблона.

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

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

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

Проблема в том, что никакие ограничения вида «Один тип» невозможны. Функция должна мочь не в строку и число, а их в обобщённые варианты. Описать это можно только логическими констрейтами/предикатами. Возможны только два варианта - это либо проводить интроспекцию, но пусть это тупиковый. Это превратиться в неведомую лапшу.

Второй же вариант - семантические интерфейсы, как это реализовано в requires {}. Вместо того, что-бы проверять «если ли в типа поле такое, а поле это метод, либо тип с перегруженными оператором(), либо ещё какая херня?» И всё это с учётом контекстов.

И природа этих интерфейсов как раз таки обусловлена семантикой использования, которая уже существует и уже написано. У меня уже написано int _ = x; и мне в интерфейсе так же нужно будет написать тоже самое.

Проблемы здесь очевидны. Я пишу два раза одно и тоже. Мне нужно как-то это согласовывать. Далее - такое место в функции не одно. И каждое мне нужно найти и вынести в интерфейс. И тоже самое для последующих функций.

Т.е. у меня может быть foo(x) { bar(x); } в котором может быть что угодно и все констрейты для bar - мне нужно прописать в for. А в реальности там таких bar будут десятки.

Зато плюсовый аналог собирается gcc ровно в 2 (два!) раза дольше

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

Повторюсь, вы можете показывать замеры/код, а не рассказывать куллстори?

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

Ну и что, если упрощения позволяют резко повысить скорость сборки

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

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

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

практически без потери выразительной силы? Короче, спокойнее надо быть, ну правда.

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

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

почему? первое — точная спецификация, не нужно, не используйте.

Проблема не в этом. Проблема в том, что у меня в С++ auto f(auto x), а Дерьме - мусор. Но это не основная проблема.

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

Проблем у этого синтаксиса много. Основная - его родил бездарный идиот, но если точнее - это его отсутствие какой-либо согласованности.

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

Кстати, это показатель. Показательно того, что авторы этой поделки бездарные идиоты, а её адептов пропаганда держит за идиотов так же.

Когда пропаганда показывала «проблему»(несуществующую) C++ вида x<y<z> >(a) - этого уже достаточно. Но почему-то пропаганда не показывает как это будет в Дерьме. x!(y!(z))(a) - да, выразительность так и прёт. Согласованность так и прёт.

Поэтому в нормальном языке параметры определяются в <> и передаются в <>, тоже самое с функциями. И разделение скобок существует как раз для выразительности, что-бы одно не смешивалось с другим.

Как Вы хотите выразить то же самое без «мусора»?

f<string>(x) - это работает всегда, не содержит мусорных символов несостоятельных в данном контексте. Список аргументов на то и список, что семантически его обозначают скобки. Везде и всегда. И если мы опускаем скобки выражая семантику одного значения, то эту семантику в языке ничего не выражает и выражать в рамках очередного кейса не должно.

Второе — а что Вам не нравится?

Выше написал.

стринг в этом примере вообще можно не писать в большинстве случаев.

Опять же, сразу видно не дюжий опыт разработки на С++ и любом сложном языке. И теперь понятно, почему сообщения об ошибке такое дерьмо и такое понятие как трейт с контекста адептам Д не знакомо.

Дак вот, в 90% я буду это читать, а не писать. Как и кто угодно другой. И вот в С++ я буду читать нормальны сигнатуры, а в Д - дерьмо.

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