In Erlang and OTP in Action (page 46), the authors state the following in a note:
It may happen that in some odd corner case, code evaluated in the shell behaves slightly differently from the same code when compiled as part of a module. In such a case, the compiled version is the gold standard. The shell tries its best to do the exact same thing when it interprets the expressions.
Can you think of one or more of these odd corner cases? Which are the slight differences in those cases?
Basically, eval is used to evaluate a single dynamically generated Python expression, and exec is used to execute dynamically generated Python code only for its side effects.
A compiler takes the program code (source code) and converts the source code to a machine language module (called an object file). Another specialized program, called a linker, combines this object file with other previously compiled object files (in particular run-time modules) to create an executable file.
To fix this error, correct the spelling of the main() function.
You can keep going with eval() ,you could actually write the string as a file and execute it with subprocess. Popen() , or you could call the function something besides main() and call it after defining it with eval() .
The most important difference is that the shell is interpreted whereas the compiled code is... well.. compiled. This has observable difference in the execution speed and memory usage of the function. In other words, you may find that the interpreted variant is slower or uses up all your memory while the compiled version does not.
This problem has bitten many a young Erlang programmer. He or she thinks Erlang is rather slow compared to other languages, while it in reality is a test of interpreted code against compiled.
The paragraph is a protective measure. Basically the interpreter and compiler ought to agree on all input/output of a function. But unfortunately that is not always the case. In practice the interpreter and compiler are distinct execution engines and may thus differ. If you native-compile through HiPE the changes might be even larger. Usually problems arise around IEEE 754 floating point numbers.
The erlang interpreter, erl_eval
, tries very hard to behave exactly like compiled code. If it doesn't it is most likely a bug.
Except in one case and that is receiving messages. Compiled code can access the internal instructions to access and manipulate the message queue. The interpreter can not do this. It must: actually remove messages from the queue (more or less with receive X -> X end
); test them to see if they match the receive patterns; keep those that don't match; and put back all the currently unwanted messages into the queue (by receiving all messages and then sending them back to itself). This means that there is a short time in which if a message arrives it may not end up in the same place in the message queue as for compiled code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With