Pull to refresh

Comments 31

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

Я так и не понял, зачем реализовывать параллелизм на asyncio, когда он про конкурентность? А потом это упоминать в PS, тем самым перечеркивая всю статью по сути.
О боже! «Горшочек, не вари!». Остановите кто-нибудь этот «автоматный генератор статей» похожих на написанное человеком.
Самолёты-пауки? Что это? Неужели нельзя было просто оставить «тех.задание» исходного примера, который вы позаимствовали, без изменений? Зачем притягивать за уши «самолёты», на код обычного «паука», который скачивает страницы из интернета?
Зачем вы вообще используете Python? Вы его абсолютно не знаете. Я даже уже сомневаюсь, что вы вообще программировать умеете. Была бы у меня возможность, я бы отобрал у вас питон и не давал пока не попросите прощения изучите его нормально по книгам и документации.
Я ещё в прошлой статье обратил ваше внимание на то, что вы используете в методах классов глобальные переменные. Но вы продолжаете писать абсолютную ересь, доводя её до абсурда. Теперь вы создали 3 одинаковых класса, которые используют внутри своих методов глобальный экземпляр ЭТОГО же самого класса. Как вообще у вас такая идея пришла в голову? Сами же потом оправдываете всё это незнанием языка и указателями (которых вообще в питоне, как языке программирования, нет). Прекратите писать о том, о чём не знаете. Изучите сначала язык, наберитесь в нём опыта, и только потом показывайте на публику свой код на нём.
И что вы вообще пытаетесь доказать своими статьям? Что автоматы — это какое-то лучшее решение чем async/await?
Только вот реализация async/await в питоне, в своей основе, сделана на генераторах. Генераторы — это просто синтаксический сахар для удобного написания итераторов. Итератор — это самый настоящий автомат. Генераторы позволяют проще писать и понимать код такого автомата, т.к. этот код не размазывается без необходимости по нескольким методам класса.
В итоге получается что код с async/await — это автомат. Просто он записан более понятным для людей образом без лишней «воды» в коде.
О боже! «Горшочек, не вари!».
Давайте снизим накал эмоций…
Как вообще у вас такая идея пришла в голову?
Вот так — взяла и посетила :)
Но, если серьезно. Я в прошлый раз Вас поблагодарил, т.к. Вы, действительно, мне помогли, подтолкнули к пониманию Python. Хотелось бы, чтобы мы такие приятные моменты приумножали :)
Скажу спасибо и в этот раз. За стимул :) Мне пришла в голову еще одна идея. Вот как она выглядит в коде:
Заголовок спойлера
import time
automaton = []

class PSleep:
    def __init__(self, t, p_FSM): self.SetTime = t; self.nState = 0; self.bIfLoop = True; self.p_mainFSM = p_FSM
    def x1(self): return time.time() - self.t0 <= self.SetTime
    def y1(self): self.t0 = time.time()
    def loop(self):
        if (self.nState == 0): self.y1(); self.nState = 1
        elif (self.nState == 1):
            if (not self.x1()): self.nState = 4

class PBSpider:
    def __init__(self, name, sleep):
        self.nState = 0; self.bIfLoop = True; self.site_name = name; self.page = 1; self.n_sleep = sleep
    def x1(self): return self.page < 4
    def y1(self):
        self.bIfLoop = False;
        self.b_sleep = PSleep(self.n_sleep, 0)
        automaton.append(self.b_sleep);
        self.b_sleep.p_mainFSM = automaton[ind]
    def y2(self): print(self.site_name, self.page)
    def y3(self): self.page += 1
    def y4(self): self.page = 1
    def loop(self):
        if (self.x1() and self.nState == 0):  self.y1(); self.nState = 1
        elif (not self.x1()  and self.nState == 0): self.y1(); self.y4(); self.nState = 33
        elif (self.nState == 1): self.y2(); self.y3(); self.nState = 0

class PAirplane:
    def __init__(self, name, n):
        self.obj = PBSpider(name, n);
        automaton.append(self.obj)

PAirplane("Blog", 1)
PAirplane("News", 2)
PAirplane("Forum", 2)

start = time.time()
while True:
    ind = 0;
    while True:
        while ind < len(automaton):
            if automaton[ind].nState == 4:
                automaton[ind].p_mainFSM.bIfLoop = True
                automaton.pop(ind)
                ind -=1
            elif automaton[ind].bIfLoop:
                automaton[ind].loop()
            elif automaton[ind].nState == 33:
                print("{:.2F}".format(time.time() - start))
                exit()
            ind += 1
        ind = 0


