guenchi / CSUG

Chez Scheme Version 9 User's Guide - Zhcn
https://guenchi.github.io/CSUG
Apache License 2.0
61 stars 16 forks source link

term modification request: parameter fixnum #16

Closed xashes closed 5 years ago

xashes commented 5 years ago

这里只是针对 @flowingfirefly 同学提出的术语的一点小的异议,以下说一点我的小想法,不一定对。

如果仅讨论parameter作为参数化过程的这个“特殊”情况,它虽然与通常所指的过程参数感觉不同,但仍然是一种向环境中注入参数绑定的方式,词意上并没有不同,只是范围更加灵活,可以全局化,也可以通过parameterize等过程任意界定参数的作用域。(如果通过eval过程求值,把eval的第二个environment参数设为其他环境,可以使这些绑定失效,也验证了这类过程只是向当前环境注入绑定,所以在某些场合译作“环境参数”似乎可以,当然,也有些场合译成某某“过程”可能更好。)

所以可能没有必要把这个术语特殊化,parameter在这里并没有超出它的本来意义,r6rs中使用parameter这个词的地方很多,1.7.中作为过程参数,6.2.中作为形式参数而把argument作为实际参数,以及A.9.中显式写明formal parameteractual parameter。本意都是参数,所以根据不同的上下文,仍译为参数,加上不同的“形式”或“作用域”修饰应该已经很灵活也很符合习惯。虽说此处讨论的是一个过程,可也并不特殊,过程句法,let句法也都隐含着绑定注入,其中是进行了参数绑定还是变量绑定,本质都一样,根据环境选择用词,也并不会使人迷惑,似乎也没有必要为此使用偏离习惯的写法。一如scheme并没有采用一个新词,而对这个过程仍然称为parameter

其实我觉得,(环境)参数应该是参数更泛化的存在,而通常习惯指代的过程参数,形式参数等倒是限定作用域或形式之后的特殊情况。另外,把它作为一个固定的术语,我也不确定是否合适,我姑且提交为“环境参数”,如果不合适的话,就请不要合并这个PR了。

第二个关于fixnum的修改提议,因为不是fix数的值,而是其二进制表示的位数长度,似乎译成“定长数”更贴切一点。

因为是对别的同学的成果提出修改意见,所以为了把理由说清楚,只好把自己的看法不论对错都说出来,以方便讨论,一个小话题写了这么多,里面理解肤浅和谬误的地方,请你们多多指点。

ghost commented 5 years ago

谢谢 @xashes 提出的意见,我很喜欢这种探讨的氛围 :smile:。

因为同样的词在不同语境下意思可能不一样,就像字典中那样,同样的词,可以定义多重意思。 我觉得术语的翻译也应如此,我提议以后在翻译术语时,如果确实表达的不是同样一个意思, 那可以写成 术语1 意思1,意思2 ...

关于 fixnum 我翻译为固定数,是因为之前我接触到它时,就自己这样直译了一下 –– “固定的数”, 方便一点,但的确会造成误解,不能见名知意,需要读者将“固定数”这个符号与它的意思在脑子里 绑定一下才行。

关于 parameter 我将它译为 “行为界限”,是因为在 spec 中一般不会对有些行为定义的十分细致, 而且还有许多实现者自己优化添加的一些行为,关于具体怎么表现需要一个量化的“度”或者“分寸”, 也就是界限所要表达的意思。“行为”一词是我添加上去,方便理解的,因为这些过程都是用来控制 某些具体行为应该怎么具体表现的。之前 parameter 对我来说,它的意思只有一个 –– 参数。在 翻译 1.3 节时,因为同一个句子中既有 parameter 又有 arguments,都翻译成参数不妥,想着 应该翻译成别的意思,所以我特地查了下字典,找到有这么一条意思 –– (in general use) a limit or boundary that defines the scope of a particular process or activity。大概就是定义一些活动或过程 范围的边界的,我把这个意思放到这个段落来整体看了下,发现很合适所以就用了。

但考虑到翻译为“行为界限”的确太偏了,所以我也赞成翻译为“环境参数”。以后遇到它与 argument(s) 冲突时,可以将后者翻译为 “过程参数” 之类的,这样区分下也没什么问题。

xashes commented 5 years ago

