Замечания и предложения

Я не понял, откуда индекс у элемента последовательности? Индекс есть у элемента массива, а у элемента последовательности понятия первого элемента, последнего, текущего и возможность перейти к следующему. ))

А это LINQ из .Net Select / Where поддерживают выдачу элемента, а также элемента и его индекса.

Не индекса. Порядкового номера в процессе перебора, отсчитываемого от нуля. Дело в том, что для PascalАВС.NЕТ и массив, и список List, и кое-что еще - разновидности все той же последовательности. Поэтому в Where, Select и т.п. LINQ старается экземпляр входного контейнерного класса “разобрать” в стандартную последовательность.

Да. Именно номер элемента в последовательности, начиная с 0

А чего я то сразу?))

Она есть при объявлении локальных переменные (но не параметров) и в is-var.

begin
  ReadArrInteger(ReadInteger)
    .Combinations(2)
    .Select(x->(x[0],x[1])) // ниже строчка не работает
    .Where(x->
    begin
      if x is (var a,var b) then
        Result := ((a+b)mod 80 =0)and((a>50)or(b>50));
    end)
    .Print();
end.

Вообще должно быть возможно красивее:

begin
  ReadArrInteger(ReadInteger)
    .Combinations(2)
    .Select(x->(x[0],x[1]))
    .Where(x->(x is (var a,var b)) and ((a+b)mod 80 =0)and((a>50)or(b>50)))
    .Print();
end.

Но - 1 и 2.

Where((x,y)->…) - тут надо не забывать, что x,y не могут трактоваться здесь как кортежи - это параметры лямбды. И ещё я не понял - зачем массив из двух элементов превращать в кортеж - всё равно потом обращаемся по индексам t[0] и t[1]

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

А, кстати да, is-var тоже может работает с массивами:

begin
  ReadArrInteger(ReadInteger)
    .Combinations(2)
    .Where(x->
    begin
      if x is [var a,var b] then
        Result := ((a+b)mod 80 =0)and((a>50)or(b>50)) else
        raise new System.InvalidOperationException;
    end)
    .Print();
end.

Тут, получается, проверяет не только x<>nil, но ещё и x.Length=2. Что очень хорошо, если решите заменить ReadArrInteger.Combinations на что то другое - тело Where не надо менять.

Ну так если вспомнили - как же переоткрыть issue?

Я же сказал - в этом контексте не поддерживается. И не будет.

1 лайк

То есть с указанием типа будет работать:

begin
  var t: (integer, integer);
  var res := t is System.Tuple<integer,integer>(var a, var b);
end.

А с сахаром - нет? Неужели так сложно?

Не понял. Что сложно?

Всё ради краткости кода. Иначе на каждую переменную еще по три символа [0]/[1], что усложняет чтение кода. Мне эта идея кажется полезной.

Да, я тоже не понял что сложно, потому что это:

t is System.Tuple<integer,integer>(var a, var b)

И это:

t is (var a, var b)

Один и тот же код, но второй - с дополнительным слоем сахара. То есть, скорее всего, всё “не поддерживается” заключается в чём то типа нехватки дубля метода визитора.
Я смотрю все коммиты-фиксы issue и обычно такое исправлялось 1-2 строчками.

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

t is System.Tuple<integer,integer>
  • это обычный is
t is System.Tuple<integer,integer>(var a, var b)
  • это расширенный is - с деконструктором

Эти элементы в языке есть

В последнем примере так писать немного глупо - обычно t должно иметь тип надкласса

а почему бы не так?

t is var (a,b)

это уже похоже на pattern matching и тут я пока слаб в хороших идеях. Моя интерпретация: проверяем что это кортеж из двух элементов и помещаем значения элементов кортежа в локальные переменные a и b

Паттерн матчинг берет своё начало из расширенного is. Расширенный is это -

перем is СовместимыйТип(var перемДляДеконтрукции)

Об этом случае представление у меня более менее есть. На C# регулярно использую. Хуже понимание реализаций в F#. Еще есть плохое различение паттерн матчинга с унификацией в Прологе. Много общего, но есть и различия

В смысле эксперементальный? Это же было добавлено вместе с a is [...] и т.п., в обновлении паттерн-мачинга, о котором вы на странице изменений писали. Или нет?

Вот, отсюда:

[25.05.19] Версия 3.5.0.2067

  • Улучшения Pattern Matching - Pattern Matching с IList, кортежами, константами

Про кортежи явно сказано, прямо рядом с IList.
Вот для IList это is [...], а для кортежей - is (...).