Здесь я учел Ваши пожелания. Теперь уже ОДИН класс и глобальных переменных меньше. Открою даже свой небольшой секрет — на С++ я вообще не использую глобальных переменных. Их вред мне известен и понятен. И с повторами кода на С++ у меня тоже нормально ;)
По поводу знаний… Да, я не очень знаю Python. Наверное, в сравнении с Вашим опытом и знаниями так от слова совсем ;) И когда получаю дельные советы и помощь, то весьма благодарен…
И я не то, что сомневаюсь, а фактически уверен, что Вы не понимаете автоматы. Но как-то не укоряю Вас за это. Да и развеять на этот счет мое мнение можно достаточно просто — нарисуйте граф автомата генератора. Получится — тогда я извинюсь за свою самоуверенность.
Т.е. давайте от эмоций переключимся на деловой стиль общения.
А так еще раз спасибо. Хотя Вы и не подсказали, но Ваш «толчок», видимо, повлиял на идею, которая меня и посетила в этот раз. Хотелось бы узнать Вашу оценку ее.

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


Теперь у вас глобальная переменная automaton, и бесполезный класс PAirplane с сайд-эффектом в конструкторе (он меняет переменную automaton). Мне казалось что "класс ради класса" это особенность разработчиков на C# (там по другому нельзя) и в Java тоже любят всё делать классами, но даже в этом случае конструктор с сайд-эффектом — это привилегия новичков.
И ещё есть хитро спрятанная глобальная переменная ind, которая не первый взгляд просто какой-то счётчик внутри "event-loop-а", а на деле оказывается используется внутри метода класса PBSpider. Даю вам 5 балов за навык "минирования кода".
И ещё +1 бал за константы 4 и 33 для поля nState. Они мне нравятся, надо бы тоже почаще их везде пихать. Ещё я люблю 7. Я ведь могу в вашем коде поменять 4 на 7? Мне лично так понятнее будет, а то я 4 обычно для других целей использую.
Вы не добавили поле p_mainFSM в класс PBSpider, но при этом используете его в "евент-лупе". Но я вас понимаю — там же есть волшебная константа 4, которая железобетонно гарантирует, что мы сейчас имеем дело с экземпляром PSleep. Ведь все знают, что нельзя использовать 4 как значение состояния в других "автоматах" кроме PSleep.


В ваш код на C++ я даже не стал детально вникать. Для начала там где-то за кадром есть какой-то непонятный ВКП(а). Интернет предложил мне только "Всесоюзная Коммунистическая Партия".
Далее там какая-то шифровка в виде массивов двухсимвольных строк. И нет кода для его декодирования.
Ну и по мелочи — непонятно от куда взявшийся метод pFAwaitSleep->FCall(), которого нет в классе FAwaitSleep.


Что значит "блок схема генератора"? А какая блок схема у автомата? Абстрактного автомата.

Снимаю своё замечание про метод FCall — не заметил, что у класса есть базовый класс.

То-то же… А то я уж, каюсь, плохо про Вас подумал :)
Вот еще великолепный вариант:
Заголовок спойлера
import time

class PSleep:
    def __init__(self, t):
        self.bIfLoop = True; self.p_mainFSM = 0; self.nState = 0;
        self.SetTime = t;
    def x1(self): return time.time() - self.t0 <= self.SetTime
    def y1(self): self.t0 = time.time()
    def loop(self):
        if (self.nState == 0): self.y1(); self.nState = 1
        elif (self.nState == 1):
            if (not self.x1()): self.nState = 666

class PBSpider:
    def __init__(self, name, sleep, p_evl):
        self.p_EventLoop = p_evl; self.bIfLoop = True; self.p_mainFSM = 0; self.nState = 0;
        self.site_name = name; self.n_sleep = sleep
        self.page = 1;
    def x1(self): return self.page < 4
    def y1(self):
        self.bIfLoop = False;
        self.b_sleep = PSleep(self.n_sleep)
        self.p_EventLoop.automaton.append(self.b_sleep);
        self.b_sleep.p_mainFSM = self.p_EventLoop.automaton[self.p_EventLoop.ind]
    def y2(self): print(self.site_name, self.page)
    def y3(self): self.page += 1
    def y4(self): self.page = 1
    def loop(self):
        if (self.x1() and self.nState == 0):  self.y1(); self.nState = 1
        elif (self.nState == 1): self.y2(); self.y3();   self.nState = 0
        elif (not self.x1()  and self.nState == 0):      self.nState = 666