@flowingfirefly ,谢谢认可:)

guenchi commented 5 years ago

首先感谢 @xashes 提出的这个论题。也非常庆幸在项目中有如此的氛围和讨论。

诚然 @xashes 提出的译法比 @flowingfirefly 更进一步,但我仍然觉得还有推敲的余地。

注意这一句话:

All Chez Scheme system customization is done via parameters. A parameter is a procedure that encapsulates a hidden state variable. When invoked without arguments, a parameter returns the value of the encapsulated variable. When invoked with one argument, the parameter changes the value of the variable to the value of its argument. A parameter may raise an exception if its argument is not appropriate, or it may filter the argument in some way.

这可能是本书中唯一一处parameter和argument同时使用的情况。也是两个词语针锋相对之地。

在其他情况下可能parameter和argument都笼统的翻译为“参数”也并无不可。

如果能把这一段话译通顺了,这两个词语该怎么翻译就能完美的解决了。

guenchi commented 5 years ago

所以我先保持PR的打开,等大家讨论结束后再合并。

guenchi commented 5 years ago

关于fixnum 建议使用 本机整数 这个意译 定长数 可能算是比较贴切的字面意思,但没有传达出这个数字会随着实现环境改变的意思。

出处:The Development of Chez Scheme 第二页 native integers (fixnums)

xashes commented 5 years ago

Chez Scheme 系统的定制化皆通过参数实现。一个环境参数过程是一个封装了隐式变量的过程。若调用时不传入实参,则此过程返回其封装变量的值。若调用时传入一个实参,则此过程把变量值改变为当前传入的参数值。如果传入不当的实参,则环境参数过程可能会抛出异常,也可能以某种方式过滤掉此参数。

xashes commented 5 years ago

在r6rs第6.2节中有,"A parameter called list means that it is the programmer's responsibility to pass an argument that is a list." 这里也并用了,我觉得还是传统的用法,根据上下文,parameter一般多指句法中的形式参数,而argument一般指实际参数或称传入的参数值 其实上文里,就把argument都译为参数,也没什么歧义吧,你们觉得呢?

xashes commented 5 years ago

本机整数,你这个译法明显要好啊。

我一开始的译文中其实这个词都没译,就是觉得“定长数”这个说法有明显缺陷,因为它的长度确实依赖于平台, 对于不同的平台,并不算是固定的。后来是要提交译文,勉强译成这样,昨天提交修改申请时,这个词也很犹豫,所以隔了两小时,才提交这个改动。

你这么解,真的很高明:)

guenchi commented 5 years ago

在r6rs第6.2节中有,"A parameter called list means that it is the programmer's responsibility to pass an argument that is a list." 这里也并用了,我觉得还是传统的用法,根据上下文,_parameter_一般多指句法中的形式参数,而_argument_一般指实际参数或称传入的参数值 其实上文里,就把_argument_都译为参数,也没什么歧义吧,你们觉得呢?

就那一句两个都有的不好译

我觉得可能作者本意也是实参和形参

guenchi commented 5 years ago

本机整数,你这个译法明显要好啊。

我一开始的译文中其实这个词都没译,就是觉得“定长数”这个说法有明显缺陷,因为它的长度确实依赖于平台, 对于不同的平台,并不算是固定的。后来是要提交译文,勉强译成这样,昨天提交修改申请时,这个词也很犹豫,所以隔了两小时,才提交这个改动。

你这么解,真的很高明:)

这个词属于专有词汇了,我觉得在术语表里保留翻译就行了,在文章中还是保留英文fixnum原文为好。

xashes commented 5 years ago

好的,那我回头把文章中的翻译改过来。至于怎么翻译上面那段更好,我再好好想一想。

xashes commented 5 years ago

关于 parameter ,你觉得在这里根据它的作用,直白地译作“参数设定过程”可否? argument 译作参数?

xashes commented 5 years ago

不过,不管怎么说,我在这里提交的“定长数”和“环境参数”都并不成立,要么,我把这个PR关了吧?

guenchi commented 5 years ago

不过,不管怎么说,我在这里提交的“定长数”和“环境参数”都并不成立,要么,我把这个PR关了吧?

先开着吧 多点人讨论下那个参数

DeathKing commented 5 years ago

一些个人的看法:

