LINUX.ORG.RU

Не учите Common Lisp!

 ,


1

7

Хочу предостеречь форумчан от изучения Common Lisp. Возьмите самую лучшую имплементацию — SBCL и скомпилируйте следуюущие лямбды:

;; Взятие элемента по индексу x из массива x
(lambda (x) (aref x x))
;; Взятие элемента по индексу y из массива x и прибавление к x
(lambda (x y) (+ x (aref x y)))
;; Один из путей выполнения: прибавление X к NIL
(lambda (x y) (+ x (funcall (lambda (x) (if x 0 x)) y)))

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

Минус коммон лиспа как языка — слишком разрешательский стандарт. Почти сплошь и рядом там фразы вроде «Эффект, производимый объявлением inline, определяется реализацией» или «Реализация вольна игнорировать то-то и вместо этого делать то-то». Из-за этого разработчики того же SBCL будут игнорировать твои баг репорты, где из-за неправильного поведения компилятора (с точки других опубликованных алгоритмов) твой код будет работать раза в 2 или 3 медленнее, чем должен бы.

Написали бы в стандарте «реализация ДОЛЖНА поступать так-то и так-то», и можно было бы тыкать разрабов носом в это место и требовать корректного поведения. А раз написали «реализация может делать, что ей захочется», то и прижучить их нельзя. В итоге все занимаются чем хотят, кроме починки багов.

Короче, учите языки с хорошей теоретической базой и статической типизацией. Байкам @lovesan не верьте ни одной.



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

Ты, старый тролль, конечно, но ты все-равно нихера не понимаешь. PHP хорош такой какой есть, уже лучше многого другого.

Чё ж ты пишешь на C# тогда?

dura4ok11
() автор топика
Ответ на: комментарий от Nervous

велика ли разница, простой это ООП или с перламутровыми пуговицами?

Зелен виноград, да. Я напоминаю, что исследовался вопрос об эквивалентности js и CL. На двух, первых прешидших в голову примерах выяснилась ошибочность этого утверждения. На этом у меня всё.

Я говорю — мне ни разу не пригодились. И таких людей, видимо, немало

Мне тоже. Вот, нас уже двое. А людей, которым ни разу не пригодилось ФП, неизменные структуры данных или STM ещё больше.

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

примитивная проверка типа это уже такое простенькое доказательство

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

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

Вот, нас уже двое. А людей, которым ни разу не пригодилось ФП, неизменные структуры данных или STM ещё больше.

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

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

да, а вот тех, кто не пользуется плодами эт самого программирования (прямо или косвенно) - куда как меньше.

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

Ответ неверный. Диапазон допустимых значений не совпадает. Ещё предложения?

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

Тайная мечта всех emacs’еров — перевести emacs на нормальный лисп, хоть cl, хоть схему. Сколько emacs существует, столько и пытаемся. Когда-нибудь обязательно получится.

снова зашевелились, делайте ваши ставки господа)

https://lwn.net/Articles/1001645/

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

Тайная мечта всех emacs’еров — перевести emacs на нормальный лисп, хоть cl, хоть схему. Сколько emacs существует, столько и пытаемся. Когда-нибудь обязательно получится.

снова зашевелились, делайте ваши ставки господа)

https://lwn.net/Articles/1001645/

А там наоборот, в Guile запилили поддержку Emacs Lisp и перетягивают редактор на него. То есть, лисп останется тем же, реализация будет чутка быстрее.

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

fuck emacs!

Бесспорно. Убогий никому не нужный аккордеон.

use Zed!

Ещё чего. Настоящие программисты редактируют через sed.

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

Ни у кого нет силы воли переписать свой .emacs отказаться от всей горы emacs’овых режимов. Собственно, без обратной совсместимости, это уже не будет emacs, а просто ещё один, по своему клёвый текстовый редактор.

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

Я вообще не понимаю, зачем нужен лисп, если есть JavaScript. Семантика ровно такая же.

Там уже появилась CLOS или перезапуски?

Нет, про такое не слышал. Объектная система в JS прототипная, перезапусков в том виде, в котором они есть в лиспе - нет

Более эталонного случая Blub Paradox я ещё не видел.

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

случая Blub Paradox

бульб? это белорусский парадокс какой-то? бульбаши? причём тут кортофан вообще, тут про лисп речь

anonymous
()

На С++

auto foo(auto x) { return x[x]; }
auto bar(auto x, auto y) { return x + x[y]; }
auto baz(auto x, auto y) { return x + [](auto x){return x?0:x;}(y); }

тоже компилируются.

Короче, учите языки с хорошей теоретической базой и статической типизацией.

Typed Racket или Haskell?

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

Лисперы не осилили статическую типизацию.

90% функций, которые легко и непринуждённо пишутся на лиспе (начиная с mapcar и apply), статически типизировать не получается. По крайней мере на C++ и Haskell.

Если такие функции не нужны, лучше писать на статически типизированном. Если нужны, приходится выбирать из динамических.

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

Пардон, прочитал ответ без контекста.

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

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

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

Шаблоны - это отдельный недомакро язык без типизации, «типизация» появилась с концертами.

Написать-то можно, но использовать невозможно, почти. В с++ можно перегрузить оператор [], что он сожрёт не только такие извращеня.

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

А зачем нужен второй хаскель, но со скобочками?

Например, ради макросов. Есть Hackett — это именно Хаскель со скобочками. И, благодаря этому, с полностью работающими гигиеническими макросами.

