【问题标题】:Using a higher order SML code, Write Nested Functions in Java使用高阶 SML 代码,用 Java 编写嵌套函数
【发布时间】:2022-01-06 13:02:20
【问题描述】:

我现在正在处理嵌套函数的任务,但在 java 中这是不可能的。我们曾考虑过 SML 中的嵌套函数。由于许多语言都不允许嵌套函数,因此我们认为激活记录带有嵌套链接。然而,我们被认为如何在图表和理论中做这些,并期望用 Java 做,但我不知道如何用 Java 做这些,因为我们甚至没有从他那里得到任何例子。我尝试在谷歌上搜索一些东西,但我找到的所有参考资料都非常基础,并没有真正的帮助。我会为此提供任何帮助。

以下是我们应该用 Java 编写的 SML 代码。

fun h (x,y) =
  let
    val z = x+1
    fun g w =
      let
        val z = y + 1
        fun f x =
          if x = 0 then 0
          else z + x + g(w - 1)
      in
        if w = 0 then x
        else z + f(w - 1)
      end
  in
    if x = 0 then g y
    else z + g(h(x - 1, y))
  end;

以下是我尝试过的代码,但实际上并没有得到任何东西。

public int f(int w, int x, int y, int z) {
    if (x == 0) {
        return 0;
    } 
    else {
        return (z + x + g(w - 1, y));
    }
}

public int g(int w, int y) {
    int z = y + 1;
    return z;
}

public void h(int w, int x, int y) {
    int z = x + 1;
    g(w, y);
    f(w, x, y, z);
}

public void last(int w, int x, int y, int z) {
    
}

以下是作业中给出的详细信息:

考虑定义在 右边的盒子,其中函数 g 是 嵌套在函数 h 和函数 f 中 嵌套在函数 g 中。 您可以在文本中键入此功能 文件并在 ML 环境中使用“使用” 加载函数并尝试一些输入以查看结果。这是一个快速增长的功能。 此作业要求您使用 没有嵌套函数的Java 支持计算函数 h on 一些输入。如您所见,这 功能快速增长。

您可以在您的 java 程序中进行递归调用以简化您的任务, 但是由于 Java 不允许您定义嵌套函数,因此您必须使用该技术 具有嵌套链接的激活记录以解决外部函数中定义的非局部变量。 您必须在报告中解释如何解决非局部变量问题。 提示:您可以将激活记录的指针传递给被调用函数,该函数用作 被调用函数可能需要的嵌套链接。 每条激活记录都应包含以下信息:

  1. 激活记录所属函数的名称。
  2. 包含所有局部变量及其值的符号表。
  3. 返回地址,当前函数完成时要继续的点和前一个 激活记录(即调用者)已恢复。
  4. 指向上一个激活记录(即调用者的激活记录)的指针。
  5. 用于解析非局部变量的嵌套链接。
  6. 保存此计算结果(要返回的值)的地方。 由于这只是计算上面定义的特定函数的模拟,因此您不必 为每一个可能的功能设计一个通用的激活记录。您可以定义三种不同的 上面定义的三种不同 ML 函数的激活记录。

这些是作业中直接给出的说明。

【问题讨论】:

  • Java 从 2014 年开始就有 lambda 表达式。(而且有很多语言可以“嵌套”函数。只是你还没有遇到过。)
  • 是的,我没有很多语言的经验。我现在还处于学习阶段。对于作业,我们被告知要使用带有嵌套链接的激活记录,我可以请教一下吗?直到现在我都找不到关于它的单一参考。我肯定会尝试使用 lambda,这会有所帮助。谢谢!!
  • 除非您正在构建一个编译器,无论是在 Java 中还是为 Java 中,这都没有多大意义——这些都是语言实现的概念。我想肯定是有什么误会。
  • 我同意。虽然 SO 不存在为人们做作业,但看看作业的实际文本会很有趣。
  • 我也更新了作业的实际文本。我们在课程作业中有一个名为激活记录的主题,而激活记录是编译器设计的一部分,所以我想我可以说我们正在研究编译器的一部分。

标签: java sml nested-function activation-record


【解决方案1】:

不确定为什么任务建议使用激活记录。有一种称为 lambda 提升 的通用技术可以将局部函数转换为全局函数:只需将函数使用的每个非局部变量添加为附加参数即可。只要不以一流的方式将本地函数用作闭包,这就足够了。您的尝试已经朝着正确的方向前进,这是我将如何解决它:

public int f(int x, int g_z, int g_w, int h_x, int h_y) {
  if (x == 0) {
    return 0;
  } else {
    return g_z + x + g(g_w - 1, h_x, h_y);
  }
}

public int g(int w, int h_x, int h_y) {
  int z = h_y + 1;
  if (w == 0) {
    return h_x;
  } else {
    return z + f(w - 1, z, w, h_x, h_y);
  }
}

public int h(int x, int y) {
  int z = x + 1;
  if (x == 0) {
    return g(y, x, y);
  } else {
    return z + g(h(x - 1, y), x, y);
  }
}

【讨论】:

    猜你喜欢
    • 2013-01-13
    • 2019-10-09
    • 1970-01-01
    • 1970-01-01
    • 2014-04-06
    • 1970-01-01
    • 2013-12-02
    • 2013-01-16
    • 2013-03-20
    相关资源
    最近更新 更多