Re[10]: Опциональные типы
От: vdimas Россия  
Дата: 27.02.17 02:38
Оценка:
Здравствуйте, meadow_meal, Вы писали:

_>ИМХО, ClanId — должен быть int, а не Optional<int>. Скажем сервисная функция GetClanInfo(ClanId clan_id) не должна принимать NotSet, а GetPlayerInfo может вернуть NotSet в поле ClanId, и я бы предпочел, чтобы в обоих случаях это было отражено в сигнатуре.


Ну и какие проблемы, делаем так:
struct ClanId {
    public int Value { get {
        if(HasValue)
            return value_;
        throw ...
    }}

    public bool HasValue { get { return Value != 0; }}
}

ClanInfo GetClanInfo(int clan_id) {}

class PlayerInfo {
    ClanId clanId;
    ...
}

...
PlayerInfo pi = ...
ClanInfo ci;

if(pi.clanId.HasValue)
    ci = GetClanInfo(pi.clanId.Value);


У вас на прямо сейчас примерно так же и выглядит. Потому что публичный интерфейс у struct ClanId и struct Optional<int> идентичный (я ориентировался на Nullabl<int>, бо вашего Optional в глаза не видел, но не суть).


_>Одна из возможных мотиваций для констант после where — экономия трафика — тоже не проходит, так как если не использовать variable encoding, то для NonSet получим 4 байта вместо 1 байта (а часто — бита)


Обычно int передают в 7-мибитной кодировке.
А когда речь о передаче бита, то это обычно речь о передаче больших структур или массива структур через автогенеренный код, который точно так же в теле сериализации ветвится через точно такое же HasValue.


_>а с variable encoding мы стараемся быть осторожнее, так как в случае частого использования и большого числа мелких пакетов нагрузка на cpu может дать больше вреда, чем минимальная экономия трафика — пользы (впрочем, если до этого дойдет, нужно конечно замерять, задумываться об этом имеет смысл лишь для очень частых событий).


Еще раз.
Да какая разница, если код сериализации ориентируется на HasValue?


_>Здесь мы тоже не можем по типу отличить обязательно наличествующее значение от опционального.


Не понял, почему не можете, если в DSL описано:
type ClanId = Optional<int> where NotSet = 0;

Кто не может отличить?
Код сериализации?
Или программист, которому студия подскажет интиллисенсом?

Ты же сам говорил, что в пакете обновлений тебе придет Optional.
Ну вот пришло Optional<ClanId>, где сам ClanId — тоже эдакий optional.

Программист в вашем стиле пишет:
void UpdateXXX(PlayerPDU pdu) {
   if(pdu.clanId.HasValue) {
      player.clanId = pdu.clanId.Value;
      player.clanInfo = GetClanInfo(player.clanId);
   }
   ...
}

class ClanInfo {...}

ClanInfo GetClanInfo(ClanId clanId) {
    if(!clanId.HasValue)
        return null;

    return RetrieveClanInfoFromCacheOrServer(clanId.Value);
}



_>Небольшая экономия памяти не кажется достаточной компенсацией.


Для простых int это экономия вдвое.
И для игр экономия памяти и эффективная её разметка — это первое дело.
Просто у вас объектов в играх, похоже, немного или активность объектов низкая, поэтому вы не паритесь.


_>Ну и не работает обобщенный код для Nullable и ??, что может быть или не быть неудобством в конкретных случаях.


Тю.
interface INullable<T> {
    bool HasValue { get; }
    T Value { get; }
}

struct ClanId : INullable<int> {...}

void SerializeHeader(T nullable, Formatter<bool> f) where T : INullable<T>
{
    f.Write(nullable.HasValue);
}

void SerializeBody(T nullable, Formatter<T> f) where T : INullable<T>
{
    if(nullable.HasValue)
        f.write(nullable.Value);
}

В заголовке пакета идут биты для nullable-полей, далее сами поля.


_>Но честно говоря, я не понимаю, зачем нужно искать замену Optional в случае его использования по самому что ни на есть прямому назначению.


Потому что есть только негодный Nullable в системной библиотеке, с отсутствующей инфраструктурой и нулевой функциональностью.

Посмотри сюда:
https://github.com/nlkl/Optional/blob/master/Optional/Option_Maybe.cs
ValueOr/Or/Else/Filter/FlatMap — и т.д.

Утилитный код по ссылке можно организовать в виде методов-расширений для INullable<T>.

А вот это: Contains/Exists/GetEnumerator — весьма остроумно, ИМХО.
Позволяет рассматривать Option<> в том числе как пустой список (нет значения), либо как список с единственным элементом (есть значение).
Тоже для обхода/сериализации подойдёт.

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


