Functional programming “是否有其他选择?”;设定&引用;论计划

Functional programming “是否有其他选择?”;设定&引用;论计划,functional-programming,scheme,lisp,racket,counting,Functional Programming,Scheme,Lisp,Racket,Counting,我想知道是否有使用set的替代方案!在计划/吵闹中。 正在做作业,我们不允许使用set 对于我的一个函数,我有一个递增函数 (set! count (+ count 1)) 我想知道我将如何改变这一点,使它不会利用设置 大概是您不允许使用set的原因吧是要求您以功能性的方式解决问题,而不是以命令式的方式。让我用两个不同的函数来说明,这两个函数都决定列表的长度: #lang racket (require rackunit) (define count 0) (define (imperat

我想知道是否有使用set的替代方案!在计划/吵闹中。 正在做作业,我们不允许使用set

对于我的一个函数,我有一个递增函数

(set! count (+ count 1))

我想知道我将如何改变这一点,使它不会利用设置

大概是您不允许使用
set的原因吧是要求您以功能性的方式解决问题,而不是以命令式的方式。让我用两个不同的函数来说明,这两个函数都决定列表的长度:

#lang racket

(require rackunit)

(define count 0)
(define (imperative-length l)
  (cond [(empty? l) count]
        [else (set! count (+ 1 count))
              (imperative-length (rest l))]))

(check-equal? (imperative-length '(4 3 2 1)) 4)


(define (functional-length l)
  (cond [(empty? l) 0]
        [else (+ 1 (functional-length (rest l)))]))


(check-equal? (functional-length '(4 3 2 1)) 4)


;; what happens if we try calling imperative-length again?


(check-equal? (imperative-length '(4 3 2 1)) 4)

;; oh no!

;; what happens if we try calling functional-length again?

(check-equal? (functional-length '(4 3 2 1)) 4)

;; yep, works fine.
这两个函数都可以很好地工作,但函数式函数可以重复调用。但是但是您可能会说,我只需要记住将计数器设置回零,或者将
count
的绑定放在函数中。这是真的,但一般来说,函数式解决方案根本不需要程序员担心这种交互


那么,这对你意味着什么?这可能意味着您需要将
count
作为另一个参数传递。只是猜测。

设定永远不需要。假设您有这个程序:

(define (count lst)
  (define num 0)
  (define (helper lst)
    (when (not (null? lst))
      (set! num (+ num 1))
      (helper (cdr lst))))
  (helper lst)
  num)
这几乎是Fortran与lisp语法的结合。在没有
设置的情况下,这将如何实现。一种方法是使用方框:

(define (count lst)
  (define num (list 0))
  (define (helper lst)
    (when (not (null? lst))
      (set-car! num (+ (car num) 1))
      (helper (cdr lst))))
  (helper lst)
  (car num))
正如SICP视频中所解释的,当你引入一种突变时,你可以用它来进行所有类型的突变。作为琐事,这是一个通常由Scheme编译器完成的转换,因此在许多情况下,实现基础语言都有
set-car和不
设置。不做突变怎么样?诀窍是隐藏绑定:

(define (count lst)
  (define (helper num lst)
    (if (not (null? lst))
        (helper (+ num 1) (cdr lst))
        num))
  (helper 0 lst))

这实际上变得更简单了。假设您只需要更新一些变量,然后在其他地方使用相同的变量进行递归

如果您的“函数”保持内部状态,那么它不是函数,而是过程:函数的定义使得
(f x)
仅依赖于
x
。可能你的目的是学习编写功能性的程序。几乎总是,替代方法是递归——特别是当有列表的时候。免费书籍:。我们也可以说,除了
set,别无选择其中
设置是完成这项工作的唯一方法(即,使用通信对象网络或其他方式,在闭包中改变隐藏绑定)。:)