LINUX.ORG.RU

Декорирование блоков в CPython

 , , ,


0

2

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

Как вы декорируете блоки кода в Python? Ну то есть все мы знаем, что можно декорировать функцию:

@decorator
def funcname(arg):
    pass

и даже декорировать класс:

@decorator
class classname:
    def __init__(self):
        pass

Но вот беда — как передать кусок кода в другую функцию? Вечная проблема лямбды в питоне, которая не решена до сих пор и никогда не будет решена:

>>> decorator(lambda: a = 2)
  File "<stdin>", line 1
SyntaxError: lambda cannot contain assignment

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

«Хорошо, наш язык говно, но давайте не отчаиваться, с этим что-то можно сделать» — сказал когда-то Гвидо, и предложил:
https://www.python.org/dev/peps/pep-0343/ — PEP 343 — The «with» Statement

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

for filename in filenames:
   with try_infinitely():
      print(open(filename, 'r').readlines())

В данном случае код должен пытаться бесконечно открывать и читать файл, пока не сможет это сделать. На питоне это можно написать как:

for filename in filenames:
    while True:
        try:
            print(open(filename, 'r').readlines())
        except Exception as e:
            print(e)
        else:
            break;

Но писать такую стенку каждый раз весьма утомительно. Как и заставлять юзверя объявлять вложенную функцию и передавать ее функции-декоратору, поскольку это будет нарушать обычную читаемость кода из-за того, что код вложенной функции будет выполняться позже своего объявления, в отличие от тех же лямбд JS, которые выполняются там, где определены. Чтобы была чуть более очевидна блевотность такого кода, я специально добавил цикл for filename in filenames снаружи:

for filename in filenames:
    @try_infinitely
    def nestedfunc():
        print(open(filename, 'r').readlines())
    nestedfunc()

или

@try_infinitely
def nestedfunc():
    print(open(filename, 'r').readlines())
for filename in filenames:
    nestedfunc()

Последнее, к моему удивлению, работает, потому что области видимости в питоне поделены на уровне функций, а не блоков, и потому filename будет видима в любом месте функции.

А хотелось бы чего-то простого и понятного, плана:

for filename in filenames:
    @try_infinitely:
        print(open(filename, 'r').readlines())

Чувствуете, как код сразу стал намного проще? Единственный выход, который я пока что вижу — это городить свой DSL через

source = inspect.get_source(func)
ast.parse(source, func.__code__.co_filename, 'exec')

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

★★★★

Последнее исправление: byko3y (всего исправлений: 1)

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

Ну вообще для этих целей обычно используется with.

Нет.

Вот в чем тут проблема?

В твоем непонимании, что try_infinitely должна вложенный блок исполнять несколько раз. Как по-твоему она должна это делать?

t184256 ★★★★★
()
Ответ на: комментарий от no-such-file

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

Картинки красивые, начальству очень понравились, вот только не совсем правильные )

Не быстрее любой другой скриптухи

Быстрее. Очень удобные библиотеки ускоряют разработку

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

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

Давай уже сразу по чесноку говорить. Деньги платят за то, что ты делаешь вид, что решаешь задачи бизнеса. Лучшие делатели вида, вроде SAP и Oracle, нынче выдают лютое дерьмище, но делают вид безукоризнено — потому и ворочают миллиардами.

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

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

Научные расчёты всегда ужасны и не очевидны, особенно когда что-то новое считают

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

потому что за переписывание и трату на это времени у дорогого и узкопрофильного специалиста по мозгам должны получить все, начиная от специалиста, кончая его начальником. Потом наймут царя сишки за 100 рублей и он всё перепишет чтобы красиво было

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

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

Сходи рынок посмотри или гитхаб. Питон живее всех живых вместе с убогой нодой и пых-пыхом

Убило — в том смысле, что его развитие встало колом. Еще до того, как удалось решить его ключевые проблемы.

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

иногда надо js-лапшу посмотреть и в качестве хобби с LUA повозиться

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

По «обзору» языков особо отвечать ничего, поскольку он слишком поверхностный (хороший/нехороший). Кроме одного:

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

https://benediktmeurer.de/images/2016/venturebeat-20161216.png

По факту разница незначительна. Реальное преимущество V8 заключается в том, что он был создан недавно и был достаточно модульным, в отличие от мозиловой лапши. К сегодняшнему дню уже есть и отдельностоящие интерпретаторы на базе SpiderMonkey, но время упущено, нода уже стала популярна потому, что нода стала популярна (оно же «сетевой эффект»).

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

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

