LINUX.ORG.RU

Vim или Emacs? А LISP в 2021?

 , ,


1

4

https://www.youtube.com/watch?v=8Q9YjXgK38I&t=42s

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

А ведь Crashbandicoot была годной игрой…

Что выбрать? Vim или Emacs?
Изучать в 2021 году Lisp? Если изучать, какой? Практика?
А не засмеют сотрудики?

Времени в сутках маловато, на всё не хватает.


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

Cразу не подумал, можно 1) лифтить туплы c помощью std::apply и 2) применять этакое «каррирование»

struct placeholder {
    auto operator + (const placeholder& a, const placeholder& b) {
        return [](auto && a, auto && b){ return a + b; }
    }
} _;

struct placeholder1 {
    auto operator % (auto n) {
        return [n](auto x, auto ...) { return x % n; };
    }
    // и т.д.
} _1;

auto collect = [](auto & vec, auto && map) {
    return [&](auto ... xs) { vec.emplace_back(map(xs...)); };
};

Получая в итоге

std::vector<int> result;
loop_(
    fors_(for_range_(1, 10), for_0(100)),
    _1 % 2,
    collect(result, _ + _)
);

Что уже куда читаемее. Осталось только for как-то красиво обозвать, чтобы меньше их писать, и отличаться будет незначительно.

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

Кресты как кресты. Это примитивщина, в которой я к тому же даже форварды для наглядности не прописывал. Меня лично в лиспе вовсе не скобки напрягают, а динамическая типизация. Даже в статическом подмножестве Racket не покидает ощущение, что типы там сверху приклеены.

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

// и т.д.

И это же придётся делать для каждой операции. И наступать на грабли, если кто-то напишет

collect(result(f(_)+g(_)))

и получит очень странное сообщение об ошибке. Красиво, но хрупко.

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

И это же придётся делать для каждой операции.

В Boost это уже сделали.

если кто-то напишет

А если острым, и в глаз? (с)

А так согласен. Возможно, с Reflection TS все было бы куда лучше.

Siborgium ★★★★★
()

Vim как-то привычнее

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

На лиспе без макросов лучшее, что можно сделать — что-то вроде

(loop (for 1 10)
      (for 100)
      (when (lambda (i j) (oddp i)))
      (collect (lambda (i j) (+ i j)))

а что должен делать этот код? на простом русском языке.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 2)
Ответ на: комментарий от Siborgium

типа так, на «псевдокоде»?

а в чем подвох?

//Для всех i от 1 до 10 и j от 0 до 100 собрать 
//суммы всех пар i и j, в которых i нечетное, в список 
//и вернуть этот список.
struct List{
	void add(int fval);
};

bool odd(int fv){ return fv/2 != 0;}

List ff(){
	List lres;
	for(int i=0; i<10; ++i){
		for(int j=0; j<100; ++j){
			if(odd(j)) lres.add(i+j);
		}
	}
	return lres;
}
alysnix ★★★
()
Ответ на: комментарий от monk
List ff(){
	List lres;
        int j = 100;
	for(int i=0; i<10; ++i, ++j){
  	   if(odd(j)) lres.add(i+j);
	}
	return lres;
}

тут j меняется от 100 до 109, а типа говорили что надо от 1 до 100.

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

вот видите… «краткая и выразительная» запись оказалась потенциально ошибочно читаемой.

а попробуй мой код на с++ прочитать неверно…

я кстати не понял, j должно меняться вместе с i???

for(int i=0; i<10; ++i, ++j){
  	   if(odd(j)) lres.add(i+j);
	}
alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от alysnix

потенциально ошибочно читаемой.

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

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

а попробуй мой код на с++ прочитать неверно…

У тебя «Для всех i от 1 до 10» … «for(int i=0; i<10; ++i)».

я кстати не понял, j должно меняться вместе с i???

Да. Переменные должны одновременно получать элементы из своих последовательностей. Может ещё такое быть

(loop for i from 1 to 10
      for j in list-n 
      when (oddp i)
      collect (+ i j))

Тогда условием окончания является либо достижение 10 переменной i либо исчерпание элементов в списке list-n

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

У тебя «Для всех i от 1 до 10» … «for(int i=0; i<10; ++i)».

мне как сказали, так я и сделал.

вот.

Для всех i от 1 до 10 и j от 0 до 100 собрать суммы всех пар i и j, в которых i нечетное, в список и вернуть этот список.

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

Ну. Тебе сказали «Для всех i от 1 до 10». Ты написал «for(int i=0; i<10; ++i)». Это одно и то же, по-твоему?