_>Нужно ли что-то менять в системе апдейт-рекордов — вопрос для нас еще открытый.


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

Разумеется, твоя задача не бросаться сходу делать как подсказывают, а лишь коллекционировать идеи, среди которых потом обычно "выстреливает" не какая-то одна, а удачная комбинация их.
Отредактировано 27.02.2017 6:44 vdimas . Предыдущая версия .
Re[10]: Опциональные типы
От: vdimas Россия  
Дата: 27.02.17 03:45
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>В С++ тоже ввели (nullptr), но 0 оставили для совместимости. Из-за этого нуля много проблем было.


Проблема более широкая — это автоматическое (implicit) приведение типов.
Конкретно с 0-м из-за этого была всего одна проблема:
void foo(void *) { std::cout << "void*" << std::endl;  }
void foo(int) { std::cout << "int" << std::endl; }

foo(NULL);
foo(nullptr);

выведет:
int
void*

А так-то, из-за "широты" проблемы даже была идиома safe bool.
Посмотри в конце статьи решение для С++11 — всего-то добавили explicit для operator bool().

Для операторов if/when/for и логических &&/|| и т.д. — приведение к bool считается за "explicit", поэтому позволяет сохранять прежний код.
Re[8]: Опциональные типы
От: vdimas Россия  
Дата: 27.02.17 05:29
Оценка:
Здравствуйте, VladD2, Вы писали:

V>>Но ведь именно в случае Optional объявление предварительно "пустого" extractedValue убивает всю идею на корню.

V>>Не видишь разве сам?
VD>Вижу, что ты в очередной раз трепишься вместо того, чтобы просто спросить у знающих людей.

Кстате, смотрю в Java 8 добавили Optional и в нём та-да-ам:
opt.ifPresent( x -> System.out.println("found " + x));


Или можно взглянуть сюда:
https://github.com/nlkl/Optional

public T ValueOr(T alternative) => hasValue ? value : alternative;

public T ValueOr(Func<T> alternativeFactory) ...

public void MatchSome(Action<T> some) {
    if (hasValue)
        some(value);
}

public Option<TResult> Map<TResult>(Func<T, TResult> mapping) ...


Т.е., я ошибся только во второй части этого утверждения:

Единственное нормальное решение в ООП — через колбэк. Но, боюсь, индустрия как такому "нормальному решению" может оказаться не готовой, ы-ы-ы.

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

=========
Знающие люди мыслят одинаково, заметь.
А незнающие — каждый на свой ляд. ))
Отредактировано 27.02.2017 5:38 vdimas . Предыдущая версия .
Re[12]: Опциональные типы
От: vdimas Россия  
Дата: 27.02.17 06:38
Оценка:
Здравствуйте, VladD2, Вы писали:

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

V>>"Пролетарское чутьё" не считается.

VD>ИЧСХ, ты то считаешь.


Я выбирал "пролетарским чутьём" из нескольких авторов, где у каждого, таки, БЫЛИ обоснования своих утверждений.
Выбирал по признаку их полноты и непротиворечивости.

А тут было замечание насчет отсутствия обоснований.
Re[20]: Опциональные типы
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.02.17 08:43
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>http://thesz.livejournal.com/1486500.html

WH>

WH>Я тут бьюсь с ANTLR4, который отдельные файлы с VHDL кодом разбирает ужасающе долго (со скоростью в 8К байт в секунду и даже меньше). Это, натурально, беда.

WH>В общем далеко ему ещё до промышленного качества. А то что его используют так это от того что остальное ещё хуже.

Почитал его статью Adaptive LL(*) Parsing: The Power of Dynamic Analysis. Там на 11-13 страницах есть отчет о производительности и сравнение с другими языками.

Отчет очень интересный, так как там показаны результаты и других технологий. В том числе там ест результаты GLR/GLL. Причем один из GLR-ов показал относительно не плохой результат (правда все равно в 4 раза медленнее АНТЛР-а), но дико слил на одном большом файле. Из чего авторы делают вывод о непредсказуемости производительности GLR/GLL-ов.

И действительно там на 12-й странице написано про тормоза на некоторых грамматиках.

Grammar     KB/sec
XML         45,993
Java        24,972
JSON        17,696
DOT         16,152
Lua          5,698
C            4,238
Verilog2001  1,994
Erlang       751


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

Some of these grammars yield reasonable but much slower parse times compared to Java and XML but demonstrate that
programmers can convert a language specification to ANTLR’s meta-syntax and get a working grammar without major modiGrammar