Проблема, как и в случае башпортянок, заключается в том, что затык по скорости выполнения достигается очень быстро. Как и в случае баша, эта проблема решается не самим башем, а внешними программами, которые баш запускает. Потому корректнее было бы говорить «под питон есть много готовых решений, которые позволяют быстро и небольшими усилиями решать огромный кусок задачек бизнеса». Потому что если ограничить решение стандартной либой. то выяснится, то уже и не быстро, и не небольшими усилиями, и на C++ решать задачи проще, поскольку на питоне неизбежно придется писать костыли на сишке. А когда костыли уже готовы, когда TensorFlow содержит встроенный механизм ввода-вывода файлов в обход питона — тогда, конечно, питон рулит.

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

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

исполнил ради прикола на JS :)

function out_of_luck(value, { kind }) {
  if (kind != 'method') {
    return;
  }

  return function (...args) {
    do {
      try {
        return value.apply(this, args);
      } catch (e) {
        console.log('gimme babe one more time');
      }
    } while (true);
  };
}

class C {
  @out_of_luck
  static may_fail() {
    if (Math.random() > 0.2) {
      throw new Error('error');
    }
    return 'result';
  }
}

console.log(C.may_fail());

https://link.javascriptdecorators.org/85kGOt

на произвольный блок навесить нельзя правда, такое короче…

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

Вы о себе слишком высокого мнения

А ты не подумал о том, что с твоей стороны ровно та же ситуация?

byko3y ★★★★
() автор топика

Первый подход к снаряду показал, что питон довольно неплохо переваривает метапрограммирование — ему даже можно скормить номера строк, чтобы в отладчике и бэктрейсах выдавались строки из исходного исходника, а не из сгенерированного. Собственно, я давно думал о том, что питон неплохо было бы переделать под мои хотелки — например, мне захотелось перехватить доступ к глобальным переменным модуля. На чтение всегда есть __getattr__ из PEP 0562, но он срабатывает только на чтение и только для не определенных в модуле идентификаторов. Однако, здесь встает вопрос:

В каком месте перехватывать загрузку модуля и переписывать ему AST? В идеале, конечно, было бы круто генерировать *.pyc из конечного AST, чтобы последующие загрузки были молниеносными. Но я боюсь, что этот механизм приколочен намертво к ванильному питону и модифицировать его не получится. Так и придется грузить текстовые сорцы каждый раз и перетряхивать их AST. Самый норм вариант, который я для этого вижу — отмечать имена обрабатываемых файлов каким-нибудь *.my.py (чтобы отличать их от многочисленных обычных питоньих модулей), далее по расширению их обнаруживать в MetaPathFinder.find_spec, и затем подсовывать для этих файлов кастомный Loader с переопределенным exec_module, который уже читает файл, делает ast.parse() и exec().

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

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

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

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

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

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

В каком месте перехватывать загрузку модуля и переписывать ему AST?

Ты бы еще вызывающего на ходу переписывал. А что, есть же доступ к пошаговому отладчику --sarcasm.

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

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

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

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

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

И каким образом это поможет реализовать сложную обработку блоков и перехват доступа к глобальным переменным внутри этого модуля? Как бы да, STORE_NAME поддерживает произвольный словарь, но вот со STORE_GLOBAL есть проблемка:

