9

我听说有些事情作为计算机程序员是不能做的,但我不知道它们是什么。我最近想到的一件事是:有一个类可以复制它运行的程序的源代码,修改该程序并向它所在的类添加一个方法,然后运行,这不是很好吗?程序的副本并自行终止。代码可以写代码吗?

4

23 回答 23

15

如果您想了解可计算性的限制,请阅读停止问题

在可计算性理论中,停机问题是一个决策问题,可以表述如下:给定程序的描述和有限的输入,在给定输入的情况下,决定程序是完成运行还是永远运行。

艾伦·图灵在 1936 年证明,不可能存在解决所有可能的程序输入对的停止问题的通用算法

于 2008-10-30T16:48:23.220 回答
13

首先查看quines,然后查看 Macro-Assemblers ,然后查看lex & yaccflex & bison。然后考虑自修改代码

这是一个quine(格式化,使用输出作为新输入):

#include<stdio.h>

main()
{
  char *a = "main(){char *a = %c%s%c; int b = '%c'; printf(a,b,a,b,b);}";
  int b = '"';
  printf(a,b,a,b,b);
}

现在,如果您只是在寻找程序员无法做到的事情,请寻找与 np-complete 相反的东西。

于 2008-10-30T16:48:46.183 回答
8

是的。这就是许多病毒的工作原理!

于 2008-10-30T16:43:37.333 回答
4

了解一下:可计算性理论

于 2008-10-30T16:48:35.827 回答
4

是的,这就是大多数 Lisp 宏所做的(仅举一个例子)。

于 2008-10-30T17:48:13.910 回答
3

是的,当然是,尽管可能不在您所指的上下文中,请查看 t4 上的这篇文章

于 2008-10-30T16:45:16.457 回答
3

如果你看看函数式编程有很多机会编写生成更多代码的代码,那么像 Lisp 这样的语言不区分代码和数据的方式是它强大的重要组成部分。

在创建新应用程序时,Rails 从数据库模式生成各种默认模型和控制器类。用动态语言做这种事情是很标准的——我有一些 PHP 可以生成 php 文件,只是因为它是我当时处理的问题的最简单的解决方案。

所以这是可能的。至于你问的问题——这可能有点模糊——你使用的是什么环境和语言?您希望代码做什么以及为什么需要添加它?一个具体的例子可能会带来更直接相关的回应。

于 2008-10-30T16:51:19.003 回答
2

是的,可以创建代码生成器。大多数时候,他们接受用户输入并生成有效代码。但还有其他可能性。

自修改程序也是可能的。但它们在dos时代更为常见。

于 2008-10-30T16:44:25.570 回答
2

当然可以!事实上,如果您使用动态语言,则该类可以在程序仍在运行时更改自身(或另一个类)。它甚至可以创建以前不存在的新类。这称为元编程,它使您的代码变得非常灵活。

于 2008-10-30T16:46:02.150 回答
2

您混淆/混淆了“写”一词的两种含义。一个含义是将字节物理写入介质,另一个含义是设计软件。当然,您可以让程序执行前者,如果它被设计为这样做的话。

程序做程序员没有明确打算做的事情的唯一方法是表现得像一个生物:变异(在自身中融入一些环境),并以不同的速率复制不同的突变体(以避免完全灭绝,如果突变是终端的)。

于 2008-10-30T16:49:19.070 回答
2

是的。我为 Paint.NET* 编写了一个效果,它为您提供了一个编辑器并允许您“即时”编写图形效果。当您暂停输入时,它会将其编译为 dll,加载并执行它。现在,在编辑器中,您只需要编写实际的渲染函数,创建 dll 所需的所有其他内容都由编辑器编写并发送到 C# 编译器。

你可以在这里免费下载:http: //www.boltbait.com/pdn/codelab/

事实上,甚至还有一个选项可以在将其发送到编译器之前查看为您编写的所有代码。帮助文件(上面链接)讨论了所有内容。

源代码也可以从该页面下载。

*Paint.NET 是一个免费的图像编辑器,您可以在这里下载:http: //getpaint.net

于 2008-10-30T16:51:25.710 回答
2

关于人工智能,请看进化算法

于 2008-10-30T17:09:32.820 回答
2

复制它运行的程序的源代码,修改该程序并向它所在的类添加一个方法,然后运行该程序的副本并自行终止

