LINUX.ORG.RU

среда для clojure: emacs или vscode?

 , ,


0

2

Недавно пришлось настраивать среду разработки для окамля. Плагины для vscode оказались пшиком, емакс помог. Какова ситуация с clojure? Среды от jetbrains почему-то не вызывают восторга, но можно тоже рассмотреть.

Контекст: я более-менее свободно работаю в Common Lisp в slime в emacs, хотя последние годы это было крайне редко (на лиспе стал писать в своей оболочке «Яр»). В остальном мой любимый редактор - это VSCode. Скорее всего, если буду играть в clojure, там же будет и что-то другое, связанное с java, js, clojurescript. Т.е. всеядность среды тоже имеет значение. В Емакс я только с лиспом действительно много работал, к остальному не знаю даже, как подступиться.

★★★★★

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

На лиспе легко писать только лиспоподобные языки,

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

а синтаксис лиспа не так уж и удобен.

а это не важно. не устраивает готовый – сделай свой.

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

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

Вот именно, и ты получаешь ту же проблему, что и внешний препроцессор AST в любом языке.

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

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

ладно в perforce ещё логично это как-то. потому что ноги растут из configuragion management, типа clear case какого-нибудь. потом, см.

например публикацию про nvidia как у них на perforce всё было устроено. single source для VHDL, симуляций, прототипирования, производства, драйверов (причём под все ОС сразу – тот же драйвер под линукс это коротенький shim для общего под все ОС кода). ну там логично – зачем бинарники, зачем монорепа (хотя тоже не совсем, по крайней мере интеграционная ветка куда сливают там есть и процесс в этой публикации описан). драйвера радеоновские – наоборот, колхозят врукопашную. поэтому процесс разработки под разные ОС – как получится.

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

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

это не значит что все эти либы нужно валить в одну монорепу. есть же IDL и прочие интерфейсы.

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

лучше скажи в чём прелести пипифакса PPX-а вместо Camlp4.

так-то понятно что AST типизированный, ну а вообще?

Не доводилось иметь дело с окамлем. МБ тебе букозу подскажет?

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

ну вот например template в C++. он first class object или нет?

можно написать template class T, template typename T. а что нужно написать чтобы было template template T?

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

вот чем его лучше писать на PPX чем на Camlp4 и кто такие «Extension Points» и в чём их преимущества?

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

Ты можешь аргументировать, почему я должен хотеть ввести новые синтаксические конструкции в язык?

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

  2. потому что в язык уже интегрированы какие-то понятия которые там first class objects

  3. потому что этот встроенный DSL получит на халяву эти понятия и батарейки хост языка.

  4. потому что эти понятия нужны – экономят мышление и сокращают выкладки. и синтаксические конструкции. выражающие их нужны тоже.

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

что значит «моего языка»? определи его семантику.

почему бы не написать свой транслятор на коленке – а транслятор во что?

потому что лень писать заодно и оптимизатор и кодогенератор.

если транслировать в уже готовый язык с нормальным компилятором, можно использовать его (на халяву).

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

на лиспе можно написать интерпретатор ML

на любом языке можно написать eval любого другого языка, например ML. интерпретатор типизированного лямбда-исчисления на нетипизированном. хинт: ой, а если эти typecase/etypecase времени компиляции писать макросами-компилирующими-макросы ?

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

В CL можно вычислять макросы во время выполнения. В Clojure — нет.

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

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

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

  • что ты вообще под этим все понимаешь
anonymous
()
Ответ на: комментарий от byko3y

Blub Paradox

Да, ни одного. И что, каким образом это опровергает хотя бы один мой аргумент?

Я тебе уже написал: ты не шаришь в теме. Я когда начал читать твои посты, хотел поначалу ответить с цитатами, но понял что это ни к чему не приведет, потому-что ты даже не понимаешь о чем говоришь. Все сводится именно к этому.

Не вижу в треде ни одного примера blub paradox.

Значит ты либо не умеешь гуглить, либо жирно набрасываешь. Скорее всего опять говоришь о вещи, которую просто решил не понимать прежде чем иметь мнение. Почему-то я не удивлен.

Аристарх.

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

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

вот есть например язык LEDA с сопутствующей книжкою по главам

обзор языка в pldi95.ps

берём синтаксис от паскаля. добавляем объектно-ориентированную, функциональную, логическую парадигму.

