Войти
ПрограммированиеФорумОбщее

Типизированные int'ы (4 стр)

Страницы: 13 4 5 69 Следующая »
#45
20:36, 14 июля 2019
Хотел идти спать, но черти понесли меня открыть гдрушечку и зайти в эту тему.... -_-

Suslik
> Типизированные int'ы
Хорошая идея. Она должна работать на уровне компиляции, по аналогии, как это делается с public/private или const/не_const: рантайму пофиг, в нём никаких проверок, но компилятор следит. Так и тут, в рантайме должны быть чистые индексы.
Иногда проблема решается через enum, но тут не тот случай.

Давайте я такое решеньице предложу.

+ класс индекса
+ класс контейнера, на коленке, чисто показать, как
+ где-то где-то в коде

Жду ваших мыслей по этому поводу.

Анекдот "хотел идти спать": приходит пьяное-пьяное Оле-Лукое домой:
- Криблее... Краблее... нетбле... всёбле.... спатьблее....
#46
21:15, 14 июля 2019

Есть такой язык, Haxe. В нем такая штука прямо на уровне языка есть, вроде с самого его зарождения; более 10 лет как. Называются абстракты

Вот пример. Не совсем с указателями: в данном случае типизированные ключи массива. В рантайме массив будет обычным, а ключи – интами. Но компилятор заругает, если попробовать отдать просто инт в качестве ключа.

class Test {
    public static function main() {
        var myArray = new MyCollection(1);
        var myIntKey = new MyIntKey(0); // value 0 of int type after compilation
        myArray[myIntKey] = "Hi";
        trace(myArray[myIntKey]);
      // trace(myArray[0]); // compile-time error
    }
}


abstract MyCollection(Array<String>) {
    public inline function new (size:Int) this = [for (i in 0...size) null];

    // overload [] access operator. this way we can use [] access with any type and cost of zero-overhead
    @:arrayAccess public inline function get(key:MyIntKey):String {
        return this[key.asInt()];
    }

    @:arrayAccess public inline function set(key:MyIntKey, val:String):String {
        return this[key.asInt()] = val;
    }
}

abstract MyIntKey(Int) {
    public inline function new(val) this = val;

    public inline function asInt():Int return this;
}

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

// Generated by Haxe 3.3.0
(function () { "use strict";
var Test = function() { };
Test.main = function() {
  var _g = [];
  var _g2 = 0;
  while(_g2 < 1) {
    ++_g2;
    _g.push(null);
  }
  var myArray = _g;
  var myIntKey = 0;
  myArray[myIntKey] = "Hi";
  console.log(myArray[myIntKey]);
};
Test.main();
})();

Но вообще, можно скомпилить и в плюсы и еще в кучу всяких вариантов.

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

Автор языка Николя Канассе, помимо компилятора, фигачит еще свой движок, heaps, который поддерживает написание шейдеров на сабсете хакса. Во время компиляции шейдеры преобразуются в синтаксическое дерево, и так хранятся в рантайме. И в рантайме же преобразуются в glsl или hlsl непосредственно перед линковкой. Это позволяет динамически и типобезопасно компоновать шейдер (навешивать эффекты, например).
На этом двигле уже вышло несколько успешных игор. Как от студии самого Николя – Evoland (1,2), Northgard, так и от их друзей – DeadCells.

#47
(Правка: 21:43) 21:43, 14 июля 2019

dirmenbitz
> Есть такой язык, Haxe.
посмотрел, очень интересно (выглядит как джава без гигабайтного тормозного движка)

а большие проекты есть на нем? (на посмотреть)

#48
21:47, 14 июля 2019

pahaa
> Доступ через asDouble - не то, доступ без asDouble - тоже не то. Бывает ещё
> какой-то способ?
Ага. Как я и сказал запрещать надо только неявное приведение типов.
Можно зайти еще дальше и сделать оператор приведения к типу доступным только в тех функциях где он действительно нужен.
А asDouble это не более чем способ сделать "по быстрому и без многабукаф". Если цель именно в этом - вперед.

#49
22:17, 14 июля 2019

Danilw

а большие проекты есть на нем? (на посмотреть)

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

Кроме того, язык используется здоровенными конторами типа MassiveInteractive и TiVo – там что-то с телевещанием интерактивным, у них там морды для телевизоров и куча тулинга. Не сильно вникал в их специфику, но часть тулз они опенсорсят на гитхабе.

Очень много движков и библиотек на все случаи жизни. Есть свой пакетный менеджер и каталог haxelib

