4 сообщения перенесены в новую тему: Шоб було
Все страньше и страньше! (Л.Кэррол. Алиса в Стране чудес)
С изумлением обнаружил сообщение:
Использование лямбда-выражений в подпрограмме при наличии вложенной подпрограммы запрещено
Ну хорошо, “Меткам - бой”, но зачем же махать саблей направо и налево? Какие-такие ужасы несет в себе локализация процедуры или функции в теле программы? Я не знаю, конечно, что там за такая странная реализация лямбд, требующая делать подобные запреты, но почти уверен, что это новация не должна быть абсолютом.
С удивлением начинаю замечать, что процесс написания программ в последнее время все больше начинает походить на прогулку по минному полю. Разработчики устали или сложность программы перешагнула пределы, в которых с ней могли справиться и приняли решение идти по наиболее простому пути: “не пущать!” *?
Если разработчики начинают безусловно запрещать лямбды, вместо того, чтобы подумать, когда действительно возможны коллизии - это плохой знак. Ну вот кто решил и где написано, что вложить в одну программную единицу другую - это “дурной тон” и должно быть закидано камнями? Почему я должен внутреннюю кухню одной программной единицы делать общей для всего модуля? В современном программировании утверждается, что глобальные объекты - это плохо и нужно максимально использовать локализацию, а тут мы наблюдаем прямо противоположное: какой-то “мелкий потрох” одной процедурки я должен тащить “наверх” и делать видимым во всем модуле. Неправильно это!
@Admin Сборка 1504, жесткий вылет на ровном месте (Win7 x64).
Я наблюдал ошибку с этим сообщением и раньше, но она проявлялась довольно редко и была “плавающей” – напр., случалась иногда при быстром открытии через историю некоторых исходников (в течение нескольких секунд сразу после старта среды). Скажем, было у меня такое одно время с PABCSystem.pas, потом вроде бы прекратилось после того как я отключил code folding в редакторе. Теперь вот падает через раз просто при попытке поставить точку после x
в таком фрагменте, но только если я быстро набираю его вручную сразу после запуска среды, а не копирую. Похоже на какой-то race condition или stack overflow из-за рекурсии (причем, вроде даже не в managed коде!)
P.S.: PascalABCCompiler.Core v3.2.0.1504 (09.07.2017), debug version Runtime version: 4.0.30319.42000 OS version: Microsoft Windows NT 6.1.7601 Service Pack 1 Processor count: 2 WorkingSet: 71020 kb
О, коллега, это мой секретный эксклюзивный тюнинг А иконки такие выдаются вообще только заслуженным пионерам по указу президента, мне вон третью только недавно открыли!
Понятно, наверно поставили какой-нибудь электронный задачник))
У меня вроде бы и на ХРюше все всегда также было, ну кроме рубиновых звезд в заставке и красных циферок, конечно Вы что в инсталляторе нарочно все галочки снимаете, там же урезанный “Абрамян” в комплекте идет! Немедленно требуйте отстоя и долива!
С удивлением начинаю замечать, что процесс написания программ в последнее время все больше начинает походить на прогулку по минному полю
Ну, использование goto это как раз прогулка по минному полю. Что касается лямбд, то по техническим причинам запрет окончательный. Лямбды еще кое-где запрещены, например во вложенных подпрограммах. И это не разработчики устали, это просто новое иногда плохо ложится на старое.
Рискну утверждать, что запрет это появился не очень давно. Во всяком случае мне что-такое помнится, когда была вложенная подпрограмма и компилятор не вещал дурным голосом, что нельзя использовать ArrGen. Т.е. структура вида
procedure A;
procedure B;
begin
end; // B
begin
B;
var x:=ArrGen(5,i->i*i);
B;
end;
begin
A;
end.
у компилятора вопросов не вызывала. Ибо как нет тут вызовов В из ArrGen и повода лямбде что-то там захватывать из B тоже нет.
И в связи с со всем этим у меня вопрос возникает общего плана. Я сейчас пытаюсь сделать библиотеку, где будет много всяких программ. Возможно, очень много. Я не знаю способа раскидать это во множество файлов, чтобы потом подключать единым uses, а делать многоэтажное подобие сишных #include это тоже не метод. Посему получается, что файл должен быть один. И исходник тоже один. Но многие задачи в свою очередь используют различные вспомогательные подпрограммы - вот тут вложенность-то и нужна, чтобы их не светить. Делать из каждой процедуры класс с его локализациями - это не выход. Так мне что, из-за поголовного запрета сожительства лямбд и вложенных программных единиц теперь писать это все в стиле ТурбоПаскаль?
Объявлять их в implementation-части модуля. Если хочется еще вложенности, то в класс.
Когда-то давно висела в TODO реализация import. Это когда в корневой модуль можно импортировать имена из других модулей, чтобы избежать монструозных uses-ов в конечных программах, а подключать только корневой модуль.
Нет, речь шла о том, чтобы в пределах единого модуля прятать внутреннюю кухню. Если у меня библиотека и в ней есть тип Point, обозначающий в одной задаче точку с координатами (x,y), в другой - тоже точку, но уже с координатами (х1,х2,… xn,y), а в третьей - снова точку, но уже в полярной системе координат (rho,phi), а в четвертой точку с комплексными координатами, почему я должен вводить имена Point1, Point2, Point3 и т.д. и как объяснить пользователю, что в задаче аппроксимации функции одной переменной надо использовать массив точек типа Point2, а при поиске минимума функции трех переменных ответ будет в массиве переменных типа Point3 ? Сослаться, как когда-то Жванецкий писал, на “потому что ГОСТ у нас дурачок”?
-Папа, а как называется конь-папа? -Жеребец -А конь-мама? -Кобыла -А конь-детка? -Жеребенок -А тогда какой конь называется просто конь?
Справка → Справочник по языку → Структура программы → Идентификаторы и ключевые слова: в списке ключевых слов присутствует слово “using”, которое ключевым словом не является.
У нас не воспроизводится.
А меня эта ошибка уже больше года мучает. Опытным путём установлено, она чаще всего (если не всегда) возникает, если поставить точку, и до того ни разу не использовать InelliSense. Причём, её иногда можно случайно поставить в любом месте, и возникнет ошибка.
Сигнатура проблемы: Имя события проблемы: CLR20r3 Сигнатура проблемы 01: PascalABCNET.exe Сигнатура проблемы 02: 3.2.0.1504 Сигнатура проблемы 03: 59614d8f Сигнатура проблемы 04: CodeCompletion Сигнатура проблемы 05: 1.0.0.0 Сигнатура проблемы 06: 59614d87 Сигнатура проблемы 07: 3f7 Сигнатура проблемы 08: 1d Сигнатура проблемы 09: System.StackOverflowException Версия ОС: 6.1.7601.2.1.0.256.1 Код языка: 1049 Дополнительные сведения 1: c029 Дополнительные сведения 2: c029c0f11049a032ed56fbfbf15c3309 Дополнительные сведения 3: cc84 Дополнительные сведения 4: cc84e7863767c39ca621ac072d78fe7f
Обнаружилась очень неприятная ошибка. Очень - потому что 1) она “плавающая”, т.е. я пока не могу четко локализовать условия, в которых она проявляется. 2) она относится к написанию методов класса где нельзя использовать ключевое слово forward и утверждается, что оно “не нужно”.
Имеется и редактируется код модуля, содержащего около десятка классов. К примеру, я редактирую код в классе X. При попытке компиляции совершенно неожиданно возникает сообщение об ошибке в классе Y о том, что невозможно найти тот или иной метод. Понятно, что у меня в коде каждого класса идет сначала конструктор, затем процедуры и функции, реализующие методы класса. Если из конструктора вызывается какой-то метод, то ВРЕМЕНАМИ возникает сообщение, что метод не найден. Если код метода поместить текстуально выше конструктора, ошибки не возникает. Я пока не привожу код модуля, потому что, повторюсь, еще не понял, какие действия вызывают сообщение об ошибке. Дело в том, что ошибка может пропасть сама собой, даже если оставить код конструктора первым… просто через время. И да, если кто-то захочет повторить эксперимент, у меня в описании конструктора имя Create отсутствует.
Вы реализуете методы сразу или позже, в разделе implementation
что такое forward для методов? они все по умолчанию “forward”
Методы пока сразу, я интерфейсы буду делать потом сразу на все.
Вот и я о том, что они все по умолчанию “forward”, а временами вдруг перестает компилироваться и не идет, пока не расставишь в порядке, чтобы сначала описать, потом вызвать.
Ну, ловите ошибку. Хотя бы вероятностно. Если мы ее тоже поймаем, то исправим.