Третий подход к for

Sergey ShishkinSergey Shishkin
5 min read

Надо признаться, что пока не могу найти за какой конец нитки тянуть, чтобы распутать весь этот клубок … В попытке выдерживать единую концептуальную схему, кажется, что её автор сконструировал очень сложную систему, слишком “ажурную архитектуру”, на которую вдобавок навешан непродуманный интерфейс, нагружающий менталитет, к которому сам он, безусловно давно привык, а чтобы привыкать к нему другим, надо иметь какую-то специфическую мотивацию. Уверен, что такой формат конвенциальным никогда не станет и уже даже хочется все это бросить и заняться, на самом деле, более оптимальными подходами к программированию. Да, оригинально, в определенном смысле эффективно, да … все работает … но такова суть любой автоматизации, любых реализованных архитектур и интерфейсов и все они расширяющиеся. Фишка, как раз в минимальном базисе … который никак не прощупывется в PicoLosp, кроме, конечно, ячейки-пары и то, как общий принцип, но который, может не так явно акцентированный, имеет место быть в любой другой системе. Но тем не менее … попробую, по крайней мере, пройтись по функциям из LLVM. Кстати, с ассемблером тоже странно. Казалось бы, что сначала должны быть тупо реализованы обертки существующих функций хоста, что-то типа транспилера, а уже на нем спроектирована база для интерпретатора. Но в PicoLisp это реализовано как-то по-своему и в купе с нативными функцями С, все выглядит очень запутанно. Рекурсия рекурсией, но похоже, что когда смешиваешь “нижний” уровень с “верхним”, то точно можно избавиться от лишних концепций, вместо того, чтобы наоборот их плодить. Конечно, я многому научился за полгода активного исследования системы и надеюсь, что что-то ещё пойму в следующие полгода на её примерах, лучший из которых сама её реализация …

А пока, перед тотальным сканированием функций из файла “map”, пройдемся по циклам и условным переходам, что составляет, собственно, суть любых вычислений. А поскольку тот же for из этой категории, то не смотря на то, что функция акцентировалась уж два раза, при сканировании общей лексики и в связи с особым её выделением автора, теперь, в связи с её определением!

   (NIL "for" _For)

src/glob.l

