如何在 Forth 中对参数进行排序

问题描述 投票:0回答:2

在 Forth 中定义单词时选择参数顺序的一般规则(经验法则)是什么?

例如,在控制几个舵机的情况下,让我们定义

SERVO!
,它将设置舵机通道的位置。

按照

!
的方式,应该是
: SERVO! ( val #ch -- )
,但另一方面,是不是看起来更原生
: SERVO! ( #ch val -- )

arguments parameter-passing coding-style conventions forth
2个回答
9
投票

如何选择参数顺序?好问题!在 Forth 中,这个问题也应该涵盖结果的顺序。

显然任何规则都应该有一定的理由。它们可能是一些基本原则的结果,或者应该解决一些问题。

我认为我们可以从代码重用(任何源代码片段,包括任何单个单词)的方便开始。这种便利的基本形式部分是一致性源代码最小化

关于参数顺序,这些部分具有以下含义。

  • 一致性:在相似的情况下我们应该使用相似的顺序(更正式的是:在相似的情况下保留一些实质性的同构)。
  • 最小化:我们应该选择一个最小化所有源代码的总词法大小的顺序(实际上,正确的顺序应该最小化堆栈操作的总数)。

因此,首先,我们应该与现有约定(或现有代码)保持一致,其次——找到最佳排序。当然,当某些必需的旧代码中已经使用了不一致的约定时,可能会出现例外情况。

一些已知的约定可以在 Leo Brodie 著名的“Thinking Forth”书中找到。其中两个如下。

让地址先于计数。提示 4.18

示例:

ERASE ( addr u -- )

让来源先于目的地。提示 4.19

示例:

MOVE ( source destination count -- )

还有一个众所周知的规则,它不仅是一种约定,也是一种优化(经过实践证实):

让不太持久的争论先于更持久的争论

通常它会减少堆栈操作。这个规则可以在很多标准单词中找到。例如,

WRITE-FILE ( addr u file-id -- ior )
SEARCH-WORDLIST ( addr u wid -- 0 | xt flag )
file-id
wid
addr u
对更持久。更持久的参数往往保存在顶级变量中,因此更容易将它们作为顶级参数传递。示例:
... GET-CURRENT SEARCH-WORDLIST ...

这条规则也隐含地反映在 Leo Brodie 的以下提示中

  • 在确定通过数据结构而不是通过堆栈处理哪些参数时,选择更永久或代表当前状态的参数。 (提示 7.3

如果出现结果,则该规则变得相反。

对于退回的物品,将较永久的物品放在较不永久的物品之前。

例如,

ior
flag
等 — 通常返回到顶部。

变化

在某些情况下,有多种变体会很方便。 例如,众所周知的单词

ROT
-ROT
。其他例子:

\ the different order of input paramenters
for-list-node ( i*x list xt -- j*x )
foreach-list-node ( i*x xt list -- j*x )

\ the different order of output parameters
split ( sd-txt sd-key -- sd-txt false | sd-left sd-right true )
split- ( sd-txt sd-key -- sd-txt false | sd-right sd-left true )

4
投票

您提到的

!
方式可能是最好的,因为在计算您希望伺服器移动到的值时,您不需要在心里记住您正在使用哪个伺服器。

此外,由于它类似于

: SERVO! ( val #ch -- )

(您将一个值存储到伺服器中),并且您将单词命名为

!
,因此如果参数顺序与
SERVO!
相反,将会造成混乱。
    

© www.soinside.com 2019 - 2024. All rights reserved.