LINUX.ORG.RU

Почему не FreePascal+Lazarus?

 , ,


0

5

На паскале пишешь? Фу таким быть...

Почему не принято для Linux писать что-то на FreePascal? Да, язык немного менее гибкий, чем C/C++, более тяжеловатый синтаксис и begin end вместо скобочек кое-кого реально задалбывают. Но зато благодаря более развитой типизации и другим более безопасным вещам меньше шансов «выстрелить в ногу» при сохранении в тоже время и достаточной при необходимости низкоуровневости, чтобы писать даже системные вещи.

Реально раздельная компиляция на уровне языка, при том, что поддерживается и заголовочно-линкерская раздельность как в Си.

Да, есть некоторое отставание по таким возможностям, как всякие там лямбды, хотя в Delphi их добавляют, но не будем о Delphi. Вот положа руку на сердце, прям так жить без них нельзя в том же C++? Или лучше использовать для них Лисп, Haskell, OcaML и тп. а не скрещивать ежа с ужом, превращая язык в какого-то необозримого монстра, все возможности которого мало кто знает. При том, что в том же FreePascal/Delphi тип процедура/функция и object дают возможность совершать некоторые фукциональные трюки.

Стандарт? Да, стандарта нет. Но как будто на практике с этим сильно лучше у C++? Фактически крупные программы пишутся под конкретный компилятор и даже версию компилятора, на других могут быть сюрпризы даже на одной платформе, заранее положиться без тестирования, что оно соберется и будет себя также вести нельзя.

★★★★★

Ответ на: комментарий от mongo

{} выделяются из текста и визуально воспринимаются.

В немалой степени, благодаря отступам.

DarkEld3r ★★★★★
()
Ответ на: комментарий от DeaDDooMER

«Необычное везение»

Ага, спасибо. Только я не совсем понимаю суть претензии. Ошибка ведь из-за того, что скобки не обязательны, а не из-за наличия «блоков»?

Ну по-моему лучше получается.

Ну хз, я тоже стараюсь писать без 100500 ретурнов, но в раннем выходе ничего не вижу, особенно, если он один. Хотя это вкусовщина.

DarkEld3r ★★★★★
()
Ответ на: комментарий от ovk48

Сначала подумал, что написано на Д, оказалось, что на лазарусе.

Забавно. А почему и правда на D не написали? У него с гуем хуже?

DarkEld3r ★★★★★
()
Ответ на: комментарий от mongo

Да, просто феерическое школоло...

anonymous
()

Граждане поцкалисты, объясните несколько вещей.

1. Зачем в этих ваших поцкалях такие ограничения на использование сложных типов данных? Вот, например, почему при передаче пресловутого массива фиксированного размера нельзя писать procedure ololo(a: array[0..9] of Int32), а надо сначала объявить этот массив типом, а потом использовать в сигнатуре? Особенно странно, если учесть, что в объявлении переменных так писать можно. Или ещё тут мелькало объявление указателя на функцию, принимающей указатель на функцию, которое из-за подобных ограничений не смогли записать в одну строчку. Вот и объясните, в чём смысл этого решения и как определить, где какими типами можно пользоваться.

2. Зачем нужны мудацкие массивы с произвольным стартовым индексом? Чтобы запутать апи сторонних библиотек, в половине из которых - индексация с 0, а в половине - с 1?

3. Отсутствие функций с произвольным числом аргументов. Из-за этого функции вывода, вместо того, чтобы запилить их в виде обычных функций стандартной библиотеки, приделали в виде костыля к языку, а для форматирования чисел сделали грёбаный спецсинтаксис, который используется только в вызовах этих функций и больше нигде. Ортогональность, мне без тебя плохо! Вы действительно считаете, что язык с подобными решениями не должен вызывать тошноты у грамотного инженера?

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

5. То же, что и в предыдущем пункте. Объявления функций должны идти перед местом использования, аналог функции main всегда в конце программы. Нельзя написать программу так, чтобы она читалась сверху вниз. После этого вы будете утверждать, что паскаль - читабельный ЯП?

6. Масса диалектов, в которых чёрт ногу сломит и никакой стандартизации, что превращает освоение языка в весёлый и полный неожиданностей процесс. Где найти аналоги K&R или The Rust Programming Language для поцкаля?

7. Как там с перегрузкой операторов? Или будете кричать, что она не нужна?

8. Полиморфизм? В т.ч. и времени компиляции?

9. Стандартные интерфейсы для контейнеров и т.п., вроде итераторов?

10. Дебильные названия стандартных типов. Как мне догадаться, что shortint и byte - знаковый и беззнаковый тип одной длины?

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

anonymous
()
Ответ на: комментарий от mongo

Кроме того }}} грамотные программисты не пишут а визуально выделяют блоки с помощью отступов.

end; end; end - тоже неграмотно. Просто end визуально длиннее, чтобы глаз за него зацепился. А скобка может легко затеряться. На первый взгляд, очень легко перепутать }}} с }} или с }}}}. А одну скобку в одной строке вообще можно упустить, особенно если не ожидаешь её там.