смысл: пишем например вычисление на графах. его удобно писать как класс. о, ну а нужны запросы на графах. добавляем function -> relation. этот relation в логической парадигме. операции, которые изменяют графы – написаны в функциональной.

в итоге: простой язык (см. интерпретатор) с простым паскалеподобным синтаксисом.

и тем, не менее – вот пример, в котором уместны все три парадигмы.

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

ну то есть: приложение устроенное как БД на графах – вот пример, который рационально писать во всех трёх парадигмах сразу.

это причина №1 почему я должен хотеть ввести новые синтаксические конструкции в язык?

причина № 2 Почему бы мне тогда уже не написать свой транслятор для моего языка?

– собственно, почему же осилили только интерпретатор, а не компилятор. и почему его вообще нужно осиливать писать самому вручную – а не транслировать в уже существующие, с готовыми отлаженными компиляторами.

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

Там в основном рассматривают опыт связанный с JVM-стеком, Scala и Java в приоритете.

А что если хаками с abcl похвастаться?

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

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

Подозреваю, что для зависимостей на уровне исходников, а не артефактов.

Кстати, с приходом clojure CLI tools в кложе можно иметь source level dependencies, не складывая все добро в один репозиторий. Можно указывать локальные каталоги, можно удаленные репозитории.

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

собственно, почему же осилили только интерпретатор, а не компилятор. и почему его вообще нужно осиливать писать самому вручную – а не транслировать в уже существующие, с готовыми отлаженными компиляторами.

я подозреваю, что пример Kaleidoscope недопитона на окамле, транслируемого LLVM вполне себе можно расширить и углубить взяв за язык не недопитон а недопаскаль LEDA и наколхозив не столько интерпретатор сколько транслятор в сам базовый окамл времени комплиляции (не нужно писать реализацию функциональной парадигмы, сделает окамл; и с логической, этими вот relation – тоже проще их реализовать на окамле чем на сишке как в ledainterp).

lex исходники по идее на camlp4 легко перекладвываются.

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

Удалил bitbucket репы на ртути — дальше что?

А я скажу что дальше. Дальше их начинает удалять не только битбакет и вскоре у тебя остаются одни маргинальные решения и сам ты тоже становишься маргиналом. Переезжаешь на self-hosted. Это не плохо и не хорошо, быть маргиналом, но может быть весьма неудобно, когда это такой пустяк как контроль версий. Может ты любишь кактусы - а я вот стараюсь выбрать тот что поменьше.

anonymous
()

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

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

Во-первых, «first class» — это слишком абстрактное и размытое понятие, чтобы от него отталкиваться.

first.tar.Z : testfiles/testrel14.l

type
  names:=(john, mary, paul);
  relation:=function(rel names, rel names)->boolean;

var
  res : boolean;
  likes : relation;

begin
  likes:=function(rel X,Y : names)->boolean;
         var 
           Z : names;
         begin
           suspend(john, Z):- likes(Z, mary);
           suspend(mary, Z):- likes(Z, mary);
           suspend(john, mary);
         end;

  res:=likes(john, mary);
  print(res);
end;

{
segmentation fault
}

здесь видно, что rel – это first class object языка.

то есть, на уровне системы типов отношения (реализующие логическую парадигму) полноценные, первоклассные члены языка – и во время компиляции, и во время интерпретации.

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

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

Я думаю, может быть ещё и такая идиотская причина, что это не проходит фильтр HR-ов. Да и сами кложуристы могут не знать, что такое CL. Или в конторе нет бюджета более чем на одного кложуриста и в итоге вообще никто не знает, что такое лисп, а кложу они взяли по-какой-то бизнес-причине, например, уже был какой-то проект, который они взяли за основу, и он оказался на кложе.

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

например публикацию про nvidia как у них на perforce всё было устроено. single source для VHDL, симуляций, прототипирования, производства, драйверов... драйвера радеоновские – наоборот, колхозят врукопашную. поэтому процесс разработки под разные ОС – как получится

Нука погоди, разве драйвер nvidia в итоге не является таким же глючным говном, как и радеон? В итоге всё зависит от того, насколько компетентным был индус, пишущий код, и насколько много времени потратили на тестирование.

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

MS не хранит всё в монорепе. MS хранит винду в одной репе, поскольку это единый проект.

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

https://github.com/catboost/catboost/

