1. Lua / Говнокод #25987

    0

    1. 001
    2. 002
    3. 003
    4. 004
    5. 005
    6. 006
    7. 007
    8. 008
    9. 009
    10. 010
    11. 011
    12. 012
    13. 013
    14. 014
    15. 015
    16. 016
    17. 017
    18. 018
    19. 019
    20. 020
    21. 021
    22. 022
    23. 023
    24. 024
    25. 025
    26. 026
    27. 027
    28. 028
    29. 029
    30. 030
    31. 031
    32. 032
    33. 033
    34. 034
    35. 035
    36. 036
    37. 037
    38. 038
    39. 039
    40. 040
    41. 041
    42. 042
    43. 043
    44. 044
    45. 045
    46. 046
    47. 047
    48. 048
    49. 049
    50. 050
    51. 051
    52. 052
    53. 053
    54. 054
    55. 055
    56. 056
    57. 057
    58. 058
    59. 059
    60. 060
    61. 061
    62. 062
    63. 063
    64. 064
    65. 065
    66. 066
    67. 067
    68. 068
    69. 069
    70. 070
    71. 071
    72. 072
    73. 073
    74. 074
    75. 075
    76. 076
    77. 077
    78. 078
    79. 079
    80. 080
    81. 081
    82. 082
    83. 083
    84. 084
    85. 085
    86. 086
    87. 087
    88. 088
    89. 089
    90. 090
    91. 091
    92. 092
    93. 093
    94. 094
    95. 095
    96. 096
    97. 097
    98. 098
    99. 099
    100. 100
    local money = 0
    local auto_money = 0
    local auto_money_lvl = 0
    local auto_money_buy = 50
    local bonus_money_lvl = 0
    local bonus_money_buy = 35
    local json_pip = require("json")
    local bacg = display.newRect(0,0,1080,1920)
    local button = display.newRect(160,190,175,175)
    button:setFillColor(0,0.4,0.3)
    local button_auto = display.newRect(70,400,111,111)
    button_auto:setFillColor(0,0.4,0.3)
    local button_bonus = display.newRect(250,400,111,111)
    button_bonus:setFillColor(0,0.4,0.3)
    local text = display.newText("Click", 161, 190, "consolas", 30)
    text:setFillColor(1,1,1)
    local text1 = display.newText("Money:", 64, -19, "consolas", 30)
    text1:setFillColor(0,0.1,0.8)
    local text2 = display.newText(money, 200, -16, "consolas", 30)
    text2:setFillColor(0,0.1,0.8)
    local text3 = display.newText("Auto", 70, 370, "consolas", 30)
    text3:setFillColor(1,1,1)
    local text4 = display.newText("click", 70, 400, "consolas", 30)
    text4:setFillColor(1,1,1)
    local text5 = display.newText(auto_money_buy, 70, 437, "consolas", 30)
    text5:setFillColor(1,1,1)
    local text6 = display.newText("Bonus", 250, 370, "consolas", 30)
    text6:setFillColor(1,1,1)
    local text7 = display.newText("click", 250, 400, "consolas", 30)
    text7:setFillColor(1,1,1)
    local text8 = display.newText(bonus_money_buy, 250, 437, "consolas", 30)
    text8:setFillColor(1,1,1)
    ocal button_shadow = display.newRect(160,280,175,10)
    button_shadow:setFillColor(0,0.3,0.4)
    local button_shadow_auto = display.newRect(70,460,111,10)
    button_shadow_auto:setFillColor(0,0.3,0.4)
    local button_shadow_bonus = display.newRect(250,460,111,10)
    button_shadow_bonus:setFillColor(0,0.3,0.4)
    local copyright = display.newText("KernelCoreSW 2018-2019", 163, 490, "consolas", 23)
    copyright:setFillColor(0,0.1,0.8)
    local function flapBird (event)
      if(event.phase == "began") then
       ---lvl
       if(bonus_money_lvl == 0) then
         money = money + 1
        end
        if(bonus_money_lvl == 1) then
         money = money + 2
        end
    --И еще такого говнаролла штук 10
    text2.text = money
    end
    local function flapBird_bonus (event)
      if(event.phase == "began") then
        if(money >= bonus_money_buy) then
         money = money - bonus_money_buy
         bonus_money_buy = bonus_money_buy * 3
         bonus_money_lvl = bonus_money_lvl + 1
        end
        text2.text = money
        text8.text = bonus_money_buy
      end
    end
    local function onUpdate (args)
    
        if(auto_money > 40) then
      auto_money = 0
        end    
        ---------levels
        if(auto_money_lvl == 1) then
      if(auto_money == 40) then
       money = money + 1
       text2.text = money
      end
        end
        ---------levels end и еще такого говна штук 10
        auto_money = auto_money + 1
    end
    local function load_settings(fileName)
        local path = system.pathForFile(fileName, system.ResourceDirectory)
        local contents = ""
        local myTable = {}
        local file = io.open(path, "r")
        if(file) then
      contents = file:read("*a")
      myTable = json.decode(contents)
      io.close(file)
      return myTable
        end
        return nil
    end
    local settings = loadSettings("settings.json")
    if(settings) then
        money = settings.money
        auto_money = settings.auto_money
        auto_money_buy = settings.auto_money_buy
        auto_money_lvl = settings.auto_money_lvl
        bonus_money_lvl = settings.bonus_money_lvl
        bonus_money_buy = settings.bonus_money_buy
    end

    button:addEventListener("touch", flapBird)
    button_auto:addEventListener("touch", flapBird_auto)
    button_bonus:addEventListener("touch", flapBird_bonus)
    Runtime:addEventListener("enterFrame", onUpdate)

    Гейдев.

    Запостил: 3oJIoTou_xyu, 23 Октября 2019

    Комментарии (191) RSS

    • Вопрос. Нахуя тут в lua сериализатор/десериализатор JSONа для своих сеттингов? Нахуя? Зачем? В чем прикол? Поясните логику сяго.
      Ответить
    • >--И еще такого говнаролла штук 10
      if(bonus_money_lvl == 18) then
           money = money + 19
          end

      ?

      какая трудолюбивая мартышка писала)


      auto_money_buy = settings.auto_money_buy
          auto_money_lvl = settings.auto_money_lvl

      так для КАЖДОЙ переменной?!
      ахахаха, какая трудолюбивая макака писала

      В луа 100500 способов есть серализовать таблицу.
      Нужно сделать таблицу настроек, и течь, это и быстрее и правильнее, и удобнее.

      Кашу из "логики", ui и сохранения файлов оставим за скобками
      Ответить
      • Да. Для каждой. Просто сюда не поместилось.
        Ответить
        • а потом надо добавить будет одну переменную во все места, ой)
          Ответить
          • В свое время, я тоже занимался такой подобной хуйней. Но там вынужденная мера была, так как текстовики довольно ветвисты и иногда нужны особые условия при определенных выборах.
            Но я все в рот ебал. Я сделал более лаконичную и по моему мнению правильную реализацию квестов - это через таблы и все это лоадить и тупо по индексам переходить и лоадить по мере необходимости и отрубать то что не нужно, а не все дерьмо держать в ОЗУ.
            globaltext = {
            [1] = {t = "ВЫ съели говно", 
                [1] = {"Теперь я хуй",2} , 
                [2] = {"Теперь я гей",2}, 
                [3] = {"Я какий петушок!",2, function() inv:add(dildo) end}}
            [2] = {t = "you dead suka",     
                [1] = {"Ну еба...",1}}}

            Чем так
            text  = 1;
            if text == 1 then
                textpnt = "ВЫ съели говно";
                if vib == 1 then
                    butt = "Теперь я хуй"
                   text  = 2;
                elseif vib == 2 then
                    butt = "Теперь я гей"
                   text  = 2;
                elseif vib == 3 then
                   butt = "Я какий петушок!"
                   text  = 2;
                  inv:add(dildo)
               end
            elseif  text == 2 then
                textpnt = "you dead suka";
                if vib == 1 then
                    butt = "Ну еба..."
                    text  = 1;
                end
            end
            Ответить
    • Хуй, ты в геймдеве?
      Ответить
    • Переведи на "PHP".
      Ответить
      • Перевёл начало (всё не влезает):
        <?php
        $money = 0;
        $auto_money = 0;
        $auto_money_lvl = 0;
        $auto_money_buy = 50;
        $bonus_money_lvl = 0;
        $bonus_money_buy = 35;
        $json_pip = require("json");
        $bacg = display::newRect(0,0,1080,1920);
        $button = display::newRect(160,190,175,175);
        $button->setFillColor(0,0.4,0.3);
        $button_auto = display::newRect(70,400,111,111);
        $button_auto->setFillColor(0,0.4,0.3);
        $button_bonus = display::newRect(250,400,111,111);
        $button_bonus->setFillColor(0,0.4,0.3);
        $text = display::newText("Click", 161, 190, "consolas", 30);
        $text->setFillColor(1,1,1);
        $text1 = display::newText("Money:", 64, -19, "consolas", 30);
        $text1->setFillColor(0,0.1,0.8);
        $text2 = display::newText(money, 200, -16, "consolas", 30);
        $text2->setFillColor(0,0.1,0.8);
        $text3 = display::newText("Auto", 70, 370, "consolas", 30);
        $text3->setFillColor(1,1,1);
        $text4 = display::newText("click", 70, 400, "consolas", 30);
        $text4->setFillColor(1,1,1);
        $text5 = display::newText(auto_money_buy, 70, 437, "consolas", 30);
        $text5->setFillColor(1,1,1);
        $text6 = display::newText("Bonus", 250, 370, "consolas", 30);
        $text6->setFillColor(1,1,1);
        $text7 = display::newText("click", 250, 400, "consolas", 30);
        $text7->setFillColor(1,1,1);
        $text8 = display::newText(bonus_money_buy, 250, 437, "consolas", 30);
        $text8->setFillColor(1,1,1);
        $button_shadow = display::newRect(160,280,175,10);
        $button_shadow->setFillColor(0,0.3,0.4);
        $button_shadow_auto = display::newRect(70,460,111,10);
        $button_shadow_auto->setFillColor(0,0.3,0.4);
        $button_shadow_bonus = display::newRect(250,460,111,10);
        $button_shadow_bonus->setFillColor(0,0.3,0.4);
        $copyright = display::newText("KernelCoreSW 2018-2019", 163, 490, "consolas", 23);
        $copyright->setFillColor(0,0.1,0.8);


        Тут ещё надо оптимизировать код: заменить двойные кавычки на одинарные. Но я думаю, ты сам справишься.
        Ответить
        • показать все, что скрытоvanished
          Ответить
          • А на чём?
            Ответить
            • показать все, что скрытоvanished
              Ответить
              • Язык Ада, например. Серьёзно, в нём можно объявлять даже контракты (предикаты, аспекты).

                http://govnokod.ru/25520#comment471813

                subtype Winter is Month
                with Static_Predicate => Winter in Dec | Jan | Feb;


                Заметь, Winter в этом примере — это даже не сабрендж, это произвольное подмножество.
                Ответить
              • У тебя тавтология Эйлера. Пассаль таки сосёт хуй.
                Ответить
              • Паскаль — говно.
                Но в нём было заложено много годных идей.
                Например писать тип после переменной, а не до. Или не делать из языка С++0z.

                >почему сабренджей нигде нету?

                Вот поскольку их нету, то в 2к19 у нас либо либо bounds checking, либо buffer overflow.

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

                А нужно так, чтоб любое обращение к строке/массиву по индексу, принимало только subrange [0..length-1].
                Ответить
                • показать все, что скрытоvanished
                  Ответить
                • Помню, у броманда была опция pcc, которая инструментацию для такого вставляла. Но не для строк. Вроде баундсы должны был определены в копулетайм.
                  Ответить
                  • Хочется чего-то такого.

                    Допустим есть имя пользователя, длина 1-32 символа.
                    Это String[1..32] (синтаксис условный, в крестошаблонах String<1,32>).

                    Например пароль: String[8..32].

                    Пустая строка String[0..0]

                    Строка фиксированного размера, например хеш-функция, возвращающая md5:
                    String<32,32> md5 (String input){
                    ...
                    }


                    Тогда конкатенация плюсом даёт сложение нижней и верхней границ. Конкатенация коммутативна: от перестановки строк местами тип не меняется.

                    String[0..4] + String[2..4] = String[2..8]


                    Взятие подстрок проверяется в компайл-тайме. Индексы — те самые диапазоны.
                    Ответить
                    • показать все, что скрытоvanished
                      Ответить
                    • показать все, что скрытоvanished
                      Ответить
                      • Да, хорошо, что божественная не делает лишних проверок и даже с -Wall не сообщает о детских ошибках, поэтому Карпову есть чем заняться.
                        Ответить
                      • показать все, что скрытоvanished
                        Ответить
                        • type dva_stula = 0..1;


                          Да, тут компилятор автовыведет тип хранилища (в данном случае он положит результат в байт, а не в интеджер).

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

                          Вот, например, переменная принимает значения от -9000 до +100500. В какой тип её класть? Придётся держать в уме лимиты int8_t, int16_t, int32_t, int64_t. Мы же не дураки и не будем использовать short int, int, long int, long long int, которые на разных платформах будут разными?
                          Ответить
                    • показать все, что скрытоvanished
                      Ответить
                      • with Ada.Text_IO; use Ada.Text_IO;
                        with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
                         
                        procedure Test is
                                pragma Assertion_Policy (Check);
                        	subtype room is Integer range 1..99;
                        	r: room := 100;
                        begin
                            Put(r);
                        end;


                        test.adb:7:20: warning: value not in range of type "room" defined at line 6
                        test.adb:7:20: warning: "Constraint_Error" will be raised at run time


                        Тут поймали ошибку ещё во время компиляции.

                        А теперь пример посложнее:
                        with Ada.Text_IO; use Ada.Text_IO;
                        with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
                        with Ada.Numerics.Discrete_Random;
                         
                        procedure Test2 is
                                pragma Assertion_Policy (Check);
                        	subtype room is Integer range 1..99;
                                package RND is new Ada.Numerics.Discrete_Random (room);
                                G: RND.Generator;
                        	r, q: room;
                        begin
                            r := 99;
                            RND.Reset(G);
                            q := r + RND.Random(G); -- гарантируем невозможность проверки в компайлтайме
                            Put(q);
                        end;


                        Тут во время выполнения срабатывает проверка:
                        raised CONSTRAINT_ERROR : test2.adb:14 range check failed

                        Компилятор добавил отладочную информацию, которую потом вывел в сосноль дефолтный обработчик исключения.
                        Ответить
                        • addl	%edx, %eax // та самая операция сложения, приводящая к переполнению
                          	testl	%eax, %eax // проверка на 0
                          	jle	L2
                          	cmpl	$99, %eax // проверка на 99
                          	jle	L3                           // если значение прошло проверку, идём дальше
                          L2:
                          	movl	$14, 4(%esp) // 14 - это номер строки, вызвавшей ошибку
                          	movl	$LC0, (%esp)
                          	call	___gnat_rcheck_CE_Range_Check // обработчик исключения Constraint_Error
                          L3:
                          Ответить
                • показать все, что скрытоvanished
                  Ответить
                  • На самом деле классический «Паскаль» был довольно простым языком. Почти как Бейсик, только со строгой типизацией.

                    Компания «Borland» же в него добавила конструкции из «Модулы» и из языка Ада, получив в итоге довольно мощное средство и сохранив строгость, но при этом не дойдя до перегруженности языка Ада. «Object Pascal», на котором основаны «Турбо Паскаль», «Delphi», «Free Pascal» и несколько тупиковых ветвей, можно рассматривать как отдельный язык программирования.

                    >> struct
                    Есть record. Но само слово «record», в отличие от сишного «struct», не нужно писа́ть постоянно, так как его можно использовать только в тайпдефах (слово «type» в «Паскале»).

                    >> class
                    В «Standard Pascal» вообще не было ООП. В «Турбо Паскале» появилось слово «object», а в «Delphi» и слово «class» (разница между «object» и «class» в хранилище и в устройстве ТВМ).
                    Ответить
                  • Нет. Его проблема в другом.
                    Например в раздутом синтаксисе, бойлерплейте и уебанских, неконсистентных циклах.

                    while .trueCondition. do 
                    begin
                    end
                    
                    repeat // Где здесь любимый Виртом begin~end?
                    until falseCondition;//здесь отрицание
                    
                    
                    for i := a downto b  //завези step из бейсика, это говно неюзабельно


                    Для сравнения божественные циклы из Сишки
                    while(trueCondition){}
                    
                    do{
                    }while(trueCondition)
                    //пред и пост- цикл консистентны


                    Для сравнения восхитительный синтаксис циклов из Бейсика:
                    Do 
                    'бесконечный цикл
                    Loop
                    
                    Do While trueCondition
                    Loop
                    
                    Do 
                    Loop While trueCondition
                    
                    For i=0 to n step x
                    Next i
                    Ответить
                    • В сишке for плохой. Очень плохой. Выглядит, как костыль. А вот while сделали лучше, да.

                      Do ... loop изначально не было в «Бейсике». Это «Quick BASIC». Do ... loop сделали под впечатлением от «Фортрана» и «Си».

                      Про шаг согласен. Однако, в Паскале цикл можно делать не только по целым числовым типам, но и по любым перечислимым, к которым относятся и символы (for c:='A' to 'Z' do), и false..true, и перечисления (аналоги сишных енумов, но только со строгой типизацией, без автокаста в целые). Видимо, Вирт решил, что для нечисловых перечислимых типов числовой шаг будет неинтуитивен, поэтому и ограничился двумя значениями (+1 и -1).
                      Ответить
                      • показать все, что скрытоvanished
                        Ответить
                        • Обратная совместимость же.

                          Ты ещё скажи, что свитч-кейс, позволяющий создать устройство Даффа, хороший.

                          Вообще сишный for есть не во всех языках, основанных на сишном синтаксисе.
                          Ответить
                          • >свитч-кейс, позволяющий создать устройство Даффа, хороший

                            switch — основная мерзость сишки. Всего-навсего слегка припудренная версия computed goto из фортранов.

                            Одни из лучших case, до того как завезли хипстерский паттерн-матчинг были в бейсике
                            Case a To b, c To d, e, f
                            Ответить
                      • >Вирт решил, что для нечисловых перечислимых типов числовой шаг будет неинтуитивен, поэтому и ограничился двумя значениями (+1 и -1).

                        for в паскале неюзабелен чуть менее чем полностью.
                        Лучше бы он сразу сделал for~each по диапазонам, массивам и остальному добру.
                        for x in [1..3] //повеяло питоном
                        for x in array


                        >Do ... loop изначально не было в «Бейсике».

                        Да. Но сделали ведь просто и консистентно. Один синтаксис на все случаи жизни.

                        Там кстати ещё было Do Until x ... Loop, Do ... Loop Until x что на мой вкус уже излишество, но то такое.
                        Ответить
                        • Кстати, for ... in появился в какой-то версии дельфятины.

                          Вообще согласен, что for i:=1 to 3 — это архитектурное излишество для языка, в котором есть диапазоны и множества. Если уж ввели их, то надо их использовать повсюду.

                          С тем, что совсем неюзабелен, не соглашусь. У него верхняя граница счётчика вычисляется один раз, а не каждую итерацию, как в сишке. Поддерживаются break и continue. Пользоваться можно.

                          Но вот что нужно писать for x:= Low(range) to High(range) вместо for x in range, это, конечно, плохо.
                          Ответить
                    • показать все, что скрытоvanished
                      Ответить
                    • Наипиздатейший синтаксис циклов в обоссаном в свое время Алкоголь-68°, он сосостоит из нескольких частей, которые можно произвольно добавлять и опукать, из них обязательеым является только тело цикла ( но правдя порядок фиксирован ) :
                      CO полный синтаксис CO
                      FOR var name FROM start BY step TO end WHILE condition
                      DO
                          something
                      OD;
                      
                      CO цикл со счетчиком от 0 до 10 включительно с шагом 1 CO
                      FOR i FROM 0 BY 1 TO 10
                      DO
                          SKIP
                      OD;
                      
                      CO если часть FROM опустить начинает с 1, шаг также по умолчанию 1 CO
                      FOR i TO 10
                      DO
                          SKIP
                      OD;
                      
                      CO можно добавить предусловие CO
                      FOR i TO 10 WHILE condition
                      DO
                          SKIP
                      OD;
                      
                      CO можно оставить только WHILE CO
                      WHILE cindition
                      DO
                          SKIP
                      OD;
                      
                      CO бесконечный цикл CO
                      DO SKIP OD;
                      
                      CO бесконечный цикл со счетчиком, считает с 1 ( падает в рунтиме с переполонием ) CO
                      FOR i DO SKIP OD;
                      
                      CO выполняется 10 раз CO
                      TO 10 DO SKIP OD;
                      
                      CO бесконечный цикл, не знаю в чем смысл, но синтаксически верно и работает, и не падает CO
                      FROM 100500 BY 666 DO SKIP OD
                      
                      CO цикл с постусловием, если не ошибаюсь это расширение современной реализаци Algol-68 Genie, также можно мешать с остальными вариантами CO
                      DO 
                        SKIP
                      UNTIL condition OD
                      Ответить
                      • Пи не понравится: тут, как и в Паскале, предусловие с WHILE, а постусловие с UNTIL.
                        Ответить
                        • Ну тогда не надо брать Algol-68g, можно взять какую-нибудь древность под DOS или еще чего постарше, там UNTIL не было.
                          Ответить
                • >> А нужно так, чтоб любое обращение к строке/массиву по индексу, принимало только subrange [0..length-1].

                  В Паскале две проверки: в компайлтайме (когда индекс принимает очевидное значение) и в рантайме. В TP проверка в рантайме регулируется директивой $R+, в компайлтайме же проверка всегда.

                  Массивы в Паскале изначально были статическими, поэтому проблем с проверкой не было (динамические появились в поздних поделках вроде «Delphi» и «Free Pascal»). В Паскале нельзя обратиться к несуществующему элементу массива.

                  Что же касается строк, то у паскалевских строк две длины: объявленная (которую превышать нельзя, ибо реалокатора нет) и текущая. Выход за объявленную длину проверяется. Выход за текущую, увы, нет.
                  Ответить
                  • >Массивы в Паскале изначально были статическими

                    Вот я и говорю что там всё по-детски просто.
                    Но сама концепция проверять в compile-time хорошая и правильная.
                    Ответить
                    • показать все, что скрытоvanished
                      Ответить
                      • В божественной сишечке возможна детская ошибка:
                        char pituh[10];
                        pituh[10] = 42; /* выход за границу, потому что диапазон индексов 0..9 */

                        Паскаль же подобное даже не даст скомпилировать:
                        https://ideone.com/WQeZxE

                        P.S. Чуть выше я ошибся: директива $R+ действует и на рантайм, и на компайлтайм.
                        Ответить
                        • показать все, что скрытоvanished
                          Ответить
                          • Царь?
                            Ответить
                            • Человек хочет ловить ошибки и переполнять буфер в продакшене, а не получать глупые питушиные ошибки компилятора.
                              Ответить
                              • Человек ещё хочет писать код, который работает только при удачном расположении звёзд:
                                http://govnokod.ru/13162#comment180683

                                В «Ideone» царский код упал, потому что «Ideone» использует питушарский защитник стека («Propolice» или аналогичный).
                                Ответить
                        • А как в современных Паскалях обстоят дела с конкатенацией массивов и строк?

                          Возможно ли что-то такое: http://govnokod.ru/25987#comment512947?
                          Ответить
                          • Интервальной арифметики нет. От ренджа ничего вычислить нельзя.

                            Ограничить минимальную длину строки нельзя. В языке Ада можно (там есть динамические предикаты, можно в качестве предиката взять неравенство для функции strlen).

                            Остальное не понял. Можно задачу поставить чётче?
                            Ответить
                            • >Остальное не понял. Можно задачу поставить чётче?

                              Допустим я конкатенирую array[0..8] of char и array[0..2] of char.

                              Хочу на выходе получить автоматом тип array[0..10] of char и соответственно компайл-тайм проверки.

                              Или я делаю slice(start=2,end=4) на array[0..8] of char. Хочу получить не абстрактную строку а array[0..2] of char.
                              Ответить
                              • показать все, что скрытоvanished
                                Ответить
                                • Эот реальный пример.

                                  У меня есть база данных, в базе лежат таблицы.

                                  В таблицах кроме всего прочего есть поля с типами char(24) и varchar(64).

                                  Вот я и хочу иметь в языке, который пишет в эту базу автоматические проверки введённых данных.

                                  Чтобы не заинсертить данные, которые потом автообрежутся.

                                  Я не хочу на каждое поле каждый раз городить новый тип и в нём руками проверять длины. ЯП обеспечить мне подобного механизма не может.
                                  Ответить
                                  • показать все, что скрытоvanished
                                    Ответить
                                    • Если я буду инсертить тип String[0..64], то я буду уверен что там не больше 64 символов.

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

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

                                      Ввод от пользователя будет кидать ему ошибку в рантайме, но и тут есть профит, мне не придётся на всякий раз писать:
                                      if (str.length()>64) error("слишком длинная строка")
                                      if (str.length()<10) error("слишком короткая строка!")


                                      Эти ошибки будет генерировать язык, так же, как например при парсинге чисел.
                                      Ответить
                                      • В языке Ада всё есть:
                                        subtype MoyaStroka is String with Dynamic_Predicate
                                        => MoyaStroka'Last >= 10 and MoyaStroka'Last <= 64;


                                        Здесь атрибут 'Last — индекс последнего элемента строки, а поскольку 'First для строки всегда равен единице, то 'Last равен длине.
                                        Ответить
                                        • Вот это реально годно выглядит.
                                          Не зря Тарас её хвалил
                                          Ответить
                                        • > MoyaStroka'Last >= 10 and MoyaStroka'Last <= 64

                                          Почитал за контракты-предикаты. Dynamic_Predicate работает как обычный assert, и отваливается в рантайме.

                                          https://steemit.com/ada-lang/@xinta/learning-ada-4-predicates
                                          Note: if you want the compiler to compile the checks, you must enable asssertions. This is done using the compile time option -gnata.

                                          Короче хуйня. Нас спасут только крестошаблоны, bormand или d++.
                                          Ответить
                                          • Оказывается, длину можно использовать и в статическом предикате:
                                            with Ada.Text_IO; use Ada.Text_IO;
                                            with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
                                             
                                            procedure Test is
                                            	subtype MoyaStroka is String with Static_Predicate => MoyaStroka'Last in 10..64;
                                            	x: MoyaStroka := "1234567890";
                                                y: MoyaStroka := "short";
                                            begin
                                                Put(x);
                                                New_Line;
                                                Put(x'Last);
                                                New_Line;
                                                Put(y);
                                                New_Line;
                                                Put(y'Last);
                                            end;


                                            Выводит:
                                            test.adb:7:22: warning: static expression fails static predicate check on "MoyaStroka"
                                            test.adb:7:22: warning: expression is no longer considered static

                                            Седьмая строка — это та, в которой y: MoyaStroka := "short";
                                            Тут компилятор видит, что мы игреку пытаемся присвоить значение короче 10 символов. Правда, выводит ворнинг, а не еррор.

                                            Я почему-то думал, что длину можно использовать только в динамическом предикате. Оказывается, в языке Ада атрибуты — это не совсем функции, они могут проверяться и в компайлтайме.
                                            Ответить
                                          • >> Dynamic_Predicate работает как обычный assert, и отваливается в рантайме.

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

                                            Кстати, статический предикат, если не поймал ошибку во время компиляции, всё равно сгенерирует ассерт, если есть директива pragma Assertion_Policy (Check);

                                            И динамический предикат тоже может вывести ворнинг во время компиляции, если выражение вычислимо в компайлтайме (что-то типа констэкспра):
                                            test.adb:7:22: warning: expression fails predicate check on "MoyaStroka"


                                            Правда, жалко, что и Static_Predicate, и Dynamic_Predicate во время компиляции выводят всего лишь ворнинг, а не ошибку.
                                            Ответить
                                            • показать все, что скрытоvanished
                                              Ответить
                                              • `-gnatwe'
                                                    Treat warnings as errors.
                                                Ответить
                                              • Вирт не имеет никакого отношения к языку Ада, он его даже критиковал за сложность.
                                                Ответить
                                                • Вирт про язык Ада: «Слишком много всего вываливается на программиста. Я не думаю, что, изучив треть Ады, можно нормально работать. Если вы не освоите всех деталей языка, то в дальнейшем можете споткнуться на них, и это приведёт к неприятным последствиям».

                                                  Дейкстра про язык Ада: «Если Ada собирается выдать стандарт, желательно, чтобы он был недвусмысленно документирован. По меньшей мере две группы попытались сделать это; в результате обе выдали около 600 страниц формального текста. Это гораздо больше, чем необходимо, чтобы удостовериться в невозможности хотя бы твердо установить, что оба документа определяют один и тот же язык. Ошибка очевидной неуправляемости этих двух документов кроется не в двух группах, составивших их, не в принятом ими формализме, а лишь в самом языке: сами не обеспечив формального определения, могут ли его разработчики скрыть, что они предлагают неуправляемого монстра. То, что Ada уменьшит проблемы программирования и увеличит надёжность наших разработок до приемлемых границ, — это лишь одна из тех сказок, в которые могут поверить только люди с военным образованием».
                                                  Ответить
                                                  • Всего 600 страниц, лол. Интересно, что бы он написал про современные кресты.
                                                    Ответить
                                                    • От современных крестов он в гробу вращается. Со скоростью, определяемой реализацией.
                                                      Ответить
                                                    • показать все, что скрытоvanished
                                                      Ответить
                                                      • Когда в 90х сделали один многословный, унылый и минималистичный язык с gc (нет, не Оберон).

                                                        То Вирт возмутился что его идею зашкварили сишкоблядским синтаксисом.
                                                        Ответить
                                                      • А я всегда говорил, что американцы тупые. Вот и старик Никлаус со мной согласен.
                                                        Ответить
                                                        • Ты перерождение Задорнова?

                                                          Не надо так говорить, например Чаке Мур'иканец придумал язык Forth.

                                                          Он тут недавно на встрече фортеров хвастался, что придумал очередной диалект colorForth'а и научился многопоточно рисовать звездно-полосатый флаг под вендой.
                                                          https://www.youtube.com/watch?v=3ML-pJFa8lY
                                                          Ответить
                                                          • А что Вирт думает о Форте?
                                                            Ответить
                                                            • Девиз, поставленный Виртом в эпиграф описания Оберона, это слова Альберта Эйнштейна "Сделай так просто, как возможно, но не проще того." На вопрос о языке Форт коллега Вирта по Оберону ответил: "А вот это как раз проще, чем возможно." Вирт же отметил, что Форт, как и Postscript, фантастические языки. Для компьютерной генерации. Но не для человеческого труда. ("Fantastic language, but not for the human to produce.")
                                                              Ответить
                                                        • показать все, что скрытоvanished
                                                          Ответить
                                                          • Смотря в каком. В «Турбо Паскале» и в его наследниках вообще никак. Аргумент case полностью игнорируется, а варианты работают точно так же, как union в сишке (ну, тупые).

                                                            В «Standard Pascal» по идее вариант должен проверяться, но я не знаю живых реализаций стандартного Паскаля. Придётся стряхивать с них пыль и проверять.
                                                            Ответить
                                                          • Пишу на переносимом диалекте:
                                                            Program Makaka(Input, Output);
                                                            
                                                            Type
                                                              TLanguage = (PHP, JavaScript);
                                                              TFramework = (Zend, Cake);
                                                              TMakaka = Record
                                                                nick: String;
                                                                Case language: TLanguage of
                                                                  PHP: 
                                                                    (framework: TFramework);
                                                                  JavaScript:
                                                                    (usesTypeScript: Boolean);
                                                              End;
                                                            
                                                            Procedure Dure(Var makaka: TMakaka);
                                                            begin
                                                                 if makaka.language = JavaScript then
                                                                    Writeln('language = JavaScript')
                                                                 else
                                                                    Writeln('language = PHP');
                                                                 makaka.usesTypeScript := True;
                                                                 Writeln('Makaka uses TypeScript.')
                                                            end;
                                                            
                                                            var makaka: TMakaka;
                                                            begin
                                                              makaka.language := JavaScript;
                                                              Dure(makaka);
                                                              makaka.language := PHP;
                                                              Dure(makaka)
                                                            end.


                                                            «Турбо Паскаль» и «Free Pascal» спокойно разрешают лазить в поле usesTypeScript, даже когда выбран вариант language = PHP. Всё, как в сишном union'е.

                                                            Беру «Irie Pascal». Производитель обещает совместимость со «Standard Pascal (i.e. ISO/IEC 7185)». Компилирую, запускаю... Рантайм на втором вызове Dure останавливает программу с сообщением:
                                                            ---------------------------
                                                            ERROR: line 21
                                                            ---------------------------
                                                            Non-active variant accessed
                                                            ---------------------------
                                                            ОК   
                                                            ---------------------------
                                                            Ответить
                                                  • показать все, что скрытоvanished
                                                    Ответить
                                                  • показать все, что скрытоvanished
                                                    Ответить
                                                  • >Вирт про язык Ада: «Слишком много всего вываливается на программиста. Я не думаю, что, изучив треть Ады, можно нормально работать

                                                    >Вирт не имеет никакого отношения к языку Ада, он его даже критиковал за сложность.

                                                    Он просто modern С++ не видел.
                                                    Ответить
                              • Понял, автовывод типа и тут же проверка.

                                Для строк в стандартном Паскале был костыль: промежуточные выражения считались в типе string[255] вне зависимости от того, какой тип имели входящие в выражение переменные. Лишь при присвоении результата вычислений переменной тип усекался.

                                В «Турбо Паскале» добавили PChar, у которого были те же проблемы, что и у сишки: за выделением памяти и проверкой индекса должен был следить программист, поэтому пользоваться этим типом было опасно.

                                В «Delphi» появились динамические строки (AnsiString, WideString). Реалокацией их занимался рантайм, размер их не ограничивался.

                                С операциями над массивами всё плохо. Конкатенировать их знаком «+» нельзя. Строки можно. Объединение множеств считать знаком «+» можно. А вот массивы нельзя.

                                В FPC, правда, добавили перегрузку операторов:
                                https://freepascal.org/docs-html/current/ref/refse100.html
                                Можно перегружать даже ** и ><, которых не было в классическом Паскале.

                                Функцию конкатенации массивов в RTL не нашёл, зато слайс в FPC всё-таки сделали:
                                https://freepascal.org/docs-html/current/rtl/system/slice.html

                                Пример:
                                Program Example113;
                                
                                { Program to demonstrate the Slice function. }
                                
                                procedure ShowArray(const A: array of Integer);
                                var
                                  I: Integer;
                                begin
                                  for I := Low(A) to High(A) do
                                    WriteLn(I, ' : ', A[i]);
                                end;
                                
                                begin
                                  ShowArray(Slice([1,2,3,4],2));
                                end.


                                Обрати внимание, что функции Low и High вычисляются от массива, который вернула функция Slice. Т. е. функция Slice возвращает массив корректного типа с явным диапазоном индексов.
                                Ответить
                                • >функция Slice возвращает массив корректного типа с явным диапазоном индексов.

                                  It returns an array with the same element type as A, but this array is not assignment compatible to any other array, and can therefor only be used in open array arguments to functions.

                                  Ну костыльно как-то.
                                  Ответить
                                  • Да, с присвоением массивов всё плохо:
                                    var
                                        x: array[-5..5] of integer;
                                        y: array[-5..5] of integer;
                                    begin
                                        x:=y; {можем обломаться, поскольку x и y для компилятора имеют разный тип}
                                    end.


                                    А так работает:
                                    type massiv = array[-5..5] of integer;
                                    var
                                        x: massiv;
                                        y: massiv;
                                    begin
                                        x := y; {x и y имеют тождественные типы}
                                    end.
                                    Ответить
                                    • > x:=y; {можем обломаться, поскольку x и y для компилятора имеют разный тип}

                                      Потому я против «Паскаль».

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

                                      Люди отчаиваются и начинают учить кресты.
                                      Ответить
                                    • показать все, что скрытоvanished
                                      Ответить
                                      • >зачем ты явно не сделал для них общий тип?
                                        Ээээ. У них и так общий тип array.

                                        >В жабе к примеру тоже нельзя кастануть Foo к Bar даже если у них одинаковые поля
                                        Аналогия неверная.

                                        Array55 и Array<Five,Five> можно кастануть в другой Array<Five,Five>.

                                        class Array55 extends Array<Five,Five>
                                        Ответить
                                • > Можно перегружать даже ><
                                  А оператор (>﹏<) можно?
                                  Ответить
                              • У тебя строгие типы отклеились, в пассале такокое нельзя.
                                Ответить
                        • https://ideone.com/bZ0TqP

                          Проблема Паскаля в том что он ловит только детские ошибки.

                          А программа, немного сложнее лабы приводит к тем же проблемам что и в сишке.

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

                            Если скомпилировать с {$R-}, то будет как в сишке: засрётся вся память программы, а об ошибке мы узнаем, только когда ОС убьёт программу за то, что она полезла в чужую память.
                            Ответить
                            • >Runtime error 201 — рантайм поймал выход за границу диапазона.

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

                                Кстати, про тавтологию:
                                http://govnokod.ru/25867
                                Ответить
                                • Моя мысль такова: нужно чтоб массивы в качестве индекса принимали не размытый integer, а вышеупомянутый subrange. С чего и началась вся дискуссия. (это и есть ответ гостю8, а нахера они вообще нужны )

                                  type array_index = 0 ... 9;

                                  Тогда я y не смогу записать хуйню, и код не скомпилится.
                                  Ответить
                                  • показать все, что скрытоvanished
                                    Ответить
                                  • {$R+}
                                    type array_index = 0 .. 9;
                                    var x: array_index;
                                    begin
                                     x := 10;
                                    end.


                                    https://ideone.com/jaemPr
                                    Ответить
                                    • Правильно.

                                      Осталось научить Паскаль принимать в качестве индекса для array [a..b] только числа типов subrange a..b, плюс те что можно к ним привести.

                                      То есть array [0..100] может принимать на вход 0..100 или 10..50.

                                      Но не может использовать переменную типа byte, который де-факто является 0..255 или например -5..5.

                                      Поскольку тогда в рантайме программа развалится.

                                      Иными словами компилятор, встретив код

                                      var x: array[0..9] of byte;
                                      var z:0..5;
                                      var y:integer;
                                      x[z] := 42; //ok
                                      >>x[y] := 42; //здесь должен плеваться и говорить, что ты делаешь, гад
                                      Ответить
                                      • В выражении x[y] игрек является не переменной (lvalue), а выражением (rvalue). Как lvalue здесь выступает только x или x[y] целиком. Ну это примерно как мы бы написали x[func(y)] := 42, где func в данном случае — функция тождественного отображения.

                                        Проблема в том, что в Паскале нет интервальной арифметики. Он не может посчитать, чему будет равна func от диапазона.

                                        Да, нам очевидно, что если y:integer (который равен диапазону -MAXINT-1..MAXINT или как там), то и у тождественного отображения игрека будет тот же диапазон значений. Осталось научить этому компилятор.
                                        Ответить
                                      • показать все, что скрытоvanished
                                        Ответить
                                      • Всё равно рано или поздно мы где-то упрёмся в приведение типов и проверку в рантайме, будь то десериализация, чтение файла или пользовательский ввод.
                                        На той стороне могут вообще ничего не знать про эти ваши ренжи.
                                        Ответить
                                        • >десериализация, чтение файла или пользовательский ввод

                                          Это всё IO. Для него есть 400 код или ошибка ввода.
                                          Но даже тут нам не придётся каждый раз проверять рейндж руками, писать ассерты и кидать исключения.

                                          Главное — быть уверенным что алгоритм не вылазит за пределы буфера.
                                          Ответить
                                          • Мне кажется, необязательно для всего этого писать новый язык с мощным компилятором и поддержкой зависимых типов.

                                            Можно просто придумать более лучший IDL и положиться на силу кодогенереции
                                            Ответить
                                    • Опять синтетическая хуита, реально будет вот так:

                                      https://ideone.com/8iOfto
                                      Ответить
          • Малость переводить говно с симпатичного язычка на говёный.
            Ответить
    • показать все, что скрытоvanished
      Ответить
    • Причем тут я? Не я же к тебе ехать собрался
      Ответить
    • показать все, что скрытоvanished
      Ответить

    Добавить комментарий