函数参数太多

发布于 2024-10-09 15:13:11 字数 427 浏览 1 评论 0原文

我开始学习 Lisp,有 Java 背景。在 SICP 的练习中有许多任务,学生应该创建具有许多参数的抽象函数,例如

 (define (filtered-accumulate combiner null-value term a next b filter)...)

练习 1.33。在 Java(具有安全、静态类型规则的语言)中,具有 4 个以上参数的方法通常会产生异味,但在 Lisp/Scheme 中却不会,不是吗?我想知道你的函数中使用了多少个参数?如果您在生产中使用它,您会制作尽可能多的层吗?

I'm starting to learn Lisp with a Java background. In SICP's exercise there are many tasks where students should create abstract functions with many parameters, like

 (define (filtered-accumulate combiner null-value term a next b filter)...)

in exercise 1.33. In Java (language with safe, static typing discipline) - a method with more than 4 arguments usually smells, but in Lisp/Scheme it doesn't, does it? I'm wondering how many arguments do you use in your functions? If you use it in production, do you make as many layers?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

沉默的熊 2024-10-16 15:13:11

SICP 使用Scheme 的子集

SICP 是一本用于计算机科学入门课程的书。虽然它解释了一些高级概念,但它使用了一种非常小的语言,Scheme 语言的子集以及典型实现提供的任何现实世界的Scheme 或 Lisp 的子集。使用 SICP 的学生应该从简单易学的语言开始。从那里他们学习实现更复杂的语言添加。

在简单的教育方案中仅使用位置参数

例如,SICP 中没有开发宏。添加标准方案确实只有函数的位置参数。

Lisp 和Scheme 还提供更具表现力的参数列表

在“真正的”Lisp 或Scheme 中,我们可以使用以下一项或多项:

  • 对事物进行分组的对象或记录/结构(穷人的闭包)。传递的对象可以包含多个数据项,否则需要传递“传播”。

  • 可选变量的默认值。因此,我们只需要传递那些我们想要具有特定非默认值的

  • 可选和命名的参数。这允许灵活的参数列表,更具描述性。

  • 计算参数。参数的值或默认值可以根据其他参数计算

上述导致编写函数接口更加复杂,但通常更易于使用。

在 Lisp 中,为参数提供描述性名称并为接口提供在线文档是一种很好的风格。开发环境将显示有关功能界面的信息,因此该信息通常只需敲击键盘即可,甚至会自动显示。

对于任何不平凡的接口来说,它也是一种很好的风格,用户/开发人员应该以交互方式使用该接口来在运行时检查其参数。

复杂但可读的参数列表示例

当有更多参数时,Common Lisp 提供命名参数,这些参数可以以任意顺序出现在普通参数之后。命名参数还提供默认值并且可以省略:

(defun order-product (product
                      &key
                      buyer
                      seller
                      (vat   (local-vat seller))
                      (price (best-price product))
                      amount
                      free-delivery-p)
  "The function ORDER-PRODUCT ..."   ; documentation string
  (declare (type ratio vat price)    ; type declarations
           (type (integer 0) amount)
           (type boolean free-delivery-p))
  ...)

我们将使用它:

(order-product 'sicp
               :seller 'mit-press
               :buyer  'stan-kurilin
               :amount  1)

上面在 buyer 参数之前使用了 seller 参数。它还省略了各种参数,其中一些参数的值是经过计算的。

现在我们可以问,如此广泛的争论是好是坏。它们的参数:

  • 函数调用获得更多描述性
  • 函数具有附加文档的标准机制
  • 可以询问函数的参数列表
  • 类型声明是可能的 ->因此类型不需要写成注释
  • 许多参数可以有合理的默认值并且不需要提及

一些Scheme实现已经采用了类似的参数列表。

SICP uses a subset of Scheme

SICP is a book used in introductory computer science course. While it explains some advanced concepts, it uses a very tiny language, a subset of the Scheme language and a sub-subset of any real world Scheme or Lisp a typical implementation provides. Students using SICP are supposed to start with a simple and easy to learn language. From there they learn to implement more complex language additions.

Only positional parameters are being used in plain educational Scheme

There are for example no macros developed in SICP. Add that standard Scheme does have only positional parameters for functions.

Lisp and Scheme offer also more expressive argument lists

In 'real' Lisp or Scheme one can use one or more of the following:

  • objects or records/structures (poor man's closures) which group things. An object passed can contain several data items, which otherwise would need to be passed 'spread'.

  • defaults for optional variables. Thus we need only to pass those that we want to have a certain non-default value

  • optional and named arguments. This allows flexible argument lists which are much more descriptive.

  • computed arguments. The value or the default value of arguments can be computed based on other arguments

Above leads to more complicated to write function interfaces, but which are often easier to use.

In Lisp it is good style to have descriptive names for arguments and also provide online documentation for the interface. The development environment will display information about the interface of a function, so this information is typically only a keystroke away or is even display automatically.

It's also good style for any non-trivial interface which is supposed to be used interactively by the user/developer to check its arguments at runtime.

Example for a complex, but readable argument list

When there are more arguments, then Common Lisp provides named arguments, which can appear in any order after the normal argument. Named arguments provide also defaults and can be omitted:

(defun order-product (product
                      &key
                      buyer
                      seller
                      (vat   (local-vat seller))
                      (price (best-price product))
                      amount
                      free-delivery-p)
  "The function ORDER-PRODUCT ..."   ; documentation string
  (declare (type ratio vat price)    ; type declarations
           (type (integer 0) amount)
           (type boolean free-delivery-p))
  ...)

We would use it then:

(order-product 'sicp
               :seller 'mit-press
               :buyer  'stan-kurilin
               :amount  1)

Above uses the seller argument before the buyerargument. It also omits various arguments, some of which have their values computed.

Now we can ask whether such extensive arguments are good or bad. The arguments for them:

  • the function call gets more descriptive
  • functions have standard mechanisms to attach documentation
  • functions can be asked for their parameter lists
  • type declarations are possible -> thus types don't need to be written as comments
  • many parameters can have sensible default values and don't need to be mentioned

Several Scheme implementations have adopted similar argument lists.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文