class PAirplane:
    def __init__(self, name, n, p_evl):
        self.p_EventLoop = p_evl
        self.obj = PBSpider(name, n, self.p_EventLoop);
        self.p_EventLoop.automaton.append(self.obj)

class PEventLoop:
    def __init__(self): self.automaton = []; self.ind = 0
    def add(self, p_tsk):
        self.automaton.append(p_tsk);
    def run_until_complete(self):
        while True:
            if len(self.automaton) != 0:
                while self.ind < len(self.automaton):
                    if self.automaton[self.ind].nState == 666:
                        if (self.automaton[self.ind].p_mainFSM != 0):
                            self.automaton[self.ind].p_mainFSM.bIfLoop = True
                            self.automaton.pop(self.ind)
                            self.ind -= 1
                        else:
                            self.automaton.pop(self.ind)
                            self.ind -= 1
                    elif self.automaton[self.ind].bIfLoop:
                        self.automaton[self.ind].loop()
                    self.ind += 1
                self.ind = 0
            else: break;

start = time.time()

evl = PEventLoop()

PAirplane("Blog", 1, evl)
PAirplane("News", 2, evl)
PAirplane("Forum1", 3, evl)
PAirplane("Forum2", 3, evl)
PAirplane("Forum3", 3, evl)
PAirplane("Forum4", 3, evl)

evl.run_until_complete()

print("{:.2F}".format(time.time() - start))
exit()


Здесь уже учтено:
1. Заключительное состояние одно и номер его «тьфу-тьфу» — 666
2. Введен класс PEventLoop, содержащий все что нужно для управления процессами-автоматами, т.е. список автоматов — automaton и их индексация — ind.
3. Цикл работает до тех пор пока не отработают ВСЕ процессы (раньше рубилось по первому закончившему работу)
4. Печать времени вынес за цикл (а то, действительно, неудобно как-то ;))
Немного напрягает меня передача ссылки на объект PEventLoop, но пока так.
Работает так, как надо — параллельно. В последнем приведенном примере при увеличении числа процессов (а времена у них замечу тоже разные) время их работы не увеличивается. Класс!
Что значит «блок схема генератора»? А какая блок схема у автомата? Абстрактного автомата.

Я сказал блок-схема? :( Я попросил граф автомата. Автомат имеет несколько типовых способов описания — граф, таблица переходов, матричное описание… Блок-схемы среди них НЕТ. Я рисую обычно граф, как наиболее понятную и известную форму (см. графы в статье).
Если, как Вы утверждаете, генератор это автомат, то «пли-з-з-з» его граф. Он его должен иметь по определению. Как-то так… :)
А Вам еще раз спасибо! Вы меня стимулируете. Так, глядишь, и питон освою хоть немного;)
А то все тут некоторые — «минусы-минусы-минусы» Они ж мне, как слону дробина! :) Тьюфу на них (и на минусы, кстати, тоже)!:) Не интересно :(

Говоря про "абстрактный" автомат, я типа намекнул, что неплохо бы добавить конкретики. Какого именно генератора? Что он должен делать? А не просто "граф генератора", как будто у любого генератора и автомата есть граф по умолчанию.
Я могу показать вам код sleep в виде генератора. Думается мне что граф у него точно такой же как у вашего PSleep, зато читается и понимается в разы проще, и кода у него сильно меньше:


import time

def sleep(secs):
    end = time.time() + secs
    while time.time() < end:
        yield

# Имитация примитивного евент-лупа (без евентов)
queue = [sleep(10), sleep(5)]
while queue:
    iterator = queue.pop(0)
    try:
        # То же самое, что вызов метода .loop() у ваших автоматов
        next(iterator)
        # Возвращаем "корутину" в конец очереди
        sleeps.append(iterator)  
    except StopIteration:
        # "Автомат" завершил свою работу, не возвращаем его в очередь
        pass

А вот так он будет выглядеть если его сделать без "сахара":


class Sleep:
    def __init__(self, secs):
        self._end = time.time() + secs

    def __next__(self):
        if time.time() >= self._end:
            raise StopIteration

queue = [Sleep(10), Sleep(5)]
...

Согласитесь — это практически тоже самое, что ваш PSleep. Можете даже вынести проверку условия в отдельный метод и назвать его x1(), если вы пишете код лично для себя.

Опечатка в коде. Вместо
sleeps.append(iterator)
надо
queue.append(iterator)

Так, да не так ;) Мне кажется, что Вы немного слукавили… Интересно посмотреть на полное решение. Объясню почему. Больше всего времени мне пришлось потратить не на сами автоматы, а на реализацию вложенной работы автоматов. А как здесь это будет выглядеть? Здесь по аналогии это надо, наверное, назвать вложенными корутинами. Т.е. в нашем случае мы имеем параллельную работу пауков. В моем случае — автоматов, в Вашем — корутин. Отдельный автомат-паук вызывает задержку-автомат, т.е. вкладывает в себя, и пока она работает — стоит. Задержка отрабатывает, удаляется, — автомат продолжает работу. Вот как-то так.
Просто по отдельному процессу-задержке судить сложно да и, думаю, нельзя.
У автомата есть состояния. Они имеют конкретные имена. В каком состоянии находится процесс можно подсмотреть со стороны и засинхронизироваться с ним. Как с этим?
У автомата есть дискретное время, которым можно управлять, замедляя, ускоряя процесс. Здесь как? И речь даже не о времени отдельного автомата, а о дискретном времени их множества, т.е. о сети автоматов…
Вот что вызывает вопросы, когда говорим об автоматах…