# (for sym 'cnt ['any | (NIL 'any . prg) | (T 'any . prg) ..]) -> any
# (for sym|(sym2 . sym) 'lst ['any | (NIL 'any . prg) | (T 'any . prg) ..]) -> any
# (for (sym|(sym2 . sym) 'any1 'any2 [. prg]) ['any | (NIL 'any . prg) | (T 'any . prg) ..]) -> any
(de _For (Exe)
   (let
      (X (cdr Exe)
         Y (++ X)
         R $Nil )
      (cond
         ((atom Y)  # (for sym 'cnt|lst ..)
            (needChkVar Exe Y)
            (let P (set $Bind (push NIL NIL (val $Bind)))  # [[sym] sym LINK]
               (set P (val Y)  2 P Y)
               (let V (eval (++ X))
                  (if (num? V)  # (for sym 'cnt ..)
                     (unless (sign? V)
                        (set Y ZERO)
                        (loop
                           (? (> (+ (val Y) (hex "10")) V)  # Increment
                              (setq R (& R -2)) )
                           (set Y @)
                           (? (=0 (& (setq R (loop1 X)) 1))) ) )
                     (save V
                        (loop  # (for sym 'lst ..)
                           (? (atom V) (setq R (& R -2)))
                           (set Y (car V))
                           (? (=0 (& (setq R (loop1 X)) 1)))
                           (safe (shift V)) ) ) ) )
               (set Y (val P)  $Bind (val 3 P)) ) )
         ((atom (cdr Y))  # (for (sym2 . sym) 'lst ..)
            (let Sym2 (needChkVar Exe @)
               (needChkVar Exe (setq Y (car Y)))
               (let P (set $Bind (push NIL NIL (val $Bind)))  # [[sym] sym LINK]
                  (set P (val Y)  2 P Y)
                  (let
                     (Q (set $Bind (push (val Sym2) Sym2 (val $Bind)))  # [[sym] sym LINK]
                        V (save (eval (++ X))) )
                     (set Y ONE)
                     (loop
                        (? (atom V) (setq R (& R -2)))
                        (set Sym2 (car V))
                        (? (=0 (& (setq R (loop1 X)) 1)))
                        (set Y (+ (val Y) (hex "10")))
                        (safe (shift V)) )
                     (set Sym2 (val Q)) )
                  (set Y (val P)  $Bind (val 3 P)) ) ) )
         ((atom (car Y))  # (for (sym ..) ..)
            (let Z (cdr Y)
               (needChkVar Exe (setq Y @))
               (let P (set $Bind (push NIL NIL (val $Bind)))  # [[sym] sym LINK]
                  (set
                     P (val Y)
                     2 P Y
                     Y (eval (++ Z)) )
                  (save R
                     (loop  # (any2 . prg)
                        (? (nil? (eval (car Z))))
                        (set $At @)
                        (? (=0 (& (setq R (loop1 X)) 1)))
                        (safe (setq R (& R -2)))
                        (when (pair (cdr Z))
                           (set Y (run @)) ) ) )
                  (set Y (val P)  $Bind (val 3 P)) ) ) )
         (T  # (for ((sym2 . sym) ..) ..)
            (let (Sym2 (cdr @)  Z (cdr Y))
               (setq Y (car @))
               (needChkVar Exe Y)
               (needChkVar Exe Sym2)
               (let P (set $Bind (push NIL NIL (val $Bind)))  # [[sym] sym LINK]
                  (set P (val Y)  2 P Y)
                  (save R
                     (let Q (set $Bind (push (val Sym2) Sym2 (val $Bind)))  # [[sym] sym LINK]
                        (set
                           Sym2 (save (eval (++ Z)))
                           Y ONE )
                        (loop
                           (? (nil? (eval (car Z))))
                           (set $At @)
                           (? (=0 (& (setq R (loop1 X)) 1)))
                           (safe (setq R (& R -2)))
                           (when (pair (cdr Z))
                              (set Sym2 (run @)) )
                           (set Y (+ (val Y) (hex "10"))) )
                        (set Sym2 (val Q)) ) )
                  (set Y (val P)  $Bind (val 3 P)) ) ) ) )
      R ) )

https://picolisp-manual.tiddlyhost.com/#for

Не правда ли нетривиально? Тот случай, чтобы попросить ИИ-бот прокомментировать каждую строку (содержимое в скобках?!), любой бот справляется с этой задачей “на ура” … каждый может привлечь для этого того бота, к которому привык … я для себя, все-таки, даже вытащу все зависимости … И похоже пока не будут разобраны “по косточкам” подобные вещи, не придет понимание авторских замыслов … Попробуйте просто взять обычный материнский язык и на нем построить скобочную конструкцию какого-нибуть содержания толстой книги (не более четырех-пяти уровней вложенности) и потом осознайте как это воспринимается в сознании … То-то и оно! Вот почему трудно ожидать конвенций в этом направлении. Код должен легко читаться не только машинами и гениями, но и людьми, далекими от всяких algol-ов и posix-ов. А что делать, если Вы хотите развивать эко-систему дальше, привлекая других людей. Что станет с системой через поколение? Тут никакие схемы и “инженерный чертежи“ не помогут, кроме самого кода … или данных … неважно! Дальше и глубже этого уже просто некуда. Системы должны быть самописанными, самоописываться … все должно быть определено и определено через конвенциональный интерфейс.

0
Subscribe to my newsletter

Read articles from Sergey Shishkin directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sergey Shishkin
Sergey Shishkin

Всегда чему-то учусь!