I mentioned that I had some pseudo code comparing erlang and felix. Anyway, rather than trying to get it perfect, here's what I got. The code is based off of Joe Armstrong's book "Programming Erlang", which happens to be quite interesting:
First the chat server in erlang: ######################################## chat_server.erl: %% --- %% Excerpted from "Programming Erlang" %% Copyrights apply to this code. It may not be used to create training material, %% courses, books, articles, and the like. Contact us if you are in doubt. %% We make no guarantees that this code is fit for any purpose. %% Visit http://www.pragmaticprogrammer.com/titles/jaerlang for more book information. %%--- -module(chat_server). -import(lib_chan_mm, [send/2, controller/2]). -import(lists, [delete/2, foreach/2, map/2, member/2,reverse/2]). -compile(export_all). start() -> start_server(), lib_chan:start_server("chat.conf"). start_server() -> register(chat_server, spawn(fun() -> process_flag(trap_exit, true), Val= (catch server_loop([])), io:format("Server terminated with:~p~n",[Val]) end)). server_loop(L) -> receive {mm, Channel, {login, Group, Nick}} -> case lookup(Group, L) of {ok, Pid} -> Pid ! {login, Channel, Nick}, server_loop(L); error -> Pid = spawn_link(fun() -> chat_group:start(Channel, Nick) end), server_loop([{Group,Pid}|L]) end; {mm_closed, _} -> server_loop(L); {'EXIT', Pid, allGone} -> L1 = remove_group(Pid, L), server_loop(L1); Msg -> io:format("Server received Msg=~p~n", [Msg]), server_loop(L) end. lookup(G, [{G,Pid}|_]) -> {ok, Pid}; lookup(G, [_|T]) -> lookup(G, T); lookup(_,[]) -> error. remove_group(Pid, [{G,Pid}|T]) -> io:format("~p removed~n",[G]), T; remove_group(Pid, [H|T]) -> [H|remove_group(Pid, T)]; remove_group(_, []) -> []. ######################################## pseudo-felix: ######################################## include "lib_chan"; include "chat_group"; module Chat_server { open List; open Assoc_list; union input_msg = | Login of Chat_client::input_channel * string * string | Closed of Chat_group::input_channel ; typedef input_channel = schannel[Return[input_msg, Chat_group::input_channel]]; typedef group_list_t = list[string*Chat_group::input_channel]; proc start () { val chat_server = start_server (); Lib_chan::start chat_server; } gen start_server () : schannel[input_channel] => spawn (proc (server_input:input_channel) { val v = server_input.server_loop Empty[group_list_t]; println $ f"server terminated with: %S" v; }) ; gen server_loop (server_input:input_channel) (gs:group_list_t) => match server_input.read with | Msg $ Login (?client_channel, ?group, ?nick) => let ?gs = match gs.find group with | Some ?group_channel => let () = group_channel.write $ Chat_group::Login (client_channel, nick) in gs | None[Chat_group::input_channel] => let ?group_channel = Chat_group::start_group nick in gs + (group, group_channel) endmatch in server_input.server_loop gs | Msg $ Closed _ => server_input.server_loop gs | Exit $ ?group_channel => let ?gs = gs.remove_group group_channel in server_input.server_loop gs endmatch ; private fun remove_group (gs:group_list_t) (g:schannel[Chat_group::input_channel]) => match gs with | Cons ((_, ?x), ?t) when x == g => t | Cons (?h, ?t) => h + (remove_group gs t) | Empty => gs endmatch ; } ######################################## You'll see that it actually looks quite similar to one another. However, the felix code feels a lot heavier. Most of that comes from the types I feel. ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language