Помощь новичкам

Я не собираюсь в Вами спорить, потому что Вы как мыслили категориями языков семейства С, так и продолжаете мыслить. Для Вас “язык” - это все, что можно подлинковать из .NET-библиотек. В Справке описано то, что так или иначе относится именно к PascalABC.NЕТ.

Я не хочу перечислять тут то, на что потратил две недели, когда писал полсотни страниц части 6 своей будущей книги.

Я не нашёл там части про методы строк, поэтому залез в PABCSystem.pas. Там со строки 1469 перечислены все методы для строк. Ну и + экстенш-методы которые видны по точке.

И единственный который индексирует строку с 1 - это Copy, то есть старьё существующее только для совместимости. Оно даже исключения не вызывает, просто игнорируя ошибочные случаи, что в современном программировании считается очень плохим стилем.

Нет подождите, мне всё же интересно понять… То есть вы говорите что раз оно не описано в справке, даже если находится в том же пространстве имён (то есть его показывает по точке для любой строки, при чём в самом начале) - это не часть PascalABC.Net?

Я же говорю не про функцию, ради которой надо что то подключать, а про то, что поумолчанию есть в каждой программе. Я так же мог бы понять, если бы вы имели в виду что часть языка - это то что запрограммировали разработчики. Но тот же .Remove - это тоже встроенная в .Net функция, которая отличается от .CopyTo только тем, что её нету в справке паскаля. А по справке сравнивать странно потому что:

Так же, разработчики сами писали когда то, что не собираются делать справку по всему что даёт .Net, ибо оно уже задокументировано на msdn, это была бы лишняя трата времени. То есть та справка так же может считаться описывающей часть данного языка. Или нет?

И можете ещё подробнее объяснить:

Я вообще не понял к чему это тут. Я хоть 2 из них знаю, но не использую, откуда у меня какое то мышление в их стиле?

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

Это вовсе не обязательно часть РasacalABС.NЕТ. И не нужно делать вид, что это Вас удивило. Вы же не считаете, что при использовании #include в С++ все перечисленное там станет частью языка? А в PascalABC.NЕТ по умолчанию часть библиотек уже прилинкована, но частью языка от этого содержимое библиотек не стало. Такими рассуждениями можно дойти до того, что весь .NET - тоже часть языка, если разработчики создадут соответствующее пространство имен.

Писал не раз, не хочу повторяться. Хотите - считайте это моим частным мнением.

Забавная дискуссия. Как не косяк, так везде С-мышление виновато! Ох же ж оно, Кернигана с Ритчи надо ретроактивно абортировать!

От сабжа ушли. Кто б там, и каким образом не был виноват в ситуации, факт остаётся фактом: то, что в пределах одного языка строки и массивы индексируются то с нуля, то с единицы - фундаментально неправильно. И, кстати, лечится оно собственной реализацией набора тех самых extension-методов для сих структур данных, если я все правильно понимаю (может быть, и нет, поправьте, если нельзя). Пользователь языка не должен уметь отличать методы PABC.NET от методов .NET. Я б сказал, это вещь, достойная Issue на гитхабе.

1 лайк

Наследие совместимости. Ну вот решил когда-то так Н.Вирт, что символы в строках надо от единицы нумеровать. Как по мне, так оно правильно именно от единицы. Вот опять мне тут сейчас про Кернигана с Ритчи напомнят, но до “языка Це” массивы индексировались либо от единицы (Фортран, Бейсик), либо от описанной нижней границы (Алгол, PL/1), а символы в строках нумеровались от единицы. И это понятно: нормальные люди, как правило, издавна ведут счет от единицы. Нумерация от нуля была только в ассемблере из-за удобства работы со смещением от начала массива.

Вы что предлагаете? Совместимость со всеми остальными паскалями уничтожить, или индексировать массивы от нуля, а строки от единицы всегда, для чего перегрузить все, взятое из .NET? А LINQ тоже будем перегружать? С Matches как - там тоже от нуля нумерация?

Тут можно подискутировать, но не не хочется.

Я предлагаю перегрузить все методы расширения для поддержки индексации массивов и строк, принятой в Паскале. В любом случае, насколько мне известно, PABCSystem.string != System.String, и, скорее всего, какие-то из перегрузок уже написаны. Linq работает с IEnumerable, не так уж и много там писать.

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