Как я понял, у вас автоматы напрямую взаимодействуют с неким внешним "планировщиком". Как минимум добавляя в него новые автоматы, результат которых им нужен.
В случае с корутинами предполагается, что сами они не работают напрямую с евент-лупом, а просто возвращают некий future-like объект (или promise). И евент-луп не вернёт управление исходной корутине пока не будет завершено выполнение этой future (а если точнее, то возврат управления — это просто callback прописанный внутри future). Future — это по сути "состояние автомата", которое имеет как минимум три значения: выполняется, завершено, ошибка. Переход из одного состояния в другой выполняется путём "внешнего воздействия" на future. И в него можно добавить callback-и на завершение и ошибку. По моему это примерно тоже самое, что у вас делается с помощью pFAwaitSleep->FCall().
И мне почему-то кажется, что future — это результат, который получился из попыток унифицировать и упростить работу с автоматами в том виде как это реализовано у вас. Евент-луп работает с future-объектами, а что там за ними стоит, какие калбяки они вызывают — это не его забота.


Фактически вся внутрянка, на которой работает асинхронный код — это всё автоматы. А за счёт специальных языковых возможностей (async/await), у программиста есть возможность писать короткий, легко читаемый код в "синхронном" стиле. В принципе можно писать код без async/await, и явно оперировать с Future-ами. Но это не удобно и порождает сильно вложенный код и callback-hell.


Согласен, что возможность отследить состояние автомата в явном виде — это удобно в некоторых случаях. При желании можно и в корутинах отслеживать статус, но он не будет обязательным для работы самой корутины, а просто как некая мета-дата. Но обычно в этом случае используют "примитивы синхронизации" (которые, наверное, тоже автоматы). Они позволяют синхронизировать разные "задачи" без использования "магических констант" и нарушения инкапсуляции, когда код снаружи "автомата" почему-то знает о его внутренних статусах.


PS: На самом деле меня не коробят ваши автоматы в C++. Пишите на нём как вам удобно. Больше всего меня задело, то что вы не зная Python пишите на нём совершенно некорректный код. А потом ещё и делаете какие-то выводы на его основе, и даже местами сравниваете с C++. Не надо так. Пишите на C++, и мне будет всё равно. Я наверное даже читать не буду, т.к. я давно на нём не пишу и не планирую в будщем.

Фактически вся внутрянка… — это всё автоматы
В этом есть 100%-я уверенность, что это не так. Иначе это как-то вылезло бы в наружу и уж я бы их распознал.