В этой репе в папке contrib тусуются все используемые библиотеки, и даже два интерпретатора CPython: contrib\tools\python и contrib\tools\python3. То есть, библиотека должна работать из коробки правильно, никто не будет заново сидеть подбирать версии библиотек, как это постоянно нужно делать в том же NPM.

Это есть типичный отлаженный и оттестированный коммерческий проект. В какой-то степени по устройству это подобно специализированному дистрибутиву линукса, где мейнтейнеры подобрали версии библиотек и оттестировали работу системы. В гугле решили, что вместо того, чтобы тащить отдельно за каждый проектом свои версии библиотек, было бы проще держать только один набор версий всех библиотек.

Это далеко не однозначное решение, поскольку обновление библиотеки требует обновления всех зависимых проектов с тестированием онных. Такая модель разработки геморнее на короткой дистанции и удобнее на длинной. К тому же, возникает довольно много проблем с внешними библиотеками: например, мне для разработки нужна фичанейм1 из либанейм1; фичанейм1 есть только в либанейм 2.0, но у нас в монорепе используется либанейм 1.0; я обновляю либанейм 1.0 до 2.0, и внезапно оказывается, что либанейм 2.0 не работает без другаялиба 5.3, а у нас в репе другаялиба версии 4.7; тогда мне нужно проаргрейдить все зависимые от другаялиба проекты на другаялиба 5.3, а потом проапгрейдить зависимые от либанейм на либанейм 2.0 — только тогда я могу продолжить разработку. В гугле эта проблема менее выражена именно потому, что у гугла очень много собственных решений.

Для собственных решений, как правило, есть только одна версия — последняя trunk/mainline, благодаря чему обновляются только непосредственные зависимости. Более того, новый код не замещает старый, а докидывается в кучу, и таким образом отдельные либы разрастаются до огромных размеров, и зависимые проекты приходится обновлять меньше. Поддержка стабильных веток минимизарована, и зачастую это просто срезы репы с минимальными обновлениями.

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

Здесь не всё гладко и далеко не каждой фирме подойдет такой подход. Но в гугле он вполне работает. И, в частности, это помогает избежать современного микросервисного ада, когда в одной системе двадцать версий библиотек, несколько версий сервера одной и той же СУБД крутятся вместе, потому что одним микросервисам нужна поновее, а другим — постарее, и никто не рискнет апгрейдить микросервис без острой необходимости. В результате любой проект из монорепы гугла, грубо говоря, можно запустить на одном единственном «дистрибутиве» линя, с единственным набором версий всех библиотек, причем, все зависимости уже прописаны в монорепозитории и система сборки может из собрать. А кого-то разные версии либ устраивают, и старые микросервисы апгрейдить никто не будет, а будут тащить их такими как есть.

это не значит что все эти либы нужно валить в одну монорепу. есть же IDL и прочие интерфейсы

Я обновил интерфейс, мне теперь нужно обновлять два конца, а то и три, и четыре. В итоге я не могу использовать новую ревизию одного подпроекта со старой ревизией второго, и наоборот. По сути у меня уже есть монорепа, только я почему-то решил ее оформить в виде нескольких проектов. Особо поехавшие такую систему оформляют в виде подмодулей, и потом очень весело любятся с ними. Android, как ни странно, сделан в таком духе, но чтобы избавить пользователей от страданий был разработан Repo, который для работы с фактически монорепозиторием добавляет к/над git необходимые отсутствующие в git фичи.

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

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

Вот именно, и ты получаешь ту же проблему, что и внешний препроцессор AST в любом языке

огласи проблему-то

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

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

можно написать template class T, template typename T. а что нужно написать чтобы было template template T?

T может быть шаблоном же ж.

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

ну в обучалке LLVM есть например язык Kaleidoscope – эдакий питон на окамле

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

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

Как же я сразу не распознал! Это же троллинг тупостью!!

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

И лисп, и питон - языки общего назначения с понятной нишей. Еще скажи, что питон нельзя сравнить с руби или js

Я уже отвечал несколько раз

И каждый раз ты отвечаешь чушь.

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

PyQt работает прекрасно, ты как всегда несешь какой-то бредок.

Точно так же JS 15 лет не был ЯП общего назначения

Исторические «справки» можешь оставить при себе, на текущий момент js, cl, pyhon, ruby - языки находящиеся в одном классе. Отрицать это может только неадекват.