fications. (In our experience, grammar specifications are rarely tuned to a particular tool or parsing strategy and are often ambiguous.)
Later, programmers can use ANTLR’s profiling and diagnostics to improve performance, as with any programming
task. For example, the C11 specification grammar is LL not SLL because of rule declarationSpecifiers, which we altered
to be SLL in our C grammar (getting a 7x speed boost).


То есть для достижения высокой скорости парсинга грамматику нужно приводить к загадочному SLL-классу (Strong LL):

Parsers that ignore the parser call stack for prediction are called Strong LL (SLL) parsers. The recursive-descent parsers
programmers build by hand are in the SLL class. By convention, the literature refers to SLL as LL but we distinguish the
terms since “real” LL is needed to handle all grammars. The above grammar is LL(2) but not SLL(k) for any k, though
duplicating A for each call site renders the grammar SLL(2).

Creating a different lookahead DFA for each possible parser call stack is not feasible since the number of stack permutations
is exponential in the stack depth. Instead, we take advantage of the fact that most decisions are not stack-sensitive and build
lookahead DFA ignoring the parser call stack. If SLL ATN simulation finds a prediction conflict (Section 5.3), it cannot be
sure if the lookahead phrase is ambiguous or stack-sensitive.
In this case, adaptivePredict must re-examine the lookahead using the parser stack γ0. This hybrid or optimized LL mode
improves performance by caching stack-insensitive prediction results in lookahead DFA when possible while retaining full
stack-sensitive prediction power. Optimized LL mode applies on a per-decision basis, but two-stage parsing, described next,
can often avoid LL simulation completely. (We henceforth use SLL to indicate stack-insensitive parsing and LL to indicate
stack-sensitive.)


Это конечно косяк. Но, тем не менее, SLL-грамматик скорость у них очень даже высокая.

А вот GLR-ам эта статья ставит однозначный приговор.

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

WH>Когда с парсером возились там вообще беда была. Любое изменение алгоритма восстановления и генерация ошибок ломалась.


Это — да. Собственно одна из причин по которой я сделал сбор ошибок на посетителе и была постоянные изменения алгоритмов и кишков. А обходчики ты уже сам чинил, так что с тех пор я ни разу этот код не переписывал.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Опциональные типы
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.02.17 09:39
Оценка: +1
Здравствуйте, vdimas, Вы писали:

V>Ну мы же идиому обсуждаем.


Мне кажется ты уже опозорился по полной. Дальше этот цирк продолжать бессмысленно. Все кто в теме поняли, что ты просто не умеешь признавать своей не правоты.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Опциональные типы
От: vdimas Россия  
Дата: 27.02.17 10:16
Оценка: :)
Здравствуйте, VladD2, Вы писали:

VD>Мне кажется ты уже опозорился по полной.


Мало ли кому что кажется?
Объективная реальность с тобой не согласна:
http://www.rsdn.org/forum/philosophy/6709512.1


VD>Дальше этот цирк продолжать бессмысленно.


Дык, не надо превращать обсуждение в цирк.
Можешь говорить по-делу — говори.
Не можешь — читай.


VD>Все кто в теме поняли


Все кто в теме, делают как я.
Сходи по ссылке, убедись.


VD>что ты просто не умеешь признавать своей не правоты.


Что я должен "признать", если не вижу ответов на вполне конкретные технические претензии?
Признавать нечего, я вижу слив.

==========
А встрял ты, действительно, зря. У тех кто в теме может может сложится такое странное ощущение, что в Немерле банально некому делать ревью на твой код. Иначе чем объяснить наличие вот такой реализации:
https://github.com/rsdn/nemerle/blob/master/lib/option.n#L217
Re[9]: Опциональные типы
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.02.17 10:32
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Кстате, смотрю в Java 8 добавили Optional и в нём та-да-ам:

V>
V>opt.ifPresent( x -> System.out.println("found " + x));
V>


Как же так? По твоей же теории в не функциональном языке без вариантов такое невозможно!

V>Или можно взглянуть сюда:

V>
V>public T ValueOr(T alternative) => hasValue ? value : alternative;
V>


Ой! Твоя теория распадается? Или ты все же решил признать очевидное?

V>Т.е., я ошибся только во второй части этого утверждения:...


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

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

