【问题标题】:Assigning the result of an expression to a variable将表达式的结果分配给变量
【发布时间】:2009-12-17 05:45:05
【问题描述】:

使用 DrScheme(语言——相当大)。试图将表达式的结果传递给稍后可以在另一个表达式中使用的变量。这是问题的简化版本:

定义窗口:

(define (tot a b c) (+ a b c))

(define (tot2) (+ (tot a b c) 1))

解释器窗口

> (tot 5 6 7)

18

> (tot2)

.   . reference to undefined identifier: a

我想要的结果当然是 19。让 DrScheme 一次做所有代数很容易,但我需要让它求解第一个表达式,然后根据结果求解第二个表达式首先。

【问题讨论】:

    标签: lisp scheme racket variable-assignment


    【解决方案1】:

    这是你要找的吗?

    (define (tot a b c) (+ a b c))
    (define (tot2 a b c) (+ (tot a b c) 1))
    

    然后

    (tot2 5 6 7)
    

    应该是 19。


    如果你想将 tot2 分配给整数值而不是函数,

    (define (tot a b c) (+ a b c))
    (define tot2 (+ (tot 5 6 7) 1))
    

    将表达式(+ (tot 5 6 7) 1) 的结果分配给名称tot2

    【讨论】:

    • 使用您建议的解决方案,当我为任一函数提供值时,它现在告诉我 tot2 是一个未定义的标识符。如果我不能在 tot2 的上下文中直接引用这些变量,有没有办法将 (tot a b c) 函数的结果滚动到另一个变量中并使用它来代替?感谢您对我的包容——我已经编程了整整三天。
    • 您是否使用三个参数调用了 tot2?例如,(tot2 5 6 7) 应该得到 19。
    • @Steve:现在很难说出了什么问题。也许更新您的问题以显示您的第二次尝试。 Ecounysis 的代码不应给出您所说的错误。
    • 昨晚发帖的时候,我一定不明白ecounysis的目的是什么。我现在看到了,但这不是我想要的行为。不够清楚是我的错。
    【解决方案2】:

    方案是lexically scoped:,所以ab,c 将只存在于tot 的动态范围内。

    过程调用的动态范围是从调用开始到调用返回(通过gnu)之间的时间段。

    【讨论】:

      【解决方案3】:

      您正在想象一种不存在的“持久性”,尽管考虑到以前的数学经验,这可能是合理的。

      也就是说:如果我正在解决一个数学问题,并且我说 x 等于 5,那么对于问题的其余部分,x 应该保持等于 5;例如,直到我擦掉黑板。

      那么,你能写出这样的编程语言吗?是的!事实上,我可以在 DrScheme 中为您编写一个小宏,它会产生您正在寻找的行为:它会设置一个全局变量表,以便每个变量绑定都会导致对这个变量表的更新。

      但是!我调查的所有程序员(一个)(好吧,是我)都同意这是一个非常糟糕的主意。

      要了解原因,假设我有一个包含多个名为“a”的变量的大型程序。然后,任何时候程序的 A 部分中的某个人调用一个带有名为“a”的变量的函数,那么程序的 B 部分将突然改变其行为。这将使我们几乎无法推断大型程序的行为。

      更一般地说,这是“状态”和“变异”的问题。

      因此,您不能引用“范围内”以外的变量。也就是说,那些其绑定形式(在本例中为“定义”)包含引用的变量。

      【讨论】:

      • 约翰,Ecounysis。感谢您解释为什么我的方法不起作用。这个问题现在更有意义了。我正在寻找这种行为,因为我正在重写一个包含 5 个不同功能的小程序。该程序有效,但前提是用户以这种形式输入值:(+(tot 1 2 3)(tot2 5 7 8))。我想要一个第 6 个函数来总计前 5 个的结果,而不会强制用户一次输入所有值。我想我应该做的是忘记重新分配变量并学习创建一个存储每个函数结果的表。听起来合理吗?
      • 我仍然不相信,但也许是因为我不完全理解你的例子。我绝对同意您不必多次提供给定的论点,但我不确定我明白您为什么必须这样做。目前,我最好的猜测是您正试图查看both 单个调用的结果, 它们的总和。如果我是正确的,那么你可能想写这样的东西:grr,愚蠢的字符限制。不适合粘贴的代码。参看。下一条评论。
      •  #lang scheme (define (tot1 a b c) (+ a b c)) (define (tot2 a b c) (* a b c)) ;; tots-and-sum : number number number number number number -> (list/c number number number) ;;返回一个列表,其中包含调用 tot1 的结果、调用 tot2 的结果以及它们的总和。 (define (tots-and-sum g h i j k l) (let ([r1 (tot1 g h i)] [r2 (tot2 j k l)]) (list r1 r2 (+ r1 r2)))) 
      • 哦,看在上帝的份上。好吧,我知道你不能那样做。
      • 我不想多次提供参数——我只想定义 5e 函数,然后在最后有另一个函数,将这些函数的结果与之前输入的参数相加.但是由于创建最终函数需要一个新的定义,所以当我在第 6 次引用前面的 5 个函数时,每个函数的变量都未定义,最终计算失败。可能是我根本没有足够的知识来提出一个好的问题,需要更多的研究。谢谢。
      【解决方案4】:

      根据您对 John 的回答的 cmets,我认为您想要的只是将每个函数调用的结果分配给一个变量(每个变量一个变量或将它们全部放在一个列表中),然后将这些结果加在一起。

      【讨论】:

        【解决方案5】:

        在阅读了每个人的 cmets 之后,我意识到我混淆了两个问题:让解释器评估带有变量的表达式,以及实际为这些变量提供值。由于这种混乱,我问的问题没有意义。这是解决方案的简化版本。如您所见,它非常简单——我只是使用“读取”让用户输入值。

        (define a (read))
        (define b (read))
        (define c (read))
        (define d (read))
        (define ee (read))
        (define f (read))
        (define tot (+ a b c))
        (define tot2 (+ d ee f))
        (define grandtotal (+ tot tot2))
        (display grandtotal)
        

        我在实际程序中使用了这种方法,现在有一个不错的小应用程序,可以计算我一周的工作时间。感谢大家耐心的帮助。

        【讨论】:

          猜你喜欢
          • 2013-12-06
          • 2011-04-10
          • 1970-01-01
          • 2012-10-12
          • 2010-10-02
          • 2021-02-04
          • 1970-01-01
          • 2021-05-22
          • 1970-01-01
          相关资源
          最近更新 更多