Решил похожий код визуализировать на различных языках.
Вот что получилось.
Dlang:
import std.stdio;
void main() {
auto i = 0;
foreach( e ; 1 .. 11) {
i++;
if(e % 2 == 0)
writeln(i, "=", e);
}
}
В D2 есть foreach с индексом, но при использовании генератора код не компилируется,
кроме того последний элемент отбрасывается. Вывод — основное преимущество Ди — скорость загрузки и выполнения.
FSharp:
[1..10]
|> List.mapi ( fun i v -> (i,v))
|> List.filter (fun (_,v) -> v % 2 = 0)
|> List.iter (fun (i,v) -> printfn "%d = %d" i v)
Неплохо, с учетом использования только ядреных функций, минус — многословный синтаксис лямбд, медленная загрузка кода перед выполнением.
плюс — очевидная семантика, информативные сообщения компилятора.
CSharp:
using System;
using System.Linq;
using System.Collections.Generic;
class Program {
static void Main(string[] args) {
foreach (var e in Enumerable.Range(1, 10).Select((e, i) =>
new { Index = i, Value = e }))
if (e.Value % 2 == 0)
Console.WriteLine($"{e.Index} = {e.Value}");
}
}
Минус — необходимость использования дополнительных библиотек, плюс — очевидная семантика.
Nemerle:
#pragma indent
using Nemerle
using System.Console
foreach(c when c % 2 == 0 in $[1 .. 10] with i)
WriteLine($"a[$i] = $c")
самый компактный и очевидный синтаксис,
делает то, что видим и предполагаем. Понимает отступы вместо скобок. Считаю код на отступах более понятным.
Common Lisp:
(let ((i 0))
(loop for e from 1 to 10
do
(incf i)
(cond
((= (mod e 2) 0) (format t "~A = ~A~%" i e)))))
Из плюсов — гомоиконность языка, семантика очень простая — выражение список, первый элемент — форма, остальные элементы аргументы формы).
Из минусов — экзотический, требует владения специальным редактором. по умолчанию работает только в среде интерператора, значительно отличающаяся
модификация clojure — позволяет компилить код в java-байт код.
А вам, семантика кого языка кажется более естественной для человеческого мышления?
Нужен ли языку расширяемый синтаксис или достаточно расширения на основе библиотек?