这是一个我一直想知道答案的问题,但从未真正问过.
一种语言编写的代码,特别是解释语言,如何被编译语言编写的代码调用.
例如,假设我正在用C++编写游戏,并且我将一些AI行为外包给要用Scheme编写.如何用Scheme编写的代码到达编译的C++代码可用的点?它是如何被C++源代码使用的,它是如何被C++编译的代码使用的?它的使用方式有所不同吗?
我更喜欢使用Lisp变体(Clojure或Scheme的奖励积分)的例子,因为这是我最熟悉的,但任何有关DBC功能性语言的反馈当然对更大的社区都有价值.
这是一个显而易见的方式:
(defn foo [action options]
(when-not (#{"go-forward" "go-backward" "turn-right" "turn-left"} action)
(throw (IllegalArgumentException.
"unknown action")))
(when-not (and (:speed options) (> (:speed options) 0))
(throw (IllegalArgumentException.
"invalid speed")))
; finally we get to the meat of the logic)
Run Code Online (Sandbox Code Playgroud)
我不喜欢这个实现的是合同逻辑掩盖了核心功能; 在条件检查中,函数的真正目的会丢失.这与我在这个问题中提出的问题相同.在像Java这样的命令式语言中,我可以使用嵌入在文档中的注释或元数据/属性来将契约移出方法实现.
有没有人考虑在Clojure中添加合同到元数据?如何使用高阶函数?还有哪些其他选择?
我试图通过fluxus获得一些乐趣,但它的手册和在线文档似乎都假设读者已经是一位从未听说过Scheme的专家网络程序员.因此,您会获得试图解释前缀表示法基础知识的段落,但假设您知道如何将声卡数据传输到程序中,或者设置并连接到OSC进程.
那里有没有相反的教程吗?IE,假设您已经掌握了Lisp/Scheme的功能,但在正确设置声源或OSC服务器之前需要一些指针?
除此之外,有没有人知道如何获得(例如)连接到(fluxus)的系统麦克风,或者如何让它从磁盘播放声音文件?
这是一个lisp过程,简单地将'a'添加到'b'的绝对值:
(define (a-plus-abs-b a b)
((if (> b 0) + -) a b))
Run Code Online (Sandbox Code Playgroud)
我认为这很漂亮,我试图找到用JavaScript编写这个的最好方法.但我的JavaScript代码不漂亮:
var plus = function(a,b) {
return a + b;
};
var minus = function(a,b) {
return a - b;
};
var aPlusAbsB = function(a,b) {
return (b > 0 ? plus : minus)(a,b);
}
Run Code Online (Sandbox Code Playgroud)
主要问题是我不能使用+
和-
符号作为他们真正代表的函数的引用,因为我可以使用lisp.任何人都可以想出更优雅的方式来做这样的事情,或者我是否达到了语言界限?
显然,我可以这样做:
var aPlusAbsB = function(a,b) {
return a + Math.abs(b);
}
Run Code Online (Sandbox Code Playgroud)
,但这更像是一个思想实验,而不是一个实用的问题.
有没有什么方法可以引用JavaScript语言中的核心函数,就像它们是用户定义的一样?
我只是在玩scheme/lisp,正在考虑如何正确地定义我自己的定义average
.我不知道如何做一些我认为必需的事情.
有人有定义的例子average
吗?我似乎不太了解LISP形成一个网络搜索,可以找回我正在寻找的结果.
很长一段时间我对这些术语感到困惑,认为最好问一下它们究竟是什么意思:
A.语法.B.语法价值.C.语法对象.Ds-expression E.datum(在syntax-> datum中)
我发现了一个代码段某处在线:
(letrec
([id (lambda (v) v)]
[ctx0 (lambda (v) `(k ,v))]
.....
.....
(if (memq ctx (list ctx0 id)) <---- condition always return false
.....
Run Code Online (Sandbox Code Playgroud)
其中ctx也是一个函数:
但是我永远不会让test语句返回true.
然后我有以下测试:
(define ctx0 (lambda (v) `(k ,v)))
(define ctx1 (lambda (v) `(k ,v)))
(eq? ctx0 ctx1)
=> #f
(eqv? ctx0 ctx1)
=> #f
(equal? ctx0 ctx1)
=> #f
Run Code Online (Sandbox Code Playgroud)
这让我怀疑两个函数总是不同,因为它们有不同的内存位置.
但是如果可以将函数与其他函数进行比较,我该如何测试两个函数是否相同?如果他们有不同的变量名怎么办?例如:
(lambda (x) (+ x 1))
和 (lambda (y) (+ y 1))
PS我使用DrRacket来测试代码.
在编写使用的宏时syntax/parse
,我创建了一个拼接语法类,用于捕获可能提供给宏的选项.这些选项都是可选的,它们可以按任何顺序提供.使用~optional
省略号头部图案使这很容易:
(define-splicing-syntax-class opts
(pattern (~seq (~or (~optional (~seq #:a a))
(~optional (~seq #:b b))
(~optional (~seq #:x x))
(~optional (~seq #:y y)))
...))
Run Code Online (Sandbox Code Playgroud)
然而,有一个问题:我希望能够到组这些选项分为两组:含组a
和b
,和包含组x
和y
.但是,用户仍可以按任何顺序指定选项,因此对于此示例输入:
(foobar #:b 3 #:y 7 #:a 2)
Run Code Online (Sandbox Code Playgroud)
我希望能够生成以下属性:
first-opts: (#:a 2 #:b 3)
second-opts: (#:y 7)
Run Code Online (Sandbox Code Playgroud)
到目前为止,我已经设法使用手动执行此操作#:with
,但它并不漂亮:
(define-splicing-syntax-class opts
#:attributes ([first-opts 1] [second-opts 1])
(pattern (~seq (~or (~optional (~seq #:a a))
(~optional (~seq #:b b))
(~optional (~seq #:x x))
(~optional …
Run Code Online (Sandbox Code Playgroud) 既然Chez Scheme是开源的,我想知道它在性能方面与Racket和其他方案或语言的比较,以便人们可以在一个项目中做出明智的选择.
不幸的是,我找不到任何相关的基准.
我找到了以下内容:
https://ecraven.github.io/r7rs-benchmarks/benchmark.html
问题:没有Racket或其他语言(更新10/13/18:Chez现在包含在一些基准测试中)
http://www.larcenists.org/benchmarksGenuineR6Linux.html
问题:没有Chez Scheme或其他语言
https://benchmarksgame-team.pages.debian.net/benchmarksgame/
问题:只有Racket,可疑的比较(例如,Python不允许使用Numpy显然有帮助,而Racket正在向GMP发出FFI调用)
因此,我找到的基准测试中没有一个允许您将Racket与Chez进行比较,或者将Chez与SBCL或Java进行比较.是否有Chez基准测试可以让您了解它的速度有多快?
Chez Scheme通常被认为是最快的Scheme/Lisp.我们应该知道它是否比典型的业务逻辑应用程序的Java更快.
scheme ×10
racket ×5
lisp ×3
c++ ×1
chez-scheme ×1
clojure ×1
compilation ×1
interpreter ×1
javascript ×1
macros ×1
mit-scheme ×1
osc ×1