一种可以编译一切的语言
我正在尝试为一个新项目进行一些研究,并且需要从随机数据动态创建对象。 为了实现这一点,我需要一种语言/编译器,它不会出现奇怪的无法编译代码的问题。
基本上,我需要尽可能多地编译(或解释)随机代码 - 这意味着不可编译的部分将被忽略,只有可编译的部分才会创建对象(可以运行)。
面向对象不是必须的,但却是一个非常强大的优势。
我想到了 ASM,但它非常混乱,我可能需要一个更具可读性的代码
谢谢!
I'm trying to do some research for a new project, and I need to create objects dynamically from random data.
For this to work, I need a language / compiler that doesn't have problems with weird uncompilable code lying around.
Basically, I need the random code to compile (or be interpreted) as much as possible - Meaning that the uncompilable parts will be ignored, and only the compilable parts will create the objects (which could be ran).
Object Oriented-ness is not a must, but is a very strong advantage.
I thought of ASM, but it's very messy, and I'd probably need a more readable code
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
听起来你正在做一些非常类似于遗传编程的事情;即使你不是,GP 也必须解决一些相同的问题——利用随机性生成有效的程序。通常使用的方法是使用语法树:不是存储
x + y * 3 - 2
,而是存储如下内容:然后,我们可以随机更改树中的节点,而不是随机更改语法。如果
x
随机更改为+
,您可以静态地知道这意味着您需要插入两个子项(或不需要,具体取决于您如何定义>+
)。任何 Lisp 方言都是一个不错的选择。在 Lisp 中,上面的程序可以写成
(- (+ x (* y 3)) 2)
,这只是使用括号来显示深度的语法树的线性化。事实上,Lisp 公开了这个功能:您可以轻松地使用对象'(- (+ x (* y 3)) 2)
(注意前面的引号)。这是一个三元素列表,第一个元素是-
,第二个元素是另一个列表,第三个元素是2
。而且,尽管您可能需要也可能不希望将其用于您的特定应用程序,但有一个eval
函数,例如(eval '(- (+ x (* y 3)) 2))< /code> 将接受给定的列表,将其视为 Lisp 语法树/程序,并对其进行评估。这就是 Lisps 对于此类工作如此有吸引力的原因; Lisp 语法基本上是语法树的具体化,如果您在语法树级别进行操作,则可以像处理值一样处理代码。 Lisp 不会帮助您直接将
/dev/random
作为程序来读取,但是通过在顶部进行一些解释,您应该能够得到您想要的东西。我还应该提到,尽管我对此一无所知(并不是说我对普通遗传编程了解很多) 线性遗传编程。这有点像您提到的装配模型——非常非常简单的指令的线性流。这里的优点似乎是,如果您正在使用
/dev/random
或类似的东西,则所需的解释量非常小;正如您所提到的,缺点是代码的低级性质。It sounds like you're doing something very much like genetic programming; even if you aren't, GP has to solve some of the same problems—using randomness to generate valid programs. The approach to this that is typically used is to work with a syntax tree: rather than storing
x + y * 3 - 2
, you store something like the following:Then, instead of randomly changing the syntax, one can randomly change nodes in the tree instead. And if
x
should randomly change to, say,+
, you can statically know that this means you need to insert two children (or not, depending on how you define+
).A good choice for a language to work with for this would be any Lisp dialect. In a Lisp, the above program would be written
(- (+ x (* y 3)) 2)
, which is just a linearization of the syntax tree using parentheses to show depth. And in fact, Lisps expose this feature: you can just as easily work with the object'(- (+ x (* y 3)) 2)
(note the leading quote). This is a three-element list, whose first element is-
, second element is another list, and third element is2
. And, though you might or might not want it for your particular application, there's aneval
function, such that(eval '(- (+ x (* y 3)) 2))
will take in the given list, treat it as a Lisp syntax tree/program, and evaluate it. This is what makes Lisps so attractive for doing this sort of work; Lisp syntax is basically a reification of the syntax-tree, and if you operate at the syntax-tree level, you can work on code as though it was a value. Lisp won't help you read/dev/random
as a program directly, but with a little interpretation layered on top, you should be able to get what you want.I should also mention, though I don't know anything about it (not that I know much about ordinary genetic programming) the existence of linear genetic programming. This is sort of like the assembly model that you mentioned—a linear stream of very, very simple instructions. The advantage here would seem to be that if you are working with
/dev/random
or something like it, the amount of interpretation needed is very small; the disadvantage would be, as you mentioned, the low-level nature of the code.我不确定这是否是您正在寻找的,但是任何编程语言都可以以这种方式运行。对于任何编程语言 P,定义语言 Palways 如下:
例如,我可以将语言设为 C++always,这样该程序:
将编译为“Hello,world!”,而该程序:
将是一个合法程序,绝对不执行任何操作。
要解决您的原始问题,只需采用任何 OOP 语言(如 Java、Smalltalk 等)并从中构造适当的 Javaalways、Smalltalkalways 等语言即可。再说一次,我不确定这是否是您正在寻找的,但它可以很容易地完成。
或者,考虑找到任何 OOP 语言的语法,然后使用该语法生成随机的语法有效的程序。然后,您可以使用该语言的 Palways 编程语言来过滤这些程序,以消除语法上有效但语义上无效的程序。
I'm not sure if this is what you're looking for, but any programming language can be made to function this way. For any programming language P, define the language Palways as follows:
For example, I could make the language C++always so that this program:
would compile as "Hello, world!", while this program:
Would be a legal program that just does absolutely nothing.
To solve your original problem, just take any OOP language like Java, Smalltalk, etc. and construct the appropriate Javaalways, Smalltalkalways, etc. language from it. Again, I'm not sure if this is at all what you're looking for, but it could be done very easily.
Alternatively, consider finding a grammar for any OOP language and then using that grammar to produce random syntactically valid programs. You could then filter those programs down by using the Palways programming language for that language to eliminate syntactically but not semantically valid programs.
将 ASCII 字节值分为 9 类(除以 9 为模会有所帮助)。然后分配给 Brainfuck 代码字(参见 http://en.wikipedia.org/wiki/Brainfuck )。然后解释为Brainfuck。
就是这样,任何 ASCII 字符序列都是一个程序。并不是说它会做任何明智的事情...与 templatetypedef 的答案相比,这种方法有更好的机会从随机字节序列中获取非平凡程序。
Divide the ASCII byte values into 9 classes (division modulo 9 would help). Then assign then to Brainfuck codewords (see http://en.wikipedia.org/wiki/Brainfuck). Then interpret as Brainfuck.
There you go, any sequence of ASCII characters is a program. Not that it's going to do anything sensible... This approach has a much better chance, compared to templatetypedef's answer, to get a nontrivial program from a random byte sequence.
文本编辑器
您可以尝试将随机字符串输入到 Emacs 或 VI 等编辑器中。许多(大多数?)角色将执行编辑操作,但有些角色不会执行任何操作(也许除了蜂鸣声)。您必须确保随机代码突变器永远不会生成退出编辑器的字符序列。然而,这种体验很像对图灵机进行编程——代码不太可读。
Mathematica
在 Mathematica 中,未定义的符号和其他表达式会自行计算,不会出现错误。因此,如果您可以安排随机代码变异器始终生成格式良好的表达式,那么该语言可能是一个可行的选择。这很容易实现,因为基本的 Mathematica 语法很简单,使得在语法单元上而不是在字符级别上操作变得容易。如果变异器是用 Mathematica 本身编写的,那就更容易了,因为表达式修改是 Mathematica 的强项。您可以在不导入系统定义符号的 Mathematica 包中定义有效操作的迷你语言。这将使您能够随心所欲地生成格式正确的表达式,而不必担心生成危险的表达式,例如
DeleteFile[FileNames["*.*", "/", Infinity]]
。Text Editors
You could try feeding random character strings to an editor like Emacs or VI. Many (most?) characters will perform an editing action but some will do nothing (other than beep, perhaps). You would have to ensure that the random code mutator never generates the character sequence that exits the editor. However, this experience would be much like programming a Turing machine -- the code is not too readable.
Mathematica
In Mathematica, undefined symbols and other expressions evaluate to themselves, without error. So, that language might be a viable choice if you can arrange for the random code mutator to always generate well-formed expressions. This would be readily achievable since the basic Mathematica syntax is trivial, making it easy to operate on syntactic units rather than at the character level. It would be even easier if the mutator were written in Mathematica itself since expression-munging is Mathematica's forte. You could define a mini-language of valid operations within a Mathematica package that does not import the system-defined symbols. This would allow you to generate well-formed expressions to your heart's content without fear of generating a dangerous expression, like
DeleteFile[FileNames["*.*", "/", Infinity]]
.我相信 Common Lisp 应该适合您的需求。我的 SLIME/Emacs 会话中总是有一些无法编译的代码。您始终可以在运行时进行调整、重新定义函数。它实际上非常适合原型设计。
几年前,我花了相当长的时间来学习。但现在我们有了 Quicklisp,一切都变得容易多了。
这里我描述一下我的开发环境:
在我的linux机器上安装lisp
PS:我想给一个例子,Common Lisp 对我有用:
大概到 2004 年为止,我都用 C 语言编写小程序(保持简单的 Unix 方式)。
在过去的三年里,我必须运行许多不同的硬件。电动平台、科学相机、IO 卡。
事实证明,这些相机非常烦人。通常你必须将它们冷却到 -50 摄氏度左右,并且(在某些 SDK 中)它们不喜欢你关闭它们。但这
这正是我的 C 开发周期的工作方式:编写(30 秒)、编译(1 秒)、运行(0.1 秒)、重复。
最终我决定只使用 Common Lisp。通常,定义与 SDK 对话的外部函数接口是很直接的,我可以在不离开正在运行的 Lisp 映像的情况下完成此操作。我早上启动编辑器定义开放设备功能,与设备对话,3 小时后我已经实现了足够的功能来设置增益、温度、感兴趣区域并获取视频。
然后我经常可以把SDK手册收起来,只使用相机。
当我必须解析某些网页或某些奇怪的 XML 时,我使用了相同的交互式编程方法。
I believe Common Lisp should suit your needs. I always have some code in my SLIME/Emacs session that wouldn't compile. You can always tweak things, redefine functions in run-time. It is actually very good for prototyping.
A few years ago it took me quite a while to learn. But nowadays we have quicklisp and everything is so much easier.
Here I describe my development environment:
Install lisp on my linux machine
PS: I want to give an example, where Common Lisp was useful for me:
Up to maybe 2004 I used to write small programs in C (the keep it simple Unix way).
The last 3 years I had to get lots of different hardware running. Motorized stages, scientific cameras, IO cards.
The cameras turned out to be quite annoying. Usually you have to cool them down to -50 degree celsius or so and (in some SDKs) they don't like it when you close them. But this
is exactly how my C development cycle worked: write (30s), compile (1s), run (0.1s), repeat.
Eventually I decided to just use Common Lisp. Often it is straight forward to define the foreign function interfaces to talk to the SDKs and I can do this without ever leaving the running Lisp image. I start the editor in the morning define the open-device function, to talk to the device and after 3 hours I have enough of the functions implemented to set gain, temperature, region of interest and obtain the video.
Then I can often put the SDK manual away and just use the camera.
I used the same interactive programming approach when I have to parse some webpage or some weird XML.