Все твои утверждения были ложными. А именно:
1. Option спокойно можно реализовать в виде Value-типа. Это собственно доказано реализацией из Немерла.
2. Варианты (они же: размеченные объединения, tagged unions, discriminated unions, disjoint union, sum type) можно реализовать в виде Value-типов. Это доказано просто их исходным названием (tagged unions), описанием и примерами реализации на С++.
3. Варианты спокойно могут быть в не функциональном языке. И вообще понятие функционального языка очень размытое.
4. Паттерн матчинг (ПМ) возможен не только вариантам, но и по любым типам. Причем типы даже не обязаны быть полиморфными, так как ПМ может проверять структуру типа (значения его членов).

Все твои придирки к конкретным реализациям не более чем попытка увести разговор в строну. Убери те члены которые тебе не нравятся и ровным счетом ничего не изменится.

Ну, а синтаксически все это можно завернуть в операторы или другие фичи языка.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Опциональные типы
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.02.17 10:34
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Проблема более широкая — это автоматическое (implicit) приведение типов.


Никто не спорит. У С++ тяжелое наследство.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Опциональные типы
От: vdimas Россия  
Дата: 27.02.17 11:42
Оценка:
Здравствуйте, WolfHound, Вы писали:

V>>Главное то, что ты сам не понимаешь, когда уже отрываешься от реальности и начинаешь спорить не с живыми людьми, а с голосами в голове.

WH>ЗТ в С++ это точно голоса.

Язык шаблонов — тьюринг полон, динамический бестиповый в исходном виде, позволяет производить вычисления в compile-time.
Однако, за счет нескольких простых трюков позволяет накладывать "типизацию" разных видов: перечисление, ограничения (type_traits как пример), в т.ч. получать параметрический полиморфизм и ЗТ в том виде, как его реализуют на HGC:
https://www.slideshare.net/fprogru/haskell-15961414
(через арифметику Пеано)

РАЗУМЕЕТСЯ, с произвольно большими диапазонами значений такая реализация ЗТ не справится ни в Хаскеле, ни на шаблонах С++.
Но это и так очевидно, не?


V>>А разве это не ты там несколько постов сам с собой спорил, не в состоянии как Брат Нибеэнимэда связать двух слов и объяснить коллегам, чего ты там сам с собой так до смерти воюешь-то?

WH>Я сразу сказал в чём проблема.

Проблема тут в другом.
Ты периодически попадаешь в состояние "укушенности" некоторой интересной тебе темы и происходит в точности одно и то же — начинаешь упоминать эту тему как офтоп в рамках других обсуждений. Сценарий получается удивительно стабильным:
— а вот тут, а вот смотрите, круто? (минимум инфы, озвучивание проблематики отсутствует как класс)
— ну и? (не вникая)
— да вы ни черта не понимаете, дебилы все, простейшие вещи понять не можете!!!1111
— эммм...

Тогда ты поставил проблему вот так: "вот вам градиентное изображение, а вот артефакты".

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

А для студента и инженера можно было озвучить совсем кратко: при перемешивании пикселей с альфаканалом последний задаёт веса компонент. И фсё! Даже формулы приводить не надо, в одном предложении содержится и проблематика и очевидное её решение.


WH>Но ты начал разговаривать с голосами в голове про фильтры.


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

Ты же показал результат наложения градиентного изображения на белый фон, где в итоге какой-нить блеклый синий цвет (127, 127, 192) мог быть получен, например, вот так: (0, 0, 255) + прозрачность 50%. Или еще кучей способов.

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


V>>Ты не в состоянии связать двух слов.

V>>Сверху этого полнейшая неадекватность.
WH>Со мной не все соглашаются, но что характерно не понимаешь меня только ты. Может в тебе проблема?

Да ладно. Я все годы наблюдаю как ты постоянно кого-то обвиняешь в тупости, хотя речь всегда о чем-то несложном.
Там с градиентами тебя тоже сходу ваапще никто не понял, бо ты проблематику не озвучил.
Это я уже по решению задачи догадался об её условии (могу в одном и том же обсуждении и "отстреливаться" на хамство и вникать по-существу).
А другие и париться не стали — тупо проигнорили тот твой офтоп и свалили из обсуждения.
В итоге, тут совсем мало тех, кто в состоянии с тобой длительно общаться (т.е. до того момента, как тема будет разобрана "по косточкам").
Ты бы эта... берег бы нервы немногочисленных своих собеседников.
Отредактировано 27.02.2017 11:51 vdimas . Предыдущая версия .
Re[12]: Опциональные типы
От: vdimas Россия  
Дата: 27.02.17 12:05
Оценка:
Здравствуйте, VladD2, Вы писали:

V>>Проблема более широкая — это автоматическое (implicit) приведение типов.