С языками с C-синтаксисом мне вполне удобно различать блоки установив размер табуляции в 2 символа.

В Паскале тоже часто ставят два символа. В Lazarus это по умолчанию.

FoodChemist
()
Ответ на: комментарий от FoodChemist

Ну я уже сказал - лично мне в руби было очень не комфортно искать глазами эти блоки без скобок. Если кому то нравится рад за него.

mongo
()
Ответ на: комментарий от anonymous

Вот, например, почему при передаче пресловутого массива фиксированного размера нельзя писать procedure ololo(a: array[0..9] of Int32), а надо сначала объявить этот массив типом, а потом использовать в сигнатуре?

Здесь всё просто - такой массив всё равно придётся объявлять дважды: один раз при описании функции, другой - при передаче через стек. И очень важно, чтобы эти описания АБСОЛЮТНО совпадали, иначе (если бы компилятор такое пропустил) в стек бы могло прийти что-то немного другого размера. Во всех других случаях массив надо передавать с модификатором const (аналог передачи в С через указатель), а там можно не заботиться о таких проблемах.

Зачем нужны мудацкие массивы с произвольным стартовым индексом? Чтобы запутать апи сторонних библиотек, в половине из которых - индексация с 0, а в половине - с 1?

Это - дело программиста, с чего начинать нумерацию. Иногда полезно начинать не с 0 и даже не с 1. Но редко, хотя вполне возможно (например, если с индексом массива ассоциирован определённый интервал целых значений).

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

Правила передачи данных немного отличаются. Воткнуть просто произвольное количество аргументов сложнее, но есть array of const.

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

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

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

Рекурсивные типы - достаточная редкость для паскаля, впрочем, для классов и указателей оно разрешено. Впрочем, порядок очевиден: класс надо предописать раньше (TMyClass=class;), а указатель - описать до определения в той же секции.

Объявления функций должны идти перед местом использования,

А как иначе? Как компилятор иначе догадается, что Вы имели в виду? Ведь надо добавить имя функции к списку разрешённых идентификаторов. Как вариант, всегда можно предописать функцию с директивой forward (ну или в модуле поставить в секции interface).

аналог функции main всегда в конце программы.

Ну так это же основная часть программы! Сначала научили делать то-то и то-то, а потом делаем. На мой взгляд, логика куда лучше, чем «делай вот так и вот так, а как это - я потом научу».

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

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

Масса диалектов, в которых чёрт ногу сломит и никакой стандартизации, что превращает освоение языка в весёлый и полный неожиданностей процесс.

На самом деле, ныне существующих диалектов раз-два и обчёлся. Есть Delphi, есть FPC в режиме delphi (можно считать одним диалектом), есть FPC в режиме objfpc. Для использования древнего кода есть ещё режим tp, но в 99 % случаев режим delphi или objfpc с ним справится. Есть PascalABC.NET, но это - особый случай (с представлениями автора, как должно быть, а не как уже давно делают, ну и .NET такой .NET). Остальные (GPC, P2C, VP и прочие) уже мертвы.

Как там с перегрузкой операторов? Или будете кричать, что она не нужна?

В режиме objfpc - отлично (operator /(a,b:string):string;) В delphi - уже можно, но через пень-колоду.

Полиморфизм? В т.ч. и времени компиляции?

Сейчас - сколько угодно. Перезагрузка (overload) процедуры/функции, тип variant, в конце концов, generic.

Дебильные названия стандартных типов. Как мне догадаться, что shortint и byte - знаковый и беззнаковый тип одной длины?

Ну, byte, word, dword - беззнаковые вполне очевидны по названию. Вот со знаковыми надо разбираться, они исторически сложились, к тому же, некоторые могут отличаться по длине. С другой стороны, в большинстве случаев легко работать, придерживаясь простого правила: беззнаковые нужны для системных целей (что-то куда-то запихать в память, считать из памяти), а знаковые - чтобы просто считать. Да, есть ещё очевидный знаковый int64.

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

Это достаточно очевидные вещи, являющиеся особенностями паскаля (и, тем не менее, все они реализуются, просто иначе). Аналогичные не идут даже за недостатки С (хотя «нарыть» их можно очень много).

FoodChemist
()
Ответ на: комментарий от anonymous

Со времен Turbo Pascal 5.5 много воды утекло, не нужно тут критиковать его.

1. Потому что строгая типизация. Тип параметра должен быть идентификатором, за некоторым исключением. Два array [0..9] of Int32 — два разных типа. Используйте типом параметра открытый массив array of Int32, он совместим с любыми массивами из Int32.

2. Вам не нужны, вы не используйте. Передайте открытым массивом, наконец, там с 0.

3. Ну не совсем нельзя, про array of const параметры посмотрите. Наконец, безтиповый параметр в помощь. Да, вызов выглядит более горомоздким, лишний раз подумаете, надо ли оно. Тошнит от языкового ввода/вывода, пользуйтесь библиотечными функциями, кто ж вам запретит, тем же printf, никаких ограничений, или просто не знаете как его из Паскаля позвать?

4. Известен размер указателя, поэтому типы-указатели могут быть декларированы до определения. Все остальные на момент использования должны быть определены.

5. Вы не в курсе про forward?

6. На K&R вы сейчас не напишете, к слову. А в остальном — 2 частично совместимые реализации (Delphi language и Free Pascal Compiler) одолеть несложно, они в сумме короче кое-какого стандарта.

7. Как-то так: http://www.freepascal.org/docs-html/ref/refch15.html

8. Хм, оказывается вы и TP 5.5 не видели, только <=4? Да, там не было.

9. Достаточно for element in container do ... Container — все, что поддерживает GetEnumerator.

10. Не надо догадываться, документация рулит.

То есть, приходится с сожалением констатировать, что пока вам в голову приходит нечто, обусловленное элементарной неосведомленностью.

Прямо «я три дня за вами гналась, чтобы сказать, как вы мне безразличны», не иначе :-)

bormant ★★★★★
()
Ответ на: комментарий от bormant

На K&R вы сейчас не напишете, к слову.

Можешь взять любой листинг из K&R и скомпилировать без всяких изменений последней версией gcc. Язык настолько чёткий без лишних сущностей что там особо нет вариантов, это у вас в паскале туева хуча режимов работы и ещё хз чего. Стандарт 1989 во основном добавил новый способ написания function declaration/definition, причём с сохранением совместимости со старым способом. Ну и ещё по мелочи type coersions, void*, правила работы с pointerами, struct assignment, короче можно взять древний код 70-х годов и скомпилировать современным компилятором добавив explicit cast в нескольких местах разве что.

mongo
()
Ответ на: комментарий от mongo

Язык настолько чёткий без лишних сущностей что там особо нет вариантов, это у вас в паскале туева хуча режимов работы и ещё хз чего.

Если взять за основу что-то вроде TP 3, то FPC тоже его откомпилирует безо всяких сложностей (ну, разве что переход от 16-разрядной системы к 64-разрядной может слегка смутить, но никто не запрещает сравнивать режим DOS16 - тогда хватит только {$mode tp}). А современный GCC (можно вообще взять С++, т.к. разница между TP и objfpc примерно такая же) может использовать разные модификации не в меньшем «ассортименте».

FoodChemist
()
Ответ на: комментарий от mongo

Можешь взять любой листинг из K&R и скомпилировать без всяких изменений последней версией gcc.

Преувеличивешь чувак. Современный gcc руганётся на функцию gets, теперь надо использовать gets_s. Из книжки Кернигана, в прошлом году, с одним примером точно была проблема, то-ли некорректно работала, то-ли компилятор её не принимал. Смутно помню, но было дело точно!

anonymous
()
Ответ на: комментарий от anonymous
~/test $ vim test.c
~/test $ cat test.c 
#include <stdio.h>

int main(int argc, char **argv) {
	char line[1024];
	printf("|%s|\n", gets(line));
	return 0;
}
~/test $ gcc test.c 
test.c: In function ‘main’:
test.c:5:2: warning: ‘gets’ is deprecated (declared at /usr/include/stdio.h:638) [-Wdeprecated-declarations]
  printf("|%s|\n", gets(line));
  ^
/tmp/cc7HB7QA.o: In function `main':
test.c:(.text+0x32): warning: the `gets' function is dangerous and should not be used.
~/test $ ls
a.out  test.c
~/test $ ./a.out 
lazarus sucks, C rocks
|lazarus sucks, C rocks|
~/test $

Код успешно компилируется и запускается. Компилятор всего лишь печатает warning, что хорошо так как позволит исправить опасный код что вполне возможно устранит возможное переполнение буфера. Ещё K&R писали во втором издании своей книги что перекомпиляция старого кода стандартным компилятором не потребует много усилий и может выявить незамеченные баги.

mongo
()
Ответ на: комментарий от mongo

Сори что встреваю, не удержался :)

Код успешно компилируется и запускается. Компилятор всего лишь печатает warning

Всего лишь deprecated в новом коде...
//Возьми спички. Да не, трением компилируется и запускается тож норм, подумаешь всего лишь печатает warning руки в мозолях.

znenyegvkby
()
Ответ на: комментарий от mongo

В новом коде используйте fgets

Вы и используете deprecated функцию в новом коде. В этом поинт. Вы изначально сказали

Можешь взять любой листинг из K&R и скомпилировать без всяких изменений последней версией gcc.

Вам и сказали что это не Ъ-way, ибо много чего уже давно deprecated. А вот если рассуждать как вы:

Код успешно компилируется и запускается. Компилятор всего лишь печатает warning

То сразу же становится понятно откуда берут путь «copy-paste погромисты».

znenyegvkby
()
Ответ на: комментарий от znenyegvkby

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

mongo
()
Ответ на: комментарий от mongo

Понятно. Извиняюсь. Я просто так фразу прочел «всего лишь warning». Звучит так беззаботно, как у древних пэхэпистов с их «всего лишь notice» :)

znenyegvkby
()

Почему не принято для Linux писать что-то на FreePascal?

Не знаю, дальше не читал, но transgui написаное на нем нравится и нужно.

hbars ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.