LINUX.ORG.RU

Пишете ли вы на языке Ada?

 , ,


0

5

Навеяно этим тредом от @hateyoufeel.

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

  1. Нет, предпочитаю другие языки 272 (52%)

    ********************************************************************************************************************************************************************************************************************************************************************************************************************************

  2. Нет, даже не знаю что это 91 (17%)

    ***********************************************************************************************************

  3. Нет, но писал/пишу на другом Pascal-like 82 (16%)

    ************************************************************************************************

  4. Нет, вообще не пишу код 58 (11%)

    ********************************************************************

  5. Да, свой проект just for fun 8 (2%)

    *********

  6. Да, участвовал в чужом проекте just for fun 5 (1%)

    *****

  7. Да, писал/пишу на коммерческой основе, основной проект 5 (1%)

    *****

  8. Да, писал/пишу на коммерческой основе факультативом 2 (0%)

    **

Всего голосов: 523

★★★★★

Проверено: hobbit ()
Последнее исправление: hobbit (всего исправлений: 1)

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

Всегда считал, что Эрланг это вещь в себе. Не ООП, не ФП, не что-то_иное_П, а близкая к идеальной синергия теоретической концепции и практической реализации в виде VM. Смолток и борщелисп тоже где-то тут, но они не смогли найти свой жирный бизнес, который бы их сильно захотел под специфичные задачи. А вот у Эрланга это получилось, поэтому он бессмертен.

Virtuos86 ★★★★★
()
Ответ на: комментарий от no-such-file

Потенциально выше, т.к. ты сразу задаёшь соотношения сущностей через map и compose2, а не конкретную последовательность вычислений как в императивном варианте.

Так именно поэтому и ниже. Когда есть конкретная последовательность вычислений с конкретными типами и значениями, компилятор это может использовать. Например, если может вывести, что в source_list значения определённого типа, для которого G(item) можно упростить, то это можно сделать.

А в функциональном у компилятора map берёт уже скомпонованную функцию и выковырять из неё отдельно G(item) заметно сложнее.

К тому же есть проблема для

target = filter(cond, map(compose2(F, G), source_list))

против

target = []
for item in source_list:
    trans1 = G(item)
    trans2 = F(trans1)
    if cond(trans2):
        target.append(trans2)

В первом случае компилятору надо быть очень умным, чтобы понять, что список, возвращаемый map не надо реально создавать, а надо условие от filter вставить внутрь map.

И ещё одна проблема: если что-то пошло не так и надо разобраться, то в императивной программе можно просто добавить

target = []
for item in source_list:
    trans1 = G(item)
    trans2 = F(trans1)
    log(item, trans1, trans2, cond(trans2))
    if cond(trans2):
        target.append(trans2)

Аналогично преобразовать функциональный код заметно сложнее.

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

Когда есть конкретная последовательность вычислений с конкретными типами и значениями, компилятор это может использовать

Использовать как? На конкретном железе эта конкретная последовательность может быть вообще не транслируема 1:1. Простой пример. Цикл задан от 1 до 10, а на железе он должен быть от 9 до 0. В ФП коде мы не задаём как конкретно производятся итерации, компилятор может сразу делать их как хочет. А в императивном коде компилятор должен соображать как поменять цикл, и вообще можно ли это делать (могут быть сайдэффекты).

Я уж не говорю про ленивые вычисления. Т.к. мы задаём только соотношения, то вообще говоря мы не просим компилятор вычислять весь map. В императивщине опять же цикл задан как есть от 1 до 10, компилятор должен быть очень умным чтобы понять что какие-то итерации можно выбросить (опять привет сайдэффекты).

А в функциональном у компилятора map берёт уже скомпонованную функцию и выковырять из неё отдельно G(item) заметно сложнее.

Наоборот же. В ФП компиляторе (настоящем, а не ЛИСП) компоновка это известная компилятору операция, а не просто f(g(x)). Поэтому он заранее знает как что выковыривать, и что вообще это x -> g -> f.

компилятору надо быть очень умным

Компилятору в этом случае нельзя быть совсем тупым. Потому что тут не будет ручных оптимизаций от программиста. Но умному компилятору легче с ФП кодом.