VD>Никто не спорит. У С++ тяжелое наследство.

Да, совместимость с С.
Однако, не было бы такой совместимости, язык не взлетел бы.

Сейчас уже всё идёт к тому, чтобы окончательно порвать с этой совместимостью на уровне исходников — уже в язык С хотят добавить элементы, которые заведомо не будут поддержаны в С++. Ну и ОК. Мавр сделал своё дело, мавр может уходить.
Re[10]: Опциональные типы
От: vdimas Россия  
Дата: 27.02.17 12:37
Оценка:
Здравствуйте, VladD2, Вы писали:

V>>Кстате, смотрю в Java 8 добавили Optional и в нём та-да-ам:

V>>
V>>opt.ifPresent( x -> System.out.println("found " + x));
V>>

VD>Как же так? По твоей же теории в не функциональном языке без вариантов такое невозможно!

Не надо меня перевирать:

Поэтому, в ООП стиле "окончательно правильно" можно только так:

Optional<MyType> optional = getValueFromSomewhere();
optional.tryExtract(extractedValue => { /* callback */ });



V>>Или можно взглянуть сюда:

V>>
V>>public T ValueOr(T alternative) => hasValue ? value : alternative;
V>>

VD>Ой! Твоя теория распадается? Или ты все же решил признать очевидное?

Опять не надо меня перевирать:

Даже взять извлечение дефолтного значения, вот это правильный код (option[T]):

    public WithDefault (val : T) : T
    {
      match (this) {
        | Some (v) => v
        | None => val
      }
    }


А вот за это руки поотрывать и отлучать от программирования на веки вечные (ValueOption[T]):
public GetValueOrDefault() : T { _value }



VD>Не. Ты с самого начала был не прав и (похоже) уже это осознал. Но пока не готов признать свою ошибку и пытаешься выкрутиться.


Я жду указания на мою ошибку.
А так же ответов на претензии технического плана.


VD>Советую тебе научиться признавать свою неправоту. В этом нет ничего зазорного. Наоборот, вот такие вот попытки выкрутиться выглядят намного хуже.


Покажи попытку выкрутиться.


VD>Все твои утверждения были ложными. А именно:

VD>1. Option спокойно можно реализовать в виде Value-типа. Это собственно доказано реализацией из Немерла.

Варианты вполне могут быть value-типами.
Я утверждал, что в ФП варианты чаще делают ссылочными типами — и на это есть причины.

И да. У тебя там не вариант.


VD>2. Варианты (они же: размеченные объединения, tagged unions, discriminated unions, disjoint union, sum type) можно реализовать в виде Value-типов.


Не утверждалось что нельзя.
Тем более, что я рядом сам показал, что CORBA и COM IDL генерят для С++ варианты как просто структуры.
Но в этом языке размеченные объединения не поддерживаются.


VD>3. Варианты спокойно могут быть в не функциональном языке. И вообще понятие функционального языка очень размытое.


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


VD>4. Паттерн матчинг (ПМ) возможен не только вариантам, но и по любым типам.


С открытой структурой.
Иначе это будет просто сахар над цепочкой if-else-if...


VD>Причем типы даже не обязаны быть полиморфными, так как ПМ может проверять структуру типа (значения его членов).


Полиморфный или нет тут ортогонально.


VD>Все твои придирки к конкретным реализациям не более чем попытка увести разговор в строну.


В сторону ОТ ЧЕГО?
Я задвинул, что вот это зло:
    public Value : T
    {
      get
      {
        if (HasValue) _value 
        else assert(false, "try use Value when it not set");
      }
    }

Немерле тут не при чём.
Это точно такое же зло в любом языке, будь то C#, Java или С++.

И я совершенно не собираюсь уводить разговор в сторону от этого, а стою на своём — аналогом ПМ для ООП являются колбэки.
Но ввиду "тяжеловесности" этой техники, она была ранее не популярна.
Наверно поэтому и не был популярна в ООП идиома Optional.


VD>Убери те члены которые тебе не нравятся и ровным счетом ничего не изменится.


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


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


Да, но я и тут сделал замечания:
1. В квадратных скобках лежит нечто плохочитаемое:
[ExtensionPattern(VSome(value) = ValueOption where(HasValue=true, Value=value))]
[ExtensionPattern(VNone()      = ValueOption where(HasValue=false))]
public struct ValueOption[T]

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

2. Спросил, что будет в ситуации (None, None):
def Plus(x : optin[int], y : optin[int])
{
  | (Some(x), None)    => x
  | (None,    Some(y)) => y
  | (Some(x), Some(y)) => x + y
}

