Erlang - Help in understanding basic erlang code - syntax

I have stumbled upon a piece of code that I can't quite understand. It looks like this:
% spawn process which waits for a message and prints it
Pid = spawn(fun() ->
receive
X -> io:fwrite("I received: ~p~n", [X])
end
end),
% send a message to the new process
Pid ! {message, "Hello"}.
In the last line, is "message" an atom that is defined in the module? I can't really understand that part.
My attempt at understanding it would be this: we save things in tuples where the first element is descriptive of the content. For example: {celsius, 55}. What is less clear is that the atom message is not defined in the module. Do you have to define it? No declaration is necessary so I guess you don't have to define the atom before using it. Am I correct?
Thanks for the help!
The code is from here.

Correct- you just use atoms at will. They're not "defined" anywhere.

Basically, You understood right. You can use everything atom you want, they are not defined anywhere. Except some reserved words in Erlang:
receive, case, if, throw, catch, else...

Atoms can be used at will, Every unique atom will be entered into an atom table. The atom table is never garbage collected. The default max atom count for an ERTS instance is 1048576. This limit can be increased by using +t option on startup.
more information regarding limits. For diagnostic purpose you can use erlang:memory(atom) - elrang:memory(atom_used) calls, to ensure you haven't exhausted the available atoms. If the atoms are exhausted it leads to immediate termination of the ERTS without warning.

Related

Prolog does not stop accepting data in read

This is my code in Prolog.
do(cinema):- parents(yes); (parents(no),weather(windy),money(less)).
do(play):- parents(no),weather(sunny).
do(stay):- parents(no),weather(rainy).
do(shopping):- parents(no),weather(windy),money(more).
start:- write('Parents: '),read(X),assert(parents(X)), write('Weather: '),read(Y),assert(weather(Y)), write('Money: '),read(Z),assert(money(Z)).
clear:- retract(parents(X));retract(weather(X));retract(money(X)).
I'm trying to accept data from user and then use decision tree to find out what task will be done.
I'm running the code as:
?-start, do(X).
But it does not write Weather after reading input for parents and keeps reading data.
There is nothing really wrong with your program. See http://swish.swi-prolog.org/p/JDAJcUhq.pl. The most likely cause is already mentioned: not finishing your term with a ".". clear/0 is indeed wrong, but not needed in the web version as each new query is executed in a fresh environment.
At least in SWI-Prolog there is no need to flush before a read operation from the terminal as flushing the console output streams is always done before the read.
Try putting some flush goals after the write goals and then remember to add a full stop on your input as you are using read/1 which wants a term.

File Exception Handling and wait for a process in SWI Prolog

I am running my code on SWI Prolog and Windows 7. In my code, I call another application using 'win_exec()' (I tried using the method 'shell()', but it won't work.), and at the end produces its output in a text file. However sometimes it runs for times like 30 minutes. Now my prolog code uses this output text file, to further parse it and process it.
This is the code I use to call the other application and then use its output file:
main(Value,X) :- win_exec('C:\\myfolder\\external_app.bat C:\\myfolder\\outputfile.txt', normal),
open('C:\\myfolder\\outputfile.txt', read, Mf),
read_file(Mf, X), % PROCEDURE TO READ FILE CONTENTS
close(Mf),
statistics(cputime, Value). % CALCULATE HOW LONG IT TOOK
However, since the file has not been outputted by that another application, it gives the error:
ERROR: open/4: source_sink `C:\myfolder\outputfile.txt' does not exist (No such file or directory)
So, as a workaround, I try to catch the error, handle it by comparing with 'existence_error' and then recursively call the open procedure, until it finally succeeds i.e. the other application has completed its processing and the output file is produced. This is my workaround code for this:
main(Value,X) :- win_exec('C:\\myfolder\\external_app.bat C:\\myfolder\\outputfile.txt', normal),
open_output(X), % PROCEDURE FOR FILE EXCEPTION HANDLING
statistics(cputime,Value).
open_output(X) :- catch((open('C:\\myfolder\\outputfile.txt', read, Mf), read_file(Mf,X), close(Mf)),
error(Err,Context),
open_output_aux(Err,X)). % AUX PROCEDURE TO RECOVER
% Write some code here
% open_output_aux code matches the error code with 'existence_error';
% if true, calls open_aux_wait procedure; else throw the error.
open_aux_wait(Z):- catch((open('C:\\myfolder\\outputfile.txt', read, Mf), read_file(Mf,Z), close(Mf)),
error(Err,Context),
open_aux_wait(Z)).
However this seems to be very inefficient of way doing this. I wanted to know if there's any better way to do this, like in java, you could simply call wait() while handling file exception. In the documentation, there's a method 'wait_for_input\3' but it says 'wait_for_input()' cannot be used for File Streams in Windows. I tried using it, but it gives error.
Any help or guidelines is greatly appreciated.
You have several options to solve this:
You can totally reconsider the way that these processes communicate. For example, SWI-Prolog ships with very powerful HTTP libraries, and you can set up the communication between the two processes to work over HTTP, using a client/server architecture. In this case, you avoid the busy waiting that currently uses many CPU cycles unnecessarily.
A much more trivial solution is to simply insert a call of the built-in sleep/1 predicate to put the process to sleep before trying to open the file again. Use for example sleep(1) to put the process to sleep for 1 second.
Use for example process_wait/2 to wait until the called process has finished and generated the file.
From what you are describing, it looks like (2) will do, (3) is slightly more elegant, and (1) may be good to know in general, for more difficult cases.

Time limit in Prolog user input (read)

I'm writing an interpreter for a game. User enters its move to the interpreter and program executes that move.
Now I want to implement a time limit for each decision. Player shouldn't be able to think more than 30 seconds to write a move and press enter.
call_with_time_limit seemed relevant but it doesnt work properly as such:
call_with_time_limit( 30, read(X) ), Problem, write(Problem).
In this case, it waits for input, and when input is entered, timer starts afterwards. But I want the timer to start at the beginning.
How can I do it?
If you are interested in I/O related timeouts please consider wait_for_input/3 or set_stream/2. The built-in you found, call_with_time_limit/2 is not a simple and reliable interface.
Edit: I just see that you use read/1 for input. Please read in above documentation how to avoid blocking in read/1. It is not clear to me why you need this, but a user might simply enter Return, thereby circumventing the initial timeout. read/1 would now read that '\n' but then would wait for further input - without a timeout, while the user lavishly skims Wikipedia for the answer... might even ask the question on SO...
Your approach seems sensible: from the SWI-Prolog docs: 'Blocking I/O can be handled using the timeout option of read_term/3. '.
That's not really informative: changing timeout on user leads to some bug (I'll test more and will report to SWI_prolog mailing list if appropriate), even under catch/3.
The following seems to work
...,
current_input(I),
wait_for_input([I], A, 30),
...
If not input given (shorter time to test here...)
?- current_input(I), wait_for_input([I],A,5).
I = <stream>(0x7fa75bb31880),
A = [].
EDIT: the variable A will keep the list will contain the list of streams with ready input: I just reported the case where the user doesn't input anything before the timeout occurs. To get the actual input, using your supplied code:
tql :-
current_player(I),
writef('Its %d. players turn: ', [I]),
flush_output,
current_input(Input),
wait_for_input([Input], [Input], 5),
read(Input, Move),
writeln(Move).
current_player(1).
HTH

ruby: How do i get the number of subprocess(fork) running

I want to limit the subprocesses count to 3. Once it hits 3 i wait until one of the processes stops and then execute a new one. I'm using Kernel.fork to start the process.
How do i get the number of running subprocesses? or is there a better way to do this?
A good question, but I don't think there's such a method in Ruby, at least not in the standard library. There's lots of gems out there....
This problem though sounds like a job for the Mutex class. Look up the section Condition Variables here on how to use Ruby's mutexes.
I usually have a Queue of tasks to be done, and then have a couple of threads consuming tasks until they receive an item indicating the end of work. There's an example in "Programming Ruby" under the Thread library. (I'm not sure if I should copy and paste the example to Stack Overflow - sorry)
My solution was to use trap("CLD"), to trap SIGCLD whenever a child process ended and decrease the counter (a global variable) of processes running.

is the code for interpreted languages re-interpreted every time the line is reached?

suppose that no bytecode is generated for a program, like in Ruby, Perl, or PHP, in this case, is line 1 below re-interpreted every time the execution reach line 1 again?
while ($indexArrayMoviesData < $countArrayMoviesData + $countNewlyAddedMoviesData) {
# do something
}
that is, if the loop runs 100,000 times, then that line will be re-interpreted 100,000 times?
and if so, the bytecode creation helps not only the initial start up of he program, but also during the execution? (because code doesn't need to be re-interpreted again)
Typically, it'll be converted into byte code and that byte code will then be executed.
But in the case of PHP for example, the byte code is regenerated on every request/page view. Unless you install a byte code (or opcode as it's called often in the case of PHP) cache, such as XCache, APC or EAccelerator.
For recent languages, including perl, the code is precompiled before being executed. So most of the analysis work is performed only once.
This is not the case for shells, which interpret every line each time they execute them.
If the interpreter is sensible it would hopefully check if $countArrayMoviesData or $countNewlyAddedMoviesData were altered during the loop and if they weren't then the sum could be calculated and kept.
If the values are updated within the loop then in all likelihood even the bytecode would require an addition operation to take place, not making it any more efficient.
Very, very few interpreters will do this. An example is the ages-old, no longer used Hypertalk interpreter for Hypercard where you could actually rewrite the text of your code programatically (it's just a string!)
Even interpreters that don't produce byte code will parse your code first, as it's hard to do that line by line and much easier to do it all at once. So a really simple interpreter will basically have a tree, with a node for the "where" loop with two children: one "less than" expression for the conditional, and one block for the body of the loop.
The answer to your question, as all consultants know, is "it depends."
You're right, in some interpreted languages, that line may be reinterpreted each time. I suspect most shells handle it roughly this way.
The original versions of Basic also did it this way.
Most current interpreters will at least tokenize the language, so that the text doesn't need to be re-scanned each time. That is, a BASIC-ish program like
00010 LET A=42
00020 DO WHILE A > 0
00025 LET A = A - 1
00030 ENDDO
would convert it at the least to small tokens for the keywords, and addresses for the variable, something like
LET $0003, 42
LABEL 00020
LETEST A, 0
IFTRUEGOTO 00030
SUB $0005, $0003, 1
GOTO 00020
LABEL 00030
where each word in upper case in the translation is a single integer internally. That way, there's a single lexical analysis pass to translate it, followed by the interpreter being able to just interpret the token values.
Of course, once you go that far, you find yourself thinking "gee, why not use real opcodes?"

Resources