比如說private int a = 1等價於private(int, =(a, 1))類似這樣的,實在是不希望一個語言引入過多語法元素,只提供最基本的函數抽象和函數應用的語法就夠了,其他的什麼訪問控制private亂七八糟的東西都用lambda calculus配合monadic calculation實現成函數,美滋滋


我高中寫的語言:https://github.com/lice-lang/lice (注意這個代碼已經頗有年頭了,Kotlin 版本之類的都比較老)

AST 定義:https://github.com/lice-lang/lice/blob/master/src/main/kotlin/org/lice/model/Ast.kt

一些功能測試(可以當成 demo 看):https://github.com/lice-lang/lice/blob/master/src/test/kotlin/org/lice/FeatureTest.kt

可以看到只有四種 AST 類型:Value, LazyValue, Symbol, Expression,其中 LazyValue 可以用 Value 實現(但是要用到 static 的變數,我不喜歡),只是我為了提高性能就寫進了語言。那麼必需的 AST 類型其實就只有三種。

關於 Expression 這個節點:我高中英語不是很好,不知道 argument 和 parameter 的區別,於是本來應該叫 arguments 的東西被我寫成了 params。這個就是函數調用了,然後 Value 其實也可以寫成是 params 為空的 Expression,所以其實 essential 的 AST 類型就只有兩種。

什麼?怎麼可能只有兩種?最簡單的 untyped lambda calculus 都有三個 AST 節點類型(var, lam, app)啊?

因為我高中年少無知,看著感覺 lambda 也可以算是寫成 application 形式的表達式,於是就把 lambda 做成了一個函數……

應該符合題主對最簡語言的 prospect 了。很可惜,這個語言比 Java 慢 20 倍,還一不小心實現成了動態作用域,完全不實用。

Parser 由 @海克斯科技大冰錘 重寫


用 Racket 創建一門只支持 lambda-calculus 的語言就好了。

https://docs.racket-lang.org/guide/module-languages.html

(module lambda-calculus racket
(provide (rename-out [1-arg-lambda lambda]
[1-arg-app #%app]
[1-form-module-begin #%module-begin]
[no-literals #%datum]
[unbound-as-quoted #%top]))
(define-syntax-rule (1-arg-lambda (x) expr)
(lambda (x) expr))
(define-syntax-rule (1-arg-app e1 e2)
(#%app e1 e2))
(define-syntax-rule (1-form-module-begin e)
(#%module-begin e))
(define-syntax (no-literals stx)
(raise-syntax-error #f "no" stx))
(define-syntax-rule (unbound-as-quoted . id)
id))

那些不提供 reader 和 expander 擴展的語言,真是限制想像力。


不過,你確定要拿 lambda-calculus 進行編程么?

我們來(用 邱奇編碼)計算一下 [公式] 吧,看看有多麻煩。

第一步,先把上面那個 module 存到本地磁碟,假設路徑為,

/Users/thzt/Documents/lambda-calculus.rkt

第二步,打開 DrRacket,在 「定義區」 (就是 DrRacket 界面的上半部分) 貼入以下代碼,

然後按 F5 運行,

#lang racket

; 引入剛才那個 module
(require (file "/Users/thzt/Documents/lambda-calculus.rkt"))

; 邱奇數 λf.λx.fx 表示自然數 1
(define one (lambda (f) (lambda (x) (f x))))
; 邱奇數 λf.λx.f(fx) 表示自然數 2
(define two (lambda (f) (lambda (x) (f (f x)))))

; print 對 邱奇數 進行列印
; (print λf.λx.fx) 將列印 xnil,其中包含一個 x,用來表示 1
; (print λf.λx.f(fx)) 將列印 xxnil,其中包含兩個 x,用來表示 2
(define (f x) (display x) x)
(define (print n) ((n f) x) nil)

; 定義 +1 函數為 λn.λf.λx.f(nfx)
(define succ (lambda (n) (lambda (f) (lambda (x) (f ((n f) x))))))

; ---- ---- ---- ----

; 我們來計算 1 + 1 = 2

; 計算 1 + 1,並列印結果
(print (succ one)) ; 將列印 xxnil,包含兩個 x 表示 2
; 列印 2
(print two) ; 也是 xxnil

為了演示方便,本例借用了從 racket module 中導出的 define 和 display,

不然就只有計算機知道 [公式] 了。


In theory, theory and practice are the same.

In practice, they are not.


Wolfram Language 呀,沒有關鍵字,全是函數,語法成分比許多 lisp 還純。


https://en.wikipedia.org/wiki/SKI_combinator_calculus


corn這是我目前在做的一個編程語言。實際上我之前有做過一個叫malt的&編程語言&黑歷史。

目前他的主體部分就是一個預處理器和一個元實現的macro,除基本語法外所有的語法和操作都是由宏構造的,他們會在預處理後被展開為&FPIR&lambda。

這樣做的好處就是你只用寫相當少的代碼生成和代碼分析。

壞處就是你必須寫一個很強大的,針對lambda的優化器,同時原本可上可不上的PE(Partial Evaluation)也會成為必選項。

實際上基本語法也能被展開為lambda,但是由於效率問題我並沒有這麼做(畢竟這玩意還是準備拿來使用而不僅僅是用於理論驗證的)

另外關於你說的語法要素,我想你指的應該是s-expression

PS:另外建議題主去看看smalltalk,應該會有小驚喜


推薦閱讀:
相关文章