Предположил, что компилятор ругаться не будет, а в рантайм вернется дефолтное значение (я Немерле не знаю).
Если я правильно предположил, то хотелось бы знать — ПОЧЕМУ?
Как раз тут мне хотелось бы быть не правым. ))
Отредактировано 27.02.2017 12:38 vdimas . Предыдущая версия .
Re[13]: Опциональные типы
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.02.17 13:20
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Да, совместимость с С.

V>Однако, не было бы такой совместимости, язык не взлетел бы.

С времен когда совместимость с С что-то значила прошло уже 20 лет. А проблемы остаются и по ныне.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Опциональные типы
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.02.17 13:42
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Не надо меня перевирать:


Помилуй! Никто и не собирался перевирать. Вот твои исходные утверждения:

Например, в ФП языках некий Т был value-тип (ну вот так компилятор решил), а после заворачивания F(T) всегда получаем ссылочный тип. Итого, храним лишнюю ссылку вместо значения.


Я тебе показал используемый на практике ValueOption в функциональном языке, что полностью опровергает твои утверждения. Но тебе по фиг. Та тым какие-то новые отмашки придумываешь.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Опциональные типы
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.02.17 14:47
Оценка: -1
Здравствуйте, alex_public, Вы писали:

VD>>Назови хотя бы 3-4 аналога написанного на С++ и объясни почему движки IDE и компиляторы теперь пишут на управляемых языках? Может они не так уж и медленны?


_>Ну вообще то полно IDE и на C++ (тот же QtCreator,


Раз! Два то будет?

_>да и VS по сути тоже, хотя сейчас уже не целиком, но я пользовался как раз полностью нативной),


Ты живешь в плену своих домыслов и фантазий. В реальности VS была нативной только во времена VS 6, но это совсем другой продукт. А VS.NET (первая версия современной студии) уже содержала некоторый объем управляемоего кода.

С каждым годом объем управляемого кода в VS рос. И сейчас уже самые значимые ее части переписаны на GC-языка.

Ты не можешь не пользоваться только нативной частью, так как весь GUI в VS сделан на GC-языках. Гуй в Студии теперь WPF-ый. Даже редактор кода переписан с нуля на C#. Я это точно знаю, так как дебажу его (в декомпилированном виде) каждый день.

_>причём они в отличие от указанных Java IDE не имеет слабого, но раздражающего торможения


Да? Значит тебя удовлетворят скорость дотнета .

Кстати, многие считают, что IDEA работает быстрее студии. Так что твое утверждение тоже спорно.

_>(говорю по личному опыту, так что могу гарантированно продемонстрировать).


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

Я тебе еще одну злую шутку Майкософта открою. С некоторого времени проектная система для С++ в VS была переписана на C#.

_>А уж если говорить про компиляторы, то вообще смешно — если предложить gcc работать с такими объёмами как в .net, то он будет компилировать молнией.


Вылезать из своих иллюзий. Объемы исходников на Шарпе и Явы существенно больше С++-ных. И обрабатываются они за секунды. Так, например, на парсинг 123 мегабайтов исходников библиотек Java парсятся компилятором явы за 4 секунды.

Понятие "тормоза менеджед-языков" очень расплывчатое. Эти тормоза они относительные. Относительно идеального кода на С++ такой же идеальный код на Шарпе или Яве будет медленнее. Но это не значит, что кода на GC-языках неприемлемо медленный. Он весьма быстрый. Его хватает для реалтайм-парсинга тех же исходников и для их редактирования в редакторе кода. Зато использование GC-язков позволяет писать более сложный код. Новый редактор Студии не сравится с поделкой на С++ используемой в прошлых ее версиях (до 2010). Он реализует "неизменяемую", версионную модель редактирования. В любой момент времени у редактора можно запросить моментальный слепок кода и это будет не очень дорогой операцией.

VD>>Может как раз AST на GC строится быстрее?


_> Ты похоже иногда не понимаешь разницу между курицей и яйцом.


Гы-гы. Верь в это.

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


Ну, конечно, не понимаю. Я правда тебе это говорил в соседней ветке, но конечно не понимаю. Верь в это.

_>Хотя бы потому, что рантайм языков с GC пишется на языках без GC. ))) А вот обратное уже не верно — в языке с обязательным GC обычно нет возможности нормального использования других механизмов.


А какая тут связь с АСТ? Ты предлагаешь написать на С++ аналог GC чтобы соревноваться с GC. Это совершенно правильный подход, но это все требует не малого объема кода и ручного контроля. А в GC-языке мы получаем все тоже самое, но из коробки без единой строчки кода.