пока кому-то не стрельнула в голову идея таки сделать его ЯП общего назначения — однако же, получился другой язык, который весьма плохо портируется на браузерный JS, ровно как и плохо портируется обратно.

Это опять же никому не интересно.

Еще скажи, что питон нельзя сравнить с руби или js

Интерпретаторы CPython, Ruby, и Node.js находятся в одной нише. Но не браузерный JS.

Почему CL не находится в одной нише с этими языками? И почему ты компиляторы называешь интерпретаторами?

Ты можешь аргументировать, почему я должен хотеть ввести новые синтаксические конструкции в язык?

Тебе - нет. Просто потому что не вижу смысла, объяснять очевидные вещи тому, кто упорно создает какую-то противоречающую реальности картину мира.

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

Ну, то есть ты это вообще все серьезно задаешь эти вопросы а не просто троллишь или безбожно тупишь?

Некоторые люди рождаются слепыми, как им узнать преимущества зрения?

А с чего ты взял, что ты — зрячий?

Из определения блаб-парадокса и из системы косвенных (и прямых) признаков.

Чем принципиально отличаются макросы в кложе от макросов CL?

В CL можно вычислять макросы во время выполнения. В Clojure — нет.

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

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

Везде можно писать какой угодно код. F# дает чуть больше статических гарантий

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

Очередной поток фантазий.

Нет там данных по jruby и groovy. Даже по котлину есть, а по груви нету. И паскалей нету, прикинь?

Угадай почему, и как это связано с размером зп

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

Как всегда не угадал.

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

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

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

Я вот писал на хаскеле, и проклял все эти сокращенные выкладки, когда в какую-нибудь ничем не примечательную строчку засовывается такое количество алгоритмов, что приходится несколько минут сидеть, чтобы понять, что на самом деле происходит: кто карируется, а кому аргумент добавляется, где замыкание, где вызов функции. Напоминаю, что в хаскеле пробел — это элемент синтаксиса, примерно как в других языках точка, потому добавив пробел в конец строки ты получаешь совершенно другую программу. Нет уж, спасибо, лучше давайте многословно, но чтоб было понятно.

потому что в язык уже интегрированы какие-то понятия которые там first class objects
потому что этот встроенный DSL получит на халяву эти понятия и батарейки хост языка

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

почему бы не написать свой транслятор на коленке – а транслятор во что?

Да хоть бы в лисп. К слову, WebAssembly в качестве текстового представления использует s-выражения. Однако же, исходники для WebAssembly обычно не пишут на s-выражениях.

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

на лиспе можно написать интерпретатор ML

на любом языке можно написать eval любого другого языка

Я не писал того, что ты цитируешь. Кому ты отвечаешь — не знаю.

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

В CL можно вычислять макросы во время выполнения. В Clojure — нет

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

Ты цитируешь два тезиса. Очевидно, вместе их нет ни в каких документациях, но по отдельности — вполне себе существуют. Тебе на оба ссылки давать?

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

Мне уже ничего от тебя не нужно, братик : ) Забей.

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

вот есть например язык LEDA с сопутствующей книжкою по главам
берём синтаксис от паскаля. добавляем объектно-ориентированную, функциональную, логическую парадигму.
смысл: пишем например вычисление на графах. его удобно писать как класс. о, ну а нужны запросы на графах. добавляем function -> relation. этот relation в логической парадигме. операции, которые изменяют графы – написаны в функциональной.

А ты не задумывался о том, почему такой замечательный язык оказался проигнорирован публикой? Потому что это как писать один текст одновременно на русском, английском, и китайском сразу, типа «возьмем из каждого языка лучшее». Качество ЯП определяется не количеством фич в нем, а простотой языка. Именно по этому критерию LEDA стал одним из худших ЯП своего времени, и от него блеванули все, кто прошел мимо.

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

Дальше их начинает удалять не только битбакет и вскоре у тебя остаются одни маргинальные решения и сам ты тоже становишься маргиналом

Я не вижу никакого «дальше», прошло уже десять лет с момента победы github, а хостингов по прежнему валом:

https://www.mercurial-scm.org/wiki/MercurialHosting

Да, в разы меньше, чем у git, и чо? У меня на рабстве проект self-hosted, например. Как правило, если ты не бомж из подворотни, то рано или поздно твой проект переходит на self-hosted, будь то gitlab или что-то другое.

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