Из опенсорсного есть армори и арморипэйинт (один чувак и то и другое пилит). Армори – это как юнити, только поверх блендера и kha. Арморипэйинт – типа сабстанспэинтера.

Много всякого добра в репах у OpenFL – как своего, так и портов с других языков.

#50
23:01, 14 июля 2019

dirmenbitz
звучит круто

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

в будущем обязательно посмотрю на движок и язык, пока с Годот вожусь

#51
23:28, 14 июля 2019

Danilw

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

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

Учитывая количество и разношерстность таргетов, я считаю уровень работы компилятора просто отменным. Лично я работал с таргетами C#, js, cpp, swf, python.

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

#52
23:52, 14 июля 2019

Great V.
> Ага. Как я и сказал запрещать надо только неявное приведение типов.
asDouble и есть явное приведение типов, не? или static_cast<>() - это что-то типа наркотика, без которого уже никак?

#53
8:02, 15 июля 2019

Suslik
> float totalDamage = GetTotalDamage(asteroidIndex, shipIndex);
Проблема от неправильной архитектуры:
float totalDamage = ship->GetTotalDamage(asteroidIndex);

#54
(Правка: 8:12) 8:10, 15 июля 2019

Olaf85
> Проблема от неправильной архитектуры:
> float totalDamage = ship->GetTotalDamage(asteroidIndex);
я правильно понимаю, что у адептов правильной архитектуры не бывает двух интов в аргументах одной функциях? сколько же в тред умников набижало, со своими поучениями, как правильно использовать ссылки, контейнеры и методы, не в состоянии понять, о чём, собственно, тред.

#55
8:27, 15 июля 2019

Suslik
Да попросту нет никакой проблемы. Языки с динамической типизацией успешно живут, хотя там можно передать что угодно и как угодно. Это только у шибко умных подход такой - выдумать на ровном месте проблему, долго бороться и, наваяв 10 килострок кода, победить. Ура, можно бежать придумывать новую проблему.

#56
(Правка: 9:23) 9:22, 15 июля 2019

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

#57
9:45, 15 июля 2019

Suslik
> у адептов "не иметь проблем на пустом месте", не бывает проблем на пустом месте
Fixed

#58
10:41, 15 июля 2019

Suslik
Хватит спорить. Ты посмотрел код, который я написал?

NyakNyakProduction
Это не проблема на пустом месте. Это существенно упрощает жизнь. Вот ещё вариант применения сабжа: часто в коде входные параметры проверяют на валидность, да? Вот это может делать сам класс типизированного int-а.

А так, да, можно писать на ассемблере, там всё в байтах, никаких проблем :)

#59
11:48, 15 июля 2019

Хорошо, сделали вы разные "особые инты", сильным тайпдефом или ее чем-то. Но теперь попробуйте представить количество кода обвязки, чтобы указать компилятору, какие операции над какими интами можно проводить, а какие - нет. Потому что сложить минуты с метрами вроде как нельзя... А умножить? Уже можно. А сложить метры с километрами можно. Но что должно получиться - метры или километры? И самая вишенка - а как быть с обычным интом? Как "инт, который метр" будет взаимодействовать с "обычным интом"? Кто в кого должен приводиться, кто не должен, явно или неявно? И любая достаточно простая система будет сквозить дырками и головняками.

meters m = 10;      // Хорошо, мы явно указали, что m - это метры.
auto m2 = m + 10;    // Так можно? То есть int неявно приводится к метрам? Какой тип m2?
auto m3 = 10 + m;    // А какой тип у m3?

sqare s = 100;
auto m3 = sqrt(s);    // А так можно? То есть квадратные метры неявно приводятся к инту? Или миллион перегрузок писать? Если первое, то как сказать, чтобы эта функция возвращала метры?
          // Если второе, то, вы что, с ума сошли?

А касательно разных типов индексов для массивов разных типов, то тут очевидная ошибка. Индекс - это индекс. Это целое число. И по определению не может быть разных типов для индекса. Хотите защиты от дурака - используйте итераторы, указатели или проверки времени исполнения. Нормальные люди (кроме убер-критических по скорости случаев) не хранят "массив астероидов" и "массив кораблей". Они хранят массив умных указателей на базовые игровые сущности, а в функции передают указатели на нужные нам объекты - наследники. Тут и устойчивость к удалению - вставке, и управлением временем жизни объекта. Намного больше всяких "защит".

Страницы: 13 4 5 69 Следующая »
ПрограммированиеФорумОбщее