<p>I am in need of a programming language/sandbox that is completely deterministic. For example, I can take a program, run it on different computers, and always be guaranteed the same result for a given input. This means no time, random numbers, file system or network access, threads, etc. It should not be possible to run code that is non-deterministic.</p>
<p>Someone suggested the Go Playground to me. <a href="https://github.com/golang/playground" rel="nofollow">https://github.com/golang/playground</a>. I see that random numbers are not possible, time is fixed, go routines didn’t seem to run, and fetching the OS/Arch always returned the same result. I’m newish to Go so I could be missing something simple. Does the playground docker image actually provide a completely deterministic sandbox across different systems?</p>
<hr/>**评论:**<br/><br/>genericbob: <pre><p>The order that maps are iterated over and select clauses are evaluated may still be random IIRC.</p></pre>f2f: <pre><p>you can consider the Go playground deterministic. at the very least (not getting into a discussion about GOMAXPROCS and concurrency), the results for a specific program are cached and subsequent replays of that program are served from cache.</p>
<p>you said "go routines didn't seem to run" but you didn't clarify what you mean by that. i suspect you were caught by GOMAXPROCS=1 and main()'s exiting stopping the whole program. if you want to see goroutines run you'll have to make main() wait for them:</p>
<p><a href="http://play.golang.org/p/XhKWLWbC0e" rel="nofollow">http://play.golang.org/p/XhKWLWbC0e</a></p></pre>foobar3: <pre><p>Thank you, that’s exactly what caught me with the goroutines. I see them run now.</p>
<p>The caching does not impact me because I’m actually taking the same program and running it on different systems.</p></pre>XANi_: <pre><blockquote>
<p>The caching does not impact me because I’m actually taking the same program and running it on different systems.</p>
</blockquote>
<p>they had to cut quite a bit to make that happen: <a href="https://blog.golang.org/playground" rel="nofollow">https://blog.golang.org/playground</a></p>
<p>in vanilla go, try to run that:</p>
<pre><code>package main
import (
"fmt"
"os"
"runtime"
"time"
)
var a int
func main() {
go func() {
for {
a = a + 1
runtime.Gosched()
}
}()
go func() {
time.Sleep( 10000)
fmt.Printf("Count: %d\n", a)
fmt.Println("Hello, playground")
os.Exit(1)
}()
select {}
}
</code></pre>
<p>it will return different value every time, and in different range depending on cpu type and load</p></pre>jerf: <pre><p>It tries its best, but I wouldn't care to guarantee there's something, somewhere that would be nondeterministic.</p>
<p>If you explain why you need what you say you need, we may be able to be more helpful. Especially in terms of the other constraints you may have. For instance, how hostile are the users? It's one thing to strongly guide users that are basically cooperating, it's another to be robust against attackers.</p>
<p>Haskell, for instance, has a couple of flags you could flip that, combined with some type signatures, could guarantee what you're looking for to some extent (google for "safe Haskell"), but you may not find that suitable for other reasons. (But it is designed to allow you to rigidly control the IO environment, which you could construct as deterministic by construction, while still leaving you a full language behind it.)</p></pre>foobar3: <pre><p>Thanks for the answer. To give a very simplified explanation, I’m working on a consensus network. Both the users writing the code and the computers running the code can not be trusted. The idea is that I’m going to take a piece of code, distribute it to X computers, and they will each send back the result. Most of the computers are not evil, so they will send back the ‘correct’ result, but there could be a few bad actors. The answer can only be verified by running the complete code provided by the user with the given inputs. Consensus is achieved by what most of the network reports, so this would not work if someone wrote non-deterministic code where network participants acting in good faith still reported conflicting results.</p>
<p>I’ll check out safe Haskell as I have not investigated this previously. </p></pre>jerf: <pre><p>Ah, you'll also want to read up on <a href="https://www.ethereum.org/" rel="nofollow">Ethereum</a>, which should at the very least be interesting.</p>
<p>"Safe Haskell" offers you the chance to define your own language with its own safe implementation with reasonable effort. Haskell's good at compilers & interpreters. Depends on what you're looking for.</p></pre>foobar3: <pre><p>Yes, I should have just mentioned Ethereum :) My problem is very similar. Instead of implementing my own VM like Ethereum, it would be great if I could let users write code in a language that was already popular and familiar to many people.</p></pre>jerf: <pre><p>Heh, well, unfortunately, "languages people know" and "languages with side-effect control" don't overlap well:-)</p>
<p>In that case, I think I personally would start with the Go playground code, but with the understanding that I would be forking Go, with all that implies. You will have to make some modifications, and it will take a few iterations. But the Go codebase is a good choice for that. It's very readable.</p></pre>XANi_: <pre><p>For start you would probably have to limit it single-threaded, no-event machine based code.</p>
<p>Then run it on VM that:</p>
<ul>
<li>have CPU time and memory limits</li>
<li>can only do restricted (or not at all) IO</li>
<li>no network access</li>
<li>no kernel access</li>
<li><strong>no external input</strong>, not even stuff like current time</li>
<li>no any kind of timer (that can be exploited by couting how long things take, so you can run different code on slower machines compared to faster ones)</li>
</ul>
<p>So you would have to take a VM that is easy to embed (Lua might be a good bet)</p>
<p>Then remove basically everything that can call OS and everything that touches internal state of VM</p></pre>gngl: <pre><blockquote>
<p>For example, I can take a program, run it on different computers, and always be guaranteed the same result for a given input. This means no time, random numbers, file system or network access, threads, etc. It should not be possible to run code that is non-deterministic.</p>
</blockquote>
<p>Isn't the actual term for such a program "buggy"? Non-determinism of a program's execution trace shouldn't make a correct program emit a different result. This is in fact the reason why Dijkstra wanted people to embrace non-determinism with his Guarded Command Language, and also a reason why Go has pieces of non-determinism carefully built in. Practice shows that wherever deterministic behavior (of implementation-defined features of a language that don't necessarily have to happen in any single deterministic way) is provided, programmers will learn to use and abuse it, leading to bugs that are subtle and often perhaps difficult to diagnose.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传