Я думаю, может быть ещё и такая идиотская причина, что это не проходит фильтр HR-ов. Да и сами кложуристы могут не знать, что такое CL. Или в конторе нет бюджета более чем на одного кложуриста

Еще раз: Clojure — надстройка над Java, над ее стандартной библиотекой, с возможностью этой самой стандартной библиотекой пользоваться, взаимодействовать с имеющимся софтом на Java. Без этого Clojure почти никому не нужна. Очень редко кто пишет проект с нуля полностью на Clojure. Потому знание жавы — обязательное условие для кодера на кложе.

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

PyQt работает прекрасно, ты как всегда несешь какой-то бредок

Посмотри на список приложух, написанных на PyQt, и заплач. Если еще не заплакал, то поставь их себе и попытайся пользоваться. Я сам пользуюсь gajim, но только как утёнок (с историями переписок за 10 лет) — так-то страшнее гаджима только IDLE.

Интерпретаторы CPython, Ruby, и Node.js находятся в одной нише. Но не браузерный JS

Почему CL не находится в одной нише с этими языками? И почему ты компиляторы называешь интерпретаторами?

Компиляция в байткод не считается, а JIT используется в V8 и только для ограниченного круга функций — все-таки интерпретация там первична.

CL использует модель данных «неизменяемые кододанные», в то время, как Ruby/CPython/JS используют модель «неизменяемые функции, неизменяемые примитивные типы, изменяемые сложные типы в виде ассоциативных массивов».

Чем принципиально отличаются макросы в кложе от макросов CL?

В CL можно вычислять макросы во время выполнения. В Clojure — нет.

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

Да, попытался изобразить факториал макросом на Clojure:

(defn add (a b) (+ a b))

(defmacro my-recursive-fact [n]
    (if (zero? n)
        1
        `(* ~n (my-recursive-fact ~(dec n)))))
		
(println (format "Hello, %d" (add (my-recursive-fact 5) 1)))

и, что характерно, эта штука вычисляется так же, как аналог на CL:

(defun add (a b) (+ a b))

(defmacro my-recursive-fact (n)
  (if (= 0 n) '1
    (let ((m (1- n)))
      `(* ,n (my-recursive-fact ,m)))))

(format t "~D." (add (my-recursive-fact 5) 1))

То есть, при слабой динамичности оба транслятора спокойно и одинаково пережевывают макросы — я ошибся. Ограничения начинаются где-то в районе apply/map, причем, как в CL, так и в Clojure. Скорее всего на fexpr мне правильно указали выше, но в CL fexpr нету.

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

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

Очередной поток фантазий

Еще раз повторяю, что clojure/F# реализованы на безопасных языках, а CPython — на языке Си. Да, в итоге CLR и JVM реализованы на C/C++, но это касается только очень ограниченной VM. В CPython же Си используется в угрожающих масштабах — потому питон опаснее Clojure/F#. Второй фактор я тоже указал — фундамент языка в виде изменяемых ассоциативных массивов создает меньше гарантий независимости работы моего кода от кода, написанного Ирашей Пратаканандой.

Как всегда не угадал

Ну ничего, в следующий раз повезет.

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

Соглашусь. Конечно, нужно писать на русском, а не на английском.

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

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

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

Если еще не заплакал, то поставь их себе и попытайся пользоваться. Я сам пользуюсь gajim, но только как утёнок (с историями переписок за 10 лет) — так-то страшнее гаджима только IDLE.

Ответ был на следующий тезис:

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

Что там за непитоновские костыли в PyQt / PySide итд? Использую приложения полет нормальный. А на чем еще писать рич-графический интерфейс под десктоп на джаве что ли или на С++? :)

Почему CL не находится в одной нише с этими языками? И почему ты компиляторы называешь интерпретаторами?

Компиляция в байткод не считается

Ну конечно «не считается». Python не является никаким интерпретатором уже давно, как и большинство подобных языков. Но вопрос был в другом, чем принципиально отличаются языки, а не их реализации? Если из CL убрать макросы, что там такого остается сильно более интересного, чем в питоне? Именно в языке, а не то, что там за 30 лет сделали компилятор +- рабочий и то с достаточно тормозящими сборщиками мусора (в открытых реализациях), ну и баги не фиксятся годами.

CL использует модель данных «неизменяемые кододанные»

Шта?

в то время, как Ruby/CPython/JS используют модель «неизменяемые функции, неизменяемые примитивные типы, изменяемые сложные типы в виде ассоциативных массивов».