MIT-Scheme 用户手册第10.3节(https://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Parameters.html),我不知道你们讨论的跟这个是否有关

Parameters are objects that can be bound to new values for the duration of a dynamic extent. See Dynamic Binding.

至于 @guenchi 提到的 R6RS 6.2 我去看了下前后文

For succinctness, the report follows the convention that if a parameter name is also the name of a type, then the corresponding argument must be of the named type.

大意是说,如果手册上条目标注的是 list-ref list n,那么调用 list-ref 的时候,程序员需要确保形式参数 list 对应的实际参数是一个表。在这类语境下,将 Parameter 和 Argument 分别译作形式参数和实际参数,我觉得是没问题的。

关于 Fixnum ,个人还是比较支持定长数这个译法。(Fixnum 通常是与 Bignum 相对,后者的大小是可变的,而不是指 Fixnum 在不同机器上所采用的字长都一样;可类比浮点数/定点数的区别)。

xashes commented 5 years ago

@DeathKing 关于形参和实参的看法我和你一样。这里讨论的 parameter 还有另一种情况,就是作为过程的 parameter:

procedure: (make-parameter object)
procedure: (make-parameter object procedure)
returns: a parameter (procedure)
libraries: (chezscheme)

它指代作为 make-parameter 返回值的过程。这个过程定义时会建立一个全局参数,直接调用时返回此参数或重绑定的参数值。或作为 parameterize的参数临时改变原参数的作用域和局部的绑定值。

A parameter is a procedure that encapsulates a hidden state variable. (CSUG1.3) In threaded versions of Chez Scheme, make-parameter creates global parameters. The procedure make-thread-parameter, described in Section 15.6, may be used to make thread parameters. (CSUG12.13)

作用是创建参数或控制参数,返回值也还是参数值,但本身是一个过程,你觉得怎么措辞为好呢?

xashes commented 5 years ago

最初我提出这个话题,是看到术语表中把作为过程的 parameter 作为了一个固定的术语,而我觉得有些场合这样译会有碍理解,我倾向于灵活使用的同时仍围绕着其“参数”的原义,而且原文根据语境也使用得很灵活。

等你们意见的时候,先罗列一下我遇到的几种情况供你们参考,后面附上我当前倾向的选择。

语境强调的是过程,比如:

The parameters gensym-prefix and gensym-count are used to access and set the internal prefix and counter ...

我倾向译为“这两个参数控制过程……用于访问和设置内置前缀和计数器……”;

语境强调的是其封装的参数值,比如:

When the parameter print-record is set to #f, records are printed using the simpler syntax ...

我倾向译为“参数 print-record 被设为 #f 时,……”,而不译为“某某参数过程封装的变量值被重绑定为 #f ”,虽然有失精确,但应该无碍理解。

还有时,上下文强调的仅仅是“parameter a 封装了一个有什么作用的变量”,我倾向于仅仅译为”过程 a 封装了一个有什么作用的参数”,而觉得不必强调这是一个“参数设置过程”或“参数过程”(这个措辞还等着你们帮着参详)。

至于 argument 的问题, parameter 作为过程的时候,argument 同时出现时都是作为它被调用时传入的实际参数,应该没什么冲突。其他情况下,大家基本是一样的看法,大多就是形参和实参。

现在在讨论这个词的翻译问题,我的看法仍然是不必找到一个全局通用的术语,不知道我这样想是不是不够严谨。

把我的看法先抛出来供你们指正,最后定了怎么译的话,我再去修改我的译文。

guenchi commented 5 years ago

All Chez Scheme system customization is done via parameters. A parameter is a procedure that encapsulates a hidden state variable. When invoked without arguments, a parameter returns the value of the encapsulated variable. When invoked with one argument, the parameter changes the value of the variable to the value of its argument. A parameter may raise an exception if its argument is not appropriate, or it may filter the argument in some way.

所以谁来优雅的翻译一下?

xashes commented 5 years ago

我只能翻译到这种程度,优雅的翻译,只能期待 @DeathKing 了,他的专业知识和翻译经验都比我多太多了。

所有 Chez Scheme 系统定制都是通过参数控制过程完成的。参数控制过程是封装了一个隐藏状态变量的过程。当不带参数调用时,该过程返回原封装变量的值。当使用一个参数调用时,该过程会将原变量值更改为其参数的值。如果传入不当的参数,该过程可能会抛出异常,也可能以某种方式过滤此参数。

DeathKing commented 5 years ago

All Chez Scheme system customization is done via parameters. A parameter is a procedure that encapsulates a hidden state variable. When invoked without arguments, a parameter returns the value of the encapsulated variable. When invoked with one argument, the parameter changes the value of the variable to the value of its argument. A parameter may raise an exception if its argument is not appropriate, or it may filter the argument in some way.

所以谁来优雅的翻译一下?

首先要明确的是,此 parameter 非彼 parameter。这里的 parameters 应该就是指 Parameter Object 了(见 https://srfi.schemers.org/srfi-39/srfi-39.html ),因此可以将 parameter 译为参数对象(虽然说 Chez Scheme 手册没有明确的使用 parameter object 这个提法,但在 SRFI 文档中,这个是标准化的术语)。

@guenchi 提到的文档中的 parameters就是指 parameter object。而且通过 SRFI 文档提供的 parameter object 的实现,我们也发现,就 parameterargument 作为“形式参数”和“实际参数”的意义,也没有超过我们的认知。因此,我的看法总结如下:

  1. 显式地出现 “parameter object” 字样,那么以参数对象为译名;
  2. 如果通过上下文,能确定 parameters 指代的是 parameter object,那么按照 1 实施;
  3. 如果 argumentparameter 同时出现,那么分别翻译为 实际参数形式参数
  4. 如果以 actual parameterformal parameter 的形式出现,那么也按照 3 实施;
  5. 如果仅仅出现 argumentparameter,应该优先采用实际参数形式参数的译法,但为了行文表达的简洁,在无歧义的情况下,译者可采用 参数 的译法。

对于以后看到本 issue 又缺乏相关 background 的同学,以下是详细解释:

;;; SRFI-39 提供的 `make-parameter` 的实现:
(define make-parameter
      (lambda (init . conv)
        (let ((converter
               (if (null? conv) (lambda (x) x) (car conv))))
          (let ((global-cell
                 (cons #f (converter init))))
            (letrec ((parameter
                      (LAMBDA new-val
                        (let ((cell (dynamic-lookup parameter global-cell)))
                          (cond ((null? new-val)
                                 (cdr cell))
                                ((null? (cdr new-val))
                                 (set-cdr! cell (converter (car new-val))))
                                (else ; this case is needed for parameterize
                                 (converter (car new-val))))))))
              (set-car! global-cell parameter)
              parameter)))))
  1. (make-parameter) 返回的是一个 lambda 表达式(注意,是最内层 letrec中、我特别用大写标出来的那个 LAMBDA 哦~),因此说 parameter object 是一种过程;
  2. global-cellcddr 部分是所谓的隐含的(hidden)状态变量;
  3. 注意看 cond 表达式的前两种 case:
    1. (null? new-val) 即无参调用参数对象,因此返回隐含的状态变量的值;
    2. (null? (cdr new-val)) 即以单个参数调用参数对象,新的状态更新为 (converter (car new-val)) 的值, converter 是在构建参数对象时传递的,可以作为实际参数的 checkertransformer/mapper
  4. 所谓的“抛出异常”,也是利用 converter 过程中的 error 过程等来实现。

结合手册中给出的一个具体例子([https://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Dynamic-Binding.html#parameterize]())来分析,一个比较有意思的现象是,`radix既是一个parameter(object)(radix)又是一个(作为number->string过程的)argument`:

(define radix
  (make-parameter
   10
   (lambda (x)
     (if (and (exact-integer?  x) (<= 2 x 16))
         x
         (error "invalid radix")))))

(define (f n) (number->string n (radix)))

(f 12)                                  ⇒ "12"
(parameterize ((radix 2))
  (f 12))                               ⇒ "1100"
(f 12)                                  ⇒ "12"
(radix 16)                              error→ Wrong number of arguments
(parameterize ((radix 0))
  (f 12))                               error→ invalid radix
DeathKing commented 5 years ago

推荐将本 issue 的 title 修改为 parameterfixnum 相关的字眼,方便日后检索。

guenchi commented 5 years ago

All Chez Scheme system customization is done via parameters. A parameter is a procedure that encapsulates a hidden state variable. When invoked without arguments, a parameter returns the value of the encapsulated variable. When invoked with one argument, the parameter changes the value of the variable to the value of its argument. A parameter may raise an exception if its argument is not appropriate, or it may filter the argument in some way. 所以谁来优雅的翻译一下?

首先要明确的是,此 parameter 非彼 parameter。这里的 parameters 应该就是指 Parameter Object 了(见 https://srfi.schemers.org/srfi-39/srfi-39.html ),因此可以将 parameter 译为参数对象(虽然说 Chez Scheme 手册没有明确的使用 parameter object 这个提法,但在 SRFI 文档中,这个是标准化的术语)。

  • 所有的 Chez Scheme 系统都可以通过参数对象(parameter)来完成定制;
  • 参数对象是一种过程,它封装了一个隐含的状态变量;
  • 当无参调用该过程时,参数对象会返会所封装变量的值
  • 当以单个参数调用该过程时,参数对象将该状态变量修改为该实参的值;
  • 如果传入的参数不当,该过程可能会抛出异常,也可能以某种方式过滤此参数。

@guenchi 提到的文档中的 parameters就是指 parameter object。而且通过 SRFI 文档提供的 parameter object 的实现,我们也发现,就 parameterargument 作为“形式参数”和“实际参数”的意义,也没有超过我们的认知。因此,我的看法总结如下:

  1. 显式地出现 “parameter object” 字样,那么以参数对象为译名;
  2. 如果通过上下文,能确定 parameters 指代的是 parameter object,那么按照 1 实施;
  3. 如果 argumentparameter 同时出现,那么分别翻译为 实际参数形式参数
  4. 如果以 actual parameterformal parameter 的形式出现,那么也按照 3 实施;
  5. 如果仅仅出现 argumentparameter,应该优先采用实际参数形式参数的译法,但为了行文表达的简洁,在无歧义的情况下,译者可采用 参数 的译法。

对于以后看到本 issue 又缺乏相关 background 的同学,以下是详细解释:

;;; SRFI-39 提供的 `make-parameter` 的实现:
(define make-parameter
      (lambda (init . conv)
        (let ((converter
               (if (null? conv) (lambda (x) x) (car conv))))
          (let ((global-cell
                 (cons #f (converter init))))
            (letrec ((parameter
                      (LAMBDA new-val
                        (let ((cell (dynamic-lookup parameter global-cell)))
                          (cond ((null? new-val)
                                 (cdr cell))
                                ((null? (cdr new-val))
                                 (set-cdr! cell (converter (car new-val))))
                                (else ; this case is needed for parameterize
                                 (converter (car new-val))))))))
              (set-car! global-cell parameter)
              parameter)))))
  1. (make-parameter) 返回的是一个 lambda 表达式(注意,是最内层 letrec中、我特别用大写标出来的那个 LAMBDA 哦~),因此说 parameter object 是一种过程;
  2. global-cellcddr 部分是所谓的隐含的(hidden)状态变量;
  3. 注意看 cond 表达式的前两种 case:

    1. (null? new-val) 即无参调用参数对象,因此返回隐含的状态变量的值;
    2. (null? (cdr new-val)) 即以单个参数调用参数对象,新的状态更新为 (converter (car new-val)) 的值, converter 是在构建参数对象时传递的,可以作为实际参数的 checkertransformer/mapper
  4. 所谓的“抛出异常”,也是利用 converter 过程中的 error 过程等来实现。

结合手册中给出的一个具体例子(https://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Dynamic-Binding.html#parameterize)来分析,一个比较有意思的现象是,`radix既是一个parameter(object)(radix)又是一个(作为number->string过程的)argument`:

(define radix
  (make-parameter
   10
   (lambda (x)
     (if (and (exact-integer?  x) (<= 2 x 16))
         x
         (error "invalid radix")))))

(define (f n) (number->string n (radix)))

(f 12)                                  ⇒ "12"
(parameterize ((radix 2))
  (f 12))                               ⇒ "1100"
(f 12)                                  ⇒ "12"
(radix 16)                              error→ Wrong number of arguments
(parameterize ((radix 0))
  (f 12))                               error→ invalid radix

这个解释很完美了 我建议按此方案实施