Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

描述 Cirru 短期计划 #41

Open
jiyinyiyong opened this Issue · 1 comment

1 participant

@jiyinyiyong
Owner

技术是我想象力被限制的一个方面, 我渴望那背后的事物, 就开始学技术
到现在我感到带着成见去学非常容易走上岔路, 至少对于学习而言是危险的
相应的, Cirru 我正在写的代码也遇到了编程经验相关的问题, 卡住了
界面部分大概可用, 对应存储成 .json 文件, 然后就是求值器的编写.. 卡住了

模块自动刷新

一个我想做的功能是模块的自动刷新, 想法来自于 Live-Coding, 之前提过

做了一些尝试, 我现在计划跑一个主进程, 用来监视文件管理其他进程, 以及汇总
比如运行文件 A, 主进程 Main 会 fork 一个线程 P(A), 并通过消息与 P(A) 交换数据
其间会因为 import 操作而阻塞, 向 Main 请求文件 B 运行的 S(B), 完成后继续运行
A 运行完成时向 Main 返回整个作用域 S(a), 而 B 在 import 时已经完成这个周期
A 和 B 的作用域在各自运行完成时都在 Main 里存一份基于绝对路径的索引

接下来是文件监视, 检测到文件 B 刷新, Main 会 kill 进程 P(B) 重新 fork P(B)
文件 B 重新加载完成后, 向 Main 发消息, Main 会通知父级的 A 更新
更新的内容是重新对 .json 结果的内容进行求值, 完成后通知 Main, 记录并通知父级
这样保证了每个文件被刷新时全体代码都会被刷新



                       Process

                         Main 
                          |                    Process
                          |
                          V
                        start ---> import -----> P(A)
                          |                       |
                          |                       V
      Process             |  <------------------import B
                          V                      
        P(B) <--------- load B
         |                |
         |                |
         V                |                       |
        run               |                       V
         |                |
         |                |
         V                |                       |
    export S(B) --------> |                       V
                          |
                          V
                      callback A  -----------> wake P(A)
         |                |                       |
         V                |                       |
                          |                      run
                          |                       |
                          |                       V
                          | <----------------- export A
         |                |
         V                |                     
                          |                       |
                          |                       V
   reload event           |
         |                |
         |                |
         V                |                       |
        run               |                       V
         |                |
         |                |
         V                |
    export S(B) --------> |
                          |
                          V
                      update A  ------------>  A restart
                          |                       |
                          |                       |
                          |                       V
                          | <----------------- import B
                          |                       |
                          |                       |
                          V                       V
                     found S(B) ------------>  wake P(A)
                          |                       |
                          |                       |
                          |                      run
                          |                       |
                          |                       |
                          |                       V
                          | <----------------- export A
                          |
                          |
                          |
                          V
                        watching

我的目标是大部分代码不动的同时, 我单个文件重新编写, 能只调试这部分代码
比如 Clojure 依赖 JVM 运行的情况, 让 JVM 环境继续跑, 只是重新刷 Clojure 代码

循环依赖问题

文件开始加载前, Main 会标记其路径, 循环依赖会先得到一个 {} 的空作用域
至少在第一次加载时, 问题不会成为死循环, 然后是向父级更新时有循环依赖的问题
我的思路是对每一次更新使用时间标记, 但目前没有去尝试过

增减模块

另一方面, 想想这样的循环依赖可能形成软件运行时动态增减模块的问题
如果软件能在运行的同时, 对其模块逐个完成替换, 这样也是不错的
在我的模型里, 只要 Main 进程不动, 其他模块刷新过程失败也不会造成全体崩溃
那么比方说往正在运行的程序增加模块做探测, 也应该是可以的

去掉模块我还没有尝试, 也许下刷新 Main 里的索引能做到

对象作为函数

虽然大家都不喜欢面向对象, 可我还过不了那一关, 可能因为写 JS 太依赖其方便
所以因为 Object 和 Function 相似的一点是接受参数返回值或能接受值的 Object
于是我考虑在检测表达式头部的类型, 当为对象时作为对象接受参数


set a
  object
    name (string demo)
    vaue (number 1)

a (string name) ;; returns (string demo) => "demo"

set b
  object
    name (string demo)
    value
      object
        name (string demo)
        value (number 1)

b (string value) (string value) ;; returns 1

如果成的话, __proto__this 等等功能可以模仿 JS 搬上去
相对 Lisp, JS 有了原型链相当于优良两个作用域的维度, 能做出一些功能
尽管同时带来的是更多的混乱.. 但还没看到 FP 中那么晦涩的概念

@jiyinyiyong
Owner

失败了.. 犯了想当然的错误, 进程间通信是拷贝一份数据再发送的, 而不是共享内存
这样的话, require 基本上没有意义了.. 最终所有动作都是在主进程跑的
一个测试的 Gist, 对消息的修改只在当前进程有效 https://gist.github.com/4576784
原先我计划每个文件一个教程, 那么有事件循环也可以随着文件的更新而被重启,
如果子进程不能同时跑代码和作为模块提供引用, 我上边这样写意义全没有了

此前考虑过, 如果要自动刷新代码进行 LiveCoding, 文件和数据库修改, 还有事件循环,
这样的不可逆操作在 LiveCoding 里是棘手的, 现在看, 在 JS 上是没法改变了

编辑器部分放了可以跑的两个 Demo, 加载器和解释器部分不知道怎么继续...
http://jiyinyiyong.github.com/cirru-editor-2/page/
http://s.jiyinyiyong.info/cirru-playground/editor/page/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.