Вот прикинь куча GC — это и есть пул. Только в этом пуле все ссылки контролируются и можно производить дефрагментацию.

А вот если ничего не делать и написать код на С++ в лоб, то получится даже медленее чем на Яве.

Еще надо не забывать, что у GC-языков из коробки доступна компонентная инфрмструктура. Мне не составит труда создавать часть АСТ из другой ДЛЛ. А в С++ на это надо специально рассчитывать, так как многие шаблонные техники пашут только во время компиляции.

_>Вообще есть такая забавная страничка: http://www.lextrait.com/Vincent/implementations.html, на которой интересны даже не сами факты, а комментарии (например типа того что у ScyllaDB и т.п... ) )))


Читай эту страничку, если она тебе душу греет. Но все же ответь на мой вопрос. Почему IDE перестали писать на С++, а имеющиеся переводят на GC-языки?

Вот возьми ту же VS. Ей недавно исполнилось 20 лет. Первые её версии были целиком на С++. В версии VS.NET от 2002 года там появились первые куски написанные на C#. По началу их было не много. Но время шло и на сегодня уже большая часть VS написана на C#.

Зачем MS переводит VS на C#, если это так плохо, а С++ — это так круто? Почему они переписали на C# компилятор того же C#? Почему даже проектную модель для С++ (в Студии) переписали на GC-языках?

Почему все новые IDE или плагины пишутся на GC-языках?

Где новые IDE на С++?

Вот ты смог назвать только QtCreator. Я его в глаза не видел, но уверен, что его функциональность не сравнима с РеШарпером или КодРашем. А скорость она должна быть достаточной. Вот ты сам того не знаю похвалил IDE в которой большая часть критичного к скорости кода написана на C#.

Ответ на эти вопросы просты, но не удовлетворят тебя:
1. Потому что разрабатывать на GC-язках проще.
2. Потому что скорости предоставляемой GC-языками хватает для решаемых задач.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[19]: Опциональные типы
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.02.17 14:50
Оценка: +1
Здравствуйте, _NN_, Вы писали:

_NN>Люди хотят ничего не ставить и чтобы работало.


В этом отношении у Явы все намного удобнее. Саму Яву можно поставлять в виде каталога внутри основного продукта. Не раз видел, что разные плагины к Эклипсу доступны не только в виде плагина из галереи, но и в виде zip-архива в котором лежит Эклип, Ява и установленный в Эклипс плагин. Тупо качаешь архив, распаковываешь и используешь плагин в Эклипсе. Очень просто получается.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Опциональные типы
От: vdimas Россия  
Дата: 27.02.17 15:25
Оценка: +1
Здравствуйте, VladD2, Вы писали:

V>>Да, совместимость с С.

V>>Однако, не было бы такой совместимости, язык не взлетел бы.
VD>С времен когда совместимость с С что-то значила прошло уже 20 лет. А проблемы остаются и по ныне.

На уровне заголовочных файлов эта совместимость востребована прямо сейчас.
АПИ современных ОС почти всегда идут в С-заголовках.
Т.е. инерционность этого момента — колоссальная.
Re[15]: Опциональные типы
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.02.17 15:38
Оценка:
Здравствуйте, vdimas, Вы писали:

V>На уровне заголовочных файлов эта совместимость востребована прямо сейчас.


Не особо.

V>АПИ современных ОС почти всегда идут в С-заголовках.