您还可以生成代码,将其构建为库而不是可执行文件,然后动态加载库,甚至无需退出当前正在运行的程序。

于 2008-10-30T17:33:23.427 回答
2

动态语言通常不像您建议的那样工作,因为它们没有完全独立的编译步骤。程序不需要修改自己的源代码、重新编译和从头开始。通常,新功能是动态编译和链接的。

Common Lisp 是一种很好的练习语言,但还有其他语言可以在其中创建代码并在其中运行它。通常,这将通过一个名为“eval”或类似的函数来实现。Perl 有一个“eval”函数,脚本语言通常都有这个能力。

有很多程序可以编写其他程序,例如 yacc 或 bison,但它们并没有您所寻找的动态质量。

于 2008-10-30T17:44:52.310 回答
2

看看Langtom 的循环。这是自我复制“程序”的最简单示例。

于 2008-11-04T22:51:16.757 回答
1

有一整类这样的东西称为“代码生成器”。(尽管,编译器也符合您设置的描述)。这些描述了这些野兽的两个领域。

大多数代码生成,采用某种形式的用户输入(大多数采用数据库模式)和然后编译的产品源代码。

更高级的可以输出可执行代码。对于 .NET,有一个专门用于创建可执行代码的完整命名空间 (System.CodeDom)。这些对象,您可以获取 C#(或其他语言)代码,对其进行编译,并将其链接到您当前正在运行的程序中。

于 2008-10-30T16:44:26.677 回答
1

我在 PHP 中执行此操作。

为了保留类的设置,我保留了一个名为$data. $data 只是一个字典/哈希表/关联数组(取决于你来自哪里)。

当您加载该类时,它包含一个基本定义数据的 php 文件。当我保存类时,它会为每个数据值写出 PHP。这是一个缓慢的写入过程(并且目前存在一些并发问题),但它比光读取要快。比使用数据库快得多(也更轻)。

像这样的东西不适用于所有语言。它在 PHP 中对我有用,因为 PHP 非常动态。

于 2008-10-30T16:48:50.147 回答
1

编写代码生成器一直是可能的。借助 XML 技术,代码生成器的使用可以成为必不可少的工具。假设您为一家必须处理来自其他公司的 XML 文件的公司工作。编写一个使用 XML 解析器解析新 XML 文件的程序并编写另一个程序,该程序设置了所有回调函数来读取该格式的 XML 文件,这是相对简单的。您仍然需要编辑新程序以使其特定于您的需要,但是使用这种类型的代码生成器可以大大减少新 XML 文件(新结构、新名称)的开发时间。在我看来,这是 XML 技术优势的一部分。

于 2008-10-30T17:28:38.693 回答
1

lisp lisp lisp lisp :p

开玩笑,如果你想让生成代码的代码运行并且你有时间放松学习它并用递归的东西生成更多代码来打破你的想法,试着学习 lisp :)

(eval '(or true false))
于 2008-11-04T22:08:28.903 回答
1

如果有一个类可以复制它运行的程序的源代码,修改该程序并向它所在的类添加一个方法,然后运行程序的副本并自行终止,这不是很好吗

几乎没有任何情况可以解决无法使用非自修改代码“更好”解决的问题。

也就是说,有一些非常常见(有用)的代码编写其他代码的案例。最明显的是任何服务器端 Web 应用程序,它生成 HTML/Javascript(嗯,HTML 是标记,但理论上是相同的)。此外,任何改变终端环境的脚本通常都会输出一个由父 shell 评估的 shell 脚本。wxGlade 生成代码以创建基于 wx 的 GUI。

于 2008-11-04T23:17:10.293 回答
1

请参阅我们的DMS 软件再造工具包。这是读取和修改程序或通过组装片段生成程序的通用机器。

于 2011-08-12T02:57:20.173 回答
0

这是人工智能的基本问题之一。我个人希望这是不可能的——否则我很快就会失业!!!:)

于 2008-10-30T16:55:48.760 回答
0

它被称为元编程,既是编写有用程序的好方法,也是一个有趣的研究课题。雅克·皮特拉 (Jacques Pitrat) 的人造生物:一本有意识的机器书的良心应该会让你很感兴趣。它主要与基于元知识的计算机程序有关。

另一个相关的术语是多阶段编程(因为有几个阶段的程序,每个阶段都会产生下一个)。

于 2011-12-24T16:40:06.557 回答