PS: вот такие штуки

for item in source_list

это вообще-то элемент ФП. По сути этот тот же map, вид сбоку.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от no-such-file

Простой пример. Цикл задан от 1 до 10, а на железе он должен быть от 9 до 0.

Так он и в функциональном будет что-то вроде map(... range(1, 10)). Тут разницы нет.

Я уж не говорю про ленивые вычисления.

А в этом случае компилятор должен быть ещё на порядок умнее. Потому что иначе в target пойдёт не список, а функция, возвращающая список (ленивость же). Более того, потом при чтении из этой функции-списка, например 10 элемента, вычислятся только первые 10 (и получение элемента будет жутко медленно, так как для каждого элемента надо будет сначала прочитать, что он не вычислен, потом сделать его вычисление). Почитай про оптимизацию скорости в Haskell. Там если надо что-то реально быстро, то лучше сразу упаковать в IO и самому указать порядок вычисления.

компилятор должен быть очень умным чтобы понять что какие-то итерации можно выбросить (опять привет сайдэффекты)

Учёт сайдэффектов даже gcc делает. И, кстати, даже преобразует

int sum = 0, x = 5;
for(int i = n1; i <= n2; i++) { sum += i; x++; } 

в t = n2 - n1 + 1; sum = t * (n1 + n2) / 2; x = 5 + t;

компоновка это известная компилятору операция, а не просто f(g(x))

То есть, если вместо встроенной компоновки написать compose2 как в примере, то у компилятора отвалится половина оптимизаций?

for item in source_list

Ну пусть будет for(auto item = source_list.begin(); item != source_list.end(); i++) { .... }. Текст от этого не поменяется, но явная императивность уже будет видна.

это вообще-то элемент ФП

Тут нет функции, поэтому не ФП.

По сути этот тот же map, вид сбоку.

Угу. А для последователя императивной парадигмы map это тот же императивный dolist вид сбоку.

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

monk ★★★★★
()
Ответ на: комментарий от no-such-file

Ada начиная с 2005 стандарта элементы ФП активно реализует.

В 2022 (а фактически лет 10 назад) вот такое появилось например (Iterated Component Association):

with Ada.Text_IO;

procedure Funcs is

   type Vector is array (Positive range <>) of Natural;

   --  Что-то вроде Map (Ada 2022)
   function Func1 (A : in Vector) return Vector is
     (for X of A => X + 1);

   --  Что-то вроде кортежей (Ada 95)
   type Tuple (Success : Boolean) is record
      case Success is
         when True => X, Y : Natural := raise Constraint_Error;
         when False => null;
      end case;
   end record;

   function Func2 (A : in Natural) return Tuple is
     (if A > 5
      then (Success => True, X => A + 5, Y => A + 6)
      else (Success => False));