а ну да… поправьте там на 1.. в нашем мире индексы начинаются с нуля. чисто привычка…

короче, хреновая эта ваша «удобочитаемая запись».

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

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

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

Угу. И справа 10 на 11. Очень читабельный формат, однако.

короче, хреновая эта ваша «удобочитаемая запись».

??? Накосячил ты, а запись хреновая наша.

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

При хорошем DSL так и есть, макросы это позволяют. Все термины описывают только предметную область, а не условности языка программирования.

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

Все термины описывают только предметную область, а не условности языка программирования.

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

язык это нотация и не более. и ее надо знать, как музыканту уметь читать ноты. а если каждый музыкант будет себе придумывать свою нотную систему… музыки не будет вообще.

??? Накосячил ты, а запись хреновая наша.

мне как сказали, так я и написал(ну начал на автомате не с того индекса, зато это сразу видно). я вообще не код писал, а алгоритм. и даже он оказался неправльным, поскольку оказывается i и j итерируются одновременно, а из того, как сказали - этого не видно. также не видно - «до» включительно или нет.

в вашей удобочитаемой записи - предел - «до» включительно или нет? зачем писать «lambda», неужто найти поприличней нотации для описания лямбды в лиспе(это лисп?) найти нельзя.

(loop (for 1 10)
      (for 100)
      (when (lambda (i j) (oddp i)))
      (collect (lambda (i j) (+ i j)))

лисп идейно правильный язык, поскольку список это универсальное представление данных, но нотация у него могда быть и повыразительней

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

примитивные циклы

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

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

loop к слову не у всех лисперов очень-то и котируется. из-за потери sexpr’ов в пользу плоских листов в нотации, индентация становиться не очень тривиальной и не всегда работает в том же емаксе, редактируется не так удобно. не всегда ясно как именно нужно писать, это правда. loop это одна из спорных в CL вещей. благо есть б-жественный iterate, ну и всякие другие тоже есть.

но прошу заметить что практически любой лиспер предпочтет именно cl’овский loop циклу любого другого языка.

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

Тот псевдокод который ты процитировал собственно неверен, его привели как пример возможного функционального подхода в лиспе, вот верный код:

(loop for i from 1 to 10
      for j from 100
      when (oddp i)
      collect (+ i j))

зачем писать «lambda», неужто найти поприличней нотации для описания лямбды в лиспе(это лисп?) найти нельзя.

Можно, и весьма просто, но эта запись стандартная.

язык это нотация и не более. и ее надо знать, как музыканту уметь читать ноты.

Это все херня. Любой живой язык постоянно развивается, дополняется терминами, словами и оборотами. И обрастает легаси.

также не видно - «до» включительно или нет.

Да, не видно. Включительно. Но есть еще below - from 0 below 100.

anonymous
()

у emacs невероятно крутое сообщество, если в него погружаться. примерно, как у perl. в хорошем смысле.

я годами сидел на vim, но мне нужно org-mode, roam, dev, shell, а теперь и elisp. поэтому я с большим трудом, но заставил себя перейти на emacs.

set -o vi везде пришлось заново менять на set -o emacs (что по умолчанию)

от vim все равно никуда не денешься, тут и там он удобнее и быстрее + вим раскладка плагины есть для многого.

мой совет - оба, но я бы начал с emacs.

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

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

итерационный цикл(типа for), это просто применение одной и той же последовательности операторов к данным, на которых есть однозначное отображение элемента этих данных на отрезок целых чисел. типа определена функция на данном отрезке Type& Array::ith(int i);

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

то есть, как только в языке появляются массивы, перечисления(не в смысле си - в си перечисления это просто наборы произвольных целочисленных констант) - там должны появиться итерационные циклы.

просто loop, в виде while, repeat и прочее - к типам данных отношения не имеют, это лишь повторения последовательности операторов до достижения некоего условия.

не надо на циклы наворачивать доп семантику.

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

итерационный цикл(типа for), это просто применение одной и той же последовательности операторов к данным

Если так сделано в С++, это не значит что все остальные люди этой планеты должны принять это за чистую монету. Ин факт, если что-то сделано в С++, стоит заранее это принимать за обосранную монету.

не надо на циклы наворачивать доп семантику.

Надо.

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

Если так сделано в С++, это не значит что все остальные люди этой планеты должны принять это за чистую монету. Ин факт, если что-то сделано в С++, стоит заранее это принимать за обосранную монету.

так сделано везде, где есть данные по которым можно итерировать. в каком-то смысле это синт.сахар, поскольку можно итерировать и обычными циклами, типа while. но ради обсуждаемой тут «краткости и выразительности» его и вводят. причем тут с++?

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

но ради обсуждаемой тут «краткости и выразительности» его и вводят

Ну так же вводят и дополнительную семантику в циклах. Problem?

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

Ну так же вводят и дополнительную семантику в циклах. Problem?

ну и с крыши прыгают… это ж не значит, что по этому поводу не нужно задавать вопросы или это осуждать например. получить премию дарвина - много охотников.

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

скучно

вместо того, чтобы скучать, нарисовали б грамматику human-lisp, и реализовали б его. а то от скобок дурно делается. это отпугивает публику.

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

… а то от скобок дурно делается. это отпугивает публику.

Высота символа «(» такая же как и остальных символов.
Поэтому они делают текст не readable.
Вот если вместо скобок в шрифте использовать какой-нибудь маленький квадратик к примеру, то скорее всего текст будет более читабельным.
Для этого даже компилятор не нужно дорабатывать.
Эту фичу можно реализовать в текстовом редакторе …

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

Приводите тогда уж полное определение loop macro, иначе это неспортивно. Мой пример полностью самодостаточен, и, как я уже показал, может быть улучшен.


А с пациентом спорить бесполезно, это клиника.

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

Приводите тогда уж полное определение loop macro, иначе это неспортивно

Да я против твоего кода ничего не имею, я пытаюсь показать товарищу, что скобки в лиспе - это не то, чего стоит бояться. В С++ не меньше скобок (а всяких значков так и больше), и ничего, пишут.

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

Эту фичу можно реализовать в текстовом редакторе …

Пятьдесят ли создатели языков программирования топчатся на одном месте.
И не могут понять, почему не получится ни кому создать читабельный синтаксис …

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

Высота символа «(» такая же как и остальных символов. Поэтому они делают текст не readable.

почему вот не ввести понятие - «именованный список».

Ident(…), где имя может быть пустым. тогда то, что первым элементом кладут и за имя считают, будет выглядеть читабельней.

а если ввести понятие именованный параметризованный список - все вроде еще читабельней становится.

было

(defun area-circle(rad)
   (format t "Radius: ~5f" rad)
   (format t "~%Area: ~10f" (* 3.141592 rad rad))
)

стало (практически песня)

area-circle(rad) (
   format(t "Radius: ~5f" rad)
   format(t "~%Area: ~10f" (* 3.141592 rad rad))
)
alysnix ★★★
()
Ответ на: комментарий от anonymous

Та в этом примере аргументы простые, а если сложные будут?

сложные - типа список? если нет имени и параметров - то это просто старая нотация - (…)

я понимаю, что может возникнуть коллизия в синтаксисе, вот вопрос - где она там будет?

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

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

я понимаю, что может коллизия в синтаксисе, вот вопрос - где она там будет?

ИМХО лучше Lisp не «улучшать», а то сделают из него C++ …

anonymous
()
Ответ на: комментарий от anonymous
Верните Ирландию - Ирландцам.mp3

Старенькая песня beatles …

anonymous
()
Ответ на: комментарий от Puzan
(sb-xc:defmacro loop-desetq (&environment env &rest var-val-pairs)
  (labels ((find-non-null (var)
             ;; See whether there's any non-null thing here. Recurse
             ;; if the list element is itself a list.
             (do ((tail var)) ((not (consp tail)) tail)
               (when (find-non-null (pop tail)) (return t))))
           (loop-desetq-internal (var val &optional temp)
             ;; Check for well-formed use of MULTIPLE-VALUE-LIST
             (when (and (typep val '(cons (eql multiple-value-list) (cons t null)))
                        (proper-list-p var))
               (return-from loop-desetq-internal
                 (let ((temps (make-gensym-list (length var))))
                   `((multiple-value-bind ,temps ,(cadr val)
                       ,@(when (member nil var)
                           `((declare (ignore ,@(mapcan (lambda (var val)
                                                          (unless var (list val)))
                                                        var temps)))))
                       ,@(mapcan (lambda (var val)
                                   (if var (list `(loop-desetq ,var ,val))))
                                 var temps))))))```

Что тут непонятного?   
Красотень же ...
anonymous
()
Ответ на: комментарий от anonymous

Так и знал, что противникам Lisp нечего будет сказать.

ПОЛНАЯ И БЕЗОГОВОРОЧНАЯ ПОБЕДА!
anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.