在BQN中设计一个套娃结构
Scheming a mise-en-abîme in BQN

原始链接: https://panadestein.github.io/blog/posts/si.html

这段BQN代码定义了一个Scheme解释器,它部分遵循R5RS标准。由于布尔值表示的限制,需要一个“1-修饰符”。解释器采用基于类的途径(使用`C`函数)来管理Scheme环境,其中包括实现为BQN函数的原始函数。 解释器本身实现为一个“1-修饰符”(`_sch`),允许通过不同的全局环境进行定制。此实现侧重于Scheme的一个子集,包含基本的元编程元素。 核心功能包括:标记化(`T`)、解析(`R`)、环境查找/执行(`E`)和字符串表示(`P`)。一个显著的限制是它继承自其基础文章的粗略错误处理。缺少'L'(循环)函数意味着单个读取-求值-打印执行周期,而不是交互式REPL。虽然BQN实现提供了比参考Scheme示例更广泛的功能集,但它的代码行数明显更多。

Hacker News new | past | comments | ask | show | jobs | submit login Scheming a mise-en-abîme in BQN (panadestein.github.io) 50 points by todsacerdoti 1 day ago | hide | past | favorite | 1 comment cluckindan 4 hours ago [–] One way ticket to job security, please. reply Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact Search:
相关文章
  • 在BQN中设计一个套盒结构 2025-05-26
  • 2025-05-26
  • 2025-05-26
  • 认知:一种新的反语法语言重新定义元编程 2024-05-03
  • 菱形语言 2025-03-18

  • 原文

    Our goal is to adhere to the Revised\(^5\) Report on the Algorithmic Language Scheme (R5RS). However, seasoned schemers will quickly notice that our implementation still has quite some distance to cover in reaching full compliance.

    Let's start by defining some utilities. One aspect I don't like about Scheme is that it uses special values for Booleans, so we unfortunately need the 1-modifier. The function, on the other hand, is a fine example of the minimalistic OOP features BQN provides. It is used to create a class for the environment used in the Scheme interpreter.

    _bool ← {𝔽◶"#f"‿"#t"}
    C ← {𝕨𝕊p‿v:
      o‿h ⇐ 𝕨 ⋈ p •HashMap v
      F ⇐ {h.Has 𝕩 ? h; @≢o ? o.F 𝕩; 0}
    }
    

    We then define a global environment (instance of the C class) with the Scheme primitives of the target subset, expressed as BQN functions:

    env ← @ C ⟨
      "sin", "cos", "tan", "asin", "acos", "atan"
      "log", "+", "-", "*", "/", ">", "<", ">=", "<=", "="
      "abs", "append", "apply", "begin", "car", "cdr", "cons"
      "eq?", "expt", "equal?", "length", "list", "list?"
      "map", "max", "min", "not", "null?", "number?"
      "print", "round", "symbol?", "nil", "pi"
    ⟩ ⋈ ⟨
      ⋆⁼, +´, -˜´⌽, ×´, ÷˜´⌽, >´, <´, ≥´, ≤´, =´
      |, ∾´, {𝕎𝕩}´, {∾𝕩}, ⊑∘∾, 1⊸↓∘∾, <⊸∾´
      ≡´_bool, ⋆´, =´_bool, ≠∘∾, ⊢, (0=•Type∘⊑)_bool
      {𝕎∘⋈¨𝕩}´, ⌈´, ⌊´, 0⊸≠_bool¬, @⊸=_bool, (1=•Type∘⊑)_bool 
      {𝕩}, ⌊0.5+⊢, 2⊸=_bool{•Type⊑∾𝕩}, @, π
    ⟩ ∾˜ •math •ns.Get¨ "sin"‿"cos"‿"tan"‿"asin"‿"acos"‿"atan"
    

    The interpreter is defined as a 1-modifier. This gives us the flexibility to create different subsets of the language by changing the input global environment:

    _sch ← {
      T ← " "⊸≢¨⊸/·(-⟜1·+`·¬⊸∧⟜»⊸∨·+˝"( )"=⌜⊢)⊸⊔(⊢+22×@=10-˜⊢)
      R ← {
        𝕊⟨⟩: "Empty program"!0;
        𝕊𝕩: {
          "("≡⊑𝕨 ? l←⟨⟩ ⋄ l⋈1↓{t‿ts: ts⊣l∾↩<t}∘R•_while_(")"≢⊑) 𝕩;
          ")"≡⊑𝕨 ? "Unexpected )"!0 ;
          𝕩 ⋈˜ •ParseFloat⎊⊢ ⊑𝕨
        }´ 1(↑⋈↓)𝕩
      }
      E ← 𝕗⊸{
        0≠𝕨.F 𝕩 ? (𝕨.F 𝕩).Get 𝕩;
        1=•Type⊑⟨𝕩⟩ ? 𝕩;
        𝕨𝕊"quote"‿arg: arg;
        𝕨𝕊"quasiquote"‿arg: 𝕨{"unquote"≡⊑𝕩 ? 𝕗𝔾1↓𝕩; (2≤≠)◶⊢‿(𝕊¨)𝕩}𝕊arg;
        𝕨𝕊"if"‿tst‿cnd‿alt: 𝕨(⊣𝕊𝕊◶alt‿cnd)tst;
        𝕨𝕊"define"‿var‿val: ⟨⟩ ⊣ var 𝕨.h.Set 𝕨𝕊val;
        𝕨𝕊"lambda"‿par‿bod: 𝕨{bod 𝕘˜ 𝕗 C par‿𝕩}𝕊;
        f ← 𝕨𝕊⊑𝕩 ⋄ F 𝕨⊸𝕊¨1↓𝕩 
      }∘⊑
      P ← "-(@  )" {'@'⊸≠⊸/·(⊢+˝(𝕗-𝕘)×𝕘=⌜⊢)∘•Repr·1⊸=∘≠◶⊢‿⊑(0<≠¨)⊸/⎊⊢} "¯⟨"",‿⟩"
      P∘E∘R∘T 𝕩
    }
    

    And now for the climax. Our interpreter inherits all the limitations of the one in the reference essay, the most critical being the lack of proper error handling. Additionally, as the names of the functions inside the modifier suggest, an L is missing to complete the Read → Eval → Print loop. In terms of golfing statistics, lispy has 117 non-comment non-blank lines, whereas Scheme has only 43. Ours, however, is a larger subset, because we include the basic metaprogramming building blocks.

    联系我们 contact @ memedata.com