case TARGET(STORE_GLOBAL): {
      PyObject *name = GETITEM(names, oparg);
      PyObject *v = POP();
      err = PyDict_SetItem(f->f_globals, name, v);

То есть, глобальный контекст, он же контекст модуля, может быть только объектом dict.

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

Пока код реализации максимально приближен к обычной семантики питона — почему бы нет? Я всего-лишь по минимуму затыкаю самые ужасные прорехи реализации.

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

И каким образом это поможет реализовать сложную обработку блоков и перехват доступа к глобальным переменным внутри этого модуля?

# keep
obj = ...

# add
obj = WrapperThatInterceptsAllAccess(obj)

так понятнее?

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

Потому что отделить теперь декоратор от оборачиваемого метода никак

def _decorated(stuff):
   raise Exception()

def decorator(fn):
   def inner(*args, **kwargs):
        try:
            fn(*args, **kwargs)
        except Exception:
            return None
    return inner

decorated = decorator(_decorated)
       

Можешь импортировать и декорированную, и исходную функцию (если в тестах нужно).

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

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

a = 2
print(a)

в

vars.a = 2
print(vars.a)

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

Обоснуй, почему это нельзя сделать враппером как я показал.

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

EDIT 2: а from dirty_magic import произвольная_фигня или import dirty_magic.произвольная_фигня тебе тоже не подходят?

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

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

Проблема в том, что целая куча вещей. которые обычно работают для классов, не работают для модулей:

https://mail.python.org/pipermail/python-dev/2009-May/089535.html

И одна из этих вещей — это доступ к глобальным переменным модуля из самого модуля. С оберткой или без обертки — не важно. Хотя это лишь одна из проблем, потому что их выросла целая куча с тех пор, как Гвидо разрешил игнорировать __getattr__ и __getattribute__ во встроенных функциях, в данном случае в функциях работы с контекстом модуля.

foo.py

import sys

class Foo:
    def __getattribute__(self, name):
      print("__getattribute__({})".format(name))
      return super().__getattribute__(name)
      
    def __setattr__(self, name, value):
      print("__setattr__({})".format(name))
      super().__setattr__(name, value)
      
    def print_a(self):
      print(a)

sys.modules[__name__] = Foo()

a = 2
print(a)

bar.py

import foo

foo.a = 3
print(foo.a)
foo.print_a()

$ python.exe bar.py
2
__setattr__(a)
__getattribute__(a)
3
__getattribute__(print_a)
2
byko3y ★★★★
() автор топика
Ответ на: комментарий от byko3y

Такую телегу написал, а на вопрос не ответил. bar.py менять хоть как-то можно?

sys.modules[__name__] = Foo()

a = 2

Правая рука не знает, что делает левая? Ты зачем создал a не там, чисто чтобы print_a на неё замкнуть, а потом пожаловаться, какие в питоне неправильные двери?

def print_a(self):

self

Ты знаешь, что делать.

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

Лучшие делатели вида, вроде SAP и Oracle, нынче выдают лютое дерьмище, но делают вид безукоризнено — потому и ворочают миллиардами.

прикольно читать фантазии лузера на грошовой работе из зажопинска про «лютое дерьмище» оракл. я даже не буду спрашивать что же не лютое дерьмище

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

Спасибо, пишу на JS на нынешнем рабстве.

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

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

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

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

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

как раз про тебя

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

decorated = decorator(_decorated)

Это понятно, но так использовать декораторы странно.

qaqa ★★
()

Найди себе другой язык программирования. Питон просто не для тебя. Если нравится JS, работай как JS программист.

P.S. Функция try_infinitely вообще не нужна. Да и сами примеры показывают как не надо делать. Исключения сделаны для исключительных ситуаций, то есть когда что-то пошло совсем не по плану.

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

Скобочки из языка нужно убрать — и тогда на нем можно начинать писать.

Скобочки лиспа волнуют только тех, кто на нём никогда не писал. Для тех же кто его постоянно использует, скобочки не существуют. Это как в Матрице, «there is no spoon».

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

Скобочки лиспа волнуют только тех, кто на нём никогда не писал. Для тех же кто его постоянно использует, скобочки не существуют. Это как в Матрице, «there is no spoon»

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

Говоря о лиспе, можно заметить, что компьютеру удобно оперировать большим числом простых конструкций. Человеку же неудобно оперировать большим числом сложносвязанных сущностей — ему удобнее вкладывать больше смысла в каждую конструкцию, но s-выражения не дают этого делать. В Лиспе уже давно поняли эту проблему, и потому придумали макросы. А что делают макросы? Рушат структуру s-выражения! Вместо того, чтобы изначально построить язык на конструкциях с развитой семантикой, создали язык на базе черт пойми чего, чтобы потом это черт знает что побеждать и возвращать в язык семантику.

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

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

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

Когда каждый васян плодит свой язык и этих васянов много, то проект, который пишет несколько человек, превращается в нечитаемый и неподдерживаемый ад

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

защитил свое раб место и знает, что стал незаменим.

Так себе долгосрочная стратегия, если честно.

переписывает проект на питон

Ты же понемаешь, что неподдерживаемую муйню на питоне написать нисколько не сложнее, чем на лиспе. Просто не пиши документацию.

Nervous ★★★★★
()
Последнее исправление: Nervous (всего исправлений: 3)

@byko3y, то декорирование в синтаксисах языков программирования от ЛЕНИ.
Многие не могут и допустить мысль, что struct может иметь и иной формат …

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

защитил свое раб место и знает, что стал незаменим.

Так себе долгосрочная стратегия, если честно

Но у многих лисперов такой подход, по крайней мере подсознательно. Типа «в питоне каждый разберется, а вот творить на лиспе нужно уметь» — вроде как и «я могу выше-быстрее-сильнее», но вроде как и «кроме меня никто так не сможет». Он как бы не договаривает про то, как контора сможет нанимать малоквалифицированных программистов с рынка на грязную работу. Или лиспер единолично будет чистить вилкой кастомную логику для одного заказчика? Нет, он скажет «я выше этого». «Пошел на xyz со своим лиспом» — отвечает ему манагер и нанимает штат более сговорчивых массовых мартышек для переписывания системы на питон.

Посмотри на любого лиспера на LOR — ты увидишь примерно этого недооцененного элитарствующего разраба, который расскажет тебе, сколько рыночек потерял от того, что не нанял его на работу. Но он не расскажет тебе, что 95% рынка программистов не смогут прочитать его код, он только ответит «я легко читаю, там всё просто и понятно». Кложа никогда бы не взлетела на рынке, если бы разраб не поставил четко приоритеты «никаких новых макросов в обычном коде, макросы только в качестве исключения для особо замороченных алгоритмов». Правда, он не подумал, что при таком подходи никаких скобочек не нужно, да и лисп, в общем-то, не нужен — построй на любом синтаксисе язык на персистентных структурах и STM, и никакие макросы не нужны.

byko3y ★★★★
() автор топика

ты дерьмище какое-то придумал, если тебе это девствейтельно нужно, то:

shit = {}
do_stuff = lambda x: x.__settitem__('x', 'y')
do_stuff(shit)
In [15]: import requests

In [16]: def check_ip():
    ...:     return requests.get('https://ifconfig.me').text
...
In [18]: class try_three_times:
    ...:     result = None
    ...:     def __init__(self, fn, args=(), kwargs={}):
    ...:         self.fn = fn
    ...:         self.args = args
    ...:         self.kwargs = kwargs
    ...:     def __enter__(self):
    ...:         for i in range(3):
    ...:             try:
    ...:                 self.result=self.fn(*self.args, **self.kwargs)
    ...:             except: pass
    ...:         return self
    ...:     __exit__ = lambda *_: None
    ...: 

In [19]: with try_three_times(check_ip) as ctx:
    ...: 
    ...:     print(ctx.result)
tz4678 ★★
()
Ответ на: комментарий от tz4678

ты дерьмище какое-то придумал, если тебе это девствейтельно нужно, то...

Зачем здесь контекст манагер вообще?

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

я весь впрос не читал, но осуждаю, потому как явное лучше неявного даже если это противорчеит DRY

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

А что тут не так? Модуль - это просто реализация паттерна Одиночка (Singleton).

~ on ☁️ tz4678@gmail.com took 24s 
➜ cd ~/workspace/                 

~/workspace via 🐍 v3.9.6 on ☁️ tz4678@gmail.com 
➜ echo 'FOO=1' > foo.py

~/workspace via 🐍 v3.9.6 on ☁️ tz4678@gmail.com 
➜ ipython
Python 3.9.6 (default, Jul 14 2021, 05:03:25) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.25.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import foo

In [2]: foo.FOO
Out[2]: 1

In [3]: foo.FOO = 2

In [4]: import foo

In [5]: foo.FOO
Out[5]: 2

In [6]: foo.__setattr__('FOO', 'bar')

In [7]: import foo; print(foo.FOO)
bar

In [8]: class govno: pass

In [9]: import sys

In [10]: sys.modules['this'] = govno()

In [11]: import this  # ничего не напечатает, так как будет взято из кеша

Зачем вообще этот sys.modules трогать? Питон позволяет делать многое… Но в жизни ты тоже можешь в приницпе, что захочешь сделать, но в последствиях для тебя глупо винить Творца

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

у многих лисперов такой подход, по крайней мере подсознательно. Типа «в питоне каждый разберется, а вот творить на лиспе нужно уметь» — вроде как и «я могу выше-быстрее-сильнее», но вроде как и «кроме меня никто так не сможет»

Зочем ви проецируете.

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

построй на любом синтаксисе язык

Лучший синтаксис — это отсутствие синтаксиса минимальный синтаксис. Как в лиспах.

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

Лучший синтаксис — это отсутствие синтаксиса минимальный синтаксис. Как в лиспах

(list (? да ладно) (? прямо-таки совсем минимальный))

byko3y ★★★★
() автор топика

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

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

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

(list (? да ладно) (? прямо-таки совсем минимальный))

(истинно (! так)). Программа состоит из выражений, построенных по одинаковому принципу. Никаких атипичных извращений — всегда список, в котором первой идет функция/макрос/спец. форма, потом аргументы.

А теперь посмотри, к примеру, на жопаскрипт, в который что ни год подвозят еще мешок нового нескучного синтаксиса.

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

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

Re:

upd: А теперь посмотри, к примеру, на жопаскрипт, в который что ни год подвозят еще мешок нового нескучного синтаксиса

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

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

синтаксис русского языка почему-то выглядит намного проще

О да. Именно поэтому школотроны от него непрерывно страдают по 10+ лет жизни и все равно в большинстве своем не осиливают.

Синтаксис лиспа может осилить кто угодно минут за пять.

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

Именно поэтому школотроны от него непрерывно страдают по 10+ лет жизни и все равно в большинстве своем не осиливают

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

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

эти же школотроны языки программирования не могут осилить вообще совсем никак

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

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

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

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

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