Массивы есть статические и динамические. Для статических массивов границы изменения индексов задаются при описании, Для динамических - начинаются с нуля. Вы предлагаете у динамических массивов тоже делать изменяемые границы? Или как в старых Бейсиках - нижний индекс директивно назначать от нуля или единицы? Если нет, то как понимать Ваши слова про принятое в паскале для массивов?

Со строками получилась смесь, как я себе представляю, из-за желания разработчиков сохранить “как было в Delphi”. А там были строки разных типов и в них была нумерация то с единицы, то с нуля. Вы предлагаете эту совместимость поломать? Похоже, разработчики пока что с Вами вряд ли согласятся.

Разные строки - может быть. Но в пределах методов одного класса разных нумераций быть не должно. ИМХО, конечно.

Динамические, статические, строки - не суть. Предложение стянуть нумерации для всех из той же Delphi (Turbo, Borland, FP, Lazarus - по вкусу), и сделать все их методы с учетом выбранной нумерации. Т.е., если уж динамические начинаем с нуля - значит, с нуля. Если строки по желанию левой пятки должны именоваться с 2 - значит, эти 2 должны поддерживаться в [], IndexOf, и т.д.

Главное, чтобы для каждого объекта не было разных нумераций в пределах одного класса. Все методы должны работать единообразно.

1 лайк

А они разных классов. У них только предок общий.

Вот тут один объект имеет одновременно две нумерации - с 0 и с 1. Вот этого быть не должно. Должно быть или 0, или 1. Хоть в operator[], хоть в IndexOf.

1 лайк

Конкретно тут - да, это плохо. Но что делать: нет совершенства в этом мире и приходится мирится с тем, что дано. Доводы, которые я так или иначе, в том или ином виде получал от разработчиков - я уже приводил выше. Нравится нам это или нет, но вот так сделано. Я не знаю, что еще тут добавить.

Некоторые классы всё же стоит описать. Строки например, списки. Весь MSDN конечно невозможно

1 лайк

Методы строк перегрузить нельзя - они вшиты в тип string. Обсуждение тут непродуктивно

Мы бы сами рады это убрать. Но тут напрямую сталкиваются два мира со своими совместимостями - мир Delphi с индексацией от 1 и мир NET с вшитой индексацией от 0. Поэтому для всех методов оставлена индексация от 0, а для внешних функций - от 1

Еще мы когда-то делали директиву компилятора:

{$string_nullbased+}
begin
  var s: string := 'ABC';
  Print(s[0]);
  
end.

Но её сейчас надо потестировать. В частности,она не работает для срезов

2 лайка

Хотелось бы так же добавить что это неправильно. Это один и тот же тип. Я даже больше скажу, string[15] это тоже тот же тип. Для типизированных файлов в компилятор вшит костыль, создающий список отступов при объявлении file of T. А в остальном - это самые обычные строки.

Нет, наоборот PABCSystem.string == System.String

Это полная совместимость с NET овскими строками

Задача. Дано целое число N (> 1). Вывести наименьшее из целых чисел K, для которых сумма 1 + 2 + … + K будет больше или равна N, и саму эту сумму.

Как написать код в функциональном стиле, без циклов. С циклами то понятно:

Summary
begin
  var N := ReadInteger();
  var Sum := 0;
  var K := 0;
  while Sum < N do
  begin
    K += 1;
    Sum += K;
  end;
  Print(K, Sum)
end.

а вот как с последовательностями SeqGen, Range…, чтоб без циклов?. Напишите пожалуйста, кому не лень.

Что-то типа

begin
  var n := 15;
  1.Step
   .Select(x -> (x, 1.to(x).sum))
   .SkipWhile(t -> t[1] < n)
   .Take(1)
   .Print
end.
1 лайк

Спасибо :slightly_smiling_face:

В данном случае, вам нужно не функциональное программирование а математика.
1+2+...+K = K*(K+1)/2. То есть решаем уравнение K*(K+1)/2 = N и округляем ответ с помощью Ceil.

P.S.

Для этого есть .First.

Ну да, конечно First. Просто промежуточный вариант не заработал с ним, вот Take и осталось.

Что касается нужности ФП в данном случае, то возможны два взгляда.

(1) В реальных задачах да, надо использовать простейшее решение по формуле арифметической прогрессии

(2) Если мы тренируемся в использовании соответствующих возможностей языка – почему бы и не решить? Главное помнить, что это совершенно неэффективно.