Конкретно, в чем отличие покажи.

и, что характерно, эта штука вычисляется так же, как аналог на CL

Внезапно.

Ограничения начинаются где-то в районе apply/map, причем, как в CL, так и в Clojure.

Ты хочешь, чтобы макрос можно было подставлять в место для передачи ф-ции как аргумента вроде (apply #'my-macrosum '(1 2 3))? https://lispy.wordpress.com/2007/11/30/your-macro-is-in-my-mapcar-no-your-map... - подобные вещи можно сделать через eval, но да, я хотел бы более универсального подхода, макросов как first class citizen.

Скорее всего на fexpr мне правильно указали выше, но в CL fexpr нету.

Нету, от них в CL отказались сознательно.

clojure/F# реализованы на безопасных языках, а CPython — на языке Си.

Они все реализованы на «опасных языках». Или ты о том, что в CPython много С в стандартной либе? На сколько это делает python опасным... Ну да, чуть опаснее, наверное. Как и любой язык, где есть CFFI.

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

Так это всех языков с duck typing касается, CL в том числе, тем более, что в нем поощряется разработка в образе.

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

? Если из CL убрать макросы,

если бы у дедушки не было члена…

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

да, я хотел бы более универсального подхода, макросов как first class citizen.

Не очень понимаю как ты себе это представляешь. И когда это представляется проблемой, то как правило она локальна и решается какой-нибудь лямбдой (в большинстве случаяев и без eval’a, т.к. последнее скорее всего подразумевало бы какую-то runtime-генерацию кода, ну или приводи пример). В той статье которую ты привел, defparameter в defun’e - искуственный пример. Если бы тебе нужно было объявить defparameter’ом например кучу переменных с генерируемыми именами, это был бы топ-левел, где можно использовать eval-when :compile-toplevel + macrolet, что, ясен пень, можно завернуть в макрос если таким приходится заниматься чаще одного раза. Никакого eval’a в таких случаях не нужно, а их - подавляющее большинство.

Если из CL убрать макросы, что там такого остается сильно более интересного, чем в питоне?

а ты не знаешь и серьезно спрашиваешь? я не стал разбираться о чем ты с ним споришь, но вот не могу просто остановится на своем предыдущем комментарии. первоклассная интерактивность вместо костылей, CLOS, префиксная нотация, скобочки + индентация где хочешь (и которая не выносит тебе мозги, если брать языки помимо питона в расчет, и которая не является дубовой, если рассматривать только питон), функциональное программирование (в пейтоне оно не поощрается), человеческие идентификаторы имен с черточками, нумерические башни, рестарты/обработка ошибок вместо трейсбэка говна.

И лисп, и питон - языки общего назначения с понятной нишей.

Мне вот ниша лиспа непонятна. Можешь подскажешь для чего этот язык /общего назначения/ предназначен? Единственное что я могу придумать - ни на том ни на другом не будут писать драйвера. Эти языки являются представительями обширнейшего класса динамических языков, зачем что-то еще придумывать?

Во сколько я уже не ставлю твоего оппонента в …, этот твой тезис мне не ясен.

ну и баги не фиксятся годами.

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

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

А, вот жеж еще вспомнил: многопоточность и скорость, лол. Даже забыв обо всем остальном, для достаточно сложных проектов обычный Python не вытаскивается из помойки просто из-за GIL’a, ибо городить прослойку с сями на каждый чих - да кому это надо если можно взять другой язык. Скорость: урезанный питон в принципе можно конпелять в нативный код, но я думаю ты согласишься что это уже не совсем питон, а си, который ездит в броневике из сахара. В лиспе ты можешь сделать slime-disassemble-symbol и посмотреть на сам угадай что.

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

Ты дичь сейчас сморозил. Дело в том, что нет никакого языка «питон» без реализации. Нет реализации - нет питона, понимаешь? Потому-что нет стандарта.

Я так полагаю ты немного фанат питона и для меня со стороны твой этот невинный вопрос про «сильно более интересного» и то что там якобы есть какая-то ниша и что они там якобы вместе находятся выглядит примерно так: https://i.kym-cdn.com/photos/images/newsfeed/001/932/122/2bd.png

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

У меня на рабстве

Начинают всплывать любопытные подробности. Тебя заставляют это все писать, правда? Поставь аватарку вверх ногами, если да.

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

будь то сервис или GUI, то внезапно выясняется, что требуется куча непитоновых костылей, чтобы это работало более-менее адекватно.
Что там за непитоновские костыли в PyQt / PySide итд? Использую приложения полет нормальный. А на чем еще писать рич-графический интерфейс под десктоп на джаве что ли или на С++?

PyQt/PySide и есть непитоновские костыли. Пользуюсь Gajim, периодически падает с сегфолтом. IDLE так не падает, потому что тикль.

А на чем еще писать рич-графический интерфейс под десктоп на джаве что ли или на С++?

Под форточки еще на дотнете пишут весьма успешно.

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

Давай все-таки разберемся с определениями. Прежде всего, набор инструкций сам по себе не является компилируемым или интерпретируемым, потому что даже какие-нибудь маш. коды ARM при выполнении в QEMU на x86 интерпретируются. Конкретно в CPython «компилятор» является не более чем препарсером, генерирующим что-то вроде AST, а выполнение AST происходит в цикле интерпретации — что есть ключевым критерием отличия интерпретации и компиляции.

Если говорить про V8, то роль JIT-компилятора в нем преувеличена:
https://v8.dev/blog/jitless
В полностью интепретируемом режиме он вполне себе неплохо бегает, потому что основной эффект оптимизации таки достигается за счет оптимизации встроенных контейнеров данных и стандартных объектов. К слову, в V8 компиляторов два — вторым является компилятор регулярных выражений.

То есть, в случае V8 можно говорить про интерпретатор, который имеет в своем составе вспомогательные компиляторы. В случае CPython препарсер генерирует код того же уровня абстракций, что и исходный текст, не собирает никакие файлы вместе, потому тут даже никакое словарно-википедийное определение компилятора не прокатывает.

CL использует модель данных «неизменяемые кододанные»

Шта?

Блин, я читаю случайно открытый плагин к emacs:
https://github.com/abo-abo/function-args/blob/master/function-args.el
и осознаю, что это тупо питон. Да, базовые типы несколько отличаются, но это отличие незначительно. Ты был полностью прав, когда говорил, что получится питон:

(setq a (list 4 5))
(setq b (list a 3))
(setf (car (car b)) 1)
(print a)
(print b)
(1 5)
((1 5) 3)

Это разительно отличается от Clojure, где set/setq/setf вообще отсутствуют в языке и все изменения выполняются в более функциональном стиле возвратом измененных значений вместо изменения объектов по месту. Правда, в функциональном стиле пишут и на других лиспах (и это считается хорошим стилем), но не Emacs конкретно, где даже есть динамическое связывание вместо лексического. Точно так же и на питоне можно писать в более функциональном стиле, так что, еще раз повторю: лисп без макросов, действительно, примерно равен питону.

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

Я уже написал по этому поводу, что процесс «опускания» макросов произошел еще раньше, до CL, так что мои додумки по поводу макросов в рантайме CL/ранней Clojure были додумками. Правда, apply-macro в Clojure таки было, но опиралось на eval и в итоге его выкинули из библиотеки:

https://clojure.github.io/clojure-contrib/apply-macro-api.html

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

clojure/F# реализованы на безопасных языках, а CPython — на языке Си

Они все реализованы на «опасных языках». Или ты о том, что в CPython много С в стандартной либе? На сколько это делает python опасным... Ну да, чуть опаснее, наверное. Как и любой язык, где есть CFFI

Еще раз: разговор не про опасно/безопасно, а про то, какова степень опасности. В конечном счете они выполняются на ОС-и, которая, скорее всего, написана на Си и ненадежна. Однако, ограниченный и тщательно оттестированный код на Си — это намного меньшая опасность, чем какое-то сишное расширение, где годами лежат багонутые функции, но их просто никто не вызывает, потому баг не проявляется.

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

Так это всех языков с duck typing касается, CL в том числе, тем более, что в нем поощряется разработка в образе

Да, эта проблема актуальна в том числе для CL. Но она не касается F# или Clojure.

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

Я отвечаю не тебе, если что, потому-что считаю что ты жирно набрасываешь, при этом не разбираясь в теме, а тем кто может читать этот тред, которым интересен лисп или emacs.

Итак, разбираем наброс.

, в функциональном стиле пишут и на других лиспах (и это считается хорошим стилем), но не Emacs конкретно, где даже есть динамическое связывание вместо лексического.

Начнем с последнего утверждения: и тот и другой тип биндинга есть и в CL и elisp. Правда поддержка лексических биндингов появилась в емаксе не так уж и давно, что не мешало никому на нем программировать и там были свои грабли для имитации кложур. Я уже не помню с какой точно версии, но можно прописать вверху файла lexical-binding t и теперь все по-умолчанию в файле имеет лексический биндинг. В CL же динамический биндинг есть для глобальных переменных, например.

Функциональный код? Никто на elisp’e не запрещает писать функциональный код, но так уж сложилось, что многие пишут императивно. Причины две основные. Первая - большинство практикантов не знают как писать функциональный код, поэтому, приходя с питона и прочей недоскриптухи, ничему не учаться и просто продолжают писать как писали. Оно и понятно: практиканты емакса пишут за идею и на энтузиазме, профессионально в лиспе они разбираться не должны. И на том им спасибо. Вторая причина - в основном сами плагины в емаксе работают над буффером как-либо изменяя его. Это отчасти фейл тех кто писал API, поощрая императивный стиль - все вот эти beginning-of-line, save-excursion и т.д, при этом не предоставив какой-то другой интерфейс, который, быть все же мог. Ни то ни другое - не проблема elisp’а, который, как мы знаем, мультипарадигменный, и писать на нем можешь как хочешь. И функциональный код для емакса на самом деле писать можно и не так сложно, просто приходится его иногда приправлять императивщиной. Вот и все.

так что, еще раз повторю: лисп без макросов, действительно, примерно равен питону.

От повторения утверждения, ясно, что это утверждение правдой не станет. Но нельзя не отметить масштабные размеры приравнивателя этого регистранта, что само по себе доставляет.

И опять же. Если бы у дедушки не было члена. Ах, что бы тогда было! Но он-то у дедушки есть. И куча всего еще, что я описал несколькими комментами выше.

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

да, я хотел бы более универсального подхода, макросов как first class citizen.

Не очень понимаю как ты себе это представляешь

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

Если из CL убрать макросы, что там такого остается сильно более интересного, чем в питоне?

а ты не знаешь и серьезно спрашиваешь?

Я спрашиваю у своего собеседника.

первоклассная интерактивность вместо костылей, CLOS,

Сюда же mop, это все понятно.

префиксная нотация

Вкусовщина. Мне нравится, но вкусовщины не отменяет.

скобочки

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

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

Поясни. Имеется ввиду, что можно автоматическими средствами отформатировать исходник, как тебе нравится или о чем-то другом?

функциональное программирование (в пейтоне оно не поощрается)

Ф-п на таком же уровне есть в руби и жс.

человеческие идентификаторы имен с черточками

Это опять же вкусовщина, хотя мне и нравится. Но мы говорили о принципиальных отличиях, черточки в именах - это не принципиально.

нумерические башни

Суть реализация.

рестарты/обработка ошибок вместо трейсбэка говна

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

Мне вот ниша лиспа непонятна. Можешь подскажешь для чего этот язык /общего назначения/ предназначен?

Как язык общего назначения - практически для чего угодно, кроме низкоуровневых штук. А вот в сравнении с другими языками преимущества (если в разрезе областей) - то как раз для исследования данных, создания прототипов и выразительных DSL, когда после прототипа не надо переписывать на сишку или другой язык для скорости, потому как скорость обычно приемлема (можно сделать так, чтобы медленнее С++ была не более чем в 10 раз, а этого зачастую достаточно). Рестарты, репл и макросы - для анализа больших данных это вообще супер круто. python и подобные языки совсем в пролете.

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

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

Во сколько я уже не ставлю твоего оппонента в …, этот твой тезис мне не ясен.

Надеюсь, пояснил.

ну и баги не фиксятся годами.

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

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

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

А, вот жеж еще вспомнил: многопоточность и скорость, лол. Даже забыв обо всем остальном, для достаточно сложных проектов обычный Python не вытаскивается из помойки просто из-за GIL’a,

Это все про реализацию, а не о принципиальных отличиях. Кроме того в питоне есть pypy.

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

Об этом написал в предыдущем сообщении.

Ты дичь сейчас сморозил. Дело в том, что нет никакого языка «питон» без реализации. Нет реализации - нет питона, понимаешь? Потому-что нет стандарта.

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

Я так полагаю ты немного фанат питона

Нет, но использую как раз в основном эти языки - лисп и питон, по совокупности причин.

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