Довольно глупо работать на уровне АПИ ОС. К тому же есть другие методы описания этих самых АПИ. Я вот только вчера использовал 4 функции из WinAPI. Никаких проблем с ними не возникло. На их поиск и описание затратил меньше процента времени от исходной задачи. Многие были нужны только в отладочных целях (рисовал на экране квадрат соответствующий активно области в редакторе). Все что нужно нашел на http://www.pinvoke.net. Вот этот код:

    [DllImport("user32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool GetCursorPos(out POINT point);
    public static POINT? GetCursorPos() => GetCursorPos(out var point) ? (POINT?)point : null;

    [DllImport("user32.dll")]
    public static extern IntPtr WindowFromPoint(POINT point);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);
    public static RECT? GetWindowRect(IntPtr hWnd)=> GetWindowRect(hWnd, out var rect) ? (RECT?)rect : null;

    [StructLayout(LayoutKind.Sequential)]
    public struct POINT
    {
      public int X;
      public int Y;

      public POINT(int x, int y)
      {
        X = x;
        Y = y;
      }

      public POINT(Point     p) : this(     p.X,      p.Y) { }
      public POINT(Wpf.Point p) : this((int)p.X, (int)p.Y) { }

      public static implicit operator Point    (POINT p) => new Point    (p.X,      p.Y);
      public static implicit operator POINT    (Point p) => new POINT    (p.X,      p.Y);
      public static implicit operator Wpf.Point(POINT p) => new Wpf.Point(p.X,      p.Y);
      public static implicit operator POINT(Wpf.Point p) => new POINT    (p);

      public override string ToString()
      {
        return $"POINT {{ X={X} Y={Y} }}";
      }
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
      public int Left;        // x position of upper-left corner
      public int Top;         // y position of upper-left corner
      public int Right;       // x position of lower-right corner
      public int Bottom;      // y position of lower-right corner

      public RECT(int left, int top, int right, int bottom)
      {
        Left   = left;
        Top    = top;
        Right  = right;
        Bottom = bottom;
      }

      public Size      Size    => new Size     (Right - Left, Bottom - Top);
      public Wpf.Size  WpfSize => new Wpf.Size (this.Size.Width, this.Size.Height);
      public Point     Pos     => new Point    (Left, Top);
      public Wpf.Point WpfPos  => new Wpf.Point(Left, Top);
      public Rectangle Rect    => new Rectangle(this.Pos, this.Size);
      public Wpf.Rect  WpfRect => new Wpf.Rect(this.WpfPos, this.WpfSize);

      public static implicit operator Rectangle(RECT p) => p.Rect;
      public static implicit operator RECT(Rectangle p) => new RECT(left:p.Left, top:p.Top, right:p.Right, bottom:p.Bottom);
      public static implicit operator Wpf.Rect(RECT p) => p.WpfRect;
      public static implicit operator RECT(Wpf.Rect p) => new RECT(left: (int)p.Left, top: (int)p.Top, right: (int)p.Right, bottom: (int)p.Bottom);

      public override string ToString()
      {
        return $"RECT {{Left={Left} Top={Top} Right={Right} Bottom={Bottom} Size={Size} }}";
      }
    }

    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr GetDC(IntPtr hWnd);

    [DllImport("user32.dll")]
    public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);

    [DllImport("gdi32.dll", EntryPoint = "CreateSolidBrush", SetLastError = true)]
    public static extern IntPtr CreateSolidBrush(int crColor);

    [DllImport("user32.dll")]
    static extern int FillRect(IntPtr hDC, [In] ref RECT rect, IntPtr hbr);

    public static void FillRect(RECT rect)
    {
      IntPtr desktop = GetDC(IntPtr.Zero);
      var blueBrush = CreateSolidBrush(0x0000FF);
      FillRect(desktop, ref rect, blueBrush);
      ReleaseDC(IntPtr.Zero, desktop);
    }


V>Т.е. инерционность этого момента — колоссальная.


Самого C API — да. Описания в виде сишных хэадеров — нет.

С++-ные же типы и хеадеры вообще не нужны в современном языке. Они слишком частны и мало применимы в других языках.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[21]: Опциональные типы
От: WolfHound  
Дата: 27.02.17 15:52
Оценка:
Здравствуйте, VladD2, Вы писали:

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

Исключительно во время восстановления. Там Эрли улетает в O(N^2) при этом порождая экспоненциально большой лес деревьев разбора. Как чинить в принципе ясно. Но пока не чинил.
Основной парсер строго линейный на всех поддерживаемых грамматиках.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[12]: Опциональные типы
От: WolfHound  
Дата: 27.02.17 16:06
Оценка:
Здравствуйте, vdimas, Вы писали:

V>РАЗУМЕЕТСЯ, с произвольно большими диапазонами значений такая реализация ЗТ не справится ни в Хаскеле, ни на шаблонах С++.

V>Но это и так очевидно, не?
Очевидно, что это профанация, а не ЗТ.

V>Тогда ты поставил проблему вот так: "вот вам градиентное изображение, а вот артефакты".

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

V>Заметь, как я расписал проблему словами для совсем уж нулевой подготовки, т.е. даже школьник-старшеклассник поймет с первого раза.

Нет. Ты начал бредить про фильтры.

V>Ес-но, первым делом было предположить ошибку в фильтре, тем более обсуждали их.

До тебя их не обсуждали.

V>Да ладно. Я все годы наблюдаю как ты постоянно кого-то обвиняешь в тупости, хотя речь всегда о чем-то несложном.

Хватит приписывать мне свои черты характера... ты эту тему прочитай... у тебя это в каждом втором сообщении.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.