А за счёт… есть возможность писать короткий, легко читаемый код в «синхронном» стиле.
Я не буду спорить, что он читается легче. Когда-то и сам так писал, да и сейчас методы автомата пишутся в этом же стиле. Это норм. А вот на уровне самого алгоритма этот «синхронный» стиль меня не устраивает. В двух словах не скажешь. На эту тему все мои предыдущие статьи.
Согласен, что возможность отследить состояние автомата в явном виде — это удобно в некоторых случаях.
В автоматном программировании (АП) это элементы естественного состояния программы. И потребоваться могут в любой момент. Мне не надо даже задумываться — беру и пользуюсь. А все эти «примитивы» это те же «костыли», о которых я пишу. Вот с чем не хочется связываться.
PS: На самом деле меня не коробят ваши автоматы в C++.
Главное, что они не коробят меня :)
… не зная Python пишите на нём совершенно некорректный код.
Ну, не знаю — узнаю. Уже сейчас я больше знаю, чем пару дней назад :) По поводу некорректности. Если питон не выдает ошибок, то в чем тогда некорректность? В корявости? Дело наживное. Последний код намного приличнее, чем первый из статьи. Еще можно что-то скрыть через наследование, как сделано в С++. Но есть ли оно у объектов питона? Думаю в Вашей, с чьей-то помощью или сам, но разберусь. Если нет (наследования), то по мне и так сойдет. Питон пока не мой основной язык. Но бросать его пока не планирую. Жизнь устаканит… Тут вот она еще один язык подсовывает :( Нежданно… Освоим… В дополнение к С++ и питону;)
В ваших статьях бывает, что поднимаются интересные проблемы, но ваш код читать очень сложно вне IDE. Когда я был маленький, меня били за переменные с незначащими именами, особенно однобуквенные. Ну и гоняться за скоростью на питоне — это какое-то неочевидное решение :)
Когда я был маленький, меня били за переменные с незначащими именами
Ну, за такое, может, и надо. Но только надо знать, конечно, меру… :)
У меня нет однобуквенных имен переменных. Если речь об «иксах» и «игреках», то, во первых, они пронумерованы. Во-вторых, имеют следующий вполне конкретный смысл. У автомата есть множество входных каналов и выходных. Входные — иксы, выходные — игреки. Каждый их номер — это номер соответствующего канала. На структурном уровне — это также «черный ящик» с множеством каналов…
Когда-то я тоже хотел подобные имена сделать более одушевленными. Но потом отказался от этой идеи. Это было сделано несколько вынужденно, но теперь уверен, что так оно даже лучше. Мне, как минимум. Может, потому, что маленьким меня за подобное не наказывали ;)
А за оценку идей — спасибо!

А если каналов будет 20? А если 50? И вы впервые видите этот код, а вам надо оперативно что-то исправить. А представитель заказчика (как назло) объясняет свою проблему обычными словами, а не блок-схемами на которых указаны правильные иксы и игреки. А блок-схему для этого кода почему-то не нашли (наверное автор её забрал с собой, когда увольнялся).
И конечно же автомат достаточно сложный. Его код минимуму на 3 экрана растягивается по высоте. Одним взглядом сразу не окинуть, и не увидеть что метод y25() вызывается не по тому условию. Там почему-то используется x23(), а надо x24() (наверное дети какие-то писали, которые не знают прописные истины).
Но это я слишком сильно далеко заглянул в будущее. Вы в этом время скорее всего ещё только запускаете дебагер, что бы по шагам разобраться в том как работает этот автомат, и у вас впереди есть один или даже два интересных дня, что бы это сделать. Что-бы заново нарисовать блок-схему и уже в ней найти ошибку, т.к. просто смотря на код её не увидеть.

А если каналов будет 20? А если 50?
Зашито до 32-х. Дальше — паника! :) Но вот сколько использую, но этого числа — за глаза! По входу обычно до 7-10, по выходу может максимум раза в два-три раза больше…
Одним взглядом сразу не окинуть
Логика — тьфу — это таблица переходов. А это десять плюс-минус строк. Рисуем — пять сек. Методы, как правило, небольшие. Классы, как видите, как правило, тоже не очень большие. Отлаживаются — на раз. Дальше только используй, т.к. все «заковано» в библиотеку отлаженных и проверенных не раз процессов. Отладка — все просто и понятно, как ясный день. Потоков — нет (тьфу-тьфу не накаркать бы)! Красота!
Короче — автоматная технология проектирования «панимашь»! Все отточено и выверено годами жесткой практики :)

Хорошо, когда всё "обычно" и не выходит за рамки того "как правило". Но в проектах, над которыми работают несколько человек, которые при этом периодически меняются, лучше на это не надеяться. Кто-нибудь обязательно запилит автомат, который упрётся в лимит "32", и засунет в него всю бизнес-логику приложения. И будет он занимать 1000+ строк.
Хотя это конечно ваше дело, видимо вы или совсем не работали в команде. Или делали небольшие приложения, которые вы лично и поддерживали, и вам не приходилось каждые полгода объяснять новым членам команды, что означают все эти иксы и игреки. И в каком именно игреке надо искать код, который нужно поправить для решения задачи. Можно даже найти плюс в таком подходе, не надо ломать голову над одной из сложнейших задач программирования — придумывание названий.
Для меня же ваш код выглядит как результат работы обфуксатора или минимайзера. Там примерно такие же названия функций из 1-2 символов.

