Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
(function($){$(document).ready(function(){
});}());
(resp/redirect "/success") (defpage [:post "/user/add"] {:as user}
(if (valid? user)
(layout
[:p "User added!"])
(render "/user/add" user)))
(defn add [x y] (+ x y))
(defn make-adder [x] (fn [y] (+ x y)))
(def inc (make-adder 1))
Лисп часто рекламируют как язык, имеющий преимущества перед остальными из-за того, что он обладает некоторыми уникальными, хорошо интегрированными и полезными фичами.
class A
{
}
class B : A
{
}
class Program
{
public static void Foo(A a)
{
Console.WriteLine("A");
}
public static void Foo(B a)
{
Console.WriteLine("B");
}
static void Main(string[] args)
{
var random = new Random();
for (int i = 0; i < 100; i++)
{
dynamic a = random.Next(10) < 5 ? new A() : new B();
Foo(a);
}
}
}
Множественное наследование?
Фичи спорные потому что их не осилили в C#?
Без dynamic никак?
А если классы не потомки друг друга?
Макросы в CL это совсем не то же самое что макросы C или шаблоны C++.
Исключения же дают только один вариант — прекращение выполенения.
В чем их идеологическое, а синтаксическое отличие?Идеологическое отличие в том, что макрос в лиспе может использовать при компиляции практически любые средства языка и таким образом может порождать произвольный код. Для макросов C и шаблонов C++ это неверно.
Например мы поделили на ноль — продолжать наши мат. вычисления дальше смысла нет.А если речь идёт не о простейшей ошибке, типа деления на ноль а, например, об ошибке при чтении сложной структуры из файла? Тогда может быть несколько вариантов — пропустить отдельную запись, использовать значение по умолчанию, прекратить чтение. Рестарты в таком случае позволяют легко отделить выбор реакции на ошибку от остального кода и не требуют обязательно прекратить работу, как обычные исключения.
Я попробовал в вашем коде убрать наследование и он не скомпилировался (mono c# 4.0).
class A
{
}
class B
{
}
class Program
{
public static void Foo(A a)
{
Console.WriteLine("A");
}
public static void Foo(B a)
{
Console.WriteLine("B");
}
static void Main(string[] args)
{
var random = new Random();
for (int i = 0; i < 100; i++)
{
var a = random.Next(10) < 5 ? (dynamic)new A() : new B();
Foo(a);
}
}
}
Динамическая диспетчеризация(то, что вы называете мультиметодами)Кстати, это не совсем верно. Мультиметоды — это множественная динамическая диспетчеризация.
dynamic a = random.Next(10) < 5? new A(): new B();Интересно, не знал о таком. А диспетчеризацию сразу по нескольким параметрам можно сделать?
В C# от него отказались в силу идеологии(оно вносит неочевидность в объектную модель). В питоне оно есть, в С++ тоже. В любом случае явно не экслюзивное преимущество лиспа.Никто же не говорил, что множественное наследование — это уникальная фишка лиспа. Дело в том, что в лиспе одновременно сочетаются многие интересные возможности. Скажем, множественное наследование в Питоне есть, а вот мультиметодов и макросов нет. А в C++ нет многого другого.
Это является большой головной болью в СВот только не надо в одну кучу совать макросы C и лиспа. Это совершенно разные вещи.
Понять откуда взялось такое поведение и как один кусок превращается в другой в большом проекте с макросами зачастую очень сложно.Эта проблема порождается не макросами самими по себе, а плохим дизайном в принципе. Скажем, точно так же можно реализовать неудачные функции или классы и при их использовании непонятно будет, откуда взялось такое поведение. Что же, надо поэтому от функций и классов отказаться?
Рестарт же спорен потому, что как правило возникновение исключения означает, что есть какая-то проблема в данной точке вычленения программы, причем она не предусмотрена разработчиком.Рестарты не надо рассматривать исключительно как механизм обработки ошибок. Это обобщённый способ передачи сигналов, и не стоит о нём судить только на основе вашего опыта работы с исключениями в других языках. Есть примеры удачного применения рестартов, можете посмотреть в том же Practical Common Lisp.
Дело в том, что в лиспе одновременно сочетаются многие интересные возможности
многое, из того, что перечислено уже есть в том же C#Во-первых, не всё, а во-вторых важно не количество фич, а качество. Вот макросы на мой взгяд в корне меняют подход к программированию. К примеру, вы знали, что основу Common Lisp составляют всего 25 формы, а всё остальное реализовано макросами?
А если не хватает, можно взять Nemerle… или лисп. Об этом и речь.
Преимущества Common Lisp