begin
   Ada.Text_IO.Put_Line (Func1 ([1, 2, 3])'Image);
   Ada.Text_IO.Put_Line (Func2 (6).X'Image);
   Ada.Text_IO.Put_Line (Func2 (3).X'Image);  --  Ошибка времени исполнения
end Funcs;

А так вообще Ada многопарадигменный язык.

Ada83 был чисто императивный;

Ada95 появился ООП (теговые типы) + обобщённое программирование (настраиваемые модули Generics);

Ada05 в стандартной библиотеке появились контейнеры (вектора, списки, и т.д.);

Ada05/12/22/SPARK появились элементы ФП + логика Хоара (контракты).

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

Тут разницы нет

Разница в том, что range(1..10) не нужен в ФП и вообще индекс.

Тут нет функции, поэтому не ФП.

ЛОЛ, тело цикла это неявная функция. А например в руби даже почти что явная. Императивный цикл, это цикл по счётчику. Цикл по коллекции это неявный map с императивным синтаксисом. Просто потому что так удобнее.

Текст от этого не поменяется, но явная императивность уже будет видна

Текст от этого радикально поменялся. Потому что теперь есть i++ которая растёт на каждом шаге. Именно растёт на 1, а не убывает, и не рандомно берётся. map или for/in не накладывают таких ограничений.

А для последователя императивной парадигмы map это тот же императивный dolist вид сбоку.

Потому что dolist это и есть map с удобным сахарком. Это элемент ФП.

no-such-file ★★★★★
()

Интересно, какой результат ты ожидал за пределами форумов подрядчиков американской военки и прочей аэрокосмической хрени.

hateyoufeel ★★★★★
()
Ответ на: комментарий от no-such-file

Я потыкивал как раз после тех тредов. Вроде норм, юзать можно.

hateyoufeel ★★★★★
()

Пишу на VHDL.

akk ★★★★★
()
Ответ на: комментарий от no-such-file

Разница в том, что range(1..10) не нужен в ФП и вообще индекс.

Массивов в твоём ФП не бывает? Или Haskell не ФП язык?

s a = sum . map (a!) $ range (5, 10)

как без range перепишешь?

Потому что теперь есть i++ которая растёт на каждом шаге. Именно растёт на 1, а не убывает, и не рандомно берётся. map или for/in не накладывают таких ограничений.

Если map или for/in внутри кода с возможными побочными эффектами (Lisp, Python, mapM в Haskell), то накладывают.

Императивный цикл, это цикл по счётчику.

То есть dolist - функциональный, а dotimes императивный? Интересное деление. А цикл с условием?

monk ★★★★★
()
Последнее исправление: monk (всего исправлений: 1)
Ответ на: комментарий от ksicom

function Func1 (A : in Vector) return Vector is

А вот эта конструкция массив редактирует или копирует и возвращает новый?

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

Копирует и возвращает новый.

А Аде есть понятие режима параметров у функций (function) и процедур (procedure).

До 2012 стандарта у функций все параметры могли иметь только режим «in». Т. е. функции были по-определению без побочных эффектов (хотя если очень надо, переменные в области видимости менять можно).

В 2012 добавили (к сожалению) возможность использовать режим параметров у функций «in out» и даже «out», что несколько размыло разницу между процедурами и функциями.

Редактировать массив можно например так с помощью процедуры:

with Ada.Text_IO;

procedure Funcs is

   type Vector is array (Positive range <>) of Natural;

   procedure Proc1 (A : in out Vector)
   is
   begin
      for X of A loop
         X := X + 1;
      end loop;
      --  Тоже самое, но менее модно
      for i in A'Range loop
         A (i) := A (i) + 1;
      end loop;
   end Proc1;

   A : Vector := (1, 2, 3);
begin
   Proc1 (A);
   Ada.Text_IO.Put_Line (A'Image);
end Funcs;
ksicom
()
Ответ на: комментарий от splinter

Это для проектов, которые пишутся один раз, а читаются много раз.

Если надо, наоборот, писать и не читать, то есть Perl и С++.

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

Если бы всё так хорошо было в Аде, не понадобились бы комментарии.

Пример :-)

with Ada.Numerics.Generic_Elementary_Functions;

function Func1
  (Vector : in Vector_Type;
   Tasks  : in Positive) return Number
is
   package GEL is new Ada.Numerics.Generic_Elementary_Functions (Number);
   function Func2 (First, Last : in Positive) return Number;
   task type Body1 is
      entry Start (First, Last : in Positive);
      entry Stop (Result : out Number);
   end;

   task body Body1 is
      First, Last : Positive;
      Sum : Number;
   begin
      accept Start (First, Last : Positive) do
         Body1.First := First;
         Body1.Last  := Last;
      end Start;
      Sum := Func2 (First, Last);

      accept Stop (Result : out Number) do
         Result := Sum;
      end Stop;
   end Body1;

   function Func2 (First, Last : in Positive) return Number is
      Sum : Number := 0.0;
   begin
      for J in First .. Last loop
         Sum := Sum + Vector (J) ** 2;
      end loop;
      return Sum;
   end Func2;

   Sub_Length : constant Positive := Vector'Length / Tasks;

   myArray1 : array (1 .. Tasks - 1) of Body1;
   Index  : Positive := Vector'First;
   Next   : Positive;
   Sum    : Number;
   Subsum : Number;

begin
   for J in myArray1'Range loop
      Next := Index + Sub_Length;
      myArray1 (J).Start (First => Index, Last => Next - 1);
      Index := Next;
   end loop;
   Sum := Func2 (Index, Vector'Last);
   for J in myArray1'Range loop
      myArray1 (J).Stop (Subsum);
      Sum := Sum + Subsum;
   end loop;
   return GEL.Sqrt (Sum);
end Func1;


Я убрал комментарии и явные наименования, можно ли сходу определить что делает данная прога? Мне вот сразу в такую кашу скучно смотреть, у LOR даже подсветки кода для ады нет :-)

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

Строго говоря определить нельзя, т.к. навскидку нет определения типов Vector_Type и Number.

А так, если качественно, то программа вычисляет длину вектора. При этом используется распараллеливание вычисления суммы квадратов с помощью задач (tasks) и старого доброго механизма рандеву (entry).

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

Код можно несколько упростить, если использовать защищённый объект с барьерами вместо Stop. Но это вкусовщина.

И использование анонимных массивов (myArray1) не приветствуется.

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

function Func1

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

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Тут однострочники. Тело Func1 само за себя говорит.

И, замечу, на J и APL тоже пишут, хотя там «иероглифы».

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

Мне вот сразу в такую кашу скучно смотреть, у LOR даже подсветки кода для ады нет :-)

Представляешь, люди даже художественную литературу читают. А там сотни страниц однообразного текста без подсветки.

P.S. Аналог на C++/Java с thread/join читался бы сложнее.

monk ★★★★★
()

паскаль вечен

bernd ★★★★★
()

Ну… формально участвовал в https://github.com/tsoding/eepers на уровне «попробовать собрать это под андроид и увидеть что gnat-llvm, мягко говоря, не готов».

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

Ты уж поверь мне на слово, больше в плане широты айтишки чем я в этом треде хорошо если человека 2 видело. Проще сказать с какими ЯП я не сталкивался ни разу, чем перечислить всё с чем мне пришлось встретиться. У тебя должны быть очень специфичные интересы, если ты реально много ЯП видел за свою жизнь и тут далеко не классические разрабы на (подставь тут свой ЯП) в лидерах. Вот если ты скажем специализировался на багхантинге за деньги или занимался исследованиями безопасности кода, то у тебя, возможно, будет больший охват ЯП чем у меня. А так мало на самом деле тех, кому надо за рамки своего стека вылезать в чужие кодовые базы, кроме разного рода профессиональных говночистов и говноподтирал из мира IT.

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

Представляешь, люди даже художественную литературу читают. А там сотни страниц однообразного текста без подсветки.

Вот, кстати, было бы интересно как-то прикрутить подстветку к естественным языкам. Она, кажется, могла бы помочь читаемости и осбенно поиску нужного на странице. Не знаю, правда, как именно. Можно выделять одним цветом объект и его признаки, другим действие, а третьим субъект, например. Не уверен, впрочем, что это поможет. А вот, например, выделять вопросы и восклицания так, чтобы было понятно, что это вопрос или восклицание до того, как дочитал до ? или ! в конце — это может быть полезно — не зря в некоторых языках в начале таких предложений тоже ставится знак ¿ или ¡. А может можно было бы как-то ещё использовать подсветку, более эффективно.

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

Ага. А ещё стрелочками подсвечивать какое слово к чему относится. И имена-идентификаторы подсвечивать. И по кнопке переходить к первому упоминанию имени и обратно.

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

Потому что искать боевые проекты на аде через гитхаб это глупо, ведь все они находятся на своих локальных репозиториях, и чаще всего закрытые, как и фортрановские, или кобол, да и большая часть С проектов.

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

язык Ada устарел, поэтому его использованием лишено смысла

Embedded real-time (например, систему автоматического регулирования для прокатного стана) на каком языке лично ты предпочтёшь писать?

VladimirP ★★★★
()

Был у меня в начале 90-х годов случай в общаге универа. В комнате у меня на полке стояла книга «Язык Ада». Классичесская, в твердом переплете, толстая такая. Заходит в гости друг, вообще из другого учебного заведения и программированием не занимающийся вообще. Ну туда, сюда и вдруг у него загораются глаза, он прямо кричит: «Ничего себе у тебя книга, язык Ада!!! Там прямо про то как демоны в аду говорят и про их язык!». А тогда были популярны всякие мистические бредни. Поржали нормально.

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