Работал и один, и в команде, и руководил командами. Мозги у программеров сначала кипят, но затем модель быстро воспринимается и работается легко и просто. Для этого даже стандарт на автоматное проектирование был создан. Есть даже ГОСТ чем-то весьма похожий на него — P-схемы программ. От него, кстати, и отталкивались…
Кто-то просто так не запилит. Если упрется, то это или исключительный случай или чел просто тупит и не понимает как процесс разбить на множество небольших автоматов. Дальше так: не может — научим, не хочет — заставим. Если конечно не безнадежный случай ;)
Вот даже Вы сказали — сложнейшая задача. Здесь она упрощается. Конечно, нужно знать, что значит каждый вход/выход автомата. Но это загоняется не в имя предиката/действия, смысл которого чуть погодя совсем забывается, а в осмысленный комментарий к нему и в правильное документирование программы, которое в случае автоматов более осмысленно, чем для блок-схем.
Есть плюсы и минусы в отделении логики от текста предикатов. Но плюсов больше. Особенно, когда надо разобраться/вспомнить как оно/она работает ;)
О! Чуть не забыл. Кроме питона есть и MATLAB, а в нем — Stateflow — автоматное проектирование. Признано многими и крутым и весьма эффективным. Используется по всему миру и, думаю, в проектах любой сложности.
Вот читаю листинг «Читаем и пьем чай асинхронно на Python» — вот зачем явные проверки state (причём сравнение с магическими числами) и вызовы нумерованных методов? Почему не задать таблицей, которая и породит экземпляр класса с нужными методами? Питон такие вещи позволяет, и это на фоне общей производительности интерпретатора, не очень дорого по памяти и времени.
Это типичный подход к реализации/имитации логики автомата. А нумерованные методы? Я уже пояснил. Я не ломаю голову над его названием, а поясняю в комментах (если, конечно, есть время и желание :)) к предикату/действию. Но в целом отделение логики от содержимого методов удобнее для понимания программы. Мне — точно.
Ну а таблица? Надо посмотреть. В С++ у меня таблица переходов. Это очень удобно и по большому счету правильнее, т.к. в точности соответствует таблице переходов автомата.
Гляньте pytransitions, там просто дёргаем по имени перехода. Можно назвать все переходы одинаково. например, next, тогда в цикле дергаем next. Асинхронные вызовы поддерживаются.

Что-то мало минусов поставлено статье на мой взгляд.

Что-то мало минусов

А на мой взгляд, так «шрамы только украшают мужчину»! :D
UFO just landed and posted this here
Автор отвечает… :)
1) Меня категорически не устраивают существующие технологии программирования. У меня автоматное параллельное мышление. По-другому уже не то, что не могу, — не хочу. Вот такой я «иносранец».
2) Шайтан попутал :) Смотрю народ от корутин тащится, которые (сопрограммы) я отринул много лет тому назад. И чего они в них нашли, думаю? ;) Вот так на питон и вынесло. Поначалу, чуть было не зацепило за Котлин, но… не сложилось как-то.

А С++ ни куда не денется, видимо. Теперь хоть немного в теме, что творится помимо него. А то уж совсем было скучно стало… Чтобы совсем не закиснуть решил задокументировать свои идеи и народ повеселить ;) Правда, тут уже наклевывается веселуха, т.к. что «горшочек», похоже, будет варить уже не так активно. Накликали, похоже… ;)
На чистый С не реагирую в принципе после того, как увлекся объектами, т.е. С++.
И Вы думаете, что меня будут интересовать корутины в С, если есть у меня автоматы и С++? Только как экзотика. ;)
Объекты сильно переоценивают :)
Скорее, кто их не использует — сильно недооценивает ;) Это просто уже другое мышление. А если еще объекты активные, то совсем красота!
UFO just landed and posted this here
Речь даже не о языке, а о сути, которую он выражает и реализует. Корутины ограничены в своих возможностей вне зависимости от того, на каком языке они реализованы. Это не вычислительная модель, как те же потоки. Здесь можно со мной спорить, но есть теория, а она на стороне автоматов.
Sign up to leave a comment.

Articles