На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (56) « Первая ... 38 39 [40] 41 42 ...  55 56  ( Перейти к последнему сообщению )  
> D vs C++ , почти сурковская пропаганда: не пора ли C++ потихоньку готовиться к пенсии?
    Цитата
    Сообщить модератору о нарушении в этой теме
    Спам.
      Цитата korvin @
      Цитата D_KEY @
      Его проблема в том, скорее всего, придётся отказаться от оператора [](как и пришлось в scala), а это тоже неудобно.

      Я почти не знаком со Scala, поэтому не могу с ходу вообразить ситуацию, когда оператор [] будет конфликтовать с использованием [] для параметризации типа

      Ну а как ты на уровне грамматики это сделаешь?

      Цитата
      Вот в D же параметры типа задаются в () и это не конфликтует с оператором () вызова процедуры.

      Так там же ! перед ними стоит.
        Цитата D_KEY @
        Ну а как ты на уровне грамматики это сделаешь?

        Э-м... А как связаны грамматики типов и грамматика операторов? Ну например:
        ExpandedWrap disabled
          type Array [T : Any] where {
              val make : T -> Int -> @This
           
              method get : Int -> T
              method set : Int -> T -> ()
           
              #implementation
          }
           
          type Map [Key : Hashable, Value : Any] where {
              val make : () -> @This
              val make : Int -> @This
           
              method get : Key -> Value
              method put : Key -> Value -> ()
           
              #implementation
          }
           
          typeclass Indexable Container where {
              type Index
              type Value
              operator _[_]      : Container -> Index -> Value
              operator _[_] <- _ : Container -> Index -> Value -> ()
          }
           
          instance Indexable Array [T] where {                               -- Array is a type, use "type grammar"
              type Index = Int
              type Value = T
              operator array[index]           =  array.get index         -- array is a variable, use "operator grammar"
              operator array[index] <- value  =  array.set index value
          }
           
          instance Indexable Map [K, V] where {
              type Index = K
              type Value = V
              operator map[key]           =  map.get key
              operator map[key] <- value  =  map.put key value
          }
           
          let arr = Array.make 3 ""
          let map : Map[String, Array[String]] =   -- Map is a type, use "type grammar"
              if random.nextBool ()
              then make ()
              else make 2
           
          do {
              arr[1] <- "foo"                  -- arr and map are variables
              map["bar"] <- arr                -- use "operator grammar"
           
              print arr[1]
              print arr
              print map["bar"]
              print map
          }

        =>
        ExpandedWrap disabled
          "foo"
          ["", "foo", ""]
          ["", "foo", ""]
          #{"bar" => ["", "foo", ""]}

        Где тут конфликт?

        Цитата D_KEY @
        Так там же ! перед ними стоит.

        А разве ! не для этих их строковых "миксинов"?
          Цитата korvin @
          А разве ! не для этих их строковых "миксинов"?

          Нет, он для шаблонов. Просто строка является аргументом шаблона.
          Цитата korvin @
          map["bar"] <- arr                -- use "operator grammar"

          Вот как парсер здесь определит, что это оператор? Можно в парсере запоминать, какие идентификаторы являются именами переменных, а какие - типов. Но и это не всегда работает, поэтому в C++ используются приписки typename и template. Можно как у тебя - имена типов заглавной буквы, имена переменных - со строчной. Но конфликт то всё равно есть, и решается он какими-то дополнительными правилами или ограничениями грамматики.
            Цитата amk @
            И кто-нибудь может объяснить, нафига в Perl'е столько долларов и процентов перед идентификаторами?

            Выбор нужного контекста. На предыдущем примере:

            ExpandedWrap disabled
              my %data; #просто объявляется локальная переменная-хэш
              # "парсим" пошагово выражение -  ${${$data{"зеленый"}}[6]}{"вес"} = [1,2,3,4,5];
              #
              # $data{"зеленый"} - по ключу "зеленый" выбираем значение хэша
              # ${$data{"зеленый"}}[6] - выбранное ранее значение - это массив, выбираем его 7-й элемент
              # ${${$data{"зеленый"}}[6]}{"вес"} - а этот 7-й элемент сам хэш, выбираем в нем значение по ключу "вес"
              # ... ну и присваиваем этому элементу массив [1,2,3,4,5]


            Вроде все просто и ясно, не? :-?

            ЗЫ: В новой редакции Perl'a (6-я версия), будет немного по другому, вроде логичнее:
            ExpandedWrap disabled
              %{@{%data{"зеленый"}}[6]}{"вес"}

            Потому, как элементы хэша уже не похожи на элементы массива, и предваряются неизменяемыми префиксами % и @. Но мне непривычно.

            Добавлено
            Цитата applegame @
            Чтобы легче парсилось, полагаю.

            Именно.
              Цитата MyNameIsIgor @
              Вот как парсер здесь определит, что это оператор?

              Наверное, по тому, что токен перед ним --- переменная?

              Цитата MyNameIsIgor @
              Можно в парсере запоминать, какие идентификаторы являются именами переменных, а какие - типов.

              Почему бы и нет?

              Цитата MyNameIsIgor @
              Но и это не всегда работает, поэтому в C++ используются приписки typename и template.

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

              Цитата MyNameIsIgor @
              Можно как у тебя - имена типов заглавной буквы, имена переменных - со строчной.

              Э-м. В моём примере это решается не за счёт регистра символов, а за счёт однозначности семантики [] в, так скажем, двух не пересекающихся видах выражений --- "типовых" и "переменных":

              ExpandedWrap disabled
                type-decl   ::= "type" <id> "[" <type> ["," <type>]* "]" "where" "{" ... "}"
                value-decl  ::= "val" <id> ":" <type>
                method-decl ::= "method" <id> ":" <type>
                typeclass-type-variable-decl ::= "type" <id>
                instance-type-let ::= "type" <id> "=" <type>
                operator-decl ::= "operator" <syntax> ":" <type>
                let ::= "let" <id> ":" <type>
                let ::= "let" <id> "=" <expr>
                let ::= "let" <id> ":" <type> "=" <expr>

              --- упрощённо. Т.е. вполне себе легко определить, что в <type> [] --- параметры, а в <expr> --- оператор.

              Цитата MyNameIsIgor @
              Но конфликт то всё равно есть, и решается он какими-то дополнительными правилами или ограничениями грамматики.

              Не вижу, в чём ограничение. Если строго разделить виды грамматик <type> и <expr>, то они никак не будут конфликтовать. В Хаскелле, например, нельзя объявить оператор ::, т.к. декларации типов можно использовать в тех же местах, что и выражения, например:
              ExpandedWrap disabled
                x = y :: z -- это объявление x = y типа z или объявление x = результат применения оператора :: к переменным y и z?

              В ML по идее с этим лучше, но всё равно для декларации типа переменной используется : , а для операции cons списка --- :: т.к. есть как минимум одна неоднозначная ситуация:
              ExpandedWrap disabled
                function (h : t) = ...

              -- это паттерн-матчинг аргумента-списка или декларация типа для аргумента?

              В моём примере никакой неоднозначности быть не может.

              А можно ли определить оператор : , чтобы он не конфликтовал с объявлением типа? --- Спросишь ты. А можно. И опять никаких неоднозначностей:
              ExpandedWrap disabled
                let x : t : y                 -- syntax error
                let x : (t : class)           -- ok, not an operator in <type> expression
                let x = y : z                 -- ok, it's operator : in <expr> expression
                let x : (t : class) = y : z   -- ok, first two : --- <type>, third --- <expr>

              Как-то так.

              Добавлено
              Да собственно, что далеко ходить: в Java выражение дженерик-класса a<b> никогда не может быть спутано с использованием операторов сравнения А вот другие скобки уже используются в синтаксисе классов и только поэтому не могли быть использованы для параметров дженериков. Ну и плюс просто выбрали похожий на шаблоны C++ синтаксис.
              Сообщение отредактировано: korvin -
                Цитата korvin @
                Наверное, по тому, что токен перед ним --- переменная?

                Если ты запоминаешь идентификаторы или идентификаторы имеют разный вид для переменных и типов. А иначе ты получишь лишь идентификатор.
                Цитата korvin @
                Почему бы и нет?

                Ну, например, потому что это применимо лишь в языках, где всё объявляется до использования. И нельзя, например, вызвать функцию, объявленную ниже.
                Цитата korvin @
                Я и говорил лишь про конкретно проблему в синтаксисе Scala и конкретно возможность её решения при использовании чуть более другого синтаксиса

                Не вижу такой возможности.
                Цитата korvin @
                Т.е. вполне себе легко определить, что в <type> [] --- параметры, а в <expr> --- оператор.

                Это всё хорошо либо при теоретизировании, либо для синтаксически нищего языка. Например, что такое a[b]© в каком-то выражении? Это я из массива a беру по индексу b функцию и вызываю её с аргументом c? Или это я прямо в выражении без объявления переменной конструирую значение параметрического типа a с параметром b и отдаю в конструктор аргумент c?
                А что такое a[b].c? Это я из массива a по индексу b получаю значение и читаю его поле c? Или это я у параметрического типа a с параметром b читаю статическое поле c?
                Цитата korvin @
                Не вижу, в чём ограничение. ... В Хаскелле, например, нельзя объявить оператор ::

                :D
                Цитата korvin @
                Да собственно, что далеко ходить: в Java выражение дженерик-класса a<b> никогда не может быть спутано с использованием операторов сравнения

                Навскидку: в Java аргументами обобщений не могут быть значения, в C++ - могут.
                Сообщение отредактировано: MyNameIsIgor -
                  В общем, мало видов скобочек :(
                  Можно, как в D, заюзать какой-то специальный символ перед обычными скобками. Но тоже не слишком изящно.
                    Цитата MyNameIsIgor @
                    Это всё хорошо либо при теоретизировании, либо для синтаксически нищего языка. Например, что такое a[b]© в каком-то выражении?

                    В каком "каком-то" выражении? Ты пишешь на языке произвольных абстрактных выражений? Perl что ли? =) И как разделение выражений на <type> и <expr> вдруг делают язык "синтаксически" нищим?

                    Цитата MyNameIsIgor @
                    Это я из массива a беру по индексу b функцию и вызываю её с аргументом c? Или это я прямо в выражении без объявления переменной конструирую значение параметрического типа a с параметром b и отдаю в конструктор аргумент c?

                    А где оператор new? :tong:

                    Цитата MyNameIsIgor @
                    А что такое a[b].c? Это я из массива a по индексу b получаю значение и читаю его поле c? Или это я у параметрического типа a с параметром b читаю статическое поле c?

                    Вот это уже чуть интересней, но допустим у нас нет статических полей, у нас есть модули, где мы можем объявить статические переменные. Поэтому ответ: зависит от того, это <type> или <expr>, а это уже строго определено синтаксисом. Более того, зачем вообще явно указывать тип-параметр, если он выводится из контекста, как во всех нормальных языках? =)

                    Цитата MyNameIsIgor @
                    :D

                    Я и не говорил, что Хаскелл --- образец для подражания в этом вопросе.

                    Цитата MyNameIsIgor @
                    Навскидку: в Java аргументами обобщений не могут быть значения, в C++ - могут.

                    Т.е. вместо a можно подставить 1? Будет 1<b>? И что тогда в C++ означает выражение 1<2>(3)? Создание объекта шаблонного класса 1 с шаблонным параметром 2 и параметром конструктора равным 3? =) Ну, допустим, про 1 я утрировал, но a<1>(2)?

                    Пара-пара-пам?

                    Добавлено
                    Цитата MyNameIsIgor @
                    Ну, например, потому что это применимо лишь в языках, где всё объявляется до использования. И нельзя, например, вызвать функцию, объявленную ниже.

                    Отчего же? Разбор неоднозначного выражения (с несвязанным идентификатором) можно отложить, как это уже делается для рекурсивных функций.

                    Цитата MyNameIsIgor @
                    :D

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

                    Добавлено
                    Цитата D_KEY @
                    В общем, мало видов скобочек :(
                    Можно, как в D, заюзать какой-то специальный символ перед обычными скобками. Но тоже не слишком изящно.

                    А может наплевать на всех, и заюзать символы вне ASCII диапазона? =)

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

                    1) вместо оператора new использовать new как специальный статический метод, new и так ключевое слово и определить такой метод нельзя. Кроме того, такой синтаксис и так поддерживается в некоторых ситуациях. Т.е. вместо
                    ExpandedWrap disabled
                      new ArrayList<T>();

                    было бы
                    ExpandedWrap disabled
                      ArrayList(T).new();


                    2) при создании анонимного класса inplace передавать аргументы конструктора не после имени класса, а после фигурных скобок его тела, т.е. вместо
                    ExpandedWrap disabled
                      new Foo(1) {
                          // ...
                      }

                    писать
                    ExpandedWrap disabled
                      new Foo {
                          // ...
                      }(1)

                    Тогда после Foo в круглых скобках можно было бы указать типы.
                    По-моему этому ничего особо не мешало, но, может, я что-то упускаю.
                    Сообщение отредактировано: korvin -
                      Цитата korvin @
                      В каком "каком-то" выражении?

                      В любом.
                      Цитата korvin @
                      И как разделение выражений на <type> и <expr> вдруг делают язык "синтаксически" нищим?

                      Вводом ограничений.
                      Цитата korvin @
                      А где оператор new?

                      В синтаксически нищих языках :-?
                      Так что я так и не понял, как ты будешь определять, что это не вызов конструктора.
                      Цитата korvin @
                      Вот это уже чуть интересней, но допустим у нас нет статических полей, у нас есть модули, где мы можем объявить статические переменные

                      Т.е. я не смогу иметь отдельные переменные для каждого инстанса параметрического типа a? Это уже семантическое, а не синтаксическое, нищенство.
                      Цитата korvin @
                      Более того, зачем вообще явно указывать тип-параметр, если он выводится из контекста, как во всех нормальных языках? =)

                      Не знаю как там в нормальных, а в самом лучшем так
                      ExpandedWrap disabled
                        template<class T>
                        struct a
                        {
                          static constexpr bool s = sizeof(T) == sizeof(char);
                        };
                         
                        int main()
                        {
                          return a<int>::s;
                        }

                      Как нормальные языки выведут, что я имел в виду именно int?
                      Цитата korvin @
                      Т.е. вместо a можно подставить 1? Будет 1<b>? И что тогда в C++ означает выражение 1<2>(3)? Создание объекта шаблонного класса 1 с шаблонным параметром 2 и параметром конструктора равным 3? =)

                      Нет. У тебя осталось две попытки ;)
                      Цитата korvin @
                      Ну, допустим, про 1 я утрировал, но a<1>(2)?

                      Пара-пара-пам?

                      Это боян. Например
                      ExpandedWrap disabled
                        a.func<A>(b); // что здесь написано?

                      Но проблема раскрывается здесь
                      ExpandedWrap disabled
                        template<class T>
                        void foo(T t)
                        {
                          t.func<1>(2); // а здесь что написано?
                        }


                      Добавлено
                      Цитата korvin @
                      Отчего же? Разбор неоднозначного выражения (с несвязанным идентификатором) можно отложить, как это уже делается для рекурсивных функций.

                      Усложнения парсера - требуется определить конец откладываемой части.
                      И не всегда осуществимо - например, ты разбираешь обобщение (как у меня в примере выше), но при этом тебе его надо положить в байт-код.
                      Ещё может возникнуть веселуха с циклически ссылающимися друг на друга кусками разбираемого кода.
                      Цитата korvin @
                      А может наплевать на всех, и заюзать символы вне ASCII диапазона? =)

                      А набирать то их как?
                      Сообщение отредактировано: MyNameIsIgor -
                        korvin, а обобщённые функции как тогда выглядели в такой Java?
                        Сообщение отредактировано: D_KEY -
                          Цитата MyNameIsIgor @
                          Вводом ограничений.

                          Как будто что-то плохое. Тебя же не смущает отсутствие возможности переопределения ключевых слов или использования их в качестве идентификаторов? А то в каком-то языке можно было легко получить код вроде
                          ExpandedWrap disabled
                            if if begin begin

                          Впрочем, ты так и не привёл ни одного нормального примера ограничения, а просто пытаешься навязать плюсовый синтаксис. =)

                          Цитата MyNameIsIgor @
                          В синтаксически нищих языках

                          Типа C++?

                          Цитата MyNameIsIgor @
                          Так что я так и не понял, как ты будешь определять, что это не вызов конструктора.

                          Как угодно, я выше D_KEY'ю написал пример про Жабу. Или так же, как парсер Хаскелла отличает идентификатор типа от идентификатора конструктора.

                          Цитата MyNameIsIgor @
                          Как нормальные языки выведут, что я имел в виду именно int?

                          В нормальных языках нет нужды в подобном коде. =)

                          Цитата MyNameIsIgor @
                          Это боян.

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

                          Цитата MyNameIsIgor @
                          Усложнения парсера - требуется определить конец откладываемой части.

                          Да какое ж тут усложнение? Я же приводил выше примерную грамматику, парсеру не нужно знать смысл []. Это смысл будет дальше определён вычислителем/компилятором. Парсер Java как отличает, где [] --- это указание размера создаваемого массива, а где --- обращение по индексу? Где {} --- инициализатор массива, а где --- блок кода? Где в () используется точка с запятой (for, try), а где --- запятая (аргументы)? У Java сложный парсер? Да уж, думаю, попроще, чем у C++, а уж "обогащённый" парсер, как я понимаю, умеет туеву кучу неоднозначностей разруливать. Или не умеет?

                          Цитата D_KEY @
                          а обобщённые функции как тогда выглядели в такой Java?

                          Вот, так и знал, что что-то упущу. Навскидку могу предложить foo(T)(x), выглядит не ок, но логично, т.е. вначале мы передаём конкретный тип и как бы создаём замыкание на его основе, а потом применяем замыкание к аргументу x. Вообще же, тут тип мог бы просто выводиться из типа аргумента, но из-за субтипирования, он может оказаться более общим, чем нужно.

                          Добавлено
                          Цитата MyNameIsIgor @
                          Т.е. я не смогу иметь отдельные переменные для каждого инстанса параметрического типа a?

                          В нормальных языках параметрический тип ---- это параметрический тип, а не хрен пойми что, плодящая кучу кода. =)

                          Добавлено
                          Цитата MyNameIsIgor @
                          А набирать то их как?

                          Compose+( например. В нормальных же операционных системах есть поддержка клавиши Compose =)
                          Сообщение отредактировано: korvin -
                            Цитата korvin @
                            Впрочем, ты так и не привёл ни одного нормального примера ограничения, а просто пытаешься навязать плюсовый синтаксис. =)

                            Т.е. обязательно new и отсутствие статических членов - это ненормальные ограничения :D
                            Цитата korvin @
                            Типа C++?

                            Нет, типа Go и Java. Впрочем, они не только синтаксически, они и семантически нищие.
                            Цитата korvin @
                            Это пример того, как духовносинтаксически богатый язык превозмогает обсуждаемую трудность. С чем ты споришь? =)

                            Нет, не превозмогает. И я привёл тебе код почему не превозмогает.
                            Цитата korvin @
                            Да какое ж тут усложнение? Я же приводил выше примерную грамматику, парсеру не нужно знать смысл [].

                            Эммм... Все твои рассуждения как раз и сводятся к тому, что мы при парсинге знаем смысл [].
                            Цитата korvin @
                            Парсер Java как отличает, где [] --- это указание размера создаваемого массива, а где --- обращение по индексу? Где {} --- инициализатор массива, а где --- блок кода? Где в () используется точка с запятой (for, try), а где --- запятая (аргументы)?

                            Это не означает, что все неоднозначности можно разрулить без дополнительных приседаний. Что ты и доказал с теми же статическими членами.
                            Цитата korvin @
                            Да уж, думаю, попроще, чем у C++, а уж "обогащённый" парсер, как я понимаю, умеет туеву кучу неоднозначностей разруливать. Или не умеет?

                            Неоднозначности потому и неоднозначности, что без дополнительных телодвижений не разруливаются. Естественно грамматика C++ однозначна, но она контекстно-зависимая и потребовала подпорок typename/template.

                            Добавлено
                            Цитата korvin @
                            В нормальных языках

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

                            Добавлено
                            Цитата korvin @
                            В нормальных же операционных системах

                            В нормальных операционных системах нормальное API, а не убожество типа epoll/kqueue...
                            Сообщение отредактировано: MyNameIsIgor -
                              Цитата korvin @
                              Цитата D_KEY @
                              В общем, мало видов скобочек :(
                              Можно, как в D, заюзать какой-то специальный символ перед обычными скобками. Но тоже не слишком изящно.

                              А может наплевать на всех, и заюзать символы вне ASCII диапазона? =)

                              Это не слишком удобно :D

                              Проще добавить в язык end. Мне не очень нравится, но {} освободит.
                              ExpandedWrap disabled
                                def foo{T}(T x)
                                    ...
                                end
                                 
                                class A{T}
                                    ...
                                end
                                 
                                ...
                                 
                                foo{int}(10);
                                 
                                A{T} a;
                                 
                                map{string, int} dict;


                              Добавлено
                              Еще таки есть вариант с дополнительным символом

                              ExpandedWrap disabled
                                map!(string, vector!int)
                                 
                                map@(string, vector@int)

                              Или чуть изменим скобки:
                              ExpandedWrap disabled
                                map(:string, vector(:int))

                              Ну или что-то в таком роде.

                              Эх, в любом случае получается отстой.
                              Сообщение отредактировано: D_KEY -
                                Цитата MyNameIsIgor @
                                В нормальных операционных системах нормальное API, а не убожество типа epoll/kqueue...
                                А что есть в нормальных ОС вместо epoll/kqueue? IOCP?
                                Сообщение отредактировано: applegame -
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (56) « Первая ... 38 39 [40] 41 42 ...  55 56


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,1091 ]   [ 16 queries used ]   [ Generated: 26.04.24, 19:32 GMT ]