Здравствуйте, kurchatov, Вы писали:
K>Каковы будут позиции языков к 2025 году? Я думаю, что:
K>С++ рулит (стандарты 17, 19, 20, 20.5, ... 25) — но концепты все еще не работают K>Java рулит тоже (куда она денется) K>Rust похоронен в 2017 (оказалось, что с++17 быстрее и удобнее) K>Haskell все еще используется (только в Standard Chartered) K>Perl все еще жив K>про .net не знаю (я и сейчас не знаю ничего)
Конечно С++ рулит и Java тоже, и dotNET никуда не денеться, с JS и Php. Первая пятерка по популярности такой же и должна остаться.
Вы про область применения лучше спросите. В веб, мобильные платформы все резко переместилось за последние годы. А в будущем это будет виртуальная реальность, embeded, ИИ.
Это все писать можно и С++ и Java впрочем. Языки я считаю устоялись. Ну можем прогнозировать сдвиг Objective-C на Swift. Бекенд на Java/.NET в сторону Node.js. Что еще существенного появилось? Dart еще может где-то заиграть с подачи Гугла. Есть вероятность популярности языка только к какой то прорывной платформе.
Здравствуйте, Философ, Вы писали:
Ф>В C ты можешь поставить бряк на printf() и посмотреть что в действительности исполняется и в каком файле, а тут бряк на WriteLn() тебе ничего не даст — тебе придётся открыть модуль MyFuckignUnit, посмотреть что импортирует он и если в нём и в остальных модулях секции инициализации.
Почему это бряк на Writeln ничего не даст?
Ф>До твоего дэлфячего аналога "мэйна" дело может даже не дойти. Разница вот в этом.
Здравствуйте, Философ, Вы писали:
Ф>1) Ф>Имеется ввиду сложность предсказания потока исполнения: слишком сложно сказать в каком порядке будут исполнены секции initialization/finalization а от этого может многое зависеть, т.к. там иногда переопределяются некоторые глобальные вещи, типа функций управления памятью. В делфе процветает чёрная магия.
Переопределить можно много чего, но это не значит, что это общепринятая практика.
Это в С++ черная магия цветет и пахнет, там для нее простора на порядок больше.
Ф>Даже если ты точно сможешь сказать, что секции initialization будут выполнены в том порядке, в котором указаны модули в файле проекта, то о необходимости блюсти этот порядок посторонний разработчик может и не знать. Ловить потом баги порождённые этим очень сложно долго.
А в каком порядке у нас в С++ инициализируются статические переменные? В строго определенном, да?
Здравствуйте, AlexRK, Вы писали: ARK>Почему это бряк на Writeln ничего не даст? Ф>>До твоего дэлфячего аналога "мэйна" дело может даже не дойти. Разница вот в этом. ARK>Чего?
Скомпилируй и посмотри
файл "FuckingDelphiProject.dpr"
program FuckingDelphiProject;
{$APPTYPE CONSOLE}
{$R *.res}uses
System.SysUtils,
MyFuckingUnit in'MyFuckingUnit.pas';
begin
WriteLn('Hello from delphi hell');
end.
файл "MyFuckingUnit.pas"
unit MyFuckingUnit;
interface
implementation
var p : ^Integer;
initialization
WriteLn(p^);
end.
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, AlexRK, Вы писали: ARK>Здравствуйте, Философ, Вы писали: Ф>>Да, говно, но не поэтому (не из-за var блока и не из-за скобочек). Ф>>Из-за модульной парадигмы (namespace'ов приделанных сбоку, unit vars, initialization/finaliztion), из-за наследования конструкторов, и тучи других причин масштабом поменьше. ARK>namespace'ы не нужны, а вот глобальные переменные это да, плохо. Ф>>из-за наследования конструкторов ARK>А что в этом плохого?
Потому, что профит от метаклассов полностью перекрывается тем, что это порождает трудноуловимые ошибки.
Попробуй, найти здесь ошибку вот здесь:
В чём ошибка я уже сказал
unit MyFuckingUnit;
interface
implementation
type TA = class (TObject)
protected
FPrivateIntVar :Integer;
public
constructor Create(p_int :Integer);
procedure WriteHimself();
end;
type TB = class (TA)
public
constructor Creatе(p_int :Integer);
end;
type TC = class (TB)
public
constructor Creatе(p_int :Integer);
end;
var obj : TA;
{ TA }constructor TA.Create(p_int :Integer);
begin
FPrivateIntVar := -1;
end;
procedure TA.WriteHimself;
begin
WriteLn(FPrivateIntVar);
end;
{ TB }constructor TB.Creatе(p_int: Integer);
begin
inherited Create(p_int);
FPrivateIntVar := p_int;
end;
{ TC }constructor TC.Creatе(p_int: Integer);
begin
inherited Creatе(p_int);
FPrivateIntVar := p_int;
end;
initialization
obj := TC.Create(1);
obj.WriteHimself(); //Ожидаем 1 увидеть, ибо в конструкторе "FPrivateIntVar := p_int", правильно? Запусти, и посмотри.end.
Это крохотный пример из одного файла, и уже всё непросто. Что будет, если у тебя >1000 файлов в проекте?
Надо на собеседованиях для делфистов такие вопросы задавать. Давать вот этот код, и спрашивать: в каком случае на экране будет (-1) и почему?
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Locksmithpc, Вы писали:
L>Здравствуйте, Философ, Вы писали:
Ф>>Этот код и есть демонстрация недостатков initialization/finaliztion. Вот здесь
Здравствуйте, Философ, Вы писали:
Ф>>>из-за наследования конструкторов ARK>>А что в этом плохого?
Ф>Потому, что профит от метаклассов полностью перекрывается тем, что это порождает трудноуловимые ошибки. Ф>Попробуй, найти здесь ошибку вот здесь:
1) этот код не компилируется (вперемешку английские и русские буквы);
2) здесь нет наследования конструкторов;
3) онлайн-компилятора Delphi не нашел, воспользовался совместимым с ним FPC здесь: http://ideone.com/
Исправленный код:
{$mode objfpc}program MyFuckingUnit;
type TA = class (TObject)
protected
FPrivateIntVar :Integer;
public
constructor Create(p_int :Integer);
procedure WriteHimself();
end;
type TB = class (TA)
public
constructor Create(p_int :Integer);
end;
type TC = class (TB)
public
constructor Create(p_int :Integer);
end;
var obj : TA;
{ TA }constructor TA.Create(p_int :Integer);
begin
FPrivateIntVar := -1;
end;
procedure TA.WriteHimself;
begin
WriteLn(FPrivateIntVar);
end;
{ TB }constructor TB.Create(p_int :Integer);
begin
inherited Create(p_int);
FPrivateIntVar := p_int;
end;
{ TC }constructor TC.Create(p_int :Integer);
begin
inherited Create(p_int);
FPrivateIntVar := p_int;
end;
begin
obj := TC.Create(1);
obj.WriteHimself(); //Ожидаем 1 увидеть, ибо в конструкторе "FPrivateIntVar := p_int", правильно? Запусти, и посмотри.end.
Здравствуйте, Философ, Вы писали:
ARK>>Почему это бряк на Writeln ничего не даст? Ф>>>До твоего дэлфячего аналога "мэйна" дело может даже не дойти. Разница вот в этом. ARK>>Чего?
Ф>[cut=Скомпилируй и посмотри]
Это просто ошибка. В чем проблема-то? Что падает до "begin"?
В С++ возможно все то же самое, см. "Static Initialization Order Fiasco".
The static initialization order fiasco is a very subtle and commonly misunderstood aspect of C++. Unfortunately it’s very hard to detect — the errors often occur before main() begins.
Ога?
Может хватит уже выискивать "недостатки", которые есть чуть менее, чем везде?
Здравствуйте, AlexRK, Вы писали:
ARK>Здравствуйте, Философ, Вы писали:
Ф>>1) Ф>>Имеется ввиду сложность предсказания потока исполнения: слишком сложно сказать в каком порядке будут исполнены секции initialization/finalization а от этого может многое зависеть, т.к. там иногда переопределяются некоторые глобальные вещи, типа функций управления памятью. В делфе процветает чёрная магия.
ARK>Переопределить можно много чего, но это не значит, что это общепринятая практика.
Это очень похоже на общепринятую практику, потому что, например, FastMM используется повсеместно.
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, AlexRK, Вы писали:
ARK>Здравствуйте, Философ, Вы писали:
Ф>>>>из-за наследования конструкторов ARK>>>А что в этом плохого?
Ф>>Потому, что профит от метаклассов полностью перекрывается тем, что это порождает трудноуловимые ошибки. Ф>>Попробуй, найти здесь ошибку вот здесь:
ARK>1) этот код не компилируется (вперемешку английские и русские буквы); ARK>2) здесь нет наследования конструкторов; ARK>3) онлайн-компилятора Delphi не нашел, воспользовался совместимым с ним FPC здесь: http://ideone.com/
Я специально поставил русскую букву, чтобы было неочевидно. Делфя это компилирует, разговор здесь именно про неё.
begin
obj := TC.Create(1); //В этой строке вызовется TA.Create() на то и был рассчётэто и есть косяк наследования контрукторов
obj.WriteHimself(); //Ожидаем 1 увидеть, ибо в конструкторе "FPrivateIntVar := p_int", правильно? Запусти, и посмотри.end.
ARK>Никаких -1. Вы сами свой пример проверяли?
Естественно проверял.
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Философ, Вы писали:
Ф>Я специально поставил русскую букву, чтобы было неочевидно. Делфя это компилирует, разговор здесь именно про неё.
Ф>
Ф>begin
Ф> obj := TC.Create(1); //В этой строке вызовется TA.Create() на то и был рассчётэто и есть косяк наследования контрукторов
Ф> obj.WriteHimself(); //Ожидаем 1 увидеть, ибо в конструкторе "FPrivateIntVar := p_int", правильно? Запусти, и посмотри.
Ф>end.
Ф>
Ну вообще-то это не наследование конструкторов, а просто вызов ошибочного метода.
Оставив в стороне надуманность данного примера (почему-то вас не насторожило в intellisence наличие двух одинаковых методов Create с одинаковой сигнатурой), замечу, что в любом языке с наследованием все то же самое.
class A
{
public void Method()
{
Console.WriteLine(1);
}
}
class B : A
{
public void Mеthod()
{
Console.WriteLine(-1);
}
}
...
(new B).Method(); // напечатало 1, о ужос
Здравствуйте, AlexRK, Вы писали:
ARK>Здравствуйте, Философ, Вы писали:
Ф>>Я специально поставил русскую букву, чтобы было неочевидно. Делфя это компилирует, разговор здесь именно про неё.
Ф>>
Ф>>begin
Ф>> obj := TC.Create(1); //В этой строке вызовется TA.Create() на то и был рассчётэто и есть косяк наследования контрукторов
Ф>> obj.WriteHimself(); //Ожидаем 1 увидеть, ибо в конструкторе "FPrivateIntVar := p_int", правильно? Запусти, и посмотри.
Ф>>end.
Ф>>
ARK>Ну вообще-то это не наследование конструкторов, а просто вызов ошибочного метода. ARK>Оставив в стороне надуманность данного примера (почему-то вас не насторожило в intellisence наличие двух одинаковых методов Create с одинаковой сигнатурой), замечу, что в любом языке с наследованием все то же самое.
Create() здесь не просто метод, а именно конструктор. То, что оно здесь с одинаковой сигнатурой — придирка ни про что. Если бы они были с разной сигнатурой, тебя бы не спасло ни разу, тем более что скорее всего не ты бы этот код писал, а кто-то до тебя. Такие ошибки вылазят не в конструкторе, а позже, когда идёт попытка использовать недоинициализированный объект. Но, самая большая трабла которая может приключится с таким подходом будет в том, что ты можешь не знать, о том какой именно класс ты инстанцируешь: у тебя может быть экземпляр метакласса базового типа, через который ты зовёшь конструктор. Чтобы вот так в шарпе попасть как в делфе, нужно Activator использовать, но тут уже ССЗБ.
По твоему примеру: компилятор шарпа на переопределение метода ругается. А чтоб он не ругался нужно new добавить: class B : A{ new public void Method()...
Надеюсь, в твоих проектах не миллион варнингов?
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Философ, Вы писали:
Ф>Create() здесь не просто метод, а именно конструктор. То, что оно здесь с одинаковой сигнатурой — придирка ни про что. Если бы они были с разной сигнатурой, тебя бы не спасло ни разу, тем более что скорее всего не ты бы этот код писал, а кто-то до тебя.
Какая разница, конструктор, не конструктор. В моем примере точно так же программа работает некорректно. Язык тут ни при чем.
И на подобные ошибки дельфи не провоцирует. Я, вместе с несколькими другими разработчиками, участвовал в создании средних размеров системы на ней, около 200000 строк, и нигде там такого идиотизма не было.
Ф>Такие ошибки вылазят не в конструкторе, а позже, когда идёт попытка использовать недоинициализированный объект.
Я думаю, излишне в очередной раз напоминать, что в С++ возможны просто горы подобных ошибок?
Ф>Но, самая большая трабла которая может приключится с таким подходом будет в том, что ты можешь не знать, о том какой именно класс ты инстанцируешь: у тебя может быть экземпляр метакласса базового типа, через который ты зовёшь конструктор.
Это не трабла, а дельфийская фича. Встроенный factory method pattern называется.
Знать, какой конкретно класс я инстанцирую, не нужно (мало того, с точки зрения создания грамотного кода знать это вредно).
Ф>По твоему примеру: компилятор шарпа на переопределение метода ругается.
В моем примере точно так же одна буква русская, ничего там не ругается. Полная идентичность.
Здравствуйте, s_aa, Вы писали:
_>Году так в 1995 мне один мужик втирал, что теперь когда в электронной таблице можно обсчитывать все что угодно, программисты уже не нужны.
Здравствуйте, Artem Korneev, Вы писали:
J>>а что не так с перлом? отличный инструмент для своих задач AK>Он трудночитаемый. Есть шутка, что Perl — это "write-only язык". Преувеличение, конечно, но некоторая почва под этим есть.
Это все равно, что винить ручку в плохом почерке врача. А все претензии к Perl фактически сводятся к набору стереотипов, истоков которых никто уже и не вспомнит.
Здравствуйте, Ops, Вы писали:
Ops>>>А он еще жив? На нем что-нибудь новое пишут? В каких областях? P>>Там же где и раньше. Mail.ru и Booking.com написаны на перле. Ops>Специально выделил. Поддержка старых проектов — это само собой, а вот что с новыми, они вообще есть?