И статическая типизация не ограничивается Хаскелем с его ограничением на один тип в списке и, фактически, на один аргумент у функции. Typed Racket позволяет описывать типы, которые невозможны в Хаскеле.

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

И статическая типизация не ограничивается Хаскелем с его ограничением на один тип в списке

Там нет такого ограничения.

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

Там нет такого ограничения.

Хорошо, как получить '(1, 2.5, "ok") в Хаскеле?

То, что в Typed Racket имеет тип (List Integer Float String).

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

словил эксепшн выше по стеку и в обработчике можешь вернуть выполнение туда, откуда он вылетел

О, у Александра Лаэртского про это песня есть.

Про муравья? Угодал? Хорошая пейсня.

anonymous
()

слишком разрешательский стандарт

Это вопрос размера.

Если скрипт умещается на виду весь. То проще типы и прочую лажу держать в памяти. Чем записывать где-то.

Если больше. То нужно эту работу сбагривать на компилятор.

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

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

За второй наверно. На втором я писал немного, а на первом — ничего.

А по поводу C++ мне пофиг. Тоже не пример для подражания

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

https://hackage.haskell.org/package/HList ?

Если честно, [Dynamic] для меня выглядит меньшим извращением.

C HList две проблемы.

  1. Это не список (Data.List), а совсем другой тип. То есть всё, что работает со списками, с ним не работает.

  2. В простую функцию крайне неудобно запихивать.

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

Хорошо, как получить ’(1, 2.5, «ok») в Хаскеле?

Про HList написали выше, но HList – это скорее кортеж (tuple) переменного, но статически известного размера. То есть, ровно твоё (List Integer Float String).

Вариант два: тупо сделать новый тип.

data T = TInt Int
       | TFloat Float
       | TString String

l = [ TInt 1, TFloat 2.0, TString "ok" ]

Вариант три, совмещающий плюсы первых двух: использовать polymorphic variant (оно же open union). Например, отсюда.

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

или

ghci> data MyList = forall a. Show a => Cons a MyList | Nil
ghci> deriving instance Show MyList
ghci> Cons 5 $ Cons "ABC" $ Cons 34.45 Nil
Cons 5 (Cons "ABC" (Cons 34.45 Nil))

Указал контекст a и хотово

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

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

Список аргументов функции тоже должен быть гомогенный? Или apply не нужен?

Или предложить хотя бы выбор

В Typed Racket есть и гомогенные. Вот, например тип для mapcar:

(All (c a b ...)
       (-> (-> a b ... b c) (Listof a) (Listof b) ... b (Listof c)))

То есть, первый аргумент = функция с первым аргументом типа a, остальными аргументами, соответствующими списку типов b и результатом типа c.

Второй аргумент список элементов типа a.

Остальные аргументы - списки элементов с типами из списка типов b.

Результат = список элементов типа c.

Несмотря на то, что все типы гомогенные, написать аналогичный тип на Haskell у меня не получилось.

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

То есть всё, что работает со списками, с ним не работает.

Оно обычно работает не со списками, а с Functor/Foldable/Traversable итд

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

Указал контекст a и хотово

А читать его как?

ghci> let car Nil = Nothing
ghci|     car (Cons x y) = Just x
ghci|

<interactive>:27:27: error: [GHC-25897]
    • Couldn't match expected type ‘a’ with actual type ‘a1’
      ‘a1’ is a rigid type variable bound by
        a pattern with constructor:
          Cons :: forall a. Show a => a -> MyList -> MyList,
        in an equation for ‘car’
        at <interactive>:27:10-17
      ‘a’ is a rigid type variable bound by
        the inferred type of car :: MyList -> Maybe a
        at <interactive>:(26,5)-(27,27)
    • In the first argument of ‘Just’, namely ‘x’
      In the expression: Just x
      In an equation for ‘car’: car (Cons x y) = Just x
    • Relevant bindings include
        x :: a1 (bound at <interactive>:27:15)
        car :: MyList -> Maybe a (bound at <interactive>:26:5)
monk ★★★★★
()
Ответ на: комментарий от monk

А какие проблемы у тебя? В том, что apply — функция от произвольного числа аргументов? Да, тогда будут проблемы, наверно

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

А какие проблемы у тебя? В том, что apply — функция от произвольного числа аргументов? Да, тогда будут проблемы, наверно

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

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

Пример:

import Data.Tuple

class NItems a where
  nitems :: a -> Int

instance NItems () where
  nitems _ = 0

instance NItems (Solo a) where
  nitems _ = 1

instance NItems (a, b) where
  nitems _ = 2

instance NItems (a, b, c) where
  nitems _ = 3

data MyList = forall a. NItems a => Cons a MyList | Nil

countItems :: MyList -> Int
countItems Nil = 0
countItems (Cons x y) =
  nitems x + countItems y

countItems $ Cons (2,4) $ Cons (1,3,4) $ Cons (3,4) Nil даёт 7

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

Список, из которого нельзя читать, это что-то трансцендентное.

А у HList обратная проблема. hMap show myList не работает, даже если все элементы myList из тайпкласса Show.

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

но там не хватает режимов

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

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

Во, я не знал. По сути это такой же экзистенциальный тип

data Dynamic where
    Dynamic :: forall a. TypeRep a -> a -> Dynamic
dura4ok11
() автор топика
Ответ на: комментарий от ugoday

Согл. Операционная система тоже есть, кстати

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

Список, из которого нельзя читать, это что-то трансцендентное.

Зато можно применить любой метод тайпкласса. А читать не надо.

dura4ok11
() автор топика
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.