From cpressey@REDACTED Sat Mar 1 02:56:38 2003 From: cpressey@REDACTED (Chris Pressey) Date: Fri, 28 Feb 2003 19:56:38 -0600 Subject: Erlang philosophy explained (was Re: Joe's "deep trickery" ) In-Reply-To: References: <20030228020324.20de7f28.cpressey@catseye.mb.ca> Message-ID: <20030228195638.65adfff6.cpressey@catseye.mb.ca> On Fri, 28 Feb 2003 17:15:44 +0100 (CET) Joe Armstrong wrote: > On Fri, 28 Feb 2003, Chris Pressey wrote: > > > But I've been using a very much simpler method for starting generic > > TCP/IP servers, roughly: > > > ... cut ... > > > This version seems to work ok for me, and even with those > > improvements, it could hardly be called deep trickery; so in deference > > to Joe's wisdom, and knowing how much of a fan he is of simplicity, I > > must assume either: > > > > a) mine has a fatal flaw or flaws that I can't presently perceive, or > > b) Joe forgot the word "efficiently" before "arrange" in his sentence > > > > Neither really, If you compare the two you'll find our code is > pretty similar - I have a bit of extra stuff so I can limit the > maximum number of simultaneously open sockets, and close down all > sockets etc. > > I think if you added this to your code they'd end up being pretty > similar in length - they *should* be similar since they solve the same > problem. Yes, I realize now, after thinking about how to code the max servers thing, that there appears to be no super simple way like I thought there might be. I still think that the warning in tcp_server, without any explanation of what is going on, is pretty harsh for a tutorial, though. > > My concern is mainly that an intimidating module like tcp_server.erl > > could scare off new Erlang programmers by giving them the impression > > that working with TCP/IP in Erlang is a bit nasty. It's not nasty at > > all, at least I don't think it is unless you want to push the > > envelope. > > Perhaps for the tutorial I should put in the simpler version. Yes :) If you could include a simpler version in the body of the tutorial, and say something about how tcp_server basically boils down to it, I think that would make it mind-blowingly approachable. > > > This is otherwise a fine tutorial. I like it. > > > > Middlemen gets me thinking: are there generic consumer/producer > > patterns that can be packaged? I find I'm writing a lot of processes > > along the lines of: accept data in arbitrary-sized chunks from one > > process and dispense it in chunks of some calculated size to another > > process, sometimes reformatting it on the way. > > yes yes yes ^ 100 > > Congratulations you have discovered the Erlang philosophy Cool :) I guess what tripped the switch for me was seeing that any problem can be decomposed into a bunch of middlemen with state - that is, a middleman that translates carriage returns to linefeeds isn't very interesting, but one that buffers data until the next linefeed, then sends a whole line, is much more interesting. > Let me reformulate what you said in another way to clarify this. > > > Middlemen gets me thinking: are there generic consumer/producer > > patterns that can be packaged? I find I'm writing a lot of processes > > along the lines of: accept data in arbitrary-sized chunks from one > > process and SEND IT AS AN ERLANG MESSAGE TO ANOTHER PROCESS > > I'm kicking myself here, this way of programming was so obvious to > me that I never explicitly wrote it down. I always used the *say* it > when giving lectures but never actually committed it to paper. > > The Erlang "philosophy" is "everything is an Erlang process" > > Remember, Erlang processes share no data and only interact by > exchanging > Erlang messages. > > So if you have a non-Erlang thing you should fake it up so that the > other things in the system think that it *is* an Erlang process. > > Then everything become ridiculously easy. > > That's where the middle-man comes in: > > > Back to my tutorial. A web sever is like this: > > +---------------------+ +--------+ > ------>------| Middle man |--------->--------| Web | > TCP/packets | defragments packets | {get,URL,Args} | server | > | parse HTTP requests | | | > ------<------| and formats HTTP |---------<--------| | > | responses | {Header,Data} +--------+ > +---------------------+ > > The middle man turns the HTTP data stream (where TCP can fragment the > packets) into a nice stream of fully parsed Erlang terms. > > An HTTP/1.0 server is trivial: > > server() -> > receive > {From, {get,URL,Args}} -> > Response = process_get(URL, Args), > From ! {self(), Response} > end. > > And an HTTP/1.1 server with keep-alive sockets > > server() -> > loop(). > > loop() -> > receive > {From, {get,URL,Args}} -> > Response = process_get(URL, Args), > From ! {self(), Response}, > loop(); > after 10000 -> > exit(timeout) > end. > > Which is *very* clear and easy to write etc. Yes. > If you munge these into a single process you get an unholy mess > (this is what I call getting the concurrency model wrong) - using one > process per connection is simple obvious and highly efficient (as I've > said earlier YAWS beats the socks of Apache) > > > > Look what we've done here, we've kind of "lifted" the abstraction > level > of a device driver. > > In unix things are nice because *everything* is a producer or > consumer of flat streams of bytes - sockets and pipes are just the > plumbing that carry the data from a producer to a consumer. > > In Erlang the data level is lifted instead of flat stream of bytes, > everything is an object of type "term" but *no parsing or deparsing is > necessary" and no fragmentation of the term can occur. > > We might like to ask what a unix pipe: > > cat file2 > > Might look like in Erlang > > This is surely 4 process linked together > > cat is a process which sends a stream of > > {self(), {line, Str}} > > followed by a stream of > > {self(), eof} > > messages > > x and y are processes that look like > > loop(IN, Out) -> > receive > {In, Msg} -> > ... > Out ! {self(), Msg2} > loop(In, Out) > > > etc. > > All of this makes me wonder if perhaps the modules with API ways of > programming is wrong. Well, I definately have some thoughts on API's that coincide with that. Current conceptions of what makes an API are crude. What you generally have is a list of entry points (names of synchronous function calls) with the number of arguments and their types for each. This is I think because this fits in with current systems-construction linker technology well. But it's not as powerful as it could be if it were to provide more information (such as the complexity of the exported functions) and to provide it in a more flexible way (in patterns, which may or may not be synchronous, i.e. like Erlang messages.) > Perhaps we should be thinking more in terms of abstractions that > allow us to glue things together with pipes etc. > > This seems to be related to my "bang bang" notation but I haven't yet > made the connection - I'm still thinking about it. > > > Is there something like a > > gen_stream that I've overlooked in OTP? > > No > > > then I start thinking: why the hell do I want more gen_* modules when > > I rarely ever use the existing ones? For better or worse, I usually > > build my own with receive and !, which I find easier to read (at least > > while coding,) with the assumption that some day, if it becomes really > > important, I'll rewrite them to be gen_*'s. So I sat myself down the > > other day and forced myself to write one each gen_server, gen_event > > and gen_fsm, to practice. > > Me too :-) The gen_ things were put together for projects with lots > of programmers in the same team - without gen_server (say) in a 20 > programmer projects we'd end up with 20 ways of writing a server - > using one way means the people can understand each other's code. Yes, I guess I can see how any convention would help with that. > For small projects you can happily "roll you own" And for that, it's just as important to know how they work, that is, to know what they look like (that is, to be able to recognize a design pattern instead of just knowing how to use the off-the-shelf implementation of the pattern.) I take that point well now... -Chris From cpressey@REDACTED Sat Mar 1 05:43:56 2003 From: cpressey@REDACTED (Chris Pressey) Date: Fri, 28 Feb 2003 22:43:56 -0600 Subject: gen_tcp:controlling_process In-Reply-To: References: Message-ID: <20030228224356.6b7e29a1.cpressey@catseye.mb.ca> On Fri, 28 Feb 2003 12:15:35 -0000 Sean Hinde wrote: > > As Martin says "use with care" it is worth pointing out > > another way of doing > > this: > > > > Have a process which owns the listening socket. This will > > spawn a socket > > process which will block in accept until a client arrives - > > at which time it > > messages back to the listening process to tell it to spawn a new > > socket/accepting process. > > > > This model is widely used but for a very nice example take a > > look at joe's > > recent web_server tutorial. http://www.sics.se/~joe > > Now I just read Chris' post pointing out Joe's comment that this is very > complex.. If you study Joes code (always an education) you will > eventually see why, but if you don't need to limit the number of > connections then my recipe will work OK (you of course do need to handle > EXIT messages from the accepting process, which may arrive before or > after the accept succeeded) > > Sean OK, I added connection capping to my version, the results can be seen at http://kallisti.mine.nu/projects/ce-2003.0228/src/ce_socket.erl With it, the complexity *does* increase - I'm beginning to see why Joe's looks the way it does. Because the accept call waits until a connection comes in, it has to be handled asynchronously if you want to be able to handle messages (like {'EXIT',Pid,Reason} to count how many sockets are currently connected) while waiting. So you need another process. I did it kind of backwards compared to Sean's description - the main loop spawns an asynchronous accept process each time it starts waiting (and kills it when it realizes it's run out of connections, so there's probably a tiny race condition there... I'll work on it not starting it in the first place, tomorrow) -Chris From spearce@REDACTED Sun Mar 2 07:25:55 2003 From: spearce@REDACTED (Shawn Pearce) Date: Sun, 2 Mar 2003 01:25:55 -0500 Subject: Linking to/from a gen_server? Message-ID: <20030302062555.GA28668@spearce.org> Ok, so I'm trying to use OTP stuff as much as I can right now, as I haven't really learned it all yet. :) I'm trying to setup a way to have a client process send a gen_server a message, where the gen_server stuffs a term and the client's pid into an ets table managed by the gen_server. I want the gen_server to link to the client process so it can remove the term and client pid when the client process exits. But it occured to me, gen_server:call/2 links to the gen_server process, sends the message, and waits for the response with a timeout. It then unlinks from the gen_server. This means the gen_server can't link to the client process during its handle_call/3 callback, as the unlink will be done by the client after the call completes. I could use gen_server:cast/2, but i do need a response to be sent back to the client so it knows the operation was successful. Ideas from the OTP experts? -- Shawn. You shall be rewarded for a dastardly deed. From valentin@REDACTED Sun Mar 2 09:21:18 2003 From: valentin@REDACTED (Valentin) Date: Sun, 2 Mar 2003 10:21:18 +0200 Subject: Linking to/from a gen_server? References: <20030302062555.GA28668@spearce.org> Message-ID: <000601c2e094$c862b950$01010d0a@moneymaker> > > I could use gen_server:cast/2, but i do need a response to be sent > back to the client so it knows the operation was successful. > I am not an expert (yet), and am not quite sure that I understand your problem completely (or even at all), but you may want to use gen_server:reply/2. V. From lennart.ohman@REDACTED Sun Mar 2 11:34:29 2003 From: lennart.ohman@REDACTED (=?ISO-8859-1?Q?Lennart_=D6hman?=) Date: Sun, 02 Mar 2003 11:34:29 +0100 Subject: Linking to/from a gen_server? References: <20030302062555.GA28668@spearce.org> Message-ID: <3E61DE35.4010308@st.se> Hi, your concerns are valid. However...: 1) In the early beginning of BOS (OTP ancestor) we choose to use a time-out *only* in gen_server:call. One reason was what you described. But the other was that internal handling of links (the structure it was stored in) was not built for having a lot of links and at the same time manage them frequently. 2) Nowdays there is another mechanism - erlang:monitor which monitors the existance of "things". Today the only "thing" which can be monitored is another process. Monitoring has two significant differences to links. (i) Monitoring is *not* bi-directional. (ii) Monitoring results in as many DOWN-messages as monitoing has be been called. Very good for writing library code for instance. Today, to my knowledge, all OTP gen-code has been rewritten in "modern style" using monitoring instead. Hence you may very well implement your solution as have your gen-server monitor the client PID, and be responsive (in handle_info) to DOWN-messages from such PIDs. /Lennart Shawn Pearce wrote: > Ok, so I'm trying to use OTP stuff as much as I can right now, as I > haven't really learned it all yet. :) > > I'm trying to setup a way to have a client process send a gen_server > a message, where the gen_server stuffs a term and the client's pid > into an ets table managed by the gen_server. I want the gen_server > to link to the client process so it can remove the term and client > pid when the client process exits. > > But it occured to me, gen_server:call/2 links to the gen_server > process, sends the message, and waits for the response with a > timeout. It then unlinks from the gen_server. This means the > gen_server can't link to the client process during its handle_call/3 > callback, as the unlink will be done by the client after the call > completes. > > I could use gen_server:cast/2, but i do need a response to be sent > back to the client so it knows the operation was successful. > > Ideas from the OTP experts? > ------------------------------------------------------------- Lennart Ohman phone : +46-8-587 623 27 Sjoland & Thyselius Telecom AB cellular: +46-70-552 6735 Sehlstedtsgatan 6 fax : +46-8-667 8230 SE-115 28 STOCKHOLM, SWEDEN email : lennart.ohman@REDACTED From jay@REDACTED Sun Mar 2 00:42:55 2003 From: jay@REDACTED (Jay Nelson) Date: Sat, 01 Mar 2003 15:42:55 -0800 Subject: Communicating processes vs. APIs Message-ID: <4.2.2.20030301152726.00ce42f0@duomark.com> Joe wrote: > We might like to ask what a unix pipe: > > cat file2 > > Might look like in Erlang > > Perhaps we should be thinking more in terms of abstractions that > allow us to glue things together with pipes etc. My thought was that a firewall router is the model of what all this abstraction is about. The purpose is to allow messages in, but to filter out the bad stuff; present a unified front end for simplicity yet allow arbitrary server complexity behind the scenes that is opaque to the caller. This translates into the following abstract pieces: 1) Stream accepter - the only way in 2) Filter - removes the bad stuff 3) Router - determines who is interested; acts as middleman 4) Handler - implements the behaviour the client expects The router is the only thing that receives from the outside and sends to the outside. Filters may exist on both sides of the router. I've always complained about error handling code because it gets in the way of the algorithms. I've wanted a way to write parallel code: one is the error-free thread of the algorithm logic, and the other is only the error handling part of the code. Finally, erlang offers a way although the partitioning is different: use intermediate processes to clean up the data before it arrives at the algorithm process. The final process can safely assume only valid data, or die if one of the upstream processes has a bug. Likewise, protocol transformation can occur a step at a time. This approach leads to maximal reuse of software, something that discrete objects does not allow: the reassembly of logical pieces in a different coherent whole. The best thing of all this discussion is that we can design, discuss and argue about the protocol semantics without considering what algorithms are being implemented. The protocol can be later tweaked without modifying the algorithms. Using filter processes gives the same capability when dealing with streams that have errors in them -- the error handling can be dealt with wholly independent of the algorithm or its efficiency in dealing with good data. Marrying this back to the UI thread, the user generates the stream and the first filter notifies the user of obvious errors without doing a round trip through the system. Errors which require more correlation of information progress deeper in the chain of processes before being sent back to the user, with only those that properly penetrate the router receiving full responses. jay From jay@REDACTED Sun Mar 2 00:26:10 2003 From: jay@REDACTED (Jay Nelson) Date: Sat, 01 Mar 2003 15:26:10 -0800 Subject: controlling_process and TCP servers Message-ID: <4.2.2.20030301130434.00cd8810@duomark.com> Sean Hinde wrote: > > This model is widely used but for a very nice example take a > > look at joe's > > recent web_server tutorial. http://www.sics.se/~joe Chris Pressey wrote: > OK, I added connection capping to my version, the results can be seen at > http://kallisti.mine.nu/projects/ce-2003.0228/src/ce_socket.erl > With it, the complexity *does* increase - I'm beginning to see why Joe's > looks the way it does. I was just completing a tutorial for a TCP proxy server using OTP gen_server when I asked the gen_tcp:controlling_process question. Now I see I'll have to do a little more reading and thinking before I post it! The subtleties are similar to analyzing the opening moves of a chess game. It turns out I implemented exactly the same thing they did without knowing it. I guess this is a popular idiom that should be available to everyone. From what I understand so far the issues involve: spawn race conditions, message ordering, which process receives messages and how many connections are active. Joe's approach: 1) Spawn a cold start and exit when it returns. 2) Create a listen socket with {active, false} in the new process, spawn an Accepter and then enter the server loop [cold start thread]. 3) Meanwhile the Accepter sends a message to the server loop when it gets a connect, sets {active, true} and transfers control to the handler routine; the server spawns a new Accepter if it hasn't reached the maximum count. Joe avoids spawn race conditions by maintaining {active, false} until the handler is ready to run, so the mailbox of messages doesn't get confused between processes and he doesn't need to call controlling_process. All of the messages received by the server come from the Accepter process, except for the query for the Children list. Each new connection is a separate process with separate messages, so no ordering issues come up. The server needs to stay up to maintain the children list, so EXITs must be caught and handled properly. Chris has a similar approach with the main differences in the over-generation of an Accept and the use of gen_tcp: controlling_process. I am taking the approach of using OTP and gen_server. The main difference is that I can be less worried about the server process going down because I will use a supervisor to restart it when it happens, and rely on error logs to tell me what is going wrong over time. It does mean that I need to avoid using state in any process I will allow to go down, however, and prevent those that need state from going down. The other difference is that where they used erlang messages to notify when connections arrive, the messages are hidden in my approach because the gen:call methods implement the messaging. I will have to add the children counting and reporting so that it is comparable to Joe's. I wasn't planning on worrying about it in the beginning. My approach is: 1) Spawn a linked gen_server that opens a Listen socket, and then spawns an Accept. 2) When Accept receives a connection, it spawns a linked Relay process that transfers the socket to the ProxyModule. 3) The Accept loops waiting for the next connection. I used {active, false} so I wouldn't have to worry about passing the controlling_process (although my next task is to read the source code for gen_tcp:controlling_process), and so that the details of parsing the stream can occur in ProxyModule. In reality I am going to give Relay enough smarts to be a simple router to one of several ProxyModules, but not enough knowledge to need to inspect the packets. Each ProxyModule can be what Joe calls a middleman process dealing with the Socket and translating to / from erlang messages. One thing I am worried about is that I am not spawning a new Accept process on every connection. I am spawning a new child, but looping on the same Accept process the whole time. This allows my Accept state to maintain statistics without resorting to message passing, but the main gen_server doesn't have access to the statistics. The worry is that somehow starting a new process on the Accept might avoid process corruption or garbage issues over the course of a month of non-stop running. It is a single function running a tight loop, so I feel justified that I can work out any problems. The big issues I need to address are managing a large number of connections without overburdening, allowing a distributed network of servers to handle the computational load, and maintaining both stateless HTTP and stateful game connections while attempting to keep a single server front (http://myserver:80/) rather than bouncing people around to different servers. I need to rework the text, add the max connection stuff, and do some more testing before I post it. Unfortunately, home chores are taking priority. I expect to have something up this weekend, though. I hope that someone will find it useful since it is so similar to everyone else's code it won't offer much insight, but will give an example of solving the same problem using gen_server. jay From jay@REDACTED Sun Mar 2 09:50:47 2003 From: jay@REDACTED (Jay Nelson) Date: Sun, 02 Mar 2003 00:50:47 -0800 Subject: Linking to/from a gen_server? Message-ID: <4.2.2.20030302002352.00cdb230@duomark.com> Tomorrow (cross fingers) I will post my tutorial showing the OTP equivalent to Joe's tcp_server.erl. In it I use an ets table to keep track of the spawned child processes and receive Info messages to delete from the ets table when a process ends. I haven't yet tested any of the code below, but in principle it should work (oh, if programming were that easy...) > I'm trying to setup a way to have a client process send > a gen_server a message The way I do it is to introduce a function entry point in the module implementing the gen_server behaviours: call_and_link(Server, PingData) -> gen_server:call(Server, {msg, PingData}). > I want the gen_server to link to the client process so > it can remove the term and client pid when the client > process exits. handle_call({msg, PingData}, From, State) when pid(From) -> link(From), Table = State#state.ets_table, ets:insert(Table, {From, erlang:now(), PingData}), do_other_stuff(), {reply, ok, State}. This approach means that your client's process calls call_and_link and waits for a response. During the response, gen_server:call runs in the client's process and sends a message to the gen_server process which triggers the Module:handle_call method to execute. When it executes, the From id of the client process is linked to the server, the ets table kept in the state is updated, and 'ok' is sent back to the gen_server:call running in the client process and it is returned as the result of the call_and_link function. You could do the same thing with gen_server:cast and handle_cast if you expect do_other_stuff() to take a long time, with the handle_cast function calling gen_server:reply before returning {noreply, State}. You will see the EXIT message in handle_info when a linked process dies: handle_info({'EXIT', Pid, Reason}, State when pid(Pid) -> Table = State#state.ets_table, ets:delete(Table, Pid), {noreply, State}. > But it occured to me, gen_server:call/2 links to the > gen_server process, sends the message, and waits > for the response with a timeout. It then unlinks from > the gen_server. I believe it only _monitors_ the process and then _demonitors_ it. This is so it can see if the node is 'DOWN', but AFAIK that is different than linking to the process. jay From jocke@REDACTED Sun Mar 2 20:24:07 2003 From: jocke@REDACTED (Joakim G.) Date: Sun, 02 Mar 2003 20:24:07 +0100 Subject: gen_tcp:controlling_process In-Reply-To: <1046447209.21719.334.camel@berimbau> References: <3E5F5FB5.3010300@bluetail.com> <1046447209.21719.334.camel@berimbau> Message-ID: <3E625A57.7060602@bluetail.com> martin j logan wrote: >Jocke, > Out of curiosity what method do you prefer to use when writing >something general that you wish a user to be able to extend with >specific functionality? I find callback programming to be the simplest >technique - at least in Erlang. I would be interested in your >opinion/preference - if you have the time and inclination to give it. > >Cheers, >Martin > >On Fri, 2003-02-28 at 07:10, Joakim G. wrote: > > >>I often argue that callback oriented programming is boring. Still I found >>myself writing: >> >>http://www.gleipnir.com/xmlrpc/unpacked/LATEST/src/tcp_serv.erl >> >>A good old ad hoc tcp server behaviour. :-) >> >>Cheers >>/Jocke >> >>Sean Hinde wrote: >> >> >> >>>>As Martin says "use with care" it is worth pointing out >>>>another way of doing >>>>this: >>>> >>>>Have a process which owns the listening socket. This will >>>>spawn a socket >>>>process which will block in accept until a client arrives - >>>>at which time it >>>>messages back to the listening process to tell it to spawn a new >>>>socket/accepting process. >>>> >>>>This model is widely used but for a very nice example take a >>>>look at joe's >>>>recent web_server tutorial. http://www.sics.se/~joe >>>> >>>> >>>> >>>> >>>Now I just read Chris' post pointing out Joe's comment that this is very >>>complex.. If you study Joes code (always an education) you will eventually >>>see why, but if you don't need to limit the number of connections then my >>>recipe will work OK (you of course do need to handle EXIT messages from the >>>accepting process, which may arrive before or after the accept succeeded) >>> >>>Sean >>> >>> >>> >>>NOTICE AND DISCLAIMER: >>>This email (including attachments) is confidential. If you have received >>>this email in error please notify the sender immediately and delete this >>>email from your system without copying or disseminating it or placing any >>>reliance upon its contents. We cannot accept liability for any breaches of >>>confidence arising through use of email. Any opinions expressed in this >>>email (including attachments) are those of the author and do not necessarily >>>reflect our opinions. We will not accept responsibility for any commitments >>>made by our employees outside the scope of our business. We do not warrant >>>the accuracy or completeness of such information. >>> >>> >>> >>> >> >> > > > From cpressey@REDACTED Sun Mar 2 21:01:02 2003 From: cpressey@REDACTED (Chris Pressey) Date: Sun, 2 Mar 2003 14:01:02 -0600 Subject: controlling_process and TCP servers In-Reply-To: <4.2.2.20030301130434.00cd8810@duomark.com> References: <4.2.2.20030301130434.00cd8810@duomark.com> Message-ID: <20030302140102.2415ab6c.cpressey@catseye.mb.ca> On Sat, 01 Mar 2003 15:26:10 -0800 Jay Nelson wrote: > Sean Hinde wrote: > > > > This model is widely used but for a very nice example take a > > > look at joe's > > > recent web_server tutorial. http://www.sics.se/~joe > > Chris Pressey wrote: > > > OK, I added connection capping to my version, the results can be seen > > at > > http://kallisti.mine.nu/projects/ce-2003.0228/src/ce_socket.erl > > With it, the complexity *does* increase - I'm beginning to see why > > Joe's looks the way it does. The URL for my latest version is http://kallisti.mine.nu/projects/ce-+ (Filename completion: just one of the many Stupid Webserver Tricks I've implemented :) I've also imported the library into Jungerl, and I'll probably publish future snapshots of it from there. > [...] > Joe avoids spawn race conditions by maintaining {active, > false} until the handler is ready to run, so the mailbox of > messages doesn't get confused between processes and > he doesn't need to call controlling_process. According to Martin, this isn't an issue anyway - all tcp messages that have already been sent are bequeathed to the new process when you call gen_tcp:controlling_process. > Chris has a similar approach with the main differences in > the over-generation of an Accept and the use of gen_tcp: > controlling_process. The other thing that controlling_process does is that it changes the owner of the socket. If the owner of a socket dies, that socket gets closed too. That's the reason I call it twice - once to transfer control from the Accepter to the main loop, and again to transfer it to the callback module. Since my Accepter dies and gets respawned, this stops the socket from disappearing before it gets to the main loop. Also, since my Accepter dies, I don't ever link to it, because I don't want to get the 'EXIT' message, because it's easier to assume in the main loop that those only come from the callbacks. It wouldn't be hard to keep the Accepter alive indefinately instead of continually spawning new ones - send it synchronization messages - but I wanted to keep the complexity down a bit initially - maybe later. -Chris From jocke@REDACTED Sun Mar 2 21:31:06 2003 From: jocke@REDACTED (Joakim G.) Date: Sun, 02 Mar 2003 21:31:06 +0100 Subject: gen_tcp:controlling_process In-Reply-To: <1046447209.21719.334.camel@berimbau> References: <3E5F5FB5.3010300@bluetail.com> <1046447209.21719.334.camel@berimbau> Message-ID: <3E626A0A.9050000@bluetail.com> martin j logan wrote: >Jocke, > Out of curiosity what method do you prefer to use when writing >something general that you wish a user to be able to extend with >specific functionality? I find callback programming to be the simplest >technique - at least in Erlang. I would be interested in your >opinion/preference - if you have the time and inclination to give it. I also find callback programming a powerful technique. For example, my xmlrpc library uses it both in its external API as well as internally, i.e. An example of an xmlrpc server implemented via a callback module: http://www.gleipnir.com/xmlrpc/unpacked/LATEST/examples/fib_server.erl Internally in the xmlrpc library I use my own callback oriented tcp server: http://www.gleipnir.com/xmlrpc/unpacked/LATEST/src/tcp_serv.erl I find the above meaningful. The problem with the gen_server (and to some extent the supervisor) module is that its main purpose is to hide central Erlang programming concepts/constructs, e.g. bang (!), pattern matching on messages in mailboxes using receive, EXIT signal propagation, tail recursive-oriented server loops etc. Sean suggested that I could rewrite my tcp_serv.erl above using the gen_server. Over my dead body I said. Why? Because it would provide me with nothing expect boredom, i.e. tracing is available anyway these days. Software replacement (if I need it) can be implemented as described here: http://www.erlang.org/doc/r9b/doc/design_principles/spec_proc.html#7 Personally I think that the recommendation to new Erlang users to use the gen_server is a disaster. At least when it comes to the growth of the Erlang user base. They just get the wrong impression on how we recommend "real" Erlang code to be written. When I discuss this with Martin B. (one of the people behind OTP) he usually points at me [like Uncle Sam in the famous president campaign poster] saying: "So you want us to copy&paste common code in order to write a new server?". I just have to say yes. Cheers /Jocke PS Sorry for the previous empty message. My son attacked the keyboard. :-) DS From ulf.wiger@REDACTED Sun Mar 2 22:24:54 2003 From: ulf.wiger@REDACTED (Wiger Ulf) Date: Sun, 2 Mar 2003 22:24:54 +0100 Subject: gen_tcp:controlling_process References: <3E5F5FB5.3010300@bluetail.com> <1046447209.21719.334.camel@berimbau> <3E626A0A.9050000@bluetail.com> Message-ID: <018001c2e102$2b2f4ea0$fd7a40d5@telia.com> From: "Joakim G." > Personally I think that the recommendation to new Erlang users to use > the gen_server is a disaster. At least when it comes to the growth of > the Erlang user base. They just get the wrong impression on how we > recommend "real" Erlang code to be written. > > When I discuss this with Martin B. (one of the people behind OTP) > he usually points at me [like Uncle Sam in the famous president > campaign poster] saying: "So you want us to copy&paste common code in > order to write a new server?". I just have to say yes. Of the various ideas I've had during the AXD 301 project, suggesting that we'd use "classic servers" for the call handling code was one of the dumbest, and I had to take that back later. In those early days, gen_server wasn't all that fast, and we were looking for any performance advantage we could get. Thus, in order to shave off some 50 us per call, "we" (mostly I) decided that gen_server was unneccessary overhead for performance-critical processes, and it wasn't that difficult after all to write those servers from scratch. So I made an example server and people could copy it. It didn't work out well. We did get some measurable (but not more) performance improvement, but we also got measurably more bugs in our system. After a while, we wrote it off as a bad idea and went back to gen_servers. So my advice to newcomers, based on past mistakes: use gen_server. Those of you who get hooked on the language and play around enough to eventually discover the Erlang Philosophy, will eventually be able to roll your own and (perhaps) leave gen_server behind you. Personally, I use gen_server a lot still. I've had my ups and downs with it, but we always make up eventually. /Uffe From urfaust@REDACTED Sun Mar 2 23:51:40 2003 From: urfaust@REDACTED (Faust) Date: Mon, 03 Mar 2003 09:51:40 +1100 Subject: Linking to/from a gen_server? In-Reply-To: <4.2.2.20030302002352.00cdb230@duomark.com> (Jay Nelson's message of "Sun, 02 Mar 2003 00:50:47 -0800") References: <4.2.2.20030302002352.00cdb230@duomark.com> Message-ID: This is a message from comp.lang.functional. Someone wanted "hot code replacement, just like erlang" I suggested using erlang. This was the reply I recieved. Perhaps someone more knowledgeable than me could answer in comp.lang.functional **************************************************** Forwarded from comp.lang.functional Faust wrote: > > Erlang is a functional language. > Is there any reason to not use erlang ? I have never programmed in Erlang, just skimmed a few chapters of written material, so take this as an account of how good or bad the Erlang PR is, not whether Erlang is good or bad. So, here's what speaks against Erlang (there are also a lot of things that speak *for* it, I'm omitting that because it would be off-topic): 1. No static typing. 2. Bytecode interpreted (i.e. not compiled to native code). 3. Possibly not "really functional", i.e. mutable stuff (message sends and state-dependent responses) play an important part when it comes to structuring and maintaining large programs. (Of course, you *can* do large parts of purely functional programming in Erlang.) (This is just an impression that I gained, something that somebody with personal experience in Erlang should confirm or deny. Hence the "possibly" in the first sentence of this paragraph.) 4. Some roots in Prolog, which I find... er... disturbing (my personal encounters with Prolog were, say, unlucky... its strengths were less useful than I had expected, and definitely not worth the weaknesses that were the payment for its strengths - IMHO (I never became a Prolog guru)). Note that all of the above points might be considered irrelevant, a showstopper, or even a plus, depending on circumstances, available expertise, and personal religion. Regards, Joachim ************************** end of forwarded message. -- natsu-gusa ya / tsuwamono-domo-ga / yume no ato summer grasses / strong ones / dreams site Summer grasses, All that remains Of soldier's dreams (Basho trans. Stryk) From urfaust@REDACTED Mon Mar 3 00:18:23 2003 From: urfaust@REDACTED (Faust) Date: Mon, 03 Mar 2003 10:18:23 +1100 Subject: Erlang questions on comp.lang.functional. In-Reply-To: (Faust's message of "Mon, 03 Mar 2003 09:51:40 +1100") References: <4.2.2.20030302002352.00cdb230@duomark.com> Message-ID: This is a message from comp.lang.functional. Someone wanted "hot code replacement, just like erlang" I suggested using erlang. This was the reply I recieved. Please not the comment about "how good or bad Erlang PR is " Perhaps someone more knowledgeable than me could answer in comp.lang.functional, thus contributing to good PR :-) **************************************************** Forwarded from comp.lang.functional Faust wrote: > > Erlang is a functional language. > Is there any reason to not use erlang ? > I have never programmed in Erlang, just skimmed a few chapters of written material, so take this as an account of how good or bad the Erlang PR is, not whether Erlang is good or bad. So, here's what speaks against Erlang (there are also a lot of things that speak *for* it, I'm omitting that because it would be off-topic): 1. No static typing. 2. Bytecode interpreted (i.e. not compiled to native code). 3. Possibly not "really functional", i.e. mutable stuff (message sends and state-dependent responses) play an important part when it comes to structuring and maintaining large programs. (Of course, you *can* do large parts of purely functional programming in Erlang.) (This is just an impression that I gained, something that somebody with personal experience in Erlang should confirm or deny. Hence the "possibly" in the first sentence of this paragraph.) 4. Some roots in Prolog, which I find... er... disturbing (my personal encounters with Prolog were, say, unlucky... its strengths were less useful than I had expected, and definitely not worth the weaknesses that were the payment for its strengths - IMHO (I never became a Prolog guru)). Note that all of the above points might be considered irrelevant, a showstopper, or even a plus, depending on circumstances, available expertise, and personal religion. Regards, Joachim ************************** end of forwarded message. -- natsu-gusa ya / tsuwamono-domo-ga / yume no ato summer grasses / strong ones / dreams site Summer grasses, All that remains Of soldier's dreams (Basho trans. Stryk) From spearce@REDACTED Mon Mar 3 00:40:15 2003 From: spearce@REDACTED (Shawn Pearce) Date: Sun, 2 Mar 2003 18:40:15 -0500 Subject: Erlang questions on comp.lang.functional. In-Reply-To: References: <4.2.2.20030302002352.00cdb230@duomark.com> Message-ID: <20030302234015.GH22853@spearce.org> Faust wrote: > **************************************************** > Forwarded from comp.lang.functional > > Faust wrote: > > > > Erlang is a functional language. > > Is there any reason to not use erlang ? > > > I have never programmed in Erlang, just skimmed a few chapters of > written material, so take this as an account of how good or bad the > Erlang PR is, not whether Erlang is good or bad. > So, here's what speaks against Erlang (there are also a lot of things > that speak *for* it, I'm omitting that because it would be off-topic): > > 1. No static typing. Unless your a lover of C++, I fail to see this as being a problem. I only see it as being an issue as far as performance optimization possibilities go. Perhaps a large number of bugs really do occur in programs as a result of not having static type checking in the compiler, but in general my experience has been that this only is a problem in Perl, and only when checking that you spell structure member names correctly everywhere. (As Perl structs tend to be just hashes with arbitrary keys used as string constants.) > 2. Bytecode interpreted (i.e. not compiled to native code). Isn't this why we have HIPE? And thus far, I have not seen HIPE improve performance over code run in the bytecode interpreter. Therefore I have to ask: - is the rest of erts slow? - is the bytecode interpreter really fast? - do I just keep my mathmatical computation outside of erlang? > 3. Possibly not "really functional", i.e. mutable stuff (message sends > and state-dependent responses) play an important part when it comes to > structuring and maintaining large programs. (Of course, you *can* do > large parts of purely functional programming in Erlang.) (This is just > an impression that I gained, something that somebody with personal > experience in Erlang should confirm or deny. Hence the "possibly" in the > first sentence of this paragraph.) I think the reality is it is impossible to build a programming language that doesn't have side effects. Consequently, Erlang offers the best of both worlds. You can build code that is side-effect free when appriopiate, but also build code that has side-effects when it is necessary for either correct function (to do IO perhaps) or for performance (like using ets vs. a pure functional datastructure). > 4. Some roots in Prolog, which I find... er... disturbing (my personal > encounters with Prolog were, say, unlucky... its strengths were less > useful than I had expected, and definitely not worth the weaknesses that > were the payment for its strengths - IMHO (I never became a Prolog guru)). Er, I hated Prolog and had as much distaste for it as I think the author of this forwarded message has. But the Prolog roots is what I think I love most about Erlang. Everything is just pattern matching and message sending. :-) How could one not love that? > ************************** > end of forwarded message. Just my two cents (USD, currently worth less than two Euro cents). :-) -- Shawn. Things past redress and now with me past care. -- William Shakespeare, "Richard II" From Marc.Vanwoerkom@REDACTED Mon Mar 3 01:09:04 2003 From: Marc.Vanwoerkom@REDACTED (Marc Ernst Eddy van Woerkom) Date: Mon, 3 Mar 2003 01:09:04 +0100 (MET) Subject: gen_tcp:controlling_process In-Reply-To: <3E626A0A.9050000@bluetail.com> (jocke@bluetail.com) Message-ID: <200303030009.h23094f02935@bonsai.fernuni-hagen.de> > Sorry for the previous empty message. My son attacked the > keyboard. :-) DS I have an extra keyboard and mouse on the table, in case my daughter attacks. :) Regards, Marc From spearce@REDACTED Mon Mar 3 01:15:38 2003 From: spearce@REDACTED (Shawn Pearce) Date: Sun, 2 Mar 2003 19:15:38 -0500 Subject: Linking to/from a gen_server? In-Reply-To: <3E61DE35.4010308@st.se> References: <20030302062555.GA28668@spearce.org> <3E61DE35.4010308@st.se> Message-ID: <20030303001538.GJ22853@spearce.org> Is there any limitation imposed by erts on the number of processes another process (my gen_server) can monitor at once? Or is it just the limitation on number of actively running processes within the local node? I'm only interested in this gen_server monitoring a large number (around 4-5k) of local processes so that if they crash or terminate unexpectedly the ets dictionary is cleaned up so future lookups for that process won't find it. Essentially its my own form of register/2 for local processes, but register/2 is too limited for me, I need to use more than just an atom to associate a process to my data. I had forgotten about the monitor/2 call, thanks for the pointer. :) Lennart ?hman wrote: > Hi, > your concerns are valid. However...: > > 1) In the early beginning of BOS (OTP ancestor) we choose to use > a time-out *only* in gen_server:call. One reason was what you > described. But the other was that internal handling of links > (the structure it was stored in) was not built for having a > lot of links and at the same time manage them frequently. > > 2) Nowdays there is another mechanism - erlang:monitor which > monitors the existance of "things". Today the only "thing" > which can be monitored is another process. > Monitoring has two significant differences to links. > (i) Monitoring is *not* bi-directional. > (ii) Monitoring results in as many DOWN-messages as monitoing > has be been called. Very good for writing library code > for instance. > > Today, to my knowledge, all OTP gen-code has been rewritten in > "modern style" using monitoring instead. > > Hence you may very well implement your solution as have your gen-server > monitor the client PID, and be responsive (in handle_info) to > DOWN-messages from such PIDs. > > /Lennart > > > Shawn Pearce wrote: > >Ok, so I'm trying to use OTP stuff as much as I can right now, as I > >haven't really learned it all yet. :) > > > >I'm trying to setup a way to have a client process send a gen_server > >a message, where the gen_server stuffs a term and the client's pid > >into an ets table managed by the gen_server. I want the gen_server > >to link to the client process so it can remove the term and client > >pid when the client process exits. > > > >But it occured to me, gen_server:call/2 links to the gen_server > >process, sends the message, and waits for the response with a > >timeout. It then unlinks from the gen_server. This means the > >gen_server can't link to the client process during its handle_call/3 > >callback, as the unlink will be done by the client after the call > >completes. > > > >I could use gen_server:cast/2, but i do need a response to be sent > >back to the client so it knows the operation was successful. > > > >Ideas from the OTP experts? > > > > > ------------------------------------------------------------- > Lennart Ohman phone : +46-8-587 623 27 > Sjoland & Thyselius Telecom AB cellular: +46-70-552 6735 > Sehlstedtsgatan 6 fax : +46-8-667 8230 > SE-115 28 STOCKHOLM, SWEDEN email : lennart.ohman@REDACTED > -- Shawn. You will gain money by a fattening action. From Marc.Vanwoerkom@REDACTED Mon Mar 3 01:47:15 2003 From: Marc.Vanwoerkom@REDACTED (Marc Ernst Eddy van Woerkom) Date: Mon, 3 Mar 2003 01:47:15 +0100 (MET) Subject: Linking to/from a gen_server? In-Reply-To: (message from Faust on Mon, 03 Mar 2003 09:51:40 +1100) Message-ID: <200303030047.h230lFx07491@bonsai.fernuni-hagen.de> > 1. No static typing. Is it just a matter of taste, if this is a good or a bad thing? One still has the possibility to run a type inference engine on existing Erlang code (think a kind of lint for types). I know at least one non-trivial one. > 2. Bytecode interpreted (i.e. not compiled to native code). This seems to be tackled by the HiPE extension, a native compiler. However I can't judge how it works in comparision to the standard VM (performance, correctness). > 3. Possibly not "really functional", i.e. mutable stuff (message sends > and state-dependent responses) play an important part when it comes to > structuring and maintaining large programs. This is true. But can one really do better? Is it possible to provide means for concurrent and distributed programming, while still ensuring that referential integrity? Or are side effects unavoidable due to the unpredictiveness of the behaviour of loose coupled real wordl concurrent/distributed systems? > 4. Some roots in Prolog, which I find... er... disturbing (my personal > encounters with Prolog were, say, unlucky... its strengths were less > useful than I had expected, and definitely not worth the weaknesses that > were the payment for its strengths - IMHO (I never became a Prolog guru)). The syntax is influenced by Prolog. And I must say I really like it. (OK I encountered Prolog before Erlang) Then there is the dynamic typing. But is there more in common? (Except that early compilers were written in Prolog). Otherwise Prolog like logic programming (the machine proof constitutes the program) is very different from Erlang. Regards, Marc From Marc.Vanwoerkom@REDACTED Mon Mar 3 02:59:05 2003 From: Marc.Vanwoerkom@REDACTED (Marc Ernst Eddy van Woerkom) Date: Mon, 3 Mar 2003 02:59:05 +0100 (MET) Subject: Erlang questions on comp.lang.functional. In-Reply-To: <20030302234015.GH22853@spearce.org> (message from Shawn Pearce on Sun, 2 Mar 2003 18:40:15 -0500) Message-ID: <200303030159.h231x5F13072@bonsai.fernuni-hagen.de> > I think the reality is it is impossible to build a programming language > that doesn't have side effects. It starts with I/O, which is done as side effect in Prolog. :) I wonder how I/O is considered by strict functional programmers, a function like int f() = return len(readkbdstring) isn't supposed to always return the same value, or? Worse, it is not even predictable. Now go from I/O to networked I/O. > (I hate prolog) When I hit Turbo Prolog in my youth, I had no clue what it was about. I thought it was some crazy AI toy (wasn't it marketed as expert system? :) that couldn't work anyway. Thus I threw it in the corner. Only a year or two ago, I was shown the light, that the power of mathematical logics is at the root of it. :) Regards, Marc From jhouchin@REDACTED Mon Mar 3 04:06:12 2003 From: jhouchin@REDACTED (Jimmie Houchin) Date: Sun, 02 Mar 2003 21:06:12 -0600 Subject: gen_tcp:controlling_process In-Reply-To: <200303030009.h23094f02935@bonsai.fernuni-hagen.de> References: <200303030009.h23094f02935@bonsai.fernuni-hagen.de> Message-ID: <3E62C6A4.90503@texoma.net> Marc Ernst Eddy van Woerkom wrote: >>Sorry for the previous empty message. My son attacked the >>keyboard. :-) DS > > > I have an extra keyboard and mouse on the table, in > case my daughter attacks. :) > > Regards, > Marc > Oh, but that doesn't work for three handed typing when the child is in your lap. :) Experience from a father of 8. :) But I have never thought to provide an extra next to me. Jimmie Houchin From spearce@REDACTED Mon Mar 3 04:27:28 2003 From: spearce@REDACTED (Shawn Pearce) Date: Sun, 2 Mar 2003 22:27:28 -0500 Subject: Does ets:select/2 block the VM? Message-ID: <20030303032728.GL22853@spearce.org> I'm wondering about the implementation of ets:select/2. If I match against a table with 200k records it takes nearly 1 second to complete on my system. I think I'm ok with this performance wise, but I can't have the ets:select/2 call block the entire emulator, other traffic still needs to be executed and processed in other processes. An informal test where I spawn up a background process and have it use io:format/2 every 10 milliseconds to print a message seems to run perfectly fine while a 1 second ets:select/2 runs in another process. I'm assuming thus that the Erlang system authors have thought about this and have ensured that it doesn't become a problem. :-) Also, the documentation is vague as to what happens if the table owner modifies a protected ets table using insert or delete while other processes are using ets:select/2 or ets:select/3 (select with a limit and continuation). Is it safe to perform this, or does the reader process have to use ets:safe_fixtable/2 ? -- Shawn. A tall, dark stranger will have more fun than you. From spearce@REDACTED Mon Mar 3 07:09:28 2003 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 3 Mar 2003 01:09:28 -0500 Subject: trap_exit with gen_server? Message-ID: <20030303060928.GM22853@spearce.org> Ok, this is an odd one for me. I thought that setting process_flag(trap_exit, true), would allow my gen_server module to receive the {'EXIT',Pid,Reason} message from the handle_info/2 callback. Apparently on line 412 of gen_server.erl in RB9-0 the gen_server behavior now traps the exit messages and calls terminate. So linked processes will always take down my gen_server. Line 52 of gen_server.erl seems to indicate that handle_info/2 can be used to receive exit messages from linked processes without the gen_server crashing. :) I guess I shouldn't link to my gen_server unless I want the gen_server to crash when the linked processes crash. :) Since this is in an OTP supervision tree, and I'm using erlang:monitor/2 now to watch processes, so this behavior is ok, but not expected. -- Shawn. Do what comes naturally. Seethe and fume and throw a tantrum. From spearce@REDACTED Mon Mar 3 07:26:19 2003 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 3 Mar 2003 01:26:19 -0500 Subject: trap_exit with gen_server? In-Reply-To: <20030303060928.GM22853@spearce.org> References: <20030303060928.GM22853@spearce.org> Message-ID: <20030303062619.GN22853@spearce.org> Uhm, never mind. This behavior of the server exiting because its parent exits even though trap_exit was set to true is supposed to happen. I didn't see that Parent was bound in gen_server on the 'EXIT' trap at line 412. Sent the message to fast I guess. It might be nice to include in the manual something to the effect letting users know that trap_exit doesn't let the gen_server trap its parent process exiting. (Which makes sense in an OTP supervision tree.) Shawn Pearce wrote: > Ok, this is an odd one for me. I thought that setting > process_flag(trap_exit, true), would allow my gen_server > module to receive the {'EXIT',Pid,Reason} message from > the handle_info/2 callback. > > Apparently on line 412 of gen_server.erl in RB9-0 the > gen_server behavior now traps the exit messages and calls > terminate. So linked processes will always take down my > gen_server. > > Line 52 of gen_server.erl seems to indicate that handle_info/2 > can be used to receive exit messages from linked processes without > the gen_server crashing. :) > > I guess I shouldn't link to my gen_server unless I want the > gen_server to crash when the linked processes crash. :) > Since this is in an OTP supervision tree, and I'm using > erlang:monitor/2 now to watch processes, so this behavior is > ok, but not expected. -- Shawn. There will be big changes for you but you will be happy. From per@REDACTED Mon Mar 3 08:33:40 2003 From: per@REDACTED (Per Bergqvist) Date: Mon, 03 Mar 2003 08:33:40 +0100 Subject: Erlang questions on comp.lang.functional. In-Reply-To: <20030302234015.GH22853@spearce.org> Message-ID: <200303030733.h237Xeq29591@lejon.levonline.com> > > 2. Bytecode interpreted (i.e. not compiled to native code). > > Isn't this why we have HIPE? And thus far, I have not seen HIPE improve > performance over code run in the bytecode interpreter. Therefore I have > to ask: > > - is the rest of erts slow? > - is the bytecode interpreter really fast? erts and beam are quite good. HIPE generates good code for the function body but the gain is "hidden" by the overhead costs. Until HIPE starts to do loop and whole program optimisations we will not see any major improvement IMHO. > - do I just keep my mathmatical computation outside of erlang? > Depends. When you have a large number of items it might be worth it. /Per ========================================================= Per Bergqvist Synapse Systems AB Phone: +46 709 686 685 Email: per@REDACTED From spearce@REDACTED Mon Mar 3 08:44:15 2003 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 3 Mar 2003 02:44:15 -0500 Subject: Erlang questions on comp.lang.functional. In-Reply-To: <200303030733.h237Xeq29591@lejon.levonline.com> References: <20030302234015.GH22853@spearce.org> <200303030733.h237Xeq29591@lejon.levonline.com> Message-ID: <20030303074415.GO22853@spearce.org> Per Bergqvist wrote: > > > 2. Bytecode interpreted (i.e. not compiled to native code). > > > > Isn't this why we have HIPE? And thus far, I have not seen HIPE >> improve > > performance over code run in the bytecode interpreter. Therefore I >> have > > to ask: > > > > - is the rest of erts slow? > > - is the bytecode interpreter really fast? > > erts and beam are quite good. > HIPE generates good code for the function body but the gain is > "hidden" by the overhead costs. > Until HIPE starts to do loop and whole program optimisations we will > not see any major improvement IMHO. Ok, now you've got me looking forward to the day HiPE starts to do that. :) AFAIK, Java is already doing this kind of optimization, it'll be nice when we can really start to compete at the performance level with other systems. Oh wait, Erlang already does. :-) The testing I've been doing today has been knocking my socks off performance wise. Just simple stuff with ets, gen_tcp, term_to_binary, yet I'm quite amazed at how fast Erlang really is. I can't remember when I had this much fun writing sorta-complex software. :) -- Shawn. Next Friday will not be your lucky day. As a matter of fact, you don't have a lucky day this year. From Vlad.Dumitrescu@REDACTED Mon Mar 3 08:59:29 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Mon, 3 Mar 2003 08:59:29 +0100 Subject: C# Interface? Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D71200F83F@esemont203.gbg.edt.ericsson.se> > From: Vance Shipley [mailto:vances@REDACTED] > On Fri, Feb 28, 2003 at 10:30:48AM +0100, Vlad Dumitrescu wrote: > } ............... I even mentioned it here, and the answer > was that this > } would impede with the Erlang node's stability (just like a > linked-in driver > } does, but since the external application is more complex, > the chances for > } it to crash are bigger). > > I keep hearing this type of thing and always find it humorous. If I > incorporate an Erlang node into a project I'm concerned about the > stability of the resulting system. While Erlang could be a shared > application environment like, a Unix system, it isn't used that way > anywhere. In OTP you see this philosophy in the release handler. > There is no way to add a new application on to a running system, you > may only upgrade. So if we are always using the Erlang node to do > just the one job, and that job needs a linked in driver, why would > I be so concerned about the possibility of a node crashing because > my code was bad? If my code is bad it doesn't work period. Hi, I agree with you, I just forwarded the answer that I got. However there might be cases when this is not true: for example if the "one thing" the node does is a Web server - if one has an admin interface using a linked-in driver GUI that keeps crashing the server, then that's not good. If the GUI was separate, the rest of the world wouldn't have to know something is broken ;-) regards, Vlad From jay@REDACTED Sun Mar 2 21:56:50 2003 From: jay@REDACTED (Jay Nelson) Date: Sun, 02 Mar 2003 12:56:50 -0800 Subject: OTP or not to OTP Message-ID: <4.2.2.20030302124405.00ce3760@duomark.com> Adding in the max connection count for accepts has caused me some problems. Once you start counting them, you must have everything linked or you won't know when the children go down. Asynchronous processes end up off in their own world, while the gen_server's state is being updated. When the asynch process needs to change state it can't because it is out of synch. Also, I do have to worry about which processes can fail or not, so OTP didn't reduce any of the thinking or subtlety of the issues. I am starting to understand what Jocke and Joe are saying about OTP. If you know it inside out, you probably wrote it and can work with it (or change it). If you don't and you hit your head, you are struggling against OTP not erlang. Once you take the leap and roll your own, you can modify it any way you want and you have finer control over issues like synchronization and state. I wouldn't have considered doing it from scratch without the examples posted here in the last few weeks. It also took me struggling to fit the concept into OTP to see where there are issues (there is a single gen_server state that must be updated synchronously -- asynch processes have to deal with that). It feels like centralized management when I had the original impression that it was more like decentralized management. Chris's new server / client library looks pretty clean (as does his whole toolbox approach). On a team project I would want a standard that everyone adheres to and a separate architecture group. It is very easy to get something 90% in erlang, but that last 10% has subtle issues. The simplicity of the code belies the issues that it solves. Of course, in another language I wouldn't get far enough on a distributed problem to realize the issues that occur. I may not be able to post my example today. I still have to work out the max connection issues clearly. jay From ake.ai.johansson@REDACTED Mon Mar 3 10:07:28 2003 From: ake.ai.johansson@REDACTED (=?iso-8859-1?Q?=C5ke_Johansson_AI_=28EAB=29?=) Date: Mon, 3 Mar 2003 10:07:28 +0100 Subject: Strange behaviour with a record in a guard Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D70FD69D27@esemont203.gbg.edt.ericsson.se> ... -record(r1,{f1}) foo(R) when R#r1.f1 == undefined -> ok. ... It seems like foo(R) matches any tuple of size 2 or bigger, where the second element is undefined. Should not the compiler add code which checks that R is a record of the correct type? A sample program and sample run is found below. / Ake -module(mt). -export([run/0]). -record(r1, {f1}). run() -> Tuple = {undefined,undefined, undefined}, io:format("Tuple = ~w~n", [Tuple]), Tuple2 = replace_undefined_f1_in_record_r1(Tuple), io:format("Tuple2 = ~w~n", [Tuple2]). replace_undefined_f1_in_record_r1(R) when R#r1.f1 == undefined -> io:format("replace_undefined_f1_in_record_r1: R=~w~n", [R]), R#r1{f1 = replaced}; replace_undefined_f1_in_record_r1(AnythingElse) -> AnythingElse. Erlang (BEAM) emulator version 5.1.1 [threads:0] Eshell V5.1.1 (abort with ^G) 1> =PROGRESS REPORT==== 3-Mar-2003::09:10:55 === supervisor: {local,sasl_safe_sup} ... {shutdown,2000}, {child_type,worker}] =PROGRESS REPORT==== 3-Mar-2003::09:10:55 === application: sasl started_at: nonode@REDACTED 1> c(mt). {ok,mt} 2> mt:run(). Tuple = {undefined,undefined,undefined} replace_undefined_f1_in_record_r1: R={undefined,undefined,undefined} Tuple2 = {r1,replaced} ok 3> From eleberg@REDACTED Mon Mar 3 10:19:12 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Mon, 3 Mar 2003 10:19:12 +0100 (MET) Subject: Strange behaviour with a record in a guard Message-ID: <200303030919.h239JCH26033@cbe.ericsson.se> > From: ?ke Johansson AI (EAB) > To: erlang-questions@REDACTED > Subject: Strange behaviour with a record in a guard > Date: Mon, 3 Mar 2003 10:07:28 +0100 > MIME-Version: 1.0 > > ... > -record(r1,{f1}) > > foo(R) when R#r1.f1 == undefined -> > ok. > ... > > It seems like foo(R) matches any tuple of size 2 or bigger, where the second element is undefined. Should not the compiler add code which checks that R is a record of the correct type? R#r1.f1 only gets the ''right'' element from the tuple. if you want to check the record type, as well as the value of a field, you need to write (here ''= R'' may be omitted if you are not interested in the whole record): foo( #r{f1=F1} = R ) when F1 == undefined -> ok. note that this means it is usually better to do #r{f1=F1} = R, than F1 = R#r.f1, bengt From etxuwig@REDACTED Mon Mar 3 10:26:18 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Mon, 3 Mar 2003 10:26:18 +0100 (MET) Subject: Linking to/from a gen_server? In-Reply-To: <20030302062555.GA28668@spearce.org> Message-ID: On Sun, 2 Mar 2003, Shawn Pearce wrote: >Ok, so I'm trying to use OTP stuff as much as I can right >now, as I haven't really learned it all yet. :) That's quite OK; I doubt that anyone can claim to master OTP fully. (: >I'm trying to setup a way to have a client process send a >gen_server a message, where the gen_server stuffs a term >and the client's pid into an ets table managed by the >gen_server. I want the gen_server to link to the client >process so it can remove the term and client pid when the >client process exits. This is _exactly_ the kind of work that erlang:monitor() was designed for. You do not really want to do it with links, precisely because of the unlinking problems (the client can unlink, and the server won't notice; and the server may well end up in a situation where it has "multiple links" to the same client, and thus has to maintain a "virtual link stack". This is all really messy with link. >But it occured to me, gen_server:call/2 links to the >gen_server process, sends the message, and waits for the >response with a timeout. It then unlinks from the >gen_server. This means the gen_server can't link to the >client process during its handle_call/3 callback, as the >unlink will be done by the client after the call completes. Yes, see above, but, gen_server:call() uses monitor() and demonitor(), which is stackable. It doesn't interfere with other monitors. >I could use gen_server:cast/2, but i do need a response to >be sent back to the client so it knows the operation was >successful. If you want a response back, use call(). It is just confusing to emulate calls with casts. The server can return {noreply,S'} if it's not possible to respond immediately, and then use gen_server:reply/2 later. Since gen_server:reply/2 uses the pid of the caller, it is no big disaster if you're not using monitors, and the client died - the reply message will go into the bit bucket. The big thing that link() can do and monitor() can't, is cascading exits. Personally, I try as much as possible to use lots of processes and not trap exits unless I absolutely have to. This way, I can split a problem into as many processes as the problem calls for (but not more than that!), tie them together with links and rely on cascading exits to clean up if there's a problem. For monitoring the well-being of another process, I always use monitor(). /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From etxuwig@REDACTED Mon Mar 3 10:36:12 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Mon, 3 Mar 2003 10:36:12 +0100 (MET) Subject: Strange behaviour with a record in a guard In-Reply-To: <200303030919.h239JCH26033@cbe.ericsson.se> Message-ID: On Mon, 3 Mar 2003, Bengt Kleberg wrote: >R#r1.f1 only gets the ''right'' element from the tuple. > >if you want to check the record type, as well as the value >of a field, you need to write (here ''= R'' may be omitted >if you are not interested in the whole record): > >foo( #r{f1=F1} = R ) when F1 == undefined -> > ok. ...or even foo(#r{f1 = undefined}) -> ok. (You don't have to bind R in this case, but the compiler should of course figure that out.) -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From spearce@REDACTED Mon Mar 3 10:42:59 2003 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 3 Mar 2003 04:42:59 -0500 Subject: Strange behaviour with a record in a guard In-Reply-To: <200303030919.h239JCH26033@cbe.ericsson.se> References: <200303030919.h239JCH26033@cbe.ericsson.se> Message-ID: <20030303094259.GP22853@spearce.org> Bengt Kleberg wrote: > foo( #r{f1=F1} = R ) when F1 == undefined -> > ok. How is that better/different from: foo( R = #r{f1=F1} ) when F1 == undefined -> ok. as I'm currently using the latter form in my code successfully. Just wondering if I need to go back and update it for any reason. -- Shawn. Don't go surfing in South Dakota for a while. From spearce@REDACTED Mon Mar 3 10:46:26 2003 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 3 Mar 2003 04:46:26 -0500 Subject: Linking to/from a gen_server? In-Reply-To: References: <20030302062555.GA28668@spearce.org> Message-ID: <20030303094626.GQ22853@spearce.org> Ulf Wiger wrote: > If you want a response back, use call(). It is just > confusing to emulate calls with casts. The server can return > {noreply,S'} if it's not possible to respond immediately, > and then use gen_server:reply/2 later. Since > gen_server:reply/2 uses the pid of the caller, it is no big > disaster if you're not using monitors, and the client died > - the reply message will go into the bit bucket. Yeah, I figured it would be a big mess trying to emulate call with cast, so I really wanted to avoid that. :) > The big thing that link() can do and monitor() can't, is > cascading exits. Personally, I try as much as possible to > use lots of processes and not trap exits unless I absolutely > have to. This way, I can split a problem into as many > processes as the problem calls for (but not more than > that!), tie them together with links and rely on cascading > exits to clean up if there's a problem. > > For monitoring the well-being of another process, I always > use monitor(). That's good to know Ulf. Currently its pretty much what I am doing. The monitor is to know when the process exits so I can garbage collect data my server has stored about the process, without requring that the process stay linked. Meanwhile, I'm using link within the OTP supervision tree to do cascading exits and proper cleanup. Excellent. This thread only got started because I had forgetten about monitor, but after reading the doc page, its exactly what I wanted. -- Shawn. Rebellion lay in his way, and he found it. -- William Shakespeare, "Henry IV" From bjorn@REDACTED Mon Mar 3 11:30:20 2003 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 03 Mar 2003 11:30:20 +0100 Subject: Linking to/from a gen_server? In-Reply-To: Shawn Pearce's message of "Sun, 2 Mar 2003 19:15:38 -0500" References: <20030302062555.GA28668@spearce.org> <3E61DE35.4010308@st.se> <20030303001538.GJ22853@spearce.org> Message-ID: Shawn Pearce writes: > Is there any limitation imposed by erts on the number of processes > another process (my gen_server) can monitor at once? Or is it just > the limitation on number of actively running processes within the > local node? There is no limit, but... > > I'm only interested in this gen_server monitoring a large number > (around 4-5k) of local processes so that if they crash or terminate > unexpectedly the ets dictionary is cleaned up so future lookups for > that process won't find it. > ... we have not optimized the code for that many processes (yet, at least). There will be a linear slowdown that will probably be quite noticeable. /Bjorn -- Bj?rn Gustavsson Ericsson Utvecklings AB bjorn@REDACTED ?T2/UAB/F/P BOX 1505 +46 8 727 56 87 125 25 ?lvsj? From Vlad.Dumitrescu@REDACTED Mon Mar 3 11:32:57 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Mon, 3 Mar 2003 11:32:57 +0100 Subject: More GUI (ravings?) Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D71200F846@esemont203.gbg.edt.ericsson.se> Hi all, Since I am working on ex11, I am also trying to see what might come ahead and try to plan for a possible widget toolkit, implemented in Erlang. As I said once before, I can't see any way to do it in a different way that it is done in most other languages, that is OO or the like. Please if there is anyone that has a link to a GUI framework that isn't OO (but not too far from Erlang's philosophy either), send it to me. The "missing feature" that would be needed has already been discussed here in many ways: building a hierarchy of behaviours. Or with another word, implementing subclassing. A generic window has behaviour that an input widget will "inherit" and that one can further be refined to become a "password input" widget. The question is how to delegate the "inherited" behaviour to the right implementation module? ---- One way is to just write lots of funs similar to set_visible(Widget) -> widget:set_visible(Widget). But this seems very heavy on the typing fingers and not extendible. Maybe some macros could help, but it would look like a C++ framework from Another way is to use for example an attribute -inherits([widget]). and then either: * change error_handler:undefined_function to check any modules named in 'inherits' for the respective function before reporting an undef error or * let the compiler generate the stubs above, but then only one "parent" can be used. Yet another way would be writing behaviours on top of other behaviours, and also let one process implement several behaviours. Or even modify the language to allow for generic functions (? la Lisp) that can be extended from another module than the one they were originally written in. ---- I am reluctant to use the term "inherit" but I found none better. What is needed is indeed a behavioural inheritance, which might not have anything to do with objects and classes as we learned to love/hate them :-) I don't think I am completely out in the bush, but if I am, please let me know. :-) I will have to give this more thought, but I feel some feedback will be useful. regards, Vlad From DANIESC.SCHUTTE@REDACTED Mon Mar 3 11:32:18 2003 From: DANIESC.SCHUTTE@REDACTED (DANIESC SCHUTTE) Date: Mon, 03 Mar 2003 12:32:18 +0200 Subject: erl-interface - ing type question Message-ID: Greetings to all the guru's thanks again for all the responses on my earlier questions. Yet again I have to enquire about the following. We have got a low level api (written in C) conversing between erlang and sybase 12.5 (if anyone is interested). Previously we sent the requests in to the api as atoms. Code such as "(strncmp(ERL_ATOM_PTR(fnp), "rpc", 3) == 0)" was used. I would like to enquire regarding the use of atoms in this case - is it a good thing or would it be more beneficial to be using lists / strings. Internally in the erlang application we try to send most data as lists - as it makes it easier to manipulate. So the first question: Is atoms a good thing to use for sending data to the api? and also for receiving data from the api? - I recall something about only a fixed number of atoms that can be used or some such thing. If we want to convert to lists - the output can be done as "colp = erl_format ("{col, ~s, ~s}", datafmt[i].name, coldata[i].value);" the ~s converting to strings instead of ~a - converting to atoms. the question however is - how would we read lists incoming - unfortuanately in erl_eterm.h i see Int / Float / PID / Port / Ref / Tuple Bin / Cons but no LIST - or am I looking for the wrong type. Or would the easiest way be sending atoms in and receiving lists? Any comments are welcome. Thanks to everyone contributing to the list. Daniel Danie Schutte Phone: +27 - 11 - 203 - 1615 Mobile: 084-468-3138 e-Mail: Daniesc@REDACTED ##################################################################################### The information contained in this message and or attachments is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any system and destroy and copies. ##################################################################################### From bjorn@REDACTED Mon Mar 3 11:48:42 2003 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 03 Mar 2003 11:48:42 +0100 Subject: Erlang questions on comp.lang.functional. In-Reply-To: Shawn Pearce's message of "Sun, 2 Mar 2003 18:40:15 -0500" References: <4.2.2.20030302002352.00cdb230@duomark.com> <20030302234015.GH22853@spearce.org> Message-ID: Shawn Pearce writes: > > > 2. Bytecode interpreted (i.e. not compiled to native code). > Beam is not byte code interpreted. The byte code in the beam files is converted to threaded code by the loader. The threaded code consists of a pointer to directly executable code, followed by the operands. The loader also specializes instructions (e.g. the 'move' instruction will be replaced with one of about a dozen specialized 'move' instructions) and does other optimizations such merging of common instructions sequences. > Isn't this why we have HIPE? And thus far, I have not seen HIPE improve > performance over code run in the bytecode interpreter. Therefore I have > to ask: > > - is the rest of erts slow? > - is the bytecode interpreter really fast? > - do I just keep my mathmatical computation outside of erlang? In R8 and R9 floating point operations are specially optimized, as long as the compiler can figure out that they indeed are floating point operations. (The best way to inform the compiler is to use the 'is_float/1' guard BIF for arguments that are known to be floating point numbers.) /Bjorn -- Bj?rn Gustavsson Ericsson Utvecklings AB bjorn@REDACTED ?T2/UAB/F/P BOX 1505 +46 8 727 56 87 125 25 ?lvsj? From spearce@REDACTED Mon Mar 3 12:40:14 2003 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 3 Mar 2003 06:40:14 -0500 Subject: Linking to/from a gen_server? In-Reply-To: References: <20030302062555.GA28668@spearce.org> <3E61DE35.4010308@st.se> <20030303001538.GJ22853@spearce.org> Message-ID: <20030303114014.GA2082@spearce.org> Bjorn Gustavsson wrote: > Shawn Pearce writes: > > I'm only interested in this gen_server monitoring a large number > > (around 4-5k) of local processes so that if they crash or terminate > > unexpectedly the ets dictionary is cleaned up so future lookups for > > that process won't find it. > > > > ... we have not optimized the code for that many processes (yet, at least). > There will be a linear slowdown that will probably be quite noticeable. Ok, I was afraid of that. :-) Within my design, it wouldn't be a problem for me to setup slaves which tracked the monitors for the master. So we have master <-- link --> n_slaves -- monitor --> 4k_processes Where n_slaves is some number of slaves such that it's not slow. :) I was originally thinking that links were limited to something like 100 links per process, and was thus going to setup about 400 slaves in a tree to handle 100 links each. Any idea of what would be a good number of monitors per process that balances between slow and reasonable? -- Shawn. Try to have as good a life as you can under the circumstances. From spearce@REDACTED Mon Mar 3 12:55:22 2003 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 3 Mar 2003 06:55:22 -0500 Subject: erl-interface - ing type question In-Reply-To: References: Message-ID: <20030303115522.GB2082@spearce.org> Yes, there is a limit in erts on how many atoms can be assigned. Its in the Efficiency Guide, section 7.2 "System Limits": The maximum number of atoms is 1048576. Also, the atoms are not garbage collected, so once you make that many atoms in erts, erts just crashes. In short, the only thing that should make atoms is your source code. If you don't write the atom by hand, you most likely shouldn't use value as an atom. Thus, external programs sending in atoms should only send in values as atoms which are hand coded in the interfacing Erlang as atoms, all other data should be binary or lists. Also, avoid list_to_atom/1. As for your Sybase interface, that's pretty cool. I think we may need to start developing a common database access interface, at least in terms of behavior. We have mnesia already, I'm going to do an Oracle one soon it looks like, you guys have a Sybase one. :) I'd say you should use atoms for all communication protocol handling, and use strings/lists/binaries for all data passed back to the database. In Erlang, atoms were meant to replace #define's in C. That said, I did a JDBC<->Erlang bridge that mapped certain values in and out of atoms. Essentially SQL NULL was mapped to Erlang 'undefined'. Some of my smaller decode tables in the database that I felt were never going to exceed say 10 or 20 entries had their keys mapped to atoms, letting my database bridge translate the entry back to the key to be stored in the database. Thus I had tables like: CREATE TABLE atomtb1 ( id numeric(5,0) not null primary key, name varchar(50) not null ); CREATE TABLE dat1 ( partner_id NUMERIC(5,0), ... foreign key (partner_id) references atomtb1(id) ); And when reading/writing dat1 records from Erlang partner_id showed up as atoms whose names were the name column from atomtb1. This more or less let me mimic how someone would use and store atoms in Mnesia, but do so in a non-Erlang database without the bloat of storing the atom directly as a string in the main data table. If you do this, be sure you have a very good handle on the growth of the atomtb1 table, or else you risk running out of atoms in erts. DANIESC SCHUTTE wrote: > We have got a low level api (written in C) conversing between erlang > and sybase 12.5 (if anyone is interested). Previously we sent the > requests in to the api as atoms. Code such as > "(strncmp(ERL_ATOM_PTR(fnp), "rpc", 3) == 0)" was used. > > I would like to enquire regarding the use of atoms in this case > - is it a good thing or would it be more beneficial to be using > lists / strings. Internally in the erlang application we try to > send most data as lists - as it makes it easier to manipulate. > > So the first question: Is atoms a good thing to use for sending > data to the api? and also for receiving data from the api? - I > recall something about only a fixed number of atoms that can be used > or some such thing. > > If we want to convert to lists - > the output can be done as > "colp = erl_format ("{col, ~s, ~s}", datafmt[i].name, coldata[i].value);" > the ~s converting to strings instead of ~a - converting to atoms. > > the question however is - how would we read lists incoming - > unfortuanately in erl_eterm.h i see Int / Float / PID / Port / Ref > / Tuple Bin / Cons but no LIST - or am I looking for the wrong type. > > Or would the easiest way be sending atoms in and receiving lists? -- Shawn. You've been leading a dog's life. Stay off the furniture. From Sean.Hinde@REDACTED Mon Mar 3 12:59:44 2003 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Mon, 3 Mar 2003 11:59:44 -0000 Subject: OTP or not to OTP Message-ID: Jay, > Adding in the max connection count for accepts has caused > me some problems. Once you start counting them, you must > have everything linked or you won't know when the children > go down. Asynchronous processes end up off in their own > world, while the gen_server's state is being updated. When > the asynch process needs to change state it can't because > it is out of synch. Also, I do have to worry about which > processes can fail or not, so OTP didn't reduce any of the > thinking or subtlety of the issues. All of these things may be easily accomplished using a standard gen_server. 'EXIT' messages end up in handle_info, and you can use gen_server:cast() variants to communicate asynchronously with the gen_server (and update its state). The main tcp/ip server model we use in our systems is made of 2 gen_servers. The only difference to the 'pure' erlang version is that the startup of the accepting gen_server process is made slightly more complex. The init function sends a message to itself to start up the accept call in the main callbacks otherwise the starting process would hang. Otherwise it is the same, and we use sys:trace and all the other good things all the time. > I am starting to understand what Jocke and Joe are saying > about OTP. If you know it inside out, you probably wrote it > and can work with it (or change it). If you don't and you hit > your head, you are struggling against OTP not erlang. Once > you take the leap and roll your own, you can modify it any > way you want and you have finer control over issues like > synchronization and state. Take some time to study gen.erl and gen_server.erl. You will recognise the structure from all the non OTP examples here and you can also see what the experts have done about linking (they use monitor instead) and startup synchronisation etc. Then decide whether you really want to roll your own in every case. > I wouldn't have considered doing it from scratch without the > examples posted here in the last few weeks. It also took me > struggling to fit the concept into OTP to see where there are > issues (there is a single gen_server state that must be > updated synchronously -- asynch processes have to deal > with that). It feels like centralized management when I had > the original impression that it was more like decentralized > management. Chris's new server / client library looks pretty > clean (as does his whole toolbox approach). > > On a team project I would want a standard that everyone adheres > to and a separate architecture group. It is very easy to get > something 90% in erlang, but that last 10% has subtle issues. > The simplicity of the code belies the issues that it solves. Of > course, in another language I wouldn't get far enough on a > distributed problem to realize the issues that occur. gen_server really works in most cases and has been designed to provide exactly the framework you are after. I would be surprised if you didn't end up re-inventing it almost the same if you made your own Sean NOTICE AND DISCLAIMER: This email (including attachments) is confidential. If you have received this email in error please notify the sender immediately and delete this email from your system without copying or disseminating it or placing any reliance upon its contents. We cannot accept liability for any breaches of confidence arising through use of email. Any opinions expressed in this email (including attachments) are those of the author and do not necessarily reflect our opinions. We will not accept responsibility for any commitments made by our employees outside the scope of our business. We do not warrant the accuracy or completeness of such information. From spearce@REDACTED Mon Mar 3 13:06:10 2003 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 3 Mar 2003 07:06:10 -0500 Subject: OTP or not to OTP In-Reply-To: References: Message-ID: <20030303120610.GC2082@spearce.org> Sean Hinde wrote: > gen_server really works in most cases and has been designed to provide > exactly the framework you are after. I would be surprised if you didn't end > up re-inventing it almost the same if you made your own After writing a non-gen_server this weekend, and then a gen_server (different task, but still), I have to say, you might have to be either nuts or Joe to think about not using gen_server. I wound up writing almost everything gen_server gives you already in much longer code, but not as good of a solution. Considering I'm on the Erlang platform partly for the OTP release handling, and partly for the OTP accelerated development, I'm crazy to think I can (as an Erlang hack, not expert!) build OTP overnight and better for my application then these fine folks have done with OTP. After 8 hours of Erlang hacking last night, I have to tip my hat to the OTP developers and say "THANK YOU!". -- Shawn. Q: How many journalists does it take to screw in a light bulb? A: Three. One to report it as an inspired government program to bring light to the people, one to report it as a diabolical government plot to deprive the poor of darkness, and one to win a Pulitzer prize for reporting that Electric Company hired a light bulb-assassin to break the bulb in the first place. From matthias@REDACTED Mon Mar 3 13:17:44 2003 From: matthias@REDACTED (Matthias Lang) Date: Mon, 3 Mar 2003 13:17:44 +0100 Subject: firewall proxy in Erlang Message-ID: <15971.18408.242938.842273@antilipe.corelatus.se> Hi, I have Telia ADSL both at home and at work. We use it in conjunction with a standalone firewall (one of our old prototype boards, which happens to have two ethernet interfaces and runs Erlang). Over time, I've hacked up a few tools to make life with Telia ADSL and a firewall more fun. They've now grown to the point where they may be useful for other Erlang hackers. >From the README file: Features - Telia ADSL autologin. Automatically logs you back into Telia's ADSL service whenever something at Telia goes wrong and logs you out. (this happens once every couple of months, and it always seems to be in the middle of the night when nobody's at the office to log in again) - ZoneEdit Dynamic DNS client. - HTTP/1.0 proxy. Proxy supports http, https and ftp methods, as well as the HTTP/1.1 CONNECT method. - FTP proxy. Allows you to connect to an FTP server on the other side of the firewall with your ordinary FTP program. Useful for uploading files to sites that don't have SSH. - Generic TCP port forwarder. Lets SSH, IMAP, POP, SMTP, NNTP, CVS, etc. through the firewall. - Incoming TCP port forwarder. Forwards external connections to a certain machine on the inside. - Bandwidth rationing. Problem: someone else is downloading an ISO, so now all the interactive SSH connections are sluggish for the next couple of hours. Solution: throttle the download in the proxy. Grab it from: http://www.corelatus.com/~matthias/eproxy-1.0.tar.gz It's 'alpha' quality, i.e. it'll probably take a couple of emails to me before it works. Matthias From DANIESC.SCHUTTE@REDACTED Mon Mar 3 13:14:18 2003 From: DANIESC.SCHUTTE@REDACTED (DANIESC SCHUTTE) Date: Mon, 03 Mar 2003 14:14:18 +0200 Subject: erl-interface - ing type question Message-ID: Thanks for the information so far The only question now remains, as we have all the data in lists internally and need to pass it to the driver - what can be used to "receive" lists in c code, instead of ERL_ATOM_PTR - since the information in erlang will either have to be converted from list to atom - NOT GOOD - or I need to receive it in a list/s. Regards >>> Shawn Pearce 03/03/03 01:55PM >>> Yes, there is a limit in erts on how many atoms can be assigned. Its in the Efficiency Guide, section 7.2 "System Limits": The maximum number of atoms is 1048576. Also, the atoms are not garbage collected, so once you make that many atoms in erts, erts just crashes. In short, the only thing that should make atoms is your source code. If you don't write the atom by hand, you most likely shouldn't use value as an atom. Thus, external programs sending in atoms should only send in values as atoms which are hand coded in the interfacing Erlang as atoms, all other data should be binary or lists. Also, avoid list_to_atom/1. As for your Sybase interface, that's pretty cool. I think we may need to start developing a common database access interface, at least in terms of behavior. We have mnesia already, I'm going to do an Oracle one soon it looks like, you guys have a Sybase one. :) I'd say you should use atoms for all communication protocol handling, and use strings/lists/binaries for all data passed back to the database. In Erlang, atoms were meant to replace #define's in C. That said, I did a JDBC<->Erlang bridge that mapped certain values in and out of atoms. Essentially SQL NULL was mapped to Erlang 'undefined'. Some of my smaller decode tables in the database that I felt were never going to exceed say 10 or 20 entries had their keys mapped to atoms, letting my database bridge translate the entry back to the key to be stored in the database. Thus I had tables like: CREATE TABLE atomtb1 ( id numeric(5,0) not null primary key, name varchar(50) not null ); CREATE TABLE dat1 ( partner_id NUMERIC(5,0), ... foreign key (partner_id) references atomtb1(id) ); And when reading/writing dat1 records from Erlang partner_id showed up as atoms whose names were the name column from atomtb1. This more or less let me mimic how someone would use and store atoms in Mnesia, but do so in a non-Erlang database without the bloat of storing the atom directly as a string in the main data table. If you do this, be sure you have a very good handle on the growth of the atomtb1 table, or else you risk running out of atoms in erts. DANIESC SCHUTTE wrote: > We have got a low level api (written in C) conversing between erlang > and sybase 12.5 (if anyone is interested). Previously we sent the > requests in to the api as atoms. Code such as > "(strncmp(ERL_ATOM_PTR(fnp), "rpc", 3) == 0)" was used. > > I would like to enquire regarding the use of atoms in this case > - is it a good thing or would it be more beneficial to be using > lists / strings. Internally in the erlang application we try to > send most data as lists - as it makes it easier to manipulate. > > So the first question: Is atoms a good thing to use for sending > data to the api? and also for receiving data from the api? - I > recall something about only a fixed number of atoms that can be used > or some such thing. > > If we want to convert to lists - > the output can be done as > "colp = erl_format ("{col, ~s, ~s}", datafmt[i].name, coldata[i].value);" > the ~s converting to strings instead of ~a - converting to atoms. > > the question however is - how would we read lists incoming - > unfortuanately in erl_eterm.h i see Int / Float / PID / Port / Ref > / Tuple Bin / Cons but no LIST - or am I looking for the wrong type. > > Or would the easiest way be sending atoms in and receiving lists? -- Shawn. You've been leading a dog's life. Stay off the furniture. ##################################################################################### The information contained in this message and or attachments is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any system and destroy and copies. ##################################################################################### From spearce@REDACTED Mon Mar 3 13:28:22 2003 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 3 Mar 2003 07:28:22 -0500 Subject: erl-interface - ing type question In-Reply-To: References: Message-ID: <20030303122822.GD2082@spearce.org> Well, since you are using the older erl_interface API, I offer two options: - Upgrade your code to ei. See the Erl_Interface Library Reference and look at the ei and ei_connect functions, they have string handling functions builtin. - Use binaries. Use list_to_binary/1 in Erlang to build up the binary and sent it to your process, and use ERL_BIN_SIZE(t) to discover the string length, and ERL_BIN_PTR(t) to get to the string. You should be able to copy it out to a char* and use it as is. Note that it won't be null byte terminated. DANIESC SCHUTTE wrote: > Thanks for the information so far > > The only question now remains, as we have all the data in lists > internally and need to pass it to the driver - what can be used > to "receive" lists in c code, instead of ERL_ATOM_PTR - since the > information in erlang will either have to be converted from list to > atom - NOT GOOD - or I need to receive it in a list/s. -- Shawn. Chicken Little was right. From Sean.Hinde@REDACTED Mon Mar 3 14:07:43 2003 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Mon, 3 Mar 2003 13:07:43 -0000 Subject: OTP or not to OTP Message-ID: > Considering I'm on the Erlang platform partly for the OTP release > handling, and partly for the OTP accelerated development, I'm crazy > to think I can (as an Erlang hack, not expert!) build OTP overnight > and better for my application then these fine folks have done with > OTP. > > After 8 hours of Erlang hacking last night, I have to tip my hat > to the OTP developers and say "THANK YOU!". I find it quite revealing that it is the people who wrote that stuff who come out here and say that they roll their own. You can interpret this two ways: 1. They think their own creations suck so they don't use them 2. They have transcended the need for any such thing and can re-create the original genius at will. I'm sure there are more explanations, but I know which one I believe after 4 years of successfully using OTP. Sean NOTICE AND DISCLAIMER: This email (including attachments) is confidential. If you have received this email in error please notify the sender immediately and delete this email from your system without copying or disseminating it or placing any reliance upon its contents. We cannot accept liability for any breaches of confidence arising through use of email. Any opinions expressed in this email (including attachments) are those of the author and do not necessarily reflect our opinions. We will not accept responsibility for any commitments made by our employees outside the scope of our business. We do not warrant the accuracy or completeness of such information. From etxuwig@REDACTED Mon Mar 3 14:18:24 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Mon, 3 Mar 2003 14:18:24 +0100 (MET) Subject: continued init (RE: OTP or not to OTP) In-Reply-To: Message-ID: On Mon, 3 Mar 2003, Sean Hinde wrote: >The main tcp/ip server model we use in our systems is made >of 2 gen_servers. The only difference to the 'pure' erlang >version is that the startup of the accepting gen_server >process is made slightly more complex. The init function >sends a message to itself to start up the accept call in >the main callbacks otherwise the starting process would >hang. Some people will probably want to strangle me for revealing this "secret", but you can actually do this: start_link() -> gen_server:start_link({local,myserver},?MODULE,self(),[]). init(Parent) -> ..., proc_lib:init_ack(Parent, {ok,self()}), State = ..., {ok, State}. The supervisor will quietly consume the second 'ack' message. It is frowned upon, but accepted for now. A better solution will eventually appear, so it will remain undocumented. Therefore, use it at your own peril, and only if you can promise not to blame me when it breaks. (: The place where this is preferrable to self() ! continue, is for example during process restarts, when clients are active and may succeed in calling the server before you have time to send to yourself. It is very difficult to close this hole entirely, and the above "hack" eliminates the problem (introducing a less serious "double ack" problem, which can be handled in supervisor.erl) The Better Solution will probably be something along the lines of init/1 returning {continue, fun()}, or something. Stay tuned (or take a look at my attached suggestion for a patch -- my way of trying to appease the OTP Gods after having promoted dirty hacks to the public... ;-) /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes -------------- next part -------------- 382,384d381 < {continue, F} when function(F) -> < proc_lib:init_ack(Starter, {ok, self()}), < continued_init(F, Parent, Name, Mod, Debug); 400,409d396 < continued_init(F, Parent, Name, Mod, Debug) -> < case catch F() of < {'EXIT', Reason} -> < terminate(Reason, Name, continued_init, Mod, undefined, []); < {ok, State} -> < loop(Parent, Name, State, Mod, infinity, Debug); < {ok, State, Timeout} -> < loop(Parent, Name, State, Mod, Timeout, Debug) < end. < 591,595d577 < error_msg(Name, Msg, State, Reason), < sys:print_log(Debug), < ok. < < error_msg(Name, continued_init, undefined, Reason) -> 597,601d578 < "** during continued_init.~n" < "** Reason for termination == ~n** ~p~n", < [Name, Reason]); < error_msg(Name, Msg, State, Reason) -> < format("** Generic server ~p terminating \n" 605c582,584 < [Name, Msg, State, Reason]). --- > [Name, Msg, State, Reason]), > sys:print_log(Debug), > ok. 607d585 < From cyberlync@REDACTED Mon Mar 3 14:18:27 2003 From: cyberlync@REDACTED (Eric Merritt) Date: Mon, 3 Mar 2003 05:18:27 -0800 (PST) Subject: More GUI (ravings?) In-Reply-To: <5F03ACA2F76DD411B8BC00508BE3B4D71200F846@esemont203.gbg.edt.ericsson.se> Message-ID: <20030303131827.48165.qmail@web40805.mail.yahoo.com> Vlad, I kind of think that you are being misguided by the OO world. Don't get me wrong I like OO and don't think it is a bad thing, but its not the only way to do things. Inheritence is not the only way to handle sub-windowing behavior either, I am pretty sure. Unfortunatly, I need to think about it before I can offer suggestions, but I would say try to think in native erlang datastructures and processes. They are a good solution and they should work for this just like they work for so much else. Don't try to reinvent OO in Erlang. I will give it some thought and try to offer some suggestions soon. --- "Vlad Dumitrescu (EAW)" wrote: > Hi all, > > Since I am working on ex11, I am also trying to see > what might come ahead and try to plan for a possible > widget toolkit, implemented in Erlang. As I said > once before, I can't see any way to do it in a > different way that it is done in most other > languages, that is OO or the like. Please if there > is anyone that has a link to a GUI framework that > isn't OO (but not too far from Erlang's philosophy > either), send it to me. > > The "missing feature" that would be needed has > already been discussed here in many ways: building a > hierarchy of behaviours. Or with another word, > implementing subclassing. A generic window has > behaviour that an input widget will "inherit" and > that one can further be refined to become a > "password input" widget. > > The question is how to delegate the "inherited" > behaviour to the right implementation module? > > ---- > One way is to just write lots of funs similar to > set_visible(Widget) -> > widget:set_visible(Widget). > But this seems very heavy on the typing fingers and > not extendible. Maybe some macros could help, but it > would look like a C++ framework from > > Another way is to use for example an attribute > -inherits([widget]). > and then either: > * change error_handler:undefined_function to > check any modules named in 'inherits' for the > respective function before reporting an undef error > or > * let the compiler generate the stubs above, but > then only one "parent" can be used. > > Yet another way would be writing behaviours on top > of other behaviours, and also let one process > implement several behaviours. > > Or even modify the language to allow for generic > functions (? la Lisp) that can be extended from > another module than the one they were originally > written in. > ---- > > I am reluctant to use the term "inherit" but I found > none better. What is needed is indeed a behavioural > inheritance, which might not have anything to do > with objects and classes as we learned to love/hate > them :-) > > I don't think I am completely out in the bush, but > if I am, please let me know. :-) I will have to give > this more thought, but I feel some feedback will be > useful. > regards, > Vlad > > > __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - forms, calculators, tips, more http://taxes.yahoo.com/ From spearce@REDACTED Mon Mar 3 14:22:39 2003 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 3 Mar 2003 08:22:39 -0500 Subject: OTP or not to OTP In-Reply-To: References: Message-ID: <20030303132239.GE2082@spearce.org> Sean Hinde wrote: > 1. They think their own creations suck so they don't use them I thinks this is it, and it would put the OTP guys into the same group of people as those that write control software for airliners (they always fly on a plane they didn't write code for, or take a train). Just a "flaw" in a programmer's character. I know I try to not to use what I write. :) > 2. They have transcended the need for any such thing and can re-create the > original genius at will. Or maybe this is it. :) They know the system so well, OTP gets in the way. Granted, its a pain writing all those callbacks which are just useless (like if I don't use cast in my gen_server), but should exist to be technically correct and prevent crashes from bad clients. Not to mention I find my simple non-OTP gen_tcp server I wrote on Saturday to be syntatically cleaner than the OTP gen_server I just wrote last night. > I'm sure there are more explanations, but I know which one I believe > after 4 years of successfully using OTP. 3. They tend not to write the massive applications those who use and love OTP write. Thus, they don't run into the 200 developers all writing different server problems that the AXD301 project must have had. No problem, no need for the "bloat" of OTP. :) Its fun being a tool builder, so long as your projects stays smaller than the projects the tool was built to help, it tends to pay to stay away from the tool as the cost of the tool exceeds the cost of the project. I've done this to myself too many times to count, there is definately a balance point. It would be interesting to see Joe's examples written using strict OTP rules, and see if they are any clearer or use any less lines of code then what he wrote without OTP. My guess is, OTP makes it harder to understand for the person who is new to Erlang, but reduces the line count (and bug count) by a lot. I've been kicking on and off Erlang for about 3 years now, as most of you have probably noticed. :) Prior to now, I have only toyed with OTP, as I had enough of a learning curve just getting through the langauge and the simple stdlib's like ets, lists, etc. With no Erlang-master nearby (save this mailing list), it was definately a very uphill battle. (And I usually learn stuff fast, oh wait, don't we all?) I'm just now getting into OTP, and just now learned how to use application, supervisor, etc. And understand why I should. :) My line counts are WAY smaller, and my bug count is a dang near zero on even new, never compiled code. :) -- Shawn. You will contract a rare disease. From etxuwig@REDACTED Mon Mar 3 14:25:01 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Mon, 3 Mar 2003 14:25:01 +0100 (MET) Subject: continued init (RE: OTP or not to OTP) In-Reply-To: Message-ID: On Mon, 3 Mar 2003, Ulf Wiger wrote: >The place where this is preferrable to self() ! continue, >is for example during process restarts, when clients are >active and may succeed in calling the server before you >have time to send to yourself. It is very difficult to >close this hole entirely, and the above "hack" eliminates >the problem (introducing a less serious "double ack" >problem, which can be handled in supervisor.erl) > >The Better Solution will probably be something along the >lines of init/1 returning {continue, fun()}, or something. >Stay tuned (or take a look at my attached suggestion for a >patch -- my way of trying to appease the OTP Gods after >having promoted dirty hacks to the public... ;-) BTW, I tested my patch with the following callback: -module(gen_server_test). -behaviour(gen_server). ... start_link() -> spawn(fun() -> spray(?MODULE,600) end), {ok,Pid} = gen_server:start_link({local, ?MODULE}, ?MODULE, [], []), Pid ! foo, {ok,Pid}. spray(Name, N) when N > 0 -> catch Name ! {evil_message,N}, spray(Name,N-1); spray(Name,_) -> ok. init([]) -> {continue, fun() -> continued_init() end}. continued_init() -> self() ! i_am_here, {ok, #state{}}. handle_info(Info, State) -> io:format("*** Info: ~p~n", [Info]), {noreply, State}. I then tested it, and got the following printout: 20> gen_server_test:start_link(). *** Info: {evil_message,101} *** Info: {evil_message,100} {ok,<0.110.0>} *** Info: {evil_message,99} *** Info: {evil_message,98} *** Info: {evil_message,97} *** Info: {evil_message,96} *** Info: {evil_message,95} *** Info: {evil_message,94} *** Info: {evil_message,93} *** Info: {evil_message,92} *** Info: {evil_message,91} *** Info: {evil_message,90} *** Info: {evil_message,89} *** Info: {evil_message,88} *** Info: {evil_message,87} *** Info: {evil_message,86} *** Info: {evil_message,85} *** Info: {evil_message,84} *** Info: {evil_message,83} *** Info: {evil_message,82} *** Info: {evil_message,81} *** Info: {evil_message,80} *** Info: i_am_here *** Info: {evil_message,79} *** Info: {evil_message,78} *** Info: {evil_message,77} *** Info: {evil_message,76} *** Info: {evil_message,75} *** Info: {evil_message,74} *** Info: {evil_message,73} *** Info: {evil_message,72} *** Info: {evil_message,71} *** Info: {evil_message,70} *** Info: foo *** Info: {evil_message,69} *** Info: {evil_message,68} ... I was able to squeeze in 23 unwanted messages before the one that I casted to myself in the init/1 function, and another 10 before the message that came from the start_link() function. Not a realistic scenario, mind you, but fairly illustrative. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From Vlad.Dumitrescu@REDACTED Mon Mar 3 14:21:43 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Mon, 3 Mar 2003 14:21:43 +0100 Subject: More GUI (ravings?) Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D71200F849@esemont203.gbg.edt.ericsson.se> > From: Eric Merritt [mailto:cyberlync@REDACTED] > I kind of think that you are being misguided by the > OO world. Don't get me wrong I like OO and don't think > it is a bad thing, but its not the only way to do > things. Inheritence is not the only way to handle > sub-windowing behavior either, I am pretty sure. > > Unfortunatly, I need to think about it before I can > offer suggestions, but I would say try to think in > native erlang datastructures and processes. They are a > good solution and they should work for this just like > they work for so much else. Don't try to reinvent OO > in Erlang. I completely agree, and that's why I asked! :-) Maybe someone here isn't as "OO-ized" :-) I too want to make this completely Erlang-based, both in spirit and in implementation. I tried to find some references that might help, but again, all are OO, or OO-like, or even further from Erlang's model (monads and stuff). Sub-classing isn't really OO, as it can be used and is used at run-time, changing behaviour of things defined elsewhere. regards, Vlad From cyberlync@REDACTED Mon Mar 3 14:50:07 2003 From: cyberlync@REDACTED (Eric Merritt) Date: Mon, 3 Mar 2003 05:50:07 -0800 (PST) Subject: More GUI (ravings?) In-Reply-To: <5F03ACA2F76DD411B8BC00508BE3B4D71200F849@esemont203.gbg.edt.ericsson.se> Message-ID: <20030303135007.16492.qmail@web40807.mail.yahoo.com> > I completely agree, and that's why I asked! :-) > Maybe someone here isn't as "OO-ized" :-) > > I too want to make this completely Erlang-based, > both in spirit and in implementation. I tried to > find some references that might help, but again, all > are OO, or OO-like, or even further from Erlang's > model (monads and stuff). > > Sub-classing isn't really OO, as it can be used and > is used at run-time, changing behaviour of things > defined elsewhere. Hmmm, its a hard problem. The following is after very little thought so take that into account. I would think you would have a single process that would handle the actual drawings to screen. It could probably take some type of screen description (maybe similar to what clacke has done in ehtml, it would have to be much more low level of course). The drawing process would probably have to extensible, maybe an init configuration could register rendering routings for individual atoms in the spec. This would maen that your logic would have to be devided into two seperate and distinct areas, drawing and behaviors. Of course, the drawing process would handle default constructs so you wouldn't have to extend that if you weren't doing anything funky. Each event handler would be a seperate process (or maybe each event should be spun into its own process?). Hmm, probably event handlers would be registered to one of two areas, screen coords to get mouse clicks and keyboard in puts. With the mouse clicks and key board inputs you would probably want to send events in a synchrounous fashion with the last registered getting the first event and if you got a valid return value continuing to send events to other registered listeners. If you got a bad value (maybe a false?) you could stop sending the event. I would think also that the event manager would be in its own process. __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - forms, calculators, tips, more http://taxes.yahoo.com/ From spearce@REDACTED Mon Mar 3 14:50:56 2003 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 3 Mar 2003 08:50:56 -0500 Subject: yeah, we're just better then awk! Message-ID: <20030303135056.GF2082@spearce.org> Not sure if everyone has seen this: http://www.bagley.org/~doug/shootout/craps.shtml Apparently Erlang is just above Awk in the totally arbitrary ranking of langauges based on memory, cpu usage and lines of code to implement the pointless tests. :) Interesting to note our beloved tool ranks down with the likes of bash and awk. :-( Also interesting to note not one of the tests even beings to show Erlang's strengths. I guess Erlang does need better PR. -- Shawn. Your goose is cooked. (Your current chick is burned up too!) From eleberg@REDACTED Mon Mar 3 15:02:58 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Mon, 3 Mar 2003 15:02:58 +0100 (MET) Subject: yeah, we're just better then awk! Message-ID: <200303031402.h23E2wH06328@cbe.ericsson.se> > Date: Mon, 3 Mar 2003 08:50:56 -0500 > From: Shawn Pearce > To: erlang-questions@REDACTED > Subject: yeah, we're just better then awk! > Mail-Followup-To: erlang-questions@REDACTED > Mime-Version: 1.0 > Content-Disposition: inline > User-Agent: Mutt/1.4i > > Not sure if everyone has seen this: > > http://www.bagley.org/~doug/shootout/craps.shtml > > Apparently Erlang is just above Awk in the totally arbitrary > ranking of langauges based on memory, cpu usage and lines of > code to implement the pointless tests. :) fyi: i have submitted more up-to-date versions of the erlang programs (that run faster and are shorter), but they have not been accepted. the reasons are 1 mr bagley is not updating his unix page. 2 the page that is updated, by somebody else, is using windows versions of all languages. the windows version of erlang does not handle erl -s module func < input_data correctly. (no ''eof'' atom at end-of-file. this has been mentioned on this list) bengt From cyberlync@REDACTED Mon Mar 3 15:12:04 2003 From: cyberlync@REDACTED (Eric Merritt) Date: Mon, 3 Mar 2003 06:12:04 -0800 (PST) Subject: yeah, we're just better then awk! In-Reply-To: <20030303135056.GF2082@spearce.org> Message-ID: <20030303141204.26137.qmail@web40803.mail.yahoo.com> --- Shawn Pearce wrote: > Not sure if everyone has seen this: > > http://www.bagley.org/~doug/shootout/craps.shtml > > Apparently Erlang is just above Awk in the totally > arbitrary > ranking of langauges based on memory, cpu usage and > lines of > code to implement the pointless tests. :) > > Interesting to note our beloved tool ranks down with > the likes > of bash and awk. :-( > > Also interesting to note not one of the tests even > beings to > show Erlang's strengths. I guess Erlang does need > better PR. > Yea the guy who did this has a comentary on Erlang that basically says the same think. That its a nice langauge and none of the tests are suited to its strengths. Also I might point out that this uses and older version of erlang and did not use Hipe at all. Also this guy was an erlang novice so I am not sure how efficient the implementations where. __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - forms, calculators, tips, more http://taxes.yahoo.com/ From Sean.Hinde@REDACTED Mon Mar 3 15:14:07 2003 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Mon, 3 Mar 2003 14:14:07 -0000 Subject: continued init (RE: OTP or not to OTP) Message-ID: > On Mon, 3 Mar 2003, Sean Hinde wrote: > > >The main tcp/ip server model we use in our systems is made > >of 2 gen_servers. The only difference to the 'pure' erlang > >version is that the startup of the accepting gen_server > >process is made slightly more complex. The init function > >sends a message to itself to start up the accept call in > >the main callbacks otherwise the starting process would > >hang. > > > Some people will probably want to strangle me for revealing > this "secret", but you can actually do this: > > start_link() -> > gen_server:start_link({local,myserver},?MODULE,self(),[]). > > init(Parent) -> > ..., > proc_lib:init_ack(Parent, {ok,self()}), > State = ..., > {ok, State}. Well, we get away with it in our tcp server because the client is going to be the other end of the new socket which is only created when accept returns, and by that time we have consumed the message to ourselves and are ready to go. But yes, otherwise you are correct of course. I do believe that we are slightly kidding ourselves when we say that Erlang makes concurrent programming easy* - it is easy (ish) to make simple 'object' type processes but it is possible to get into an enormous mess of deadlocks and so on if you try to get too tricky. This to me is another reason why gen_servers and so on are a good thing - they stop people trying to get too complex and then find that after a couple of months some weird network conition occurs which deadlocks the whole thing. Sean * Vastly easier than the pthreads type model favoured elsewhere of course, but still not VB easy NOTICE AND DISCLAIMER: This email (including attachments) is confidential. If you have received this email in error please notify the sender immediately and delete this email from your system without copying or disseminating it or placing any reliance upon its contents. We cannot accept liability for any breaches of confidence arising through use of email. Any opinions expressed in this email (including attachments) are those of the author and do not necessarily reflect our opinions. We will not accept responsibility for any commitments made by our employees outside the scope of our business. We do not warrant the accuracy or completeness of such information. From spearce@REDACTED Mon Mar 3 15:19:35 2003 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 3 Mar 2003 09:19:35 -0500 Subject: yeah, we're just better then awk! In-Reply-To: <20030303141204.26137.qmail@web40803.mail.yahoo.com> References: <20030303135056.GF2082@spearce.org> <20030303141204.26137.qmail@web40803.mail.yahoo.com> Message-ID: <20030303141935.GG2082@spearce.org> Eric Merritt wrote: > Yea the guy who did this has a comentary on Erlang > that basically says the same think. That its a nice > langauge and none of the tests are suited to its > strengths. Also I might point out that this uses and > older version of erlang and did not use Hipe at all. > Also this guy was an erlang novice so I am not sure > how efficient the implementations where. Given the number of languages he implemented in, I have to wonder how good his implementation was in anything, save C or Java. :) Also, the tests are very small tests that only test simple operations. Nearly all languages have about the same number of lines of code, each test does no useful work, and the tests run fast on bare hardware and slower when higher levels are in the way. Thus they are unfairly biased against the native compiled languages. Its also unfairly biased against apps that can startup/shutdown very fast, which both Java and Erlang don't do well. SAE may have faired better. -- Shawn. The smallest worm will turn being trodden on. -- William Shakespeare, "Henry VI" From spearce@REDACTED Mon Mar 3 15:23:02 2003 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 3 Mar 2003 09:23:02 -0500 Subject: continued init (RE: OTP or not to OTP) In-Reply-To: References: Message-ID: <20030303142302.GH2082@spearce.org> Sean Hinde wrote: > But yes, otherwise you are correct of course. I do believe that we are > slightly kidding ourselves when we say that Erlang makes concurrent > programming easy* - it is easy (ish) to make simple 'object' type processes > but it is possible to get into an enormous mess of deadlocks and so on if > you try to get too tricky. This to me is another reason why gen_servers and > so on are a good thing - they stop people trying to get too complex and then > find that after a couple of months some weird network conition occurs which > deadlocks the whole thing. Ah, now we need gen_deadlock to perform deadlock detection by polling gen_* processes with alive operations to verify they are still sane, and if not, kill them so the supervisor restarts them. :) When can we expect to see gen_deadlock? :) > * Vastly easier than the pthreads type model favoured elsewhere of > course, but still not VB easy You can do concurrent programming in VB? You must be insane Sean. :) What I think Erlang does well is hide the easy stuff, so we only deal with the hard stuff. In other words, if we were doing this in C with pthreads, we wouldn't have time to address the hard stuff, we'd only have time to address the easy stuff, and ship. Perhaps that's one reason OTP works so well. -- Shawn. You will overcome the attacks of jealous associates. From matthias@REDACTED Mon Mar 3 15:29:14 2003 From: matthias@REDACTED (Matthias Lang) Date: Mon, 3 Mar 2003 15:29:14 +0100 Subject: continued init (RE: OTP or not to OTP) In-Reply-To: References: Message-ID: <15971.26298.913011.516594@antilipe.corelatus.se> Sean Hinde writes: > I do believe that we are > slightly kidding ourselves when we say that Erlang makes concurrent > programming easy* - it is easy (ish) to make simple 'object' type processes > but it is possible to get into an enormous mess of deadlocks and so on if > you try to get too tricky. This to me is another reason why gen_servers and > so on are a good thing - they stop people trying to get too complex and then > find that after a couple of months some weird network conition occurs which > deadlocks the whole thing. Even with gen_servers, the only thing preventing deadlock in most of the systems I write is the diagram on my whiteboard of which gen_servers are allowed to call which other gen_servers. Otherwise it's too easy to get into this situation: a.erl: lookup_something_else() -> gen_server:call(?MODULE, lookup_something_else). handle_call(_,_,_) -> b:lookup_something(), ... b.erl: lookup_something() -> gen_server:call(?MODULE, lookup_something). handle_call(_,_,_) -> a:lookup_something_else(), ... The positive thing about Erlang is that these types of mistakes almost always result in a deadlock followed by a timeout (as compared to corruption, crash or a permanently hung thread). Matthias From cyberlync@REDACTED Mon Mar 3 15:36:08 2003 From: cyberlync@REDACTED (Eric Merritt) Date: Mon, 3 Mar 2003 06:36:08 -0800 (PST) Subject: yeah, we're just better then awk! In-Reply-To: <20030303141935.GG2082@spearce.org> Message-ID: <20030303143608.67085.qmail@web40805.mail.yahoo.com> > Given the number of languages he implemented in, I > have > to wonder how good his implementation was in > anything, > save C or Java. :) > > Also, the tests are very small tests that only test > simple operations. Nearly all languages have about > the same number of lines of code, each test does no > useful work, and the tests run fast on bare hardware > and slower when higher levels are in the way. Thus > they are unfairly biased against the native compiled > languages. Its also unfairly biased against apps > that can startup/shutdown very fast, which both > Java and Erlang don't do well. SAE may have > faired better. > Just on a side not you can remove startup times from the equation on the individual tests. __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - forms, calculators, tips, more http://taxes.yahoo.com/ From Sean.Hinde@REDACTED Mon Mar 3 15:39:14 2003 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Mon, 3 Mar 2003 14:39:14 -0000 Subject: continued init (RE: OTP or not to OTP) Message-ID: > You can do concurrent programming in VB? You must be insane Sean. :) OK, perhaps I should have explicitly stated the context shift there.. Sean NOTICE AND DISCLAIMER: This email (including attachments) is confidential. If you have received this email in error please notify the sender immediately and delete this email from your system without copying or disseminating it or placing any reliance upon its contents. We cannot accept liability for any breaches of confidence arising through use of email. Any opinions expressed in this email (including attachments) are those of the author and do not necessarily reflect our opinions. We will not accept responsibility for any commitments made by our employees outside the scope of our business. We do not warrant the accuracy or completeness of such information. From david.wallin@REDACTED Mon Mar 3 17:08:43 2003 From: david.wallin@REDACTED (david wallin) Date: Mon, 03 Mar 2003 16:08:43 +0000 Subject: yeah, we're just better then awk! In-Reply-To: <20030303135056.GF2082@spearce.org> References: <20030303135056.GF2082@spearce.org> Message-ID: <1046707723.16567.4.camel@wintermute.csis.ul.ie> On Mon, 2003-03-03 at 13:50, Shawn Pearce wrote: > Not sure if everyone has seen this: > > http://www.bagley.org/~doug/shootout/craps.shtml > > Apparently Erlang is just above Awk in the totally arbitrary > ranking of langauges based on memory, cpu usage and lines of > code to implement the pointless tests. :) > > Interesting to note our beloved tool ranks down with the likes > of bash and awk. :-( > > Also interesting to note not one of the tests even beings to > show Erlang's strengths. I guess Erlang does need better PR. Here's another shootout where erlang is doing pretty ok (i.e., slightly faster than Java.) http://dada.perl.it/shootout/ackermann.html -- david wallin From Vlad.Dumitrescu@REDACTED Mon Mar 3 17:18:49 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Mon, 3 Mar 2003 17:18:49 +0100 Subject: More GUI (ravings?) Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D3F0@esemont203.gbg.edt.ericsson.se> > Hmmm, its a hard problem. The following is after very > little thought so take that into account. I would > think you would have a single process that would > handle the actual drawings to screen. <> Yes, something like that, but that was not the problem (or I misunderstood you). The problem is how to define these event handlers without heaps of copy-and-paste, and also how the plumbing between events and the corresponding response (signals and slots maybe?) should be done. The first problem is illusterated by an example: a widget is represented by a process. All widgets share some common behaviour - that might be implemented by the widget.erl module. Now a specific widget, let's say an InputField, has to redefine some of this behaviour, for example key presses it grabs have to be displayed. This can be done by a) copying widget.erl and replacing the affected code; b) somehow only specifying what's changed and referring to widget.erl for the rest. This will happen in several levels, for example a PasswordInputField that will display it's content as stars. Thus a hierarchy is implicitly defined. As you say, this needs a lot of thinking! :-) regards, Vlad From tony@REDACTED Mon Mar 3 17:27:23 2003 From: tony@REDACTED (Tony Rogvall) Date: Mon, 03 Mar 2003 17:27:23 +0100 Subject: GUI & ex11 References: <1046160453.5926@DNS02> Message-ID: <3E63826B.5080708@rogvall.com> Vlad Dumitrescu (EAW) wrote: > Hi all, > > After all the debate about GUIs (which I hope isn't over yet :-) I came to think about one thing that is actually rather obvious, but hey, I'm not from the Unix world! > > The language that Joe was looking for might very well be the X11 protocol! > Especially since there is a XPrint extension and also XFree86/Cygwin works on Windows. > > Now I started converting Tobbe's old ex11 package to use the binary format (I'm one third through it), but am wondering why didn't anyone else thought about it before... Is there anything wrong with the approach? I can't see any showstoppers. Then one can start building a Xtoolkit entirely in Erlang :-) > > Tobbe: I thought I would add ex11 to Jungerl, is this okay? > > best regards, > Vlad > > I am about 50% ready with the x11 client :-) Got stuck with image stuff. I can load fonts, display text, display graphics etc etc. I have an automated process for turning xproto header file into records and binary syntax parsing etc. We definietly need merge the stuff, or? Why am I doing this? Actually not becuase of joe's ides, but becuase I wanted to write a window manager completly in erlang! (look at http://www.inria.fr/koala/gwm for a lispish variant) /Tony From Vlad.Dumitrescu@REDACTED Mon Mar 3 17:25:53 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Mon, 3 Mar 2003 17:25:53 +0100 Subject: GUI & ex11 Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D3F1@esemont203.gbg.edt.ericsson.se> > From: Tony Rogvall [mailto:tony@REDACTED] > I am about 50% ready with the x11 client :-) Got stuck with > image stuff. > We definietly need merge the stuff, or? Yes, of course! There's no need to duplicate work, especially as implementing encoding/decoding X protocol messages isn't the most fun thing I can think of! :-) How should we go forward with it? regards, Vlad From erlang@REDACTED Mon Mar 3 17:42:53 2003 From: erlang@REDACTED (Peter-Henry Mander) Date: Mon, 03 Mar 2003 16:42:53 +0000 Subject: More GUI (ravings?) References: <20030303135007.16492.qmail@web40807.mail.yahoo.com> Message-ID: <3E63860D.5090902@manderp.freeserve.co.uk> Maybe I'm way of the mark, but why not use Erlang messages as you would OO "messages"? So if you "inherit" from a generic widget, you selectively receive the messages the "subclass" module process uses and delegate the rest to a "superclass" module process. I think that a deep inheritance tree means lots of layered processes, but there again Erlang apparently copes with that very well. I kinda like the ability of this model to pipeline the messages toward a superclass instance, but a round trip of sending a message to the base-class module an receiving the response may have an impact on responsivity. But maybe the concurrency in Erlang will offset this. Am I utterly deluded? If this works, why insist on a FP UI model? Could it be a better match for the asyncronously networked nature of X11? Pete. Eric Merritt wrote: >>I completely agree, and that's why I asked! :-) >>Maybe someone here isn't as "OO-ized" :-) >> >>I too want to make this completely Erlang-based, >>both in spirit and in implementation. I tried to >>find some references that might help, but again, all >>are OO, or OO-like, or even further from Erlang's >>model (monads and stuff). >> >>Sub-classing isn't really OO, as it can be used and >>is used at run-time, changing behaviour of things >>defined elsewhere. > > > Hmmm, its a hard problem. The following is after very > little thought so take that into account. I would > think you would have a single process that would > handle the actual drawings to screen. It could > probably take some type of screen description (maybe > similar to what clacke has done in ehtml, it would > have to be much more low level of course). The drawing > process would probably have to extensible, maybe an > init configuration could register rendering routings > for individual atoms in the spec. This would maen that > your logic would have to be devided into two seperate > and distinct areas, drawing and behaviors. Of course, > the drawing process would handle default constructs so > you wouldn't have to extend that if you weren't doing > anything funky. > > Each event handler would be a seperate process (or > maybe each event should be spun into its own > process?). Hmm, probably event handlers would be > registered to one of two areas, screen coords to get > mouse clicks and keyboard in puts. > > With the mouse clicks and key board inputs you would > probably want to send events in a synchrounous fashion > with the last registered getting the first event and > if you got a valid return value continuing to send > events to other registered listeners. If you got a bad > value (maybe a false?) you could stop sending the > event. > > I would think also that the event manager would be in > its own process. > > __________________________________________________ > Do you Yahoo!? > Yahoo! Tax Center - forms, calculators, tips, more > http://taxes.yahoo.com/ > > From vances@REDACTED Mon Mar 3 18:25:07 2003 From: vances@REDACTED (Vance Shipley) Date: Mon, 3 Mar 2003 12:25:07 -0500 Subject: Strange behaviour with a record in a guard In-Reply-To: <5F03ACA2F76DD411B8BC00508BE3B4D70FD69D27@esemont203.gbg.edt.ericsson.se> References: <5F03ACA2F76DD411B8BC00508BE3B4D70FD69D27@esemont203.gbg.edt.ericsson.se> Message-ID: <20030303172507.GI90014@frogman.motivity.ca> Ake, foo(R) when record(R, r1), R#r1.f1 == undefined -> file://localhost/usr/local/lib/erlang/doc/extensions/records.html#1.6 -Vance On Mon, Mar 03, 2003 at 10:07:28AM +0100, ?ke Johansson AI (EAB) wrote: } ... } -record(r1,{f1}) } } foo(R) when R#r1.f1 == undefined -> } ok. } ... } } It seems like foo(R) matches any tuple of size 2 or bigger, where the } second element is undefined. Should not the compiler add code which } checks that R is a record of the correct type? } } A sample program and sample run is found below. } } / Ake From kenneth@REDACTED Mon Mar 3 18:22:54 2003 From: kenneth@REDACTED (Kenneth Lundin) Date: Mon, 03 Mar 2003 18:22:54 +0100 Subject: Erlang vs Linux References: Message-ID: <3E638F6E.9020104@erix.ericsson.se> Hi, Just to make things clear about the patent regarding Erlang used in a special way in a special application. Ericsson relased Erlang as Open Source because we want many users of Erlang. All that Joe Armstrong has written below is correct, I see no problem whatsoever with Erlang applications written by Open Source users , they do not violate any patent by Ericsson just because they are written in Erlang and uses the OTP components and concepts. Regards Kenneth Lundin (Product Manager within Ericsson for Erlang/OTP) Joe Armstrong wrote: > On Wed, 26 Feb 2003, Miguel Barreiro Paz wrote: > > >> Just out of curiosity, I've coincidentally found that patent >>EP0544637 (equivalent to WO9311484, for those out of the EU) effectively >>patents Erlang and OTP. > > > No it doesn't - The patent covers the combination of Erlang + A > particular application + A particular way of programming the > application. > > The language was Erlang as is was in 1993 which is very different to > today (this was before Funs, binaries, bit syntax, etc.) had been > added to the language so it refers to a *different* version of the > language. > > The particular application was a PABX programmed with the so called > "half call model" > > The architecture was the so-called AOS (Application OS) this > was *before* BOS (basic OS) which was *before* OTP. > > In no way can todays Erlang/OTP be considered as a minor variation > of the Erlang/AOS referred to in the patent - there are several major > an nonobvious additions since the work in 1993. > > > > > In any case even if the patent referred was applicable to the current > Erlang/OTP (which it is not) then 2.1b of the license would apply > > --- quote > 2. Source Code License. > > 2.1. The Initial Developer Grant. > The Initial Developer hereby grants You a world-wide, royalty-free, > non-exclusive license, subject to third party intellectual property > claims: > > (a) to use, reproduce, modify, display, perform, sublicense and > distribute the Original Code (or portions thereof) with or without > Modifications, or as part of a Larger Work; and > > (b) under patents now or hereafter owned or controlled by Initial > Developer, to make, have made, use and sell (``Utilize'') the > Original Code (or portions thereof), but solely to the extent that > any such patent is reasonably necessary to enable You to Utilize > the Original Code (or portions thereof) and not to any greater > extent that may be necessary to Utilize further Modifications or > combinations. > > --- end > > The initial developer was Ericsson. 2.1(b) says that you can > "Utilize" the system even if such utilisation is regulated by patents > "now or hereafter owned or controlled by Initial Developer". > > Since Ericsson wants you to use Erlang (That's why it was released > as Open Source) - they explicitly granted you the right to use the > system - even if the use of the system was covered by their own > patents. > > If a competitor to Ericsson (say Nortel) held such a patent then > their might have been a problem. > > ---- > > Summary: > > 1) The patent refers to a historical vsn of Erlang + AOS + A PABX > application written in a particular manner. This is very different to > todays' Erlang + OTP. > > 2) Ericsson granted you the right to use OTP even when such use is > governed by patents held by Ericsson. > > /Joe > > > > >>I understand that its purpose is to guard >>Ericsson's shoulders, but the legal status of an opensourced system that >>is at the same time covered by a patent is a bit questionable without >>an explicit statement by the patent holder. > > > 2.1(b) was an explicit statement > > >> Can anyone comment on this? >> >>Regards, >> >>Miguel >> > > > > -- Kenneth Lundin Ericsson AB kenneth@REDACTED ?T2/UAB/UKH/K BOX 1505 +46 8 727 57 25 125 25 ?lvsj? From vances@REDACTED Mon Mar 3 18:36:41 2003 From: vances@REDACTED (Vance Shipley) Date: Mon, 3 Mar 2003 12:36:41 -0500 Subject: erl-interface - ing type question In-Reply-To: References: Message-ID: <20030303173641.GJ90014@frogman.motivity.ca> Daniel, I would also highly recommend using ei for any new project. However if you're already using erl_interface, as I am for one driver, you can indeed handle strings. Here's a snippet from one of my drivers: ETERM *Msg, *pattern, *A; char *filename; pattern = erl_format("{filename, A}"); if (erl_match(pattern, Msg)) { A = erl_var_content(pattern, "A"); if (ERL_IS_LIST(A)) { filename = erl_iolist_to_string(A); ... erl_free(filename); } erl_free_term(A); } erl_free_term(pattern); -Vance From luke@REDACTED Mon Mar 3 19:39:40 2003 From: luke@REDACTED (Luke Gorrie) Date: 03 Mar 2003 19:39:40 +0100 Subject: ensure_started In-Reply-To: References: Message-ID: Luke Gorrie writes: > Also, I'll probably be laughed at for this, but I just asked the > sourceforge guys to consider accepting SSH connections on port 80 of > cvs.sourceforge.net. Disgusting. It turns out they have already done this, and 'cvs-ssh.sourceforge.net' will accept CVS-over-SSH connections on ports 80 and 443. The details are at https://sourceforge.net/docman/display_doc.php?docid=768&group_id=1#firewall Of course this won't help if that whole IP address has been especially firewalled off. Cheers, Luke From Sean.Hinde@REDACTED Mon Mar 3 19:55:31 2003 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Mon, 3 Mar 2003 18:55:31 -0000 Subject: ensure_started Message-ID: > Luke Gorrie writes: > > > Also, I'll probably be laughed at for this, but I just asked the > > sourceforge guys to consider accepting SSH connections on port 80 of > > cvs.sourceforge.net. Disgusting. > > It turns out they have already done this, and > 'cvs-ssh.sourceforge.net' will accept CVS-over-SSH connections on > ports 80 and 443. The details are at > https://sourceforge.net/docman/display_doc.php?docid=768&group _id=1#firewall >Of course this won't help if that whole IP address has been especially >firewalled off. All I need to do now is stick a proxy in front of the thing which generates the HTTP CONNECT mechanism and I'm in.. unless you've already got a solution for that? Sean NOTICE AND DISCLAIMER: This email (including attachments) is confidential. If you have received this email in error please notify the sender immediately and delete this email from your system without copying or disseminating it or placing any reliance upon its contents. We cannot accept liability for any breaches of confidence arising through use of email. Any opinions expressed in this email (including attachments) are those of the author and do not necessarily reflect our opinions. We will not accept responsibility for any commitments made by our employees outside the scope of our business. We do not warrant the accuracy or completeness of such information. From luke@REDACTED Mon Mar 3 20:11:22 2003 From: luke@REDACTED (Luke Gorrie) Date: 03 Mar 2003 20:11:22 +0100 Subject: ensure_started In-Reply-To: References: Message-ID: Sean Hinde writes: > > Luke Gorrie writes: > > > > > Also, I'll probably be laughed at for this, but I just asked the > > > sourceforge guys to consider accepting SSH connections on port 80 of > > > cvs.sourceforge.net. Disgusting. > > > > It turns out they have already done this, and > > 'cvs-ssh.sourceforge.net' will accept CVS-over-SSH connections on > > ports 80 and 443. The details are at > > https://sourceforge.net/docman/display_doc.php?docid=768&group > _id=1#firewall > > >Of course this won't help if that whole IP address has been especially > >firewalled off. > > All I need to do now is stick a proxy in front of the thing which generates > the HTTP CONNECT mechanism and I'm in.. unless you've already got a solution > for that? Not sure that I understand. Is the problem that your outgoing port 80 connections are intercepted by a proxy server which mangles them? If so, how about port 443 (https)? Or something else? For me, with no firewalling at all, it works to add these two lines to ~/.ssh/config: Host cvs-ssh.sourceforge.net Port 443 Then I can use cvsroot lukeg@REDACTED:/cvsroot/jungerl -Luke From spearce@REDACTED Mon Mar 3 21:07:21 2003 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 3 Mar 2003 15:07:21 -0500 Subject: Using ets:match outside of ets? Message-ID: <20030303200721.GR22853@spearce.org> I basically need to do something like: M = #some_rec{f1=Type,f2=Y,_='_'}, % MatchSpec as per ets:match P = #some_rec{...}, % object to test case match(M, P) of true -> % good; false -> % bad; end. ideas? Note that I don't have the object P in an ets table and have no desire in registering it into an ets table for this test. :) -- Shawn. Q: What's the difference between USL and the Titanic? A: The Titanic had a band. From matthias@REDACTED Mon Mar 3 22:03:27 2003 From: matthias@REDACTED (Matthias Lang) Date: Mon, 3 Mar 2003 22:03:27 +0100 Subject: ensure_started In-Reply-To: References: Message-ID: <15971.49951.347782.228053@antilipe.corelatus.se> sean> All I need to do now is stick a proxy in front of the thing sean> which generates the HTTP CONNECT mechanism and I'm in.. unless sean> you've already got a solution for that? Try http://www.taiyo.co.jp/~gotoh/ssh/connect.html luke> Not sure that I understand. Is the problem that your outgoing port 80 luke> connections are intercepted by a proxy server which mangles them? Yep, that's exactly what happens. HTTP 1.1 finally added a simple way of getting from A to B: instead of issuing a 'GET' request, you say 'CONNECT ' and you get a clear socket channel there. Matt From p.caven@REDACTED Tue Mar 4 02:23:30 2003 From: p.caven@REDACTED (Peter Caven) Date: Mon, 3 Mar 2003 20:23:30 -0500 Subject: More GUI (ravings?) References: <5F03ACA2F76DD411B8BC00508BE3B4D71200F846@esemont203.gbg.edt.ericsson.se> Message-ID: <004c01c2e1ec$aa2c5a00$6501a8c0@Smaug> Hello Vlad, In my opinion, there has been some very deep thinking and a lot of work done in this area by Kevin Sullivan, Ira Kalet and David Notkin. My enlightenment occurred when I read their paper about the implementation of the Prism system: Mediators in a Radiation Treatment Planning Environment (1996) http://citeseer.nj.nec.com/sullivan96mediators.html Some additional papers are: http://citeseer.nj.nec.com/sullivan94mediators.html http://citeseer.nj.nec.com/sullivan93prism.html -- Peter. ----- Original Message ----- From: "Vlad Dumitrescu (EAW)" To: "Erlang-questions (E-mail)" Sent: Monday, March 03, 2003 5:32 AM Subject: More GUI (ravings?) > Hi all, > > Since I am working on ex11, I am also trying to see what might come ahead and try to plan for a possible widget toolkit, implemented in Erlang. As I said once before, I can't see any way to do it in a different way that it is done in most other languages, that is OO or the like. Please if there is anyone that has a link to a GUI framework that isn't OO (but not too far from Erlang's philosophy either), send it to me. > > The "missing feature" that would be needed has already been discussed here in many ways: building a hierarchy of behaviours. Or with another word, implementing subclassing. A generic window has behaviour that an input widget will "inherit" and that one can further be refined to become a "password input" widget. > > The question is how to delegate the "inherited" behaviour to the right implementation module? > > ---- > One way is to just write lots of funs similar to > set_visible(Widget) -> > widget:set_visible(Widget). > But this seems very heavy on the typing fingers and not extendible. Maybe some macros could help, but it would look like a C++ framework from > > Another way is to use for example an attribute > -inherits([widget]). > and then either: > * change error_handler:undefined_function to check any modules named in 'inherits' for the respective function before reporting an undef error > or > * let the compiler generate the stubs above, but then only one "parent" can be used. > > Yet another way would be writing behaviours on top of other behaviours, and also let one process implement several behaviours. > > Or even modify the language to allow for generic functions (? la Lisp) that can be extended from another module than the one they were originally written in. > ---- > > I am reluctant to use the term "inherit" but I found none better. What is needed is indeed a behavioural inheritance, which might not have anything to do with objects and classes as we learned to love/hate them :-) > > I don't think I am completely out in the bush, but if I am, please let me know. :-) I will have to give this more thought, but I feel some feedback will be useful. > regards, > Vlad > > > From p-news@REDACTED Tue Mar 4 03:31:44 2003 From: p-news@REDACTED (Per Einar =?iso-8859-1?q?Str=F6mme?=) Date: Tue, 4 Mar 2003 03:31:44 +0100 Subject: Installation problem R9B-0 In-Reply-To: <20030303200721.GR22853@spearce.org> References: <20030303200721.GR22853@spearce.org> Message-ID: <200303040331.44323.p-news@telia.com> Hej ! I had some problems installing Erlang R9B-0 on my SuSE Linux version 8.1 (I hope the choise of SuSE is not a problem in it self ! ? ). Since I'm not quite sure on if this is a bug, I post this little report here. The main problem appears to have been my choice of SWEDISH instead of English as preferred language. ~/div/otp_src_R9B-0> echo $LANG sv_SE ~/div/otp_src_R9B-0> The symptom was: ---------------------------------------------------------------------- ~/div/otp_src_R9B-0> make cd erts/emulator && ERL_TOP=~/div/otp_src_R9B-0 make generate depend make[1]: Entering directory `~/div/otp_src_R9B-0/erts/emulator' make -f i686-pc-linux-gnuoldld/Makefile generate make[2]: Entering directory `~/div/otp_src_R9B-0/erts/emulator' make[2]: i686-pc-linux-gnuoldld/Makefile: Filen eller katalogen finns inte make[2]: *** No rule to make target `i686-pc-linux-gnuoldld/Makefile'. Stop. make[2]: Leaving directory `~/div/otp_src_R9B-0/erts/emulator' make[1]: *** [generate] Error 2 make[1]: Leaving directory `~/div/otp_src_R9B-0/erts/emulator' make: *** [depend] Error 2 ~/div/otp_src_R9B-0> ---------------------------------------------------------------------- The short short story: ---------------------- In the file 'otp_src_R9B-0/erts/autoconf/config.guess' (row 884 & 886) the printout from 'ld --help' is searched for the text: 'supported emulations' but in my version it returns the swedish text: 'emuleringar som st?ds'. I certainly did'nt expect the help text from ld to be translated but it was. So I changed the rows in 'config.guess' to the swedish text and 'make' workt. For 'make install' I had to change it back to the original text. The short story: ---------------- Since I had to do some trial and error to get things to work I'm a bit confused on what in the end did do a difference. I downloaded the otp_src_R9B-0.tar.gz to one user and copied the uncompressed/untared file three to another user trying to 'make' the system there aswell but it finaly was made to work in the original users filesystem. At some stage it looked like something wanted to have access to the otp_src_R9B-0.tar.gz, 'configure' or 'make' I don't remember I also tried this: ./configure --host=i686-pc-linux-gnu \ --target=i686-pc-linux-gnu \ --build=i686-pc-linux-gnu \ --enable-threads The following was recomended in some other posting on installation problems: LANG=c export LANG=c LANGUAGE=c export LANGUAGE=c and added: 'use bytes;' to erts/emulator/utils/make_preload However I definitely changed the rows in 'config.guess' to the Swedish text for 'make' to work and then back to the English version for 'make install'. --------------------------------------------- end of the short story ---- I suspect a hint about language versions in the README file is appropriate. For the sake of easing the spreading of Erlang I guess some hints could be added on what is recommended practice for running as root: 'configure' 'make' 'make install' none, some or all and possible consequences thereof. I'm no UNIX guru myself so I could use this hint. Rgrds Per Einar -------------------------------------------------------------------------------- Per Einar Str?mme p-news@REDACTED -------------------------------------------------------------------------------- From p-news@REDACTED Tue Mar 4 03:45:14 2003 From: p-news@REDACTED (Per Einar =?iso-8859-1?q?Str=F6mme?=) Date: Tue, 4 Mar 2003 03:45:14 +0100 Subject: Installation problem R9B-0 Message-ID: <200303040345.14046.p-news@telia.com> .....There's a first time for everything, I hope this posting ends at the right level. Hej ! I had some problems installing Erlang R9B-0 on my SuSE Linux version 8.1 (I hope the choise of SuSE is not a problem in it self ! ? ). Since I'm not quite sure on if this is a bug, I post this little report here. The main problem appears to have been my choice of SWEDISH instead of English as preferred language. ~/div/otp_src_R9B-0> echo $LANG sv_SE ~/div/otp_src_R9B-0> The symptom was: ---------------------------------------------------------------------- ~/div/otp_src_R9B-0> make cd erts/emulator && ERL_TOP=~/div/otp_src_R9B-0 make generate depend make[1]: Entering directory `~/div/otp_src_R9B-0/erts/emulator' make -f i686-pc-linux-gnuoldld/Makefile generate make[2]: Entering directory `~/div/otp_src_R9B-0/erts/emulator' make[2]: i686-pc-linux-gnuoldld/Makefile: Filen eller katalogen finns inte make[2]: *** No rule to make target `i686-pc-linux-gnuoldld/Makefile'. Stop. make[2]: Leaving directory `~/div/otp_src_R9B-0/erts/emulator' make[1]: *** [generate] Error 2 make[1]: Leaving directory `~/div/otp_src_R9B-0/erts/emulator' make: *** [depend] Error 2 ~/div/otp_src_R9B-0> ---------------------------------------------------------------------- The short short story: ---------------------- In the file 'otp_src_R9B-0/erts/autoconf/config.guess' (row 884 & 886) the printout from 'ld --help' is searched for the text: 'supported emulations' but in my version it returns the swedish text: 'emuleringar som st?ds'. I certainly did'nt expect the help text from ld to be translated but it was. So I changed the rows in 'config.guess' to the swedish text and 'make' workt. For 'make install' I had to change it back to the original text. The short story: ---------------- Since I had to do some trial and error to get things to work I'm a bit confused on what in the end did do a difference. I downloaded the otp_src_R9B-0.tar.gz to one user and copied the uncompressed/untared file three to another user trying to 'make' the system there aswell but it finaly was made to work in the original users filesystem. At some stage it looked like something wanted to have access to the otp_src_R9B-0.tar.gz, 'configure' or 'make' I don't remember I also tried this: ./configure --host=i686-pc-linux-gnu \ --target=i686-pc-linux-gnu \ --build=i686-pc-linux-gnu \ --enable-threads The following was recomended in some other posting on installation problems: LANG=c export LANG=c LANGUAGE=c export LANGUAGE=c and added: 'use bytes;' to erts/emulator/utils/make_preload However I definitely changed the rows in 'config.guess' to the Swedish text for 'make' to work and then back to the English version for 'make install'. --------------------------------------------- end of the short story ---- I suspect a hint about language versions in the README file is appropriate. For the sake of easing the spreading of Erlang I guess some hints could be added on what is recommended practice for running as root: 'configure' 'make' 'make install' none, some or all and possible consequences thereof. I'm no UNIX guru myself so I could use this hint. Rgrds Per Einar -------------------------------------------------------------------------------- Per Einar Str?mme p-news@REDACTED -------------------------------------------------------------------------------- From vances@REDACTED Tue Mar 4 04:57:49 2003 From: vances@REDACTED (Vance Shipley) Date: Mon, 3 Mar 2003 22:57:49 -0500 Subject: How nice should I be on exit? Message-ID: <20030304035749.GD389@frogman.motivity.ca> Following the Erlang philosophy we let crashes occur when there are things going wrong. A process should die when it is abused, this is normal. It takes some getting used to though as we tend to want to program defensively. Now I'm asking myself whether I should worry about cleaning up when a process is going to die normally. In this case I have set up monitoring of a number of other processes and stored the references. It's a small pain to go through the list, pull out the references and run erlang:demonitor/1 on them. I'm thinking that in all likelyhood it would be more effecient (oops!) to let the run time system clean up after me. The same could apply to ets tables, ???, ... What say the experts? -Vance From jay@REDACTED Tue Mar 4 06:55:09 2003 From: jay@REDACTED (Jay Nelson) Date: Mon, 03 Mar 2003 21:55:09 -0800 Subject: OTP or not to OTP Message-ID: <4.2.2.20030303214611.00ccf100@duomark.com> OK, I'm back in the OTP camp. I have figured out what to change, but I have only 1 hour every few days during the week for this so it will definitely be next weekend before I have a chance to post my example. The struggles I had were due to two things: inexperience with the erlang way and having to restructure my original approach because of the process counting. I was fighting the mindset that I started the project with. I will also incorporate the discussions of monitor / demonitor and the more correct record testing method as well as the deadlock issue which can bite with just 1 server. The biggest effort will be rewriting the text of the tutorial because the issues have all changed from what I was originally highlighting. It will explicitly identify the design tradeoffs and why the approach presented was chosen. Thanks all for a very insightful discussion. jay From bernardp@REDACTED Tue Mar 4 09:17:24 2003 From: bernardp@REDACTED (Pierpaolo BERNARDI) Date: Tue, 4 Mar 2003 09:17:24 +0100 Subject: Using ets:match outside of ets? References: <20030303200721.GR22853@spearce.org> Message-ID: <011501c2e226$7d72b7e0$b8f06850@c1p4e3> From: "Shawn Pearce" > I basically need to do something like: > > M = #some_rec{f1=Type,f2=Y,_='_'}, % MatchSpec as per ets:match > P = #some_rec{...}, % object to test > case match(M, P) of > true -> > % good; > false -> > % bad; > end. > > ideas? the function ets:test_ms/2 does *almost* exactly what you want. Perhaps you can adapt your code to use it. P. From bjorn@REDACTED Tue Mar 4 09:42:09 2003 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 04 Mar 2003 09:42:09 +0100 Subject: Does ets:select/2 block the VM? In-Reply-To: Shawn Pearce's message of "Sun, 2 Mar 2003 22:27:28 -0500" References: <20030303032728.GL22853@spearce.org> Message-ID: Answer from Patrik Nyblom: Shawn Pearce writes: > I'm wondering about the implementation of ets:select/2. > > If I match against a table with 200k records it takes nearly 1 second to > complete on my system. I think I'm ok with this performance wise, but > I can't have the ets:select/2 call block the entire emulator, other traffic > still needs to be executed and processed in other processes. It will be. The process will be rescheduled several times during the 'select', precisely because we cannot have it blocking the emulator. > > An informal test where I spawn up a background process and have it > use io:format/2 every 10 milliseconds to print a message seems to run > perfectly fine while a 1 second ets:select/2 runs in another process. > > I'm assuming thus that the Erlang system authors have thought about this > and have ensured that it doesn't become a problem. :-) Oh, yes :-) > > > Also, the documentation is vague as to what happens if the table owner > modifies a protected ets table using insert or delete while other > processes are using ets:select/2 or ets:select/3 (select with > a limit and continuation). Is it safe to perform this, or does > the reader process have to use ets:safe_fixtable/2 ? Sorry for the vague documentation. What should have been in the doc is this: It is "safe" to use select/2 (or match/match_object) on a table while another process is updating it. It will however not be a real transaction. The table is fixed during the select-operation, but if an object appears in the table it depends on the hash value (in the set/bag/duplicate bag case) if the simultaneous select will see it, i.e. if the select has already traversed the hash bucket where the new object is inserted, it wont see it and vice versa. In the ordered set case, the effect is rougly the same, but it depends on the key value itselt if it will be seen (the order). In the case of select/3, the "automatic fixation" of the table cannot be done (cause ets does not know when you're done traversing), so you have to use safe_fixtable/2 to achieve the same effect. If you use ordered_set, the safe_fixtable/2 is a noop however, it simply isn't needed for trees, so strictly speeking it isn't really needed for that table type, but it costs very little to use it anyway. Best regards, /Patrik From spearce@REDACTED Tue Mar 4 09:58:29 2003 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 4 Mar 2003 03:58:29 -0500 Subject: Using ets:match outside of ets? In-Reply-To: <011501c2e226$7d72b7e0$b8f06850@c1p4e3> References: <20030303200721.GR22853@spearce.org> <011501c2e226$7d72b7e0$b8f06850@c1p4e3> Message-ID: <20030304085829.GS22853@spearce.org> Doh! I remember seeing that function 2 days ago. :) These darn docs cover so much stuff! Thanks, I'll try ets:test_ms/2, it does look like it would work for me. Pierpaolo BERNARDI wrote: > From: "Shawn Pearce" > > > I basically need to do something like: > > > > M = #some_rec{f1=Type,f2=Y,_='_'}, % MatchSpec as per ets:match > > P = #some_rec{...}, % object to test > > case match(M, P) of > > true -> > > % good; > > false -> > > % bad; > > end. > > > > ideas? > > the function ets:test_ms/2 does *almost* exactly what you want. > Perhaps you can adapt your code to use it. > > P. > -- Shawn. The only way to keep your health is to eat what you don't want, drink what you don't like, and do what you'd rather not. -- Mark Twain From spearce@REDACTED Tue Mar 4 09:59:35 2003 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 4 Mar 2003 03:59:35 -0500 Subject: Does ets:select/2 block the VM? In-Reply-To: References: <20030303032728.GL22853@spearce.org> Message-ID: <20030304085935.GT22853@spearce.org> Bjorn Gustavsson wrote: > > Also, the documentation is vague as to what happens if the table owner > > modifies a protected ets table using insert or delete while other > > processes are using ets:select/2 or ets:select/3 (select with > > a limit and continuation). Is it safe to perform this, or does > > the reader process have to use ets:safe_fixtable/2 ? > Sorry for the vague documentation. What should have been in the doc is > this: > > It is "safe" to use select/2 (or match/match_object) on a table while > another process is updating it. It will however not be a real transaction. > The table is fixed during the select-operation, but if an object appears > in the table it depends on the hash value (in the set/bag/duplicate bag > case) if the simultaneous select will see it, i.e. if the select has > already traversed the hash bucket where the new object is inserted, it > wont see it and vice versa. In the ordered set case, the effect is rougly > the same, but it depends on the key value itselt if it will be seen (the > order). > > In the case of select/3, the "automatic fixation" of the table cannot be > done (cause ets does not know when you're done traversing), so you have to > use safe_fixtable/2 to achieve the same effect. If you use ordered_set, > the safe_fixtable/2 is a noop however, it simply isn't needed for trees, > so strictly speeking it isn't really needed for that table type, but it > costs very little to use it anyway. I recently switched to select/3, so this is good to know (that I must safe_fixtable/2 before and after). Thanks. -- Shawn. Q: What's buried in Grant's tomb? A: A corpse. From spearce@REDACTED Tue Mar 4 10:09:45 2003 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 4 Mar 2003 04:09:45 -0500 Subject: Does ets:select/2 block the VM? In-Reply-To: <20030304085935.GT22853@spearce.org> References: <20030303032728.GL22853@spearce.org> <20030304085935.GT22853@spearce.org> Message-ID: <20030304090945.GU22853@spearce.org> Ok, I just read the ets:safe_fixtable/2 docs: Note that no deleted objects are actually removed from a fixed table until it has been released. If a process fixes a table but never releases it, the memory used by the deleted objects will never be freed. The performance of operations on the table will also degrade significantly. Use info/2 to retrieve information about which processes have fixed which tables. A system with a lot of processes fixing tables may need a monitor which sends alarms when tables have been fixed for too long. The implied meaning behind these kind of worries me a little. :-) It seems like the table can be modified while other proccesses have outstanding fixtable requests (traversing), but that objects which are deleted won't get deleted until all fixtable requests are released. What happens if this never occurs because a process is always fixtable'd? (A fixtables, B fixtables, A releases, A fixtables, B releases...) What assurances are made that the table is timely GC'd after all fixtable's have been removed? I may be in a situation of a "system with a lot of processes fixing tables". Or at least something like that. It all depends, I have a single operation that requires me to scan a group of ets tables when a process/connection starts up, but after that I should rarely, if ever scan the ets tables again. Problem is, I don't know what my connection rate is yet. I'm assuming it'll be something like hundreds of connections in a 15 minute window in the morning as people sign on to the system when they arrive at work, and then almost no activity for the rest of the day. I'm just wondering if I may run into trouble with this by having hundreds of processes scanning the ets tables around the same time or not. Must test this soon I guess. Shawn Pearce wrote: > Bjorn Gustavsson wrote: > > > Also, the documentation is vague as to what happens if the table owner > > > modifies a protected ets table using insert or delete while other > > > processes are using ets:select/2 or ets:select/3 (select with > > > a limit and continuation). Is it safe to perform this, or does > > > the reader process have to use ets:safe_fixtable/2 ? > > Sorry for the vague documentation. What should have been in the doc is > > this: > > > > It is "safe" to use select/2 (or match/match_object) on a table while > > another process is updating it. It will however not be a real transaction. > > The table is fixed during the select-operation, but if an object appears > > in the table it depends on the hash value (in the set/bag/duplicate bag > > case) if the simultaneous select will see it, i.e. if the select has > > already traversed the hash bucket where the new object is inserted, it > > wont see it and vice versa. In the ordered set case, the effect is rougly > > the same, but it depends on the key value itselt if it will be seen (the > > order). > > > > In the case of select/3, the "automatic fixation" of the table cannot be > > done (cause ets does not know when you're done traversing), so you have to > > use safe_fixtable/2 to achieve the same effect. If you use ordered_set, > > the safe_fixtable/2 is a noop however, it simply isn't needed for trees, > > so strictly speeking it isn't really needed for that table type, but it > > costs very little to use it anyway. > > > I recently switched to select/3, so this is good to know (that I must > safe_fixtable/2 before and after). Thanks. -- Shawn. Today is the last day of your life so far. From eleberg@REDACTED Tue Mar 4 10:21:45 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Tue, 4 Mar 2003 10:21:45 +0100 (MET) Subject: yeah, we're just better then awk! Message-ID: <200303040921.h249LjH14882@cbe.ericsson.se> > Date: Mon, 3 Mar 2003 09:19:35 -0500 > From: Shawn Pearce > To: erlang-questions@REDACTED > Subject: Re: yeah, we're just better then awk! > Mail-Followup-To: erlang-questions@REDACTED > Mime-Version: 1.0 > Content-Disposition: inline > User-Agent: Mutt/1.4i > ...deleted > Given the number of languages he implemented in, I have > to wonder how good his implementation was in anything, > save C or Java. :) they are not all his implementations. anybody can send in a version. most exotic languages have other authors. > Also, the tests are very small tests that only test > simple operations. Nearly all languages have about > the same number of lines of code, each test does no > useful work, are we talking about http://www.bagley.org/~doug/shootout ? most of the tests there do real work (ex: word count, sorting, reversing, adding numbers) on file contents. > and the tests run fast on bare hardware > and slower when higher levels are in the way. Thus > they are unfairly biased against the native compiled > languages. Its also unfairly biased against apps > that can startup/shutdown very fast, which both > Java and Erlang don't do well. SAE may have > faired better. i do not think it is unfairly biased. for this kind of problems it is a good thing to be fast in startup and excution speed. moreover, some of the languages that are fast are very high level (ex: ocaml, haskell, sml). perhaps you mean that the higher levels are virtual machines? bengt From kent@REDACTED Tue Mar 4 10:38:00 2003 From: kent@REDACTED (Kent Boortz) Date: 04 Mar 2003 10:38:00 +0100 Subject: Installation problem R9B-0 In-Reply-To: <200303040345.14046.p-news@telia.com> References: <200303040345.14046.p-news@telia.com> Message-ID: Per Einar Str?mme writes: > In the file 'otp_src_R9B-0/erts/autoconf/config.guess' (row 884 & 886) > the printout from 'ld --help' is searched for the text: 'supported emulations' > but in my version it returns the swedish text: 'emuleringar som st?ds'. > I certainly did'nt expect the help text from ld to be translated but > it was. > > So I changed the rows in 'config.guess' to the swedish text and 'make' workt. > For 'make install' I had to change it back to the original text. Thank you for your detailed report. This is a bug that has been corrected in later releases of config.guess. From the ChangeLog 2002-02-12 Ben Elliston * config.guess: Set LC_ALL, not LANG, when running ld --help. From Nicola Pero . 2002-01-22 Nicola Pero * config.guess (i*86:Linux:*:*): Fixed: export LANG=C before running ld so that linker output can be assumed to be in English, and it works with non-default locales. We will update the config.guess and config.sub before R9B-2, kent Ref: http://savannah.gnu.org/cgi-bin/viewcvs/config/config/ From vances@REDACTED Tue Mar 4 10:38:57 2003 From: vances@REDACTED (Vance Shipley) Date: Tue, 4 Mar 2003 04:38:57 -0500 Subject: Documenting the Language Message-ID: <20030304093857.GA1993@frogman.motivity.ca> There really does need to be a document which definetivly decribes the core langauge. Now I know there is the "Reference Manual" but it is dated February 9, 1999 and is "DRAFT (0.7)". It's the Erlang 4.7.3 reference manual and we're currently on 5.2. It's also only available as a postscript file and I haven't had any luck text searching it. A case in point is the collection of boolean BIFs: is_atom/1, is_constant/1, is_float/1, is_integer/1, is_list/1, is_number/1, is_pid/1, is_port/1, is_reference/1, is_tuple/1, is_binary/1, is_function/1, is_record/1 The closest these come to being documented is in the ERTS User's Guide under Match Specifications in Erlang. Other than this they were mentioned in the release notes of the compiler and there is a passing mention in Erlang Extensions Since 4.4 under Boolean expressions in guards. Another issue is in what is allowed in a guard. I found through trial and error that is_process_alive/1 is not allowed in a guard despite it's encouraging name. There is a function exported from erl_internal, and documented, which tests if a function is valid in a guard: guard_bif(Name, Arity) -> bool() Types: Name = atom() Arity = integer() Returns true if Name/Arity is an Erlang BIF which is allowed in guards, otherwise false. That was a little hard to find though and it still doesn't give me a list, it only allows me to test what the compiler will complain about later. When try & cond show up will they only be mentioned in the release notes? There has been a lot of talk about promoting Erlang here. I think having a definitive list of BIFS would be a good start. I would do it myself but I don't appear to be qualified as I tried but quickly got lost in categorizing bifs,operators,guards,tests,etc. -Vance From spearce@REDACTED Tue Mar 4 10:41:07 2003 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 4 Mar 2003 04:41:07 -0500 Subject: yeah, we're just better then awk! In-Reply-To: <200303040921.h249LjH14882@cbe.ericsson.se> References: <200303040921.h249LjH14882@cbe.ericsson.se> Message-ID: <20030304094107.GV22853@spearce.org> Bengt Kleberg wrote: > > Given the number of languages he implemented in, I have > > to wonder how good his implementation was in anything, > > save C or Java. :) > > they are not all his implementations. anybody can send in a version. > most exotic languages have other authors. I didn't realize that. I guess that makes more sense than one poor sap learning enough of each langauge to be dangerous and write up examples for the shootout. > > Also, the tests are very small tests that only test > > simple operations. Nearly all languages have about > > the same number of lines of code, each test does no > > useful work, > > are we talking about http://www.bagley.org/~doug/shootout ? > most of the tests there do real work (ex: word count, sorting, > reversing, adding numbers) on file contents. Yes. I guess I consider that although this is real work, in the grand scheme of what most computing is today, they are overtly simple. Meaning lets take an example such as a modern peice of software that is slighlty larger and more complex than sort: a web browser, or a network server, or some other such "beast" of a program. The expressive power of each language, coupled with the builtin toolbox (standard libraries) will make huge differences between them when it comes to lines of code required to solve the problem. Compare that to a word count or sorting problem, where most langauges either have equivilent expressivity to access their equivilient standard sorting routines, or will have equivilient expressivity to express quicksort or some such sorting routine. I definately see your point that these tests do real work for which quite a few programs exist in product do. (I couldn't live without wc, sort, etc.) However, my (poorly) made point was more to the "these programs are all fairly small" when talking about lines of code to solve a problem, and performance of language to solve said problem. > > and the tests run fast on bare hardware > > and slower when higher levels are in the way. Thus > > they are unfairly biased against the native compiled > > languages. Its also unfairly biased against apps > > that can startup/shutdown very fast, which both > > Java and Erlang don't do well. SAE may have > > faired better. > > i do not think it is unfairly biased. for this kind of problems it is a > good thing to be fast in startup and excution speed. > moreover, some of the languages that are fast are very high level (ex: > ocaml, haskell, sml). > perhaps you mean that the higher levels are virtual machines? Ok, I see your points. I felt it was unfairly biased against languages which tend to have higher startup costs, I wouldn't see these used to solve the kinds of problems the shootout throws at them, for exactly that reason: they just take too long to startup compared to other languages, but lines of code wise they are equal. I guess in that context the language shootout is a big success, as it shows what many of us feel we inherently "know" about these tools: who would use Java to count the number of words in a file given the amount of memory it needs and the time it takes to startup/shutdown relative to native C? I meant it was "unfairly biased" against Erlang in that few of us (I think anyway) would use Erlang for these problems, as the language (imho) is ill-suited for these tasks. The strong points of Erlang are for building larger, complex systems which demand reliability, vs. smaller, fast tasks which demand speed and low resource consumption. I didn't pay enough attention to the shootout relative to the other langauges to note that ocaml, etc. came out as being good performers. Next time I better do so. :) I do think though that I was implying more the virtual machine langauges when I said "higher level", but to some degree I was also implying the langauges themselves in that higher levels of abstraction do tend to pay in performance (but not always). Just as we tended away from assembly to C, we'll tend to higher level languages than C soon enough. Hardware is getting so fast and compilers are getting so good that its just a matter of a few years before people do seriously consider writting `wc' in Java. What a sad, sad day that will be. :) -- Shawn. Man is the only animal that blushes -- or needs to. -- Mark Twain From gunilla@REDACTED Tue Mar 4 10:59:20 2003 From: gunilla@REDACTED (Gunilla Arendt) Date: Tue, 04 Mar 2003 10:59:20 +0100 Subject: Documenting the Language References: <20030304093857.GA1993@frogman.motivity.ca> Message-ID: <3E6478F8.3F341FA9@erix.ericsson.se> As a coincidence, I'm right now in the process of putting together an 'Erlang Reference Manual'. When your message arrived, I was making a list of BIFs allowed in guards... The reference manual will be included in OTP as soon as possible, which means in the commercial R9C release planned for August and possibly in an Open Source snapshot before that. / Gunilla Arendt, Erlang/OTP team Vance Shipley wrote: > > > There really does need to be a document which definetivly > decribes the core langauge. Now I know there is the > "Reference Manual" but it is dated February 9, 1999 and is > "DRAFT (0.7)". It's the Erlang 4.7.3 reference manual and > we're currently on 5.2. It's also only available as a > postscript file and I haven't had any luck text searching it. > > A case in point is the collection of boolean BIFs: > > is_atom/1, is_constant/1, is_float/1, > is_integer/1, is_list/1, is_number/1, > is_pid/1, is_port/1, is_reference/1, > is_tuple/1, is_binary/1, is_function/1, > is_record/1 > > The closest these come to being documented is in the ERTS > User's Guide under Match Specifications in Erlang. Other than > this they were mentioned in the release notes of the compiler > and there is a passing mention in Erlang Extensions Since 4.4 > under Boolean expressions in guards. > > Another issue is in what is allowed in a guard. I found through > trial and error that is_process_alive/1 is not allowed in a guard > despite it's encouraging name. There is a function exported from > erl_internal, and documented, which tests if a function is valid > in a guard: > > guard_bif(Name, Arity) -> bool() > > Types: > Name = atom() > Arity = integer() > > Returns true if Name/Arity is an Erlang BIF which is allowed > in guards, otherwise false. > > That was a little hard to find though and it still doesn't give > me a list, it only allows me to test what the compiler will > complain about later. > > When try & cond show up will they only be mentioned in the release > notes? There has been a lot of talk about promoting Erlang here. > I think having a definitive list of BIFS would be a good start. > > I would do it myself but I don't appear to be qualified as I tried > but quickly got lost in categorizing bifs,operators,guards,tests,etc. > > > -Vance From spearce@REDACTED Tue Mar 4 11:35:51 2003 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 4 Mar 2003 05:35:51 -0500 Subject: Doc error in gen_fsm Message-ID: <20030304103551.GW22853@spearce.org> R9B-0 gen_fsm manpage for sync_send_all_state_event/2,3: The gen_fsm will call Module:handle_event/3 to handle the event. I think they meant to say "will call Module:handle_event/4" instead. Minor doc error. :) -- Shawn. Of course you have a purpose -- to find a purpose. From bernardp@REDACTED Tue Mar 4 12:12:52 2003 From: bernardp@REDACTED (Pierpaolo BERNARDI) Date: Tue, 4 Mar 2003 12:12:52 +0100 Subject: yeah, we're just better then awk! References: <20030303141204.26137.qmail@web40803.mail.yahoo.com> Message-ID: <006101c2e23f$03470c00$fcf06850@c1p4e3> From: "Eric Merritt" > Yea the guy who did this has a comentary on Erlang > that basically says the same think. That its a nice > langauge and none of the tests are suited to its > strengths. Hmmm... I have been surprised by Erlang in a test which probably is as far from its strengths as possible. I rewrote in Erlang a Common Lisp program which, essentially, accesses repeatedly a big 2d array, and does some manipulations of short lists. I obtain these times: Clisp: 11/12s HCL: 1.5/2s Erlang using gb_trees as arrays: 32/34s Erlang using an ets table as array: 7/8s Clisp is a free CL that compiles to byte code. HCL is a commercial CL compiling to native code. Erlang is the byte code compiler, no Hipe. I was expecting much worse results for Erlang. Code available at http://space.tin.it/romebern/erlab.zip BTW, is there a better data structure to be used as an array (i.e. a map from fixed length tuples of integers)? P. From jonathan@REDACTED Tue Mar 4 12:35:20 2003 From: jonathan@REDACTED (Jonathan Coupe) Date: Tue, 4 Mar 2003 11:35:20 -0000 Subject: yeah, we're just better then awk! References: <200303040921.h249LjH14882@cbe.ericsson.se> <20030304094107.GV22853@spearce.org> Message-ID: <001601c2e244$f5948500$890bfea9@mimbi> > > > Also, the tests are very small tests that only test > > > simple operations. Nearly all languages have about > > > the same number of lines of code, each test does no > > > useful work, > > > > are we talking about http://www.bagley.org/~doug/shootout ? > > most of the tests there do real work (ex: word count, sorting, > > reversing, adding numbers) on file contents. > > Yes. I guess I consider that although this is real work, in > the grand scheme of what most computing is today, they are > overtly simple. Bagley does call this a ***scripting*** language shootout, where script == a short program that reads in a text file, does something to it, and then exits. Within these terms of reference the benchmarks seem well chosen. And he does note - or maybe I'm thinking of the twin Windows shootout site - that Erlang is designed for a completely different set of tasks, and that his benchmarks don't measure its strengths. > > Its also unfairly biased against apps > > that can startup/shutdown very fast, which both > > Java and Erlang don't do well. Should "can" have been "can't"? - Jonathan Coupe From eleberg@REDACTED Tue Mar 4 12:53:17 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Tue, 4 Mar 2003 12:53:17 +0100 (MET) Subject: yeah, we're just better then awk! Message-ID: <200303041153.h24BrHH19413@cbe.ericsson.se> > Date: Tue, 4 Mar 2003 04:41:07 -0500 > From: Shawn Pearce ...deleted > I definately see your point that these tests do real work > for which quite a few programs exist in product do. (I couldn't > live without wc, sort, etc.) However, my (poorly) made point was > more to the "these programs are all fairly small" when talking > about lines of code to solve a problem, and performance of > language to solve said problem. please read the paper that ''started'' the whole project: http://cm.bell-labs.com/cm/cs/who/bwk/interps/pap.html this will probably explain the assumptions behind the tests. ...deleted > I felt it was unfairly biased against languages > which tend to have higher startup costs, I wouldn't see these used to > solve the kinds of problems the shootout throws at them, for exactly > that reason: they just take too long to startup compared to other > languages, but lines of code wise they are equal. I guess in that > context the language shootout is a big success, as it shows what > many of us feel we inherently "know" about these tools: who would > use Java to count the number of words in a file given the amount > of memory it needs and the time it takes to startup/shutdown > relative to native C? the major benefit of this project is that small (few users) languages get a chance to show that they are faster than c (which nobody will belive. some peopel still refuse to belive it after having read the results). moreover, small langugages can also show how much more readable they are than perl (which is the only well known high level language (again, some people still think java is the only high level language)). ...deleted > Just as we tended away from assembly to C, we'll tend to higher level > languages than C soon enough. Hardware is getting so fast and compilers > are getting so good that its just a matter of a few years before people > do seriously consider writting `wc' in Java. What a sad, sad day that > will be. :) say that, for some reason, java is not the next c (eg, the language that everybody knows about, and that everybody uses since it is the lowest common denominator). this reason just might be that enough people saw this test and noticed that other languages than java are: 1 higher level 2 faster 3 more readable (arguably this follows from 1, but think apl) bengt, who does not expect this to happen From etxuwig@REDACTED Tue Mar 4 14:04:53 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Tue, 4 Mar 2003 14:04:53 +0100 (MET) Subject: How nice should I be on exit? In-Reply-To: <20030304035749.GD389@frogman.motivity.ca> Message-ID: On Mon, 3 Mar 2003, Vance Shipley wrote: >Following the Erlang philosophy we let crashes occur when >there are things going wrong. A process should die when it >is abused, this is normal. It takes some getting used to >though as we tend to want to program defensively. Yes, and yes, and yes. (: >Now I'm asking myself whether I should worry about cleaning >up when a process is going to die normally. In this case I >have set up monitoring of a number of other processes and >stored the references. It's a small pain to go through the >list, pull out the references and run erlang:demonitor/1 on >them. I'm thinking that in all likelyhood it would be more >effecient (oops!) to let the run time system clean up after >me. The same could apply to ets tables, ???, ... Anything that the system cleans up automatically should be left to the system to clean up. As a general rule (in my opinion), you should introduce as little code as possible to react to software errors. For every cleanup or fault containment procedure you add, chances are that you'll compound the error by making further mistakes. You should start with the simplest possible mechanism (let it crash, and rely on the system/infrastructure for cleanup and recovery). Then test your system through fault insertion in order to see what happens as processes are killed. If your simple recovery procedures are not sufficient in practice, put some energy into fine-tuning them where it matters. I've attached a small program that runs through an OTP supervision tree killing processes and checking to see if they bounce back, then proceeding up to the next higher level. Perhaps it might be of some help to you. My two cents. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes -------------- next part -------------- %%% %%% The contents of this file are subject to the Erlang Public License, %%% Version 1.0, (the "License"); you may not use this file except in %%% compliance with the License. You may obtain a copy of the License at %%% http://www.erlang.org/license/EPL1_0.txt %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Original Code is ape_test-1.0 %%% %%% The Initial Developer of the Original Code is Ericsson Telecom %%% AB. Portions created by Ericsson are Copyright (C), 1998, Ericsson %%% Telecom AB. All Rights Reserved. %%% %%% Contributor(s): ______________________________________. %%%---------------------------------------------------------------------- %%% #0. BASIC INFORMATION %%%---------------------------------------------------------------------- %%% File: ape_test.erl %%% Author : Ulf Wiger %%% Description : Fault insertion testing for OTP supervision trees %%% %%% Modules used : application, application_controller, ets, error_logger %%% lists, supervisor %%%---------------------------------------------------------------------- -module(aptest). -date('97-12-13'). -author('ulf.wiger@REDACTED'). -export([start/0, start/2, start/3]). -export([find_pids/0]). -compile(export_all). -import(error_logger, [info_msg/2, error_msg/2]). -define(TAB, apTestProcs). %% ----------------------------------------------------------------------- %% %% start(Interval, Reason, Applications) -> %% %% Interval ::= integer() %% Reason ::= term() %% Applications ::= [atom()] %% %% Starts issuing exit(Pid, Reason) - one every Interval seconds - %% for all registered and supervised processes in Applications. %% The killing starts at the bottom and goes through one level at a %% time across Applications. After finishing one level, it checks %% to see if the processes have been restarted. It then moves on to %% the next higher level. %% %% Progress is reported via error_logger:info_msg/2. %% Unexpected events are reported via error_logger:error_msg/2. %% ----------------------------------------------------------------------- start(Interval, Reason, Apps) -> MaxLevel = find_pids(Apps), kill_pids(MaxLevel, Interval, Reason). %% ----------------------------------------------------------------------- %% start(Interval, Reason) %% %% Same as above, but for all applications. %% ----------------------------------------------------------------------- start(Interval, Reason) -> Apps = [A || {A, _, _} <- application:which_applications()], start(Interval, Reason, Apps). %% ----------------------------------------------------------------------- %% start() %% %% Interval = 30 secs %% Reason = aptest %% Apps = %% ----------------------------------------------------------------------- start() -> start(30000, aptest). %%% --------------------------------------------------------- %%% Internal functions %%% --------------------------------------------------------- %% ----------------------------------------------------------------------- %% find_pids(Apps) -> MaxLevel %% %% finds all registered processes in the supervision tree for Apps %% and stores them in an ets table. %% Returns the maximum depth of the processed supervision tree. %% ----------------------------------------------------------------------- find_pids() -> new_ets(), Apps = [A || {A, _, _} <- application:which_applications()], find_pids(Apps). find_pids(Apps) -> new_ets(), Levels = find_pids1(Apps), lists:max(lists:flatten(Levels)). find_pids1([App|T]) -> case application_controller:get_master(App) of Pid when pid(Pid) -> {Root, _} = application_master:get_child(Pid), [get_procs(supervisor:which_children(Root), App, 1)| find_pids1(T)]; _ -> find_pids1(T) end; find_pids1([]) -> []. get_procs([], _App, _Level) -> []; get_procs(Children, App, Level) -> {Workers, Supers} = check_children(Children), [maybe_register(P, App, Level) || P <- Workers ++ Supers], [Level|[get_procs(supervisor:which_children(SPid), App, Level+1) || {_, SPid} <- Supers, pid(SPid)]]. check_children(Ch) -> check_children(Ch, [], []). check_children([{Name, Pid, worker, _}|Ch], Ws, Ss) -> check_children(Ch, Ws ++ [{Name, Pid}], Ss); check_children([{Name, Pid, supervisor, _}|Ch], Ws, Ss) -> check_children(Ch, Ws, Ss ++ [{Name, Pid}]); check_children([], Ws, Ss) -> {Ws, Ss}. %% ----------------------------------------------------------------------- %% maybe_register({Name, Pid}, AppName, Level) -> true | false %% %% Store process in ets, only if it has a registered name %% The reason is that we can't keep up with anonymous pids anyway, %% since pids will change as the processes restart, %% so it gets too complicated to include them in the killing spree. %% ----------------------------------------------------------------------- maybe_register({Name, Pid}, App, Level) when pid(Pid) -> case process_info(Pid, registered_name) of {registered_name, N} -> ets:insert(?TAB, {N, App, Level}), true; _ -> false end; maybe_register(_, _, _) -> false. kill_pids(Level, Interval, Reason) when Level > 0 -> Ps = ets:match_object(?TAB, {'_','_',Level}), info_msg("Procs to kill at level ~p: ~p.~n", [Level, Ps]), Regs0 = registered(), RegPids0 = [{N, whereis(N)} || N <- Regs0], do_kill_pids(Ps, Interval, Reason), Regs1 = registered(), Lost = Regs0 -- Regs1, SamePids = same_pids(RegPids0), info_msg("Done killing procs at level ~p.~n" " Stayed up: ~p~n" " Restarted: ~p~n" " Disappeared: ~p~n", [Level, [N || {N,A,L} <- Ps, lists:member(N, SamePids)], Regs1 -- SamePids, Lost]), kill_pids(Level-1, Interval, Reason); kill_pids(_, _, _) -> done. do_kill_pids([{Name, App, _Level}|Ps], Interval, Reason) -> case whereis(Name) of undefined -> error_msg("~p no longer registered.~n", [Name]); Pid -> info_msg("Killing ~p (~p, app = ~p), Reason = ~p.~n", [Name, Pid, App, Reason]), exit(Pid, Reason), sleep(Interval) end, do_kill_pids(Ps, Interval, Reason); do_kill_pids([],_, _) -> done. same_pids([{N, P}|T]) -> case whereis(N) of P1 when P1 == P -> [N|same_pids(T)]; _ -> same_pids(T) end; same_pids([]) -> []. new_ets() -> case ets:info(?TAB) of undefined -> ok; _ -> ets:delete(?TAB) end, ets:new(?TAB, [set, public, named_table]). sleep(Time) -> receive after Time -> ok end. From etxuwig@REDACTED Tue Mar 4 14:18:04 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Tue, 4 Mar 2003 14:18:04 +0100 (MET) Subject: Does ets:select/2 block the VM? In-Reply-To: <20030304090945.GU22853@spearce.org> Message-ID: On Tue, 4 Mar 2003, Shawn Pearce wrote: >I may be in a situation of a "system with a lot of >processes fixing tables". Or at least something like that. >It all depends, I have a single operation that requires me >to scan a group of ets tables when a process/connection >starts up, but after that I should rarely, if ever scan the >ets tables again. Problem is, I don't know what my >connection rate is yet. I'm assuming it'll be something >like hundreds of connections in a 15 minute window in the >morning as people sign on to the system when they arrive at >work, and then almost no activity for the rest of the day. If safe_fixtable() scares you, you may want to consider serializing the select/3 and insert/2 operations with a server. This will eliminate the need for fixtable. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From Marc.Vanwoerkom@REDACTED Tue Mar 4 15:19:53 2003 From: Marc.Vanwoerkom@REDACTED (Marc Ernst Eddy van Woerkom) Date: Tue, 4 Mar 2003 15:19:53 +0100 (MET) Subject: Documenting the Language In-Reply-To: <20030304093857.GA1993@frogman.motivity.ca> (message from Vance Shipley on Tue, 4 Mar 2003 04:38:57 -0500) Message-ID: <200303041419.h24EJr325031@bonsai.fernuni-hagen.de> > There really does need to be a document which definetivly > decribes the core langauge. Now I know there is the > "Reference Manual" but it is dated February 9, 1999 and is > "DRAFT (0.7)". It's the Erlang 4.7.3 reference manual and > we're currently on 5.2. That baffled me as well. How is the language defined? (Except as commented source code of the compiler :-) And it looks bad, if both the standard book and the reference doc are outdated. > It's also only available as a > postscript file and I haven't had any luck text searching it. What about searching the raw postscript in vi? Regards, Marc From vances@REDACTED Tue Mar 4 18:44:30 2003 From: vances@REDACTED (Vance Shipley) Date: Tue, 4 Mar 2003 12:44:30 -0500 Subject: Doc error in gen_fsm In-Reply-To: <20030304103551.GW22853@spearce.org> References: <20030304103551.GW22853@spearce.org> Message-ID: <20030304174430.GF389@frogman.motivity.ca> On Tue, Mar 04, 2003 at 05:35:51AM -0500, Shawn Pearce wrote: } R9B-0 gen_fsm manpage for sync_send_all_state_event/2,3: } } The gen_fsm will call Module:handle_event/3 to handle the event. } } I think they meant to say "will call Module:handle_event/4" instead. I think you meant to say Module:handle_sync_event/4 instead. :) -Vance From spearce@REDACTED Tue Mar 4 18:51:59 2003 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 4 Mar 2003 12:51:59 -0500 Subject: Doc error in gen_fsm In-Reply-To: <20030304174430.GF389@frogman.motivity.ca> References: <20030304103551.GW22853@spearce.org> <20030304174430.GF389@frogman.motivity.ca> Message-ID: <20030304175159.GA5320@spearce.org> Vance Shipley wrote: > On Tue, Mar 04, 2003 at 05:35:51AM -0500, Shawn Pearce wrote: > } R9B-0 gen_fsm manpage for sync_send_all_state_event/2,3: > } > } The gen_fsm will call Module:handle_event/3 to handle the event. > } > } I think they meant to say "will call Module:handle_event/4" instead. > > > I think you meant to say Module:handle_sync_event/4 instead. :) *rofl* Yes, I did. Great, my error report had an error. :) Thanks for the correction, much appreciated. -- Shawn. You look like a million dollars. All green and wrinkled. From jonathan@REDACTED Tue Mar 4 20:47:16 2003 From: jonathan@REDACTED (Jonathan Coupe) Date: Tue, 4 Mar 2003 19:47:16 -0000 Subject: yeah, we're just better then awk! References: <20030303141204.26137.qmail@web40803.mail.yahoo.com> <006101c2e23f$03470c00$fcf06850@c1p4e3> Message-ID: <001e01c2e286$dc98ed60$890bfea9@mimbi> ----- Original Message ----- From: Pierpaolo BERNARDI > Hmmm... I have been surprised by Erlang in a test > which probably is as far from its strengths as possible. > > I rewrote in Erlang a Common Lisp program which, > essentially, accesses repeatedly a big 2d array, > and does some manipulations of short lists. > > I obtain these times: > > Clisp: 11/12s > HCL: 1.5/2s > Erlang using gb_trees as arrays: 32/34s > Erlang using an ets table as array: 7/8s > > I was expecting much worse results for Erlang. The benchmarks I have put Clisp at about 1/4-1/8 the speed of ACL, usually considred the fastest CL except possibly for CMUCL. (In the Scheme world Gambit is much faster again at this sort of benchmark.) ACL had at best 1/4 the speed of C for floating point intensive code the last time I checked, assuming you really optimize to death. (The manufacturer's optimization guy couldn't do any better than that.) So that puts Erlang at a ~ 1/10 the speed of C, using the best possible(?) data struture - which is what I though Ericson claimed for its performance in general, until threading overhead becomes significant. Did you try using a guard to specify that the data was floating point, as Bj?rn Gustavsson suggested recently? I tried to get the code from the link you gave (http://space.tin.it/romebern/erlab.zip) but it was broken. - Jonathan Coupe PS Is there a site for HCL? Although I've already decided I prefer Erlang to any sort of Lisp. From daniel.dudley@REDACTED Tue Mar 4 21:22:24 2003 From: daniel.dudley@REDACTED (Daniel Dudley) Date: Tue, 4 Mar 2003 21:22:24 +0100 Subject: yeah, we're just better then awk! References: <20030303141204.26137.qmail@web40803.mail.yahoo.com> <006101c2e23f$03470c00$fcf06850@c1p4e3> Message-ID: <008b01c2e28b$c4fa1350$a3d3b33e@dld2000> "Pierpaolo BERNARDI" wrote: [snipped] > BTW, is there a better data structure to be used as an array > (i.e. a map from fixed length tuples of integers)? One way to emulate arrays is to use a keyed AVL. Tke keys are cell index numbers (0..n), the cell contents any term. Use integer division and the mod operator to compute row and column 0-based indices from a given cell index. The divisor is the number of columns. A chess board, for example, will have 8 rows and 8 columns, both indexed 0...7. The row index of cell 28 is 28 : 8 = 3, the column index 28 mod 8 = 4. Conversely, computing the cell index from given row and column indices would be row * columns + column, for example 3 * 8 + 4 = 28. The advantage of an AVL is its super-fast access times on individual cells. It's relatively easy to extract slices, too (simple computations). HTH, Daniel From bernardp@REDACTED Tue Mar 4 22:24:58 2003 From: bernardp@REDACTED (Pierpaolo BERNARDI) Date: Tue, 4 Mar 2003 22:24:58 +0100 Subject: yeah, we're just better then awk! References: <20030303141204.26137.qmail@web40803.mail.yahoo.com> <006101c2e23f$03470c00$fcf06850@c1p4e3> <001e01c2e286$dc98ed60$890bfea9@mimbi> Message-ID: <002f01c2e294$83594ca0$adf06850@c1p4e3> From: "Jonathan Coupe" > Did you try using a guard to specify that the data was floating point, > as Bj?rn Gustavsson suggested recently? This test does not use floating point. However, I missed BG's suggestion, I'll search the archives. > I tried to get the code from the > link you gave (http://space.tin.it/romebern/erlab.zip) but it was broken. Sorry, my fault. Should have been http://space.virgilio.it/romebern/erlab.zip > PS Is there a site for HCL? I meant Harlequin CL: www.lispworks.com. (OK, I shouldn't use anymore the acronym HCL). P. From thomasl_erlang@REDACTED Tue Mar 4 22:55:52 2003 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Tue, 4 Mar 2003 13:55:52 -0800 (PST) Subject: Strange behaviour with a record in a guard In-Reply-To: <5F03ACA2F76DD411B8BC00508BE3B4D70FD69D27@esemont203.gbg.edt.ericsson.se> Message-ID: <20030304215552.82456.qmail@web13309.mail.yahoo.com> --- ?ke_Johansson_AI_(EAB) wrote: > ... > -record(r1,{f1}) > > foo(R) when R#r1.f1 == undefined -> > ok. > ... > > It seems like foo(R) matches any tuple of size 2 or > bigger, where the second element is undefined. > Should not the compiler add code which checks that R > is a record of the correct type? If it's any consolation, I definitely think it should. The very same bug also means that: -record(a, {f1, f2}). -record(b, {f3, f4}). foo() -> X = #a{f1 = 1, f2 = 2}, X#b.f3. will return 1 rather than failing. I think this is a bug because this behaviour is strange and unexpected, and a point of Erlang philosophy is to avoid that. The right way to do it is to check the record type first. Best, Thomas __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - forms, calculators, tips, more http://taxes.yahoo.com/ From jonathan@REDACTED Tue Mar 4 23:59:58 2003 From: jonathan@REDACTED (Jonathan Coupe) Date: Tue, 4 Mar 2003 22:59:58 -0000 Subject: yeah, we're just better then awk! References: <20030303141204.26137.qmail@web40803.mail.yahoo.com> <006101c2e23f$03470c00$fcf06850@c1p4e3> <001e01c2e286$dc98ed60$890bfea9@mimbi> <002f01c2e294$83594ca0$adf06850@c1p4e3> Message-ID: <002401c2e2a1$fce9fbc0$890bfea9@mimbi> >This test does not use floating point. >However, I missed BG's suggestion, I'll search the archives. Spot the professional graphics programmer: years of matrix manipulation have left me unable to believe that a 2D array can be used for anything else. - Jonathan Coupe From rprice@REDACTED Wed Mar 5 00:14:54 2003 From: rprice@REDACTED (Roger Price) Date: Wed, 5 Mar 2003 00:14:54 +0100 (CET) Subject: Compiling R9B-0 on SuSE Linux Linux 8.1 Message-ID: Hi, has anyone gotten R9B-0 to install on SuSE Linux 8.1 ? Here is what happens when I run configure: olive:/mnt/home/erlang/otp_src_R9B-0 # ./configure checking host system type... i686-pc-linux-gnu ===============lines omitted=============== checking size of short... (cached) 2 checking size of int... (cached) 4 checking size of long... (cached) 4 checking size of void *... (cached) 4 checking size of unsigned long long... (cached) 8 checking size of size_t... (cached) 4 checking size of off_t... (cached) 4 checking int/long/void*/size_t sizes... failed configure: error: Cannot handle this combination of int/long/void*/size_t sizes configure: error: /mnt/home/erlang/otp_src_R9B-0/erts/configure failed for erts This is the version of gcc: olive:/mnt/home/erlang/otp_src_R9B-0 # gcc -v Reading specs from /usr/lib/gcc-lib/i486-suse-linux/3.2/specs Configured with: ../configure --enable-threads=posix --prefix=/usr --with-local-prefix=/usr/local --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib --enable-languages=c,c++,f77,objc,java,ada --enable-libgcj --with-gxx-include-dir=/usr/include/g++ --with-slibdir=/lib --with-system-zlib --enable-shared --enable-__cxa_atexit i486-suse-linux Thread model: posix gcc version 3.2 Roger From luke@REDACTED Wed Mar 5 00:25:14 2003 From: luke@REDACTED (Luke Gorrie) Date: 05 Mar 2003 00:25:14 +0100 Subject: "defensive programming" (Was: Re: How nice should I be on exit?) In-Reply-To: <20030304035749.GD389@frogman.motivity.ca> References: <20030304035749.GD389@frogman.motivity.ca> Message-ID: Vance Shipley writes: > It takes some getting used to though as we tend to want to program > defensively. I'm not sure if this has confused anyone else, but I think there are two definitions of "defensive programming" floating around. For years I'd been a bit confused about the standard "don't program defensively" Erlang advice, but just recently I saw a definition of what that really means. I was doing some remedial programming study with a copy of "Software Tools" by Kernighan and Plauger that I borrowed from an Erlang programmer, and found this text marked in pencil: A point of style: After appending a short string to the buffer, we tested whether 'nsave' was equal to _or greater than_ its maximum safe value. But from reading the code, we _know_ that 'nsave' can never exceed MAXCHUNK or go negative, so why bother? This is what is known as "defensive programming." It costs next to nothing in source text or execution time, yet it reduces the chance of the program going wild should an important control variable somehow be damaged. You can't print out error messages everywhere, but you can and should take out insurance whenever possible. It is much easier to debug a program if the output is not voluminous and if additional storage overwrites do not occur as a side effect of the original bug. The way to ensure saner behaviour is to do the sort of things we did. Write your 'if', 'while', and 'until' tests so they steer crazy situations back in a safe direction. Use the last 'else' of a chain of 'else-if's to catch conditions that should "never" occur, but just might. Never check for equality if it doesn't hurt to check for "greater than or equal to" or for "less than or equal to." In particular, don't let loops repeat when a variable is out of its expected range. Don't make your program a sucker for bugs. So, they're talking about trying to continue somehow after reaching "impossible" states, and I can see that this is against the Erlang philosophy. Taking this definition, the "don't program defensively in Erlang" advice makes perfect sense. The other definition of defensive programming comes, I think, from "Code Complete" by Steve McConnel. In this one, being "defensive" means not blindly trusting your inputs, and instead checking them with assertions so that you detect "impossible" states and fail as soon as possible. This is very much in line with the Erlang philosophy - it's like putting strict guards on your functions so that calling them with bad arguments will cause a crash. Using this definition, "don't program defensively" would mean "don't bother with extra guards and stricter pattern matches", which would be totally against the grain of all the other rules, and does indeed cause confusion :-) Hope that clears things up for someone else who learned the other definition than the Erlang guys :-) Cheers, Luke From kent@REDACTED Wed Mar 5 01:01:50 2003 From: kent@REDACTED (Kent Boortz) Date: 05 Mar 2003 01:01:50 +0100 Subject: Compiling R9B-0 on SuSE Linux Linux 8.1 In-Reply-To: References: Message-ID: Roger Price writes: > Hi, has anyone gotten R9B-0 to install on SuSE Linux 8.1 ? > Here is what happens when I run configure: > > olive:/mnt/home/erlang/otp_src_R9B-0 # ./configure > checking host system type... i686-pc-linux-gnu > ===============lines omitted=============== > checking size of short... (cached) 2 > checking size of int... (cached) 4 > checking size of long... (cached) 4 > checking size of void *... (cached) 4 > checking size of unsigned long long... (cached) 8 > checking size of size_t... (cached) 4 > checking size of off_t... (cached) 4 > checking int/long/void*/size_t sizes... failed > configure: error: Cannot handle this combination of int/long/void*/size_t > sizes You could try to remove the "config.cache" file and rerun configure. If it still doesn't work, could you please send me the output from the program #include int main() { printf("void * = %d\n", sizeof(void *)); printf("size_t = %d\n",sizeof(size_t)); printf("int = %d\n",sizeof(int)); printf("long = %d\n",sizeof(long)); exit(0); } kent From cpressey@REDACTED Wed Mar 5 01:58:24 2003 From: cpressey@REDACTED (Chris Pressey) Date: Tue, 4 Mar 2003 18:58:24 -0600 Subject: More GUI (ravings?) In-Reply-To: <5F03ACA2F76DD411B8BC00508BE3B4D71200F846@esemont203.gbg.edt.ericsson.se> References: <5F03ACA2F76DD411B8BC00508BE3B4D71200F846@esemont203.gbg.edt.ericsson.se> Message-ID: <20030304185824.7fda4cbc.cpressey@catseye.mb.ca> On Mon, 3 Mar 2003 11:32:57 +0100 "Vlad Dumitrescu (EAW)" wrote: > Hi all, > > Since I am working on ex11, I am also trying to see what might come > ahead and try to plan for a possible widget toolkit, implemented in > Erlang. As I said once before, I can't see any way to do it in a > different way that it is done in most other languages, that is OO or the > like. Please if there is anyone that has a link to a GUI framework that > isn't OO (but not too far from Erlang's philosophy either), send it to > me. The structural parts of GUIs tend to be modelled as OO objects, because, well, it fits. But there are other aspects that don't get as much press - GUIs almost universally work in terms of events when it comes to the dynamic aspects, and rules when it comes to layout - but these generally get downplayed, because the structure is more 'obvious' to the visually-inclined end user I guess. > The "missing feature" that would be needed has already been discussed > here in many ways: building a hierarchy of behaviours. Or with another > word, implementing subclassing. A generic window has behaviour that an > input widget will "inherit" and that one can further be refined to > become a "password input" widget. > > The question is how to delegate the "inherited" behaviour to the right > implementation module? > > ---- > One way is to just write lots of funs similar to > set_visible(Widget) -> > widget:set_visible(Widget). > But this seems very heavy on the typing fingers and not extendible. > Maybe some macros could help, but it would look like a C++ framework > from > > Another way is to use for example an attribute > -inherits([widget]). > and then either: > * change error_handler:undefined_function to check any modules named > in 'inherits' for the respective function before reporting an undef > error While this would work great, for better or worse, it's not very Erlang-y. I think the Erlang-y solution would be loop(Parent, State) -> receive ... AnyMessageIDontUnderstand -> Parent ! AnyMessageIDontUnderstand, loop(Parent, State); end. But honestly, I like trapping undefined_function better - this pass-the-message-through-back-to-the-parent-process way will result in a *lot* of processes, and even though that's OK here, it still feels wrong - because the processes seem *superfluous*. One process per real-world activity - the textbox underlying a passwordbox isn't *really* a discrete real-world activity, is it? It doesn't seem to have an existence independent of the passwordbox, to me. -Chris From cpressey@REDACTED Wed Mar 5 07:12:07 2003 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 5 Mar 2003 00:12:07 -0600 Subject: Erlang questions on comp.lang.functional. In-Reply-To: <200303030159.h231x5F13072@bonsai.fernuni-hagen.de> References: <20030302234015.GH22853@spearce.org> <200303030159.h231x5F13072@bonsai.fernuni-hagen.de> Message-ID: <20030305001207.3b54213c.cpressey@catseye.mb.ca> On Mon, 3 Mar 2003 02:59:05 +0100 (MET) Marc Ernst Eddy van Woerkom wrote: > > I think the reality is it is impossible to build a programming > > language that doesn't have side effects. > > It starts with I/O, which is done as side effect in Prolog. :) > > I wonder how I/O is considered by strict functional programmers, > a function like > > int f() = return len(readkbdstring) > > isn't supposed to always return the same value, or? > Worse, it is not even predictable. > > Now go from I/O to networked I/O. My (fuzzy) understanding is that referentially transparent I/O requires lazy evaluation - thus confirming the wisdom (which we, deep in our hearts, know *unshakably* to be true) that no language except Haskell can *really* be called functional. After all: - there is NO way to analyze code that isn't referentially transparent! (Church showed how Turing's model is inherently flawed!) - proving code is something you should always do AFTER it's written! (Never during! What a waste of time THAT would be!) - proving code is a ROCK SOLID GUARANTEE that the proof is correct, too! (There's a Knuth quote that'll back me up on this!) My, but I'm snarky tonight. Must have been that hot salsa on an empty stomach. Anyway. My feeling is that referentially transparent I/O (or referentially transparent *everything*, if you like) is a) very beautiful; and b) completely unnatural. But it's no secret that I'm biased; Haskell seems to me like its sole purpose is to make mathematicians salivate. Again, I have to say, my understanding is fuzzy, probably because anyone who tries to explain Haskell to me immediately goes into "mathematician's-dream mode", but I for one can't see why one would choose one language feature which makes sharing explicit (single assignment) then go and choose another that hides sharing (monads.) Aren't we right back where we started? And don't get me started about Haskell's readablity or I'll start drawing unflattering (but, AFAICT, completely accurate) parallels between it and Unlambda... As to the original post which started this thread: old superstitions die hard. The poster was looking for a systems-construction language (strong typing + native compilation + thorough optimization, presumably) that also supports hot-swapping code. All I can say to that is - good luck! OK, enough vitriol - back to your regularly scheduled erlang-questions list... -Chris From Vlad.Dumitrescu@REDACTED Wed Mar 5 09:15:16 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Wed, 5 Mar 2003 09:15:16 +0100 Subject: FW: UI thoughts Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D407@esemont203.gbg.edt.ericsson.se> Hi, I will take the liberty to resend to the list the mail that Jay sent me, because I think it will be an interesting reading. I hope it's okay with you, Jay. best regards, Vlad -----Original Message----- From: Jay Nelson [mailto:jay@REDACTED] At 04:31 PM 3/4/03 +0100, you wrote: >yes, you are right and it's a good way to build an application. But this >will be the next level, right now I am wondering about how to build the >graphical engine and all controls/widgets in a good way. You will continue to have conceptual problems if you start by building a toolkit of UI "objects". As soon as you use the word widget you have already set your mind in the wrong direction. >There has to be some kind of framework that will provide building bricks >for the UI. Then of course, a framework for writing applications will be >needed too, bu I haven't been thinking that far yet. I wouldn't agree with that. What you need is a behavioral description of the interaction first. Just as client / gen_server specifies the protocol completely independent of the content. Then you add a rendering capability for displaying things. For example, don't think of a window, think of interaction styles: 1) A rectangular area that is resizeable 2) Rectangular hotspots like stamps that can be pasted on top of a rectangular area 3) Hotspots can render chars or change appearance when a mouse passes over These are all behaviors. No one has defined a window or a hierarchy. If you want a window, create WindowManagerSupervisor (WMS) and pass it an ordered list of items: [ [resize_area, {width, 300}, {height 400}] {relative, {name, minimize}, {x, +270}, {y, +3}, [hotspot, {click, {send, minimize}}]} {relative, {name, maximize}, {x, +280}, {y, +3}, [hotspot, {click, {send, maximize}]} {relative, {name, close}, {x, +290}, {y, +3}, [hotspot, {mouseover, blue.gif}, {mouseoff, red.gif}, {click, {send, kill}]} ] Each of what you call "widgets" can be hotspots. A hotspot is a process that works like gen_fsm. Mouse click, mouse move, etc can all cause an event that means a state change when the message is received. The WMS binds the areas together and specifies the drawing order so that you get a flattened view that looks like a window, but it is really a dynamic collection of behaviors that could fly apart or transfer themselves to other processes (think of docking toolbars) or react in concert with another process (think slider bars). Modelling this way allows the user to choose the elements of a "window" that he would like to keep, instead of hard coding them into an inflexible object construct that simulates flexibility by varying its internal state member variables. As soon as you call something a widget, or think in terms of a window and a menu object, you have already pre-disposed yourself to non-erlang thinking. Think in terms of behaviors only, and implement them with collections of processes. What does the user want to do? Nothing on the screen, he actually wants to enter, remove or modify data. The screen is a crutch to see what is happening, audio would work just as well, but with a GUI you are pasting on non-Graphical things as a way of being compliant with accessibility standards rather than presenting the data in the most natural way for interaction. What does the data want to do? These are very independent from: How should the data be displayed? or What controls allow interaction? Chris said a textbox cannot live independent of a password box, but classification systems are slippery slopes. As soon as you choose one item to classify on (think Euclidean geometry) you have eliminated a whole realm of possibilities that are not only improbable, but impossible once you start (a great arc is a shorter distance than a straight line -- on a globe). Both a text box and a password box are visual displays of an internal text string. In one case the user needs feedback as he types, but no display; in the other he wants both feedback and display. The processes that accept keystrokes, filter for validity, and store to the internal text string are separate because they may be recombined to create other chains of events. The fact that the two screen representations are similar is of no consequence other than predictability on the part of the user. What is important is the task and the feedback. A password box could just be a single block that changes color with each keypress and uses three different beeps -- one for characters and two for accept or reject. > One process per real-world activity - the textbox underlying > a passwordbox isn't *really*a discrete real-world activity This is the atomic argument (as in physics) versus the quark argument. Do you model physical real-world things, or the elements that combine to create different kinds of reality? Either is valid, they are just different views but they lead to drastically different explanations of the seemingly same external behavior. jay From etxuwig@REDACTED Wed Mar 5 11:32:08 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Wed, 5 Mar 2003 11:32:08 +0100 (MET) Subject: FW: UI thoughts In-Reply-To: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D407@esemont203.gbg.edt.ericsson.se> Message-ID: On Wed, 5 Mar 2003, Vlad Dumitrescu (EAW) wrote: >Hi, > >I will take the liberty to resend to the list the mail that >Jay sent me, because I think it will be an interesting >reading. I hope it's okay with you, Jay. Wow! Of course, one would want to allow non-rectangular areas as well, but -- very interesting stuff! (-: /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From daniel.dudley@REDACTED Wed Mar 5 11:44:03 2003 From: daniel.dudley@REDACTED (Daniel Dudley) Date: Wed, 5 Mar 2003 11:44:03 +0100 Subject: UI thoughts References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D407@esemont203.gbg.edt.ericsson.se> Message-ID: <002101c2e304$23c8ed20$a3d3b33e@dld2000> Yes, this is interesting reading -- and well-written, too. It underlines the required way of thinking when modelling FSMs, which you will also find in the Libero documentation (confer the "Visualization tools for Erlang/OTP programs?" thread--early January 2003--in this mailing list). And yes, FWIW, I do think this is the way to go in Erlang. BTW, it is not good etiquette to write private mail on subjects originating in the mailing list; the contents may well be of interest to other subscribers -- something one should/must respect if the the mailing list is to have any meaning (without which there would be no subscribers). :( OTOH, it is bad form to repost private mail without first asking permission from the author. :( Daniel "Vlad Dumitrescu (EAW)" wrote > > Hi, > > I will take the liberty to resend to the list the mail that Jay > sent me, because I think it will be an interesting reading. I > hope it's okay with you, Jay. > > best regards, > Vlad > > -----Original Message----- > From: Jay Nelson > > At 04:31 PM 3/4/03 +0100, you wrote: > >yes, you are right and it's a good way to build an application. > >But this will be the next level, right now I am wondering about > >how to build the graphical engine and all controls/widgets in a > >good way. > > You will continue to have conceptual problems if you start > by building a toolkit of UI "objects". As soon as you use the > word widget you have already set your mind in the wrong > direction. > > > >There has to be some kind of framework that will provide > >building bricks for the UI. Then of course, a framework for > >writing applications will be needed too, bu I haven't been > >thinking that far yet. > > I wouldn't agree with that. What you need is a behavioral > description of the interaction first. Just as client / > gen_server specifies the protocol completely independent of > the content. Then you add a rendering capability for > displaying things. > > For example, don't think of a window, think of interaction > styles: > > 1) A rectangular area that is resizeable > 2) Rectangular hotspots like stamps that can be pasted on top > of a rectangular area > 3) Hotspots can render chars or change appearance when a > mouse passes over > > These are all behaviors. No one has defined a window or a > hierarchy. If you want a window, create WindowManagerSupervisor > (WMS) and pass it an ordered list of items: > > [ [resize_area, {width, 300}, {height 400}] > {relative, {name, minimize}, {x, +270}, {y, +3}, [hotspot, > {click, > {send, minimize}}]} > {relative, {name, maximize}, {x, +280}, {y, +3}, [hotspot, > {click, > {send, maximize}]} > {relative, {name, close}, {x, +290}, {y, +3}, [hotspot, > {mouseover, > blue.gif}, {mouseoff, red.gif}, {click, {send, kill}]} > ] > > Each of what you call "widgets" can be hotspots. A hotspot is > a process that works like gen_fsm. Mouse click, mouse move, etc > can all cause an event that means a state change when the > message is received. The WMS binds the areas together and > specifies the drawing order so that you get a flattened view > that looks like a window, but it is really a dynamic collection > of behaviors that could fly apart or transfer themselves to > other processes (think of docking toolbars) or react in concert > with another process (think slider bars). Modelling this way > allows the user to choose the elements of a "window" that he > would like to keep, instead of hard coding them into an > inflexible object construct that simulates flexibility by > varying its internal state member variables. > > As soon as you call something a widget, or think in terms of a > window and a menu object, you have already pre-disposed > yourself to non-erlang thinking. Think in terms of behaviors > only, and implement them with collections of processes. > What does the user want to do? Nothing on the screen, he > actually wants to enter, remove or modify data. The screen > is a crutch to see what is happening, audio would work just as > well, but with a GUI you are pasting on non-Graphical things as > a way of being compliant with accessibility standards rather > than presenting the data in the most natural way for > interaction. What does the data want to do? These are very > independent from: How should the data be displayed? or What > controls allow interaction? > > Chris said a textbox cannot live independent of a password box, > but classification systems are slippery slopes. As soon as you > choose one item to classify on (think Euclidean geometry) you > have eliminated a whole realm of possibilities that are not > only improbable, but impossible once you start (a great arc is > a shorter distance than a straight line -- on a globe). > > Both a text box and a password box are visual displays of > an internal text string. In one case the user needs feedback > as he types, but no display; in the other he wants both > feedback and display. The processes that accept keystrokes, > filter for validity, and store to the internal text string are > separate because they may be recombined to create other chains > of events. The fact that the two screen representations are > similar is of no consequence other than predictability on the > part of the user. What is important is the task and the > feedback. A password box could just be a single block that > changes color with each keypress and uses three different beeps > -- one for characters and two for accept or reject. > > > One process per real-world activity - the textbox underlying > > a passwordbox isn't *really*a discrete real-world activity > > This is the atomic argument (as in physics) versus the quark > argument. Do you model physical real-world things, or the > elements that combine to create different kinds of reality? > Either is valid, they are just different views but they lead to > drastically different explanations of the seemingly same > external behavior. > > jay From bjorn@REDACTED Wed Mar 5 11:46:29 2003 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 05 Mar 2003 11:46:29 +0100 Subject: FW: UI thoughts In-Reply-To: Ulf Wiger's message of "Wed, 5 Mar 2003 11:32:08 +0100 (MET)" References: Message-ID: Ulf Wiger writes: > On Wed, 5 Mar 2003, Vlad Dumitrescu (EAW) wrote: > > >Hi, > > > >I will take the liberty to resend to the list the mail that > >Jay sent me, because I think it will be an interesting > >reading. I hope it's okay with you, Jay. > > Wow! Of course, one would want to allow non-rectangular > areas as well, but -- very interesting stuff! (-: I think handling only rectangular areas is a reasonable assumption for a GUI. If necessary, one could use an alpha channel to simulate round windows. /Bjorn -- Bj?rn Gustavsson Ericsson Utvecklings AB bjorn@REDACTED ?T2/UAB/F/P BOX 1505 +46 8 727 56 87 125 25 ?lvsj? From etxuwig@REDACTED Wed Mar 5 11:49:18 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Wed, 5 Mar 2003 11:49:18 +0100 (MET) Subject: FW: UI thoughts In-Reply-To: Message-ID: On 5 Mar 2003, Bjorn Gustavsson wrote: >Ulf Wiger writes: > >> On Wed, 5 Mar 2003, Vlad Dumitrescu (EAW) wrote: >> >> >Hi, >> > >> >I will take the liberty to resend to the list the mail that >> >Jay sent me, because I think it will be an interesting >> >reading. I hope it's okay with you, Jay. >> >> Wow! Of course, one would want to allow non-rectangular >> areas as well, but -- very interesting stuff! (-: > >I think handling only rectangular areas is a reasonable assumption >for a GUI. If necessary, one could use an alpha channel to simulate >round windows. True. Why make it more complicated than it has to be. /U -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From Vlad.Dumitrescu@REDACTED Wed Mar 5 11:48:04 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Wed, 5 Mar 2003 11:48:04 +0100 Subject: UI thoughts Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D40A@esemont203.gbg.edt.ericsson.se> > BTW, it is not good etiquette to write private mail on > subjects originating in the mailing list; the contents may > well be of interest to other subscribers -- something one > should/must respect if the the mailing list is to have any > meaning (without which there would be no subscribers). :( > OTOH, it is bad form to repost private mail without first > asking permission from the author. :( Yes, I know, but I think it is just a case of pressing "Reply" instead of "Reply to All". There isn't anything personal in the mail either. Jay, if you felt offended in any way by my action, I apologize and will buy you a beer! :-) I think I read somewhere that one can do it online. regards, Vlad From joe@REDACTED Wed Mar 5 12:25:08 2003 From: joe@REDACTED (Joe Armstrong) Date: Wed, 5 Mar 2003 12:25:08 +0100 (CET) Subject: "defensive programming" (Was: Re: How nice should I be on exit?) In-Reply-To: Message-ID: On 5 Mar 2003, Luke Gorrie wrote: ... cut ... > Hope that clears things up for someone else who learned the other > definition than the Erlang guys :-) Yes :-) I have two "thumb rules" Check inputs where they are "untrusted" - at a human interface - a foreign language program Or when you want a better error diagnostic that the default one - in this case just exit with the better diagnostic. For example if I'm parsing an integer I'd write I = list_to_integer(L) or case (catch list_to_integer(L)) of {'EXIT', _} -> exit(["Most honored user I regrettably have to inform you that your input on line", Ln, "was not an integer in fact it was ",L, "which IMHO is wrong have a nice day Mr. C. Computer"]); I -> I end. The latter is "an industrial quality" error message :-) Note (important) the semantics of both are to raise an exception in the event of an error. Aside: I once saw code like this: x(a) -> 1; x(b) -> 2; x(X) -> %% what do I do now io:format("expecting a or b"). The programmer had actually added a comment (What do I do now) - of course they had done the wrong thing. The program: x(a) -> 1; x(b) -> 2. Is correct. Evaluating x(c) generates an exception as required. In their modified program x(c) evaluates to the atom 'ok' (i.e. the return value of io:format) - which is incorrect. If they had wanted a better diagnostic they should have written: x(a) -> 1; x(b) -> 2; x(X) -> exit({x,expects,argument,'a or b'}). If you do *nothing* to your code you get a good diagnostic anyway: If x in in the module m and you call this in the shell you'd get: (catch m:x(c)). {'EXIT',{function_clause,[{m,x,[c]}, {erl_eval,expr,3}, {erl_eval,exprs,4}, {shell,eval_loop,2}]}} function_clause means you couldn't match a function head. [{m,x,[c]}, ... means you were calling function x with argument c So in this case NOT programming the error case results in 1) shorted code 2) clearer code 3) no chance of accidentally violating the spec by introducing ad hock "out of spec" code to correct the error 4) perfectly acceptable error diagnostic IMHO 3) is a big gain - specifications always say what to do if everything works - but never what to do if the input conditions are not met - the usual answer is something sensible - but what you're the programmer - In C etc. you have to write *something* if you detect an error - in Erlang it's easy - don't even bother to write code that checks for errors - "just let it crash". Then write a *independent* process that observes the crashes (a linked process) - the independent process should try to correct the error, if it can't correct the error it should crash (same principle) - each monitor should try a simpler error recovery strategy - until finally the error is fixed (this is the principle behind the error recovery tree behaviour). Why was error handling designed like this? Easy - to make fault-tolerant systems you need TWO processors. You can never ever make a fault tolerant system using just one processor - because if that processor crashes you are scomblonked. One physical processor does the job - another separated physical processor watches the first processor fixes errors if the first processor crashes - this is the simplest possible was of making a fault-tolerant system. This principle is mirrored exactly in the Erlang process structure - this is because we want to have "location transparency" of processes - in other words at a certain level of abstraction we do not wish to know which physical processor an individual Erlang process runs on. This is the fundamental reason why we use "remote error recovery" (i.e. handling the error in a different process, to the process in which the error occurred) - it turns out that this has beneficial implications for the design of a system; mainly because there is a clean separation between doing a job, observing if the job was done and fixing an error if an error has occurred. This organization corresponds nicely to a idealized human organization of bosses and workers - bosses say what is to be done, workers do stuff. Bosses do quality control and check that things get done, if not they fire people re-organize and tell other people to do the stuff. If they fail (the bosses) they get sacked etc. <> /Joe From Vlad.Dumitrescu@REDACTED Wed Mar 5 13:07:17 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Wed, 5 Mar 2003 13:07:17 +0100 Subject: "defensive programming" (Was: Re: How nice should I be on exi t?) Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D40D@esemont203.gbg.edt.ericsson.se> Hi, About Joe's comments: I think this is the kind of explanations that should be found in more visible places in the documentation. Or at least in the FAQ. Searching through the archives for such pearls is rather tedious and I think they are very important for learning to "think Erlang". regards, Vlad From olgeni@REDACTED Wed Mar 5 13:20:20 2003 From: olgeni@REDACTED (Jimmy Olgeni) Date: Wed, 5 Mar 2003 13:20:20 +0100 (CET) Subject: xmerl-0.18 available as freebsd port Message-ID: <20030305131932.V57136@dev1.localdomain.net> Just FYI. Have fun :) -- jimmy From Marc.Vanwoerkom@REDACTED Wed Mar 5 14:02:48 2003 From: Marc.Vanwoerkom@REDACTED (Marc Ernst Eddy van Woerkom) Date: Wed, 5 Mar 2003 14:02:48 +0100 (MET) Subject: "defensive programming" (Was: Re: How nice should I be on exit?) In-Reply-To: (message from Joe Armstrong on Wed, 5 Mar 2003 12:25:08 +0100 (CET)) Message-ID: <200303051302.h25D2m420883@bonsai.fernuni-hagen.de> > (interesting stuff) > Easy - to make fault-tolerant systems you need TWO processors. You > can never ever make a fault tolerant system using just one processor - > because if that processor crashes you are scomblonked. To scomblonk has a Google score of zero.. ist that Bork? :) Regards, Marc From kent@REDACTED Wed Mar 5 16:31:01 2003 From: kent@REDACTED (Kent Boortz) Date: 05 Mar 2003 16:31:01 +0100 Subject: The update R9B-1 is released Message-ID: Bug fix release : otp_src_R9B-1 Build from snapshot : 2003-03-05 This is a bug fix release R9B-1. You can download the full source distribution from http://www.erlang.org/download/otp_src_R9B-1.tar.gz http://www.erlang.org/download/otp_src_R9B-1.readme (this file) If you have access to the Ericsson intranet you can find the same files at http://erlang.ericsson.se/opensource/download/ Note that to unpack the TAR archive you need a GNU TAR compatible program. For example on MacOS X you need to use the 'gnutar' command, you can't use the 'tar' command or StuffIt to unpack the sources. For installation instructions please read the README that is part of the distribution. There is no support for building a Windows version from source. The Windows binary distribution can be downloaded from http://www.erlang.org/download/otp_win32_R9B-1.exe The documentation at http://www.erlang.org will be updated. You can also download the complete HTML documentation or the Unix manual files http://www.erlang.org/download/otp_html_R9B-1.tar.gz http://www.erlang.org/download/otp_man_R9B-1.tar.gz For some OTP applications there are more detailed release notes in the HTML documentation. We also want to thank those that sent us patches, suggestions and bug reports, The OTP Team -- erts ------------------------------------------------------------------- OTP-4555 A seq_trace token on an unread message in a process that did a garbage collect that caused the heap to be reallocated to a new address, caused the garbage collector to read freed memory, which caused a segmentation fault. This bug is now corrected OTP-4563 The emulator sometimes mixed up port identities when many ports had been closed, so an old (dead) port identity could be used, but accessed another (new) port. OTP-4571 The possibility to allocate binaries with sl_alloc has been added. The command line switch "+Sb true" enables this feature. See the sl_alloc man page for more information. OTP-4578 The maximum number of ports can now be changed to an arbitrary value using the environment variable ERL_MAX_PORTS on windows, corresponding to the behaviour on other operating systems. The maximum number of simultaneously open i.e. sockets or port programs is now only limited by operating system imposed limits. OTP-4603 An unneccessary garbage collection at process exit for processes with heap fragments is removed. OTP-4612 The script 'start' now spawns off an run_erl that's completely disconnected from the controlling terminal and that ignores sighup (run_erl -daemon) OTP-4625 Some internal memory allocation routines (used in BIFs) would allocate more memory than necessary, especially if the default mininum heap size had been raised. Corrected. OTP-4626 A mixup of read buffers in the inet driver could cause unpredictable results when communicating over TCP and for distributed erlang. -------- An bug in the parsing of GET request on the form semi broken HTTP 0.9 requests was corrected. -------- Missing driver symbols is now exported for Windows DLL Erlang drivers. -- compiler --------------------------------------------------------------- OTP-4557 Three compiler problems fixed: 1) Constant expression were not evaluated at compile time as they should be (unless inlining was turned on). 2) In unusual cases, incorrect code would be generated for "," or "and" in guards. 3) A floating point expressions that failed (e.g. with overflow) and whose value was not used would cause the next floating point expression to fail on some Pentium platforms (Linux, possibly FreeBSD; not on Windows). -- kernel & stdlib -------------------------------------------------------- OTP-4516 A bug in sofs:partition/2 has been fixed. OTP-4519 c:memory() only reported half of the amount of ets memory allocated on 64-bit architectures. This bug has now been fixed. OTP-4530 The disk_log module has been slightly changed for the purpose of reducing the risk of memory problems due to corrupt files. The chunk commands have been optimized by increasing the chunk size from 8 kilobytes to 64 kilobytes. OTP-4554 New function dets:is_compatible_bchunk_format/2 to be used in conjunction with the new info tag bchunk_format. OTP-4568 If a naughty child process did unlink(Supervisor), and then the supervisor decides to terminate that child, it would hang forever. The supervisor now uses erlang:monitor instead of waiting for exit-signals, so that naughty child processes can not make a supervisor hang. OTP-4585 Fixes bug introduced in patch erl_458 that might have damaging effects on the supervisor causing unwanted behavior in the node. OTP-4600 The names of temporary files created by the module file_sorter are now more unique than they used to be. OTP-4609 A bug in Dets that could cause a loop has been fixed. OTP-4641 A file descriptor leak was removed in the error logger. -- odbc ------------------------------------------------------------------- OTP-4593 API function commit/3 is now exported. OTP-4605 Improved error messages so that the implementation not shall shine through. Added possibility to let a connection return rows as tuples instead of lists. OTP-4606 If an ODBC API function times out it will cause the client to exit with reason timeout. If this exit was caught and the client continued using the connection, the next request could get the answer meant for the previously timed out request, this is no longer the case. OTP-4624 Scrollable cursors are nice but causes some overhead. For some connections speed might be more important than flexible data access and then you can disable scrollable cursor for a connection, limiting the API but gaining speed. OTP-4636 Some error messages originating from the sql-driver where corrupted so that odbc only returned the end of the error message. This has now been fixed. OTP-4639 The erlang odbc process will now die normally if a connection can not be established. No connection no process it is expected. And as the client has already received the error message that would be the reason with which the erlang process would be stopped, the supervisor report will be superfluous. Naturally you may still get supervisor reports if the erlang process is stopped for any other reason than the above. -- os_mon ----------------------------------------------------------------- OTP-4223 A configurable "helper timeout" has been added to memsup. It defines how long timeout time, in seconds, the memsup process should use when communicating with the memsup_helper process (an application internal server). The default is 30 seconds. The "helper timeout" can be set with the memsup_helper_timeout configuration parameter, or the memsup:set_helper_timeout/1 function. memsup:get_helper_timeout/0 can be used to retrieve the currently used "helper timeout". OTP-4515 A bug which could cause memsup to be erroneously initialized has been fixed. The erroneous initialization could in turn cause the system_memory_high_watermark alarm to be set too early. -- orber ------------------------------------------------------------------ OTP-4577 If a call-back module illegally caused an EXIT, clients residing on another ORB was not notified (hanged). OTP-4576 The stub/skeleton-files generated by IC have been improved, i.e., depending on the IDL-files, reduced the size of the erl- and beam-files and decreased dependencies off Orber's Interface Repository. It is necessary to re-compile all IDL-files and use COS-applications, including Orber, compiled with IC-4.2. OTP-4541 It is now possible to configure Orber to use the host name in exported IOR:s instead of the IP-number. OTP-4542 When Orber acted as server-side ORB and one tried to setup a SSL-connection and using native Interceptors at the same time it failed. OTP-4543 Oneway operations, using a multi-node Orber, failed for inter-node communication. -- mnesia ----------------------------------------------------------------- OTP-4564 Nested transactions could be aborted with {aborted,{node_not_running,Node}}. OTP-4524 Mnesia could not load dets files of old format over the network. OTP-4565 mnesia:change_table_copy_type/3 failed to copy data when changing storage type from disc_only_copies to ram_copies. OTP-4596 Calls to mnesia:transaction() which makes a badarg, e.g. calls to mnesia:select/2 with a bad match spec as argument, loops forever. OTP-4597 Mnesia could be deadlocked during start of several nodes. OTP-4599 Mnesia used table names as the name on opened disk_log files, which could cause strange behavoiurs if the name interfered with other opened disk_log files. OTP-4610 Mnesia-4.1.2 couldn't load tables from mnesia-3.10.* nodes. -- megaco ----------------------------------------------------------------- -------- Added support for the Megaco mib. OTP-4566 Result of catch gen_udp:open not properly handled. OTP-4632 Service change reason text encoding now always quoted string. -- inets ------------------------------------------------------------------ OTP-4549 FTP client now supports chunked receive. Proposal of Luke Gorrie provided inspiration but not algorithm. OTP-4552 HTTP client updated to jnets-0.1, now supporting proxy. Author: Johan Blom of Mobile Arts AB. OTP-4548, OTP-4207 Body length calculation incorrect. OTP-4550 HTTP-request with a BODY length longer than 0 does not work. OTP-4551 Calculation of remaining chunk size incorrect. OTP-4556 Wrong module name used when attempting to stop the security server (mod_sec_server instead of mod_security_server). OTP-4588 HTTP client now updated to jnets-0.1. OTP-4628 HTTP client called undefined function in HTTP server (httpd_response:send_status/3). -- asn1 ------------------------------------------------------------------- OTP-4559 It was an internal failure when permitted alphabet constraint existed together with for instance a size constraint. E.g. when a referenced type is constrained by a size constraint and the defined type in turn is constrained by a permitted alphabet constraint. OTP-4560 Record is generated in hrl file for a CHOICE with extension mark that has an internal SEQUENCE/SET definition. OTP-4590 Now is the length of a SEQUENCE/SET OF correctly encoded/decoded (PER). OTP-4591 The problem with unordered decoded terms when a component is a ObjectClassFieldType has been solved. OTP-4592 To gain performance in decode the runtime module now makes use of a driver to do the tlv decode. OTP-4631 More complex definitions with TableConstraints where the SimpleTable and ComponentRelation are on different levels is now fully supported. OTP-4633 Now is the Default value for an ENUMERATED returned as the name from the NamedList when decoding. -- ic --------------------------------------------------------------------- OTP-4521 Operation names were always scoped in C server backend, irrespective of the setting of the option scoped_op_calls. OTP-4532 IDL-files containing 'result' or 'Result' as, for example, parameter name, caused an exit with reason bad_match. OTP-4537 Uninitialized variables were used in ic_init_ref for C backends. OTP-4538 CORBA_Environment_alloc() left some fields uninitialized in the returned pointer to an CORBA_Environment for C backends. OTP-4539 The function ic_compare_refs() for C backends could find two unequal references to be equal. OTP-4576 The CORBA stub/skeleton-files generated by IC have been improved, i.e., depending on the IDL-files, reduced the size of the erl- and beam-files and decreased dependencies off Orber's Interface Repository. It is necessary to re-compile all IDL-files and use COS-applications, including Orber, compiled with IC-4.2. -- crypto ----------------------------------------------------------------- -------- 'des_ede3_cbc_encrypt' was added -- tools ------------------------------------------------------------------ OTP-4572 The make option 'par' is removed Emakefiles can now contain compiler options -- observer --------------------------------------------------------------- OTP-4527 Missing priv dir in observer application -- gs --------------------------------------------------------------------- OTP-4522 The communication between Erlang and the external Tcl/Tk process was improved. Compatibility problems with the Microsoft Windows version of Tcl/Tk 8 and menu handling was solved. The grid handing code was corrected to avoid intermittent crashes. gs:info() was changed not to crash when called with the wrong argument. -- misc ------------------------------------------------------------------- -------- Support for cursor keys in X/MacOS X was added. -- EOF -- From daniel.dudley@REDACTED Wed Mar 5 18:56:45 2003 From: daniel.dudley@REDACTED (Daniel Dudley) Date: Wed, 5 Mar 2003 18:56:45 +0100 Subject: The update R9B-1 is released References: Message-ID: <006b01c2e340$969f9c90$a3d3b33e@dld2000> "Kent Boortz" wrote: > > There is no support for building a Windows version from source. Ok, so we're on our own after we've installed it. But is there a cvs "build" tree available for Windows? Or is it part of http://www.erlang.org/download/otp_src_R9B-1.tar.gz (the full source distribution)? Regards, Daniel From erlang@REDACTED Wed Mar 5 15:30:17 2003 From: erlang@REDACTED (Inswitch Solutions - Erlang Evaluation) Date: Wed, 5 Mar 2003 15:30:17 +0100 Subject: Binaries - pattern matching Message-ID: <001a01c2e323$bf83ed90$1e00a8c0@design> I have executed the following commands in the Erlang shell: 1) L = [1,2,3,4,5,6,7,8,9,10,11,12,13]. 2) LB = list_to_binary(L). 3) <> = LB. 4) A. 5) 4759477275222530853130 Please, does anyone know what type is 'A' variable ? 'A' variable contains 10 bytes, how can I retrieve each byte from it? Thanks, Eduardo Figoli INSwitch Solutions. -------------- next part -------------- An HTML attachment was scrubbed... URL: From kent@REDACTED Wed Mar 5 19:55:45 2003 From: kent@REDACTED (Kent Boortz) Date: 05 Mar 2003 19:55:45 +0100 Subject: The update R9B-1 is released In-Reply-To: <006b01c2e340$969f9c90$a3d3b33e@dld2000> References: <006b01c2e340$969f9c90$a3d3b33e@dld2000> Message-ID: "Daniel Dudley" writes: > "Kent Boortz" wrote: > > > > There is no support for building a Windows version from source. > > Ok, so we're on our own after we've installed it. But is > there a cvs "build" tree available for Windows? Or is it > part of > http://www.erlang.org/download/otp_src_R9B-1.tar.gz > (the full source distribution)? It is all there I think but it is targeted our build environment. We will "soon" release a native Windows build that use Cygwin. I don't quite understand what you mean by "so we're on our own after we've installed it". You can compile the Erlang source as well as write and load dynamic drivers (dll). What you can't do (easily) is rebuild the Erlang emulator (virtual machine), kent From cpressey@REDACTED Wed Mar 5 20:10:44 2003 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 5 Mar 2003 13:10:44 -0600 Subject: FW: UI thoughts In-Reply-To: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D407@esemont203.gbg.edt.ericsson.se> References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D407@esemont203.gbg.edt.ericsson.se> Message-ID: <20030305131044.132beba2.cpressey@catseye.mb.ca> On Wed, 5 Mar 2003 09:15:16 +0100 "Vlad Dumitrescu (EAW)" wrote: > Hi, > > I will take the liberty to resend to the list the mail that Jay sent me, > because I think it will be an interesting reading. I hope it's okay with > you, Jay. > > best regards, > Vlad > > -----Original Message----- > From: Jay Nelson [mailto:jay@REDACTED] > [...] Hmmm... this is very interesting, but I don't want to be misunderstood (well not in a bad way anyway...) > Chris said a textbox cannot live independent of a password box, > but classification systems are slippery slopes. As soon as you > choose one item to classify on (think Euclidean geometry) you > have eliminated a whole realm of possibilities that are not only > improbable, but impossible once you start (a great arc is a shorter > distance than a straight line -- on a globe). > > Both a text box and a password box are visual displays of > an internal text string. In one case the user needs feedback > as he types, but no display; in the other he wants both feedback > and display. The processes that accept keystrokes, filter for > validity, and store to the internal text string are separate because > they may be recombined to create other chains of events. The > fact that the two screen representations are similar is of no > consequence other than predictability on the part of the user. (and ease on the part of the programmer - & both are good things) > What is important is the task and the feedback. A password > box could just be a single block that changes color with each > keypress and uses three different beeps -- one for characters > and two for accept or reject. I think my point was - once you have a textbox (behaviour or object or widget or control or scomblonker or whatever you want to call the classification/boundary that you've arbitrarily decided should surround the activity of accumulating keystrokes into a bit of text) - you should only need to make a small change to turn that into a passwordbox, since they needn't differ in anything but the most marginal way. If you're thinking in terms of objects, then it's not unreasonable to think of the passwordbox being a subclass (specialization) of the textbox (although it's also not unreasonable to think of it the other way around too) If you're thinking in terms of processes, then it's not unreasonable to think of the passwordbox delegating to a textbox. But when that's the only function of the textbox - to be the 'back end' of a passwordbox - then it seems like a bit of a waste, especially if the passwordbox has to duplicate the textbox functionality anyway (like display area etc.) > > One process per real-world activity - the textbox underlying > > a passwordbox isn't *really*a discrete real-world activity > > This is the atomic argument (as in physics) versus the quark > argument. Do you model physical real-world things, or the > elements that combine to create different kinds of reality? > Either is valid, they are just different views but they lead to > drastically different explanations of the seemingly same > external behavior. > > jay Yes... but there is a point of diminishing returns. If you're simulating an ideal gas it seems like a waste to simulate it down to the quark level, when billiard balls will give you a result within 0.1%. I mean, the logical extension of the quark argument as it applies to GUIs would appear to be that the best way to build a GUI in Erlang would be to *not* build a GUI, thus allowing all programmers *full* control over the HCI without introducing preconceived notions of 'widgets' that, despite how useful they may be, could be deemed inflexible and stifling to creativity... So - I don't see a problem looking at GUI elements as widgets, as long as you can admit that those widgets are composed of sets of behaviours, and that you can make those behaviours somehow 'rewirable' at a fine level of detail - e.g. a textbox consists of a focusable area, visible text display, a cursor, and sensitivity to keypresses. To make a readonly textbox, you'd take a textbox and remove the sensitivity to keypresses; to make it into a passwordbox, you'd replace the visible text display with visible *** display; etc. To make a novel widget you'd combine a variety of behaviours, possibly traditionally associated with a variety of different widgets. I still think that Erlang, in its honourable effort to subvert OO-mania, is in danger of developing OO-phobia - but that is a more general subject than GUI's and I'll try to address it in a future thread. -Chris From cyberlync@REDACTED Wed Mar 5 20:22:35 2003 From: cyberlync@REDACTED (Eric Merritt) Date: Wed, 5 Mar 2003 11:22:35 -0800 (PST) Subject: Erlang Image In-Reply-To: Message-ID: <20030305192235.57099.qmail@web40812.mail.yahoo.com> Hello all, Lately I have been playing with image based dev systems like Lisp and Smalltalk. From a server prospective I think that images have quite allot going for them. I wonder if Erlang would benefit from being image based? The low level binary format is already in place. Of course, there would probably be more then a few problems with serializing processes. This is just another Erlang bent rambling of mine. I just was wondering if anyone had similar ideas, etc. Thanks, Eric __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - forms, calculators, tips, more http://taxes.yahoo.com/ From daniel.dudley@REDACTED Wed Mar 5 21:12:01 2003 From: daniel.dudley@REDACTED (Daniel Dudley) Date: Wed, 5 Mar 2003 21:12:01 +0100 Subject: The update R9B-1 is released References: <006b01c2e340$969f9c90$a3d3b33e@dld2000> Message-ID: <00b101c2e353$7bf21a90$a3d3b33e@dld2000> "Kent Boortz" wrote: > > "Daniel Dudley" writes: > > "Kent Boortz" wrote: > > > > > > There is no support for building a Windows version from > > > source. > > > > Ok, so we're on our own after we've installed it. But is > > there a cvs "build" tree available for Windows? Or is it > > part of > > http://www.erlang.org/download/otp_src_R9B-1.tar.gz > > (the full source distribution)? > > It is all there I think but it is targeted our build environment. > We will "soon" release a native Windows build that use Cygwin. Good, although I'd have preferred a VC6 build. What do they say...if you give them a finger they'll take a hand? ;-) It would be nice, though -- even if I do get the point with Cygwin, which I use to build a couple of other languages. > I don't quite understand what you mean by "so we're on our own > after we've installed it". You can compile the Erlang source as > well as write and load dynamic drivers (dll). What you can't do > (easily) is rebuild the Erlang emulator (virtual machine), I was merely noting that there isn't official support in OTP and, according to the readme file (the line above), specifically building the Windows version from source. Thanks for the explanation, but exactly why is the emulator not so easily rebuilt? And does this apply to the other platforms, too? Daniel From david.wallin@REDACTED Wed Mar 5 22:40:39 2003 From: david.wallin@REDACTED (david wallin) Date: Wed, 05 Mar 2003 21:40:39 +0000 Subject: problem with shared heap? Message-ID: <1046900438.28550.13.camel@wintermute.csis.ul.ie> When trying the new R9B-1 I decided to compile with --enable-shared-heap to see how much faster my code would run, to my surprise the result was quite alot slower. My system is a Pentium4 running Linux 2.4.18 and R9B-1 with HiPE enabled (actually: not disabled) in both cases. Is this a known problem (and why shared heap is still experimental), or is there any rule of thumb when to use or not to use shared heap ? ./configure --enable-shared-heap: 135.15s real 110.87s user 23.89s system 135.13s real 110.24s user 24.68s system 135.09s real 111.00s user 23.89s system 135.48s real 111.14s user 24.13s system 134.77s real 110.52s user 23.80s system 134.66s real 110.25s user 24.18s system 135.02s real 110.58s user 24.23s system 134.91s real 110.58s user 24.08s system 135.43s real 110.13s user 24.72s system 143.83s real 111.39s user 24.61s system ./configure: 48.72s real 47.60s user 0.46s system 49.12s real 47.76s user 0.57s system 48.28s real 47.01s user 0.69s system 48.65s real 47.15s user 0.68s system 48.30s real 47.02s user 0.74s system 48.34s real 47.10s user 0.65s system 49.03s real 46.93s user 0.90s system 49.31s real 47.36s user 0.62s system 48.11s real 47.05s user 0.66s system 49.40s real 47.38s user 0.70s system cheers, --david. -- david wallin From kent@REDACTED Wed Mar 5 23:13:19 2003 From: kent@REDACTED (Kent Boortz) Date: 05 Mar 2003 23:13:19 +0100 Subject: The update R9B-1 is released In-Reply-To: <00b101c2e353$7bf21a90$a3d3b33e@dld2000> References: <006b01c2e340$969f9c90$a3d3b33e@dld2000> <00b101c2e353$7bf21a90$a3d3b33e@dld2000> Message-ID: "Daniel Dudley" writes: > Thanks for the explanation, but exactly why is the emulator > not so easily rebuilt? And does this apply to the other > platforms, too? All sources are there so of course you can build it somehow. Our current build process is to build a Unix build first and contact a small rpc daemon (a Perl script) on a Windows machine that run nmake to compile the C files. As OTP has grown the Windows build has become unnecessary complicated (Perl calling an Erlang progam, calling Perl...). Because of this the Windows builds and test runs sometimes fail in our daily build and test - not because of bugs in OTP but because of the build process used. We will now use Cygwin to create a cleaner build process that also will be similar on Unix and Windows enabling us to share make files etc. Other platforms we build on are mostly Unix/Linux/MacOS X and there we have no problem building because they can all use the GNU development tools. We also build for VxWorks and OSE but they are cross builds from Solaris that mostly use the GNU development tools, kent From vances@REDACTED Wed Mar 5 23:27:33 2003 From: vances@REDACTED (Vance Shipley) Date: Wed, 5 Mar 2003 17:27:33 -0500 Subject: Binaries - pattern matching In-Reply-To: <001a01c2e323$bf83ed90$1e00a8c0@design> References: <001a01c2e323$bf83ed90$1e00a8c0@design> Message-ID: <20030305222733.GE2799@frogman.motivity.ca> 10> is_integer(A). true On Wed, Mar 05, 2003 at 03:30:17PM +0100, Inswitch Solutions - Erlang Evaluation wrote: } } I have executed the following commands in the Erlang shell: } 1) L = [1,2,3,4,5,6,7,8,9,10,11,12,13]. } 2) LB = list_to_binary(L). } 3) <> = LB. } 4) A. } 5) 4759477275222530853130 } } Please, does anyone know what type is 'A' variable ? } 'A' variable contains 10 bytes, how can I retrieve each byte from it? } } } Thanks, } Eduardo Figoli } INSwitch Solutions. } From vances@REDACTED Wed Mar 5 23:57:05 2003 From: vances@REDACTED (Vance Shipley) Date: Wed, 5 Mar 2003 17:57:05 -0500 Subject: Binaries - pattern matching In-Reply-To: <20030305222733.GE2799@frogman.motivity.ca> References: <001a01c2e323$bf83ed90$1e00a8c0@design> <20030305222733.GE2799@frogman.motivity.ca> Message-ID: <20030305225705.GA3692@frogman.motivity.ca> 1> L = [1,2,3,4,5,6,7,8,9,10,11,12,13]. [1,2,3,4,5,6,7,8,9,10,11,12,13] 2> LB = list_to_binary(L). <<1,2,3,4,5,6,7,8,9,10,11,12,13>> 3> <> = LB. <<1,2,3,4,5,6,7,8,9,10,11,12,13>> 4> A. <<1,2,3,4,5,6,7,8,9,10>> 5> B. 723981 6> <> = A. <<1,2,3,4,5,6,7,8,9,10>> 10> First. 1 11> Second. 2 12> Third. 3 On Wed, Mar 05, 2003 at 03:30:17PM +0100, Inswitch Solutions - Erlang Evaluation wrote: } } I have executed the following commands in the Erlang shell: } 1) L = [1,2,3,4,5,6,7,8,9,10,11,12,13]. } 2) LB = list_to_binary(L). } 3) <> = LB. } 4) A. } 5) 4759477275222530853130 } } Please, does anyone know what type is 'A' variable ? } 'A' variable contains 10 bytes, how can I retrieve each byte from it? } } } Thanks, } Eduardo Figoli } INSwitch Solutions. } From luke@REDACTED Thu Mar 6 00:22:29 2003 From: luke@REDACTED (Luke Gorrie) Date: 06 Mar 2003 00:22:29 +0100 Subject: FW: UI thoughts In-Reply-To: References: Message-ID: Ulf Wiger writes: > >I think handling only rectangular areas is a reasonable assumption > >for a GUI. If necessary, one could use an alpha channel to simulate > >round windows. > > True. Why make it more complicated than it has to be. It's a pity that the "Project Oberon" book is so hard/expensive to get. It's got a really fun and extreme "throw away everything that's not absolutely necessary and would complicate the implementation" approach to GUIs. Its overall design is reassuringly Emacs-like, I think :-) Cheers, Luke From luke@REDACTED Thu Mar 6 02:54:55 2003 From: luke@REDACTED (Luke Gorrie) Date: 06 Mar 2003 02:54:55 +0100 Subject: Jungerl mailing lists Message-ID: Ahoy, I created two mailing lists for the Jungerl: jungerl-commit: automatically receives log entries and diffs for CVS commits (except really big ones.) URL is http://lists.sourceforge.net/mailman/listinfo/jungerl-commit jungerl-hackers: General discussion list. Not clear that we need it right now, but available as an alternative to posting Jungerl things to erlang-questions (incase we start making too much noise.) URL is http://lists.sourceforge.net/mailman/listinfo/jungerl-hackers BTW, the 'pan' application that Mats Cronqvist has checked in is well worth checking out. Perhaps he can say a few words about it. Cheers, Luke From jim@REDACTED Thu Mar 6 05:22:47 2003 From: jim@REDACTED (Jim Larson) Date: Wed, 05 Mar 2003 20:22:47 -0800 Subject: FW: UI thoughts In-Reply-To: Your message of "06 Mar 2003 00:22:29 +0100." Message-ID: <200303060422.h264MlFK016863@krumkake.jetcafe.org> In message Luke Gorrie writes: >It's a pity that the "Project Oberon" book is so hard/expensive to >get. It's got a really fun and extreme "throw away everything that's >not absolutely necessary and would complicate the implementation" >approach to GUIs. Its overall design is reassuringly Emacs-like, I >think :-) Oberon inspired Rob Pike's "acme" interface, which you can read about at: http://www.cs.bell-labs.com/sys/doc/acme/acme.html Acme has been ported to Unix/X11 under the name Wily: http://www.cs.yorku.ca/~oz/wily/ Jim From jay@REDACTED Thu Mar 6 04:39:40 2003 From: jay@REDACTED (Jay Nelson) Date: Wed, 05 Mar 2003 19:39:40 -0800 Subject: UI, etiquette and OO phobia Message-ID: <4.2.2.20030305182714.00cd35d0@duomark.com> Daniel Dudley wrote: > BTW, it is not good etiquette to write private mail on > subjects originating in the mailing list; Unintended consequence of a heavy deadline at work. My original email said "Have some ideas, no time to write, think about behaviours" or some such. I hadn't thought through any of this, just had ideas rattling around and have only 2 waking hours to eat, shower and hit the road or go to bed. Vlad's reply about building widgets triggered me to spill the ideas on the keyboard quickly and roll into bed. I hadn't formulated the ideas and didn't intend to type them until I had thought more about it. Just had a visceral reaction to his reply and rambled about what I had been thinking on the drives to and from work. It was mostly intended to inspire him to forget everything he had seen and think with a clean slate, or just to shake him up a little. I have been able to keep up with the list waiting for compiles :-) but can only post occasionally from home. Chris Pressey: > I don't want to be misunderstood Sorry, I was trying to point out that it is possible to throw every assumption you have made out the window and think from a fresh point of view. When I get stuck thinking about something, or finding the cause of a bug, invariably a fundamental assumption was violated which made the solution invisible to me. I have a tendency to abuse metaphors against their will. The atom / quark thing was more to say there are differing points of view, not necessarily a real way of breaking down the problem. > I still think that Erlang, in its honourable effort to > subvert OO-mania, is in danger of developing > OO-phobia - but that is a more general subject > than GUI's and I'll try to address it in a future thread. That definitely is a new topic. I was a big OO fan before OO was commonly practiced. I have a tendency to get bored and move on to new things and to be on the fringe rather than in the pack (I like to think the leading edge, but fringe dwellers have no global context for relative position). I'm not OO-phobic but I am always grasping at new approaches and new ways of thinking, and frankly am bored with the status quo of UIs and programming in general. I want to rattle some cages and challenge some stagnant thinking. If I have to solve a real problem and OO looks good, I will use it. I am very much a proponent of using the best language or paradigm for the problem at hand. I have a reasonable collection of Java classes for my game server and website management, but I wanted a better solution and that is why I am testing the erlang waters. OO may very well be the best approach for UI, but I want to think about a different way and see what it feels like. Back to the UI. OpenGL is planning an embedded subset that could work out well for an erlang sandbox: http://www.khronos.org/embeddedapi/ Also of note, Microsoft quits OpenGL board: http://news.com.com/2100-1025-991280.html?tag=lh jay From etxmacr@REDACTED Thu Mar 6 08:48:18 2003 From: etxmacr@REDACTED (Mats Cronqvist) Date: Thu, 06 Mar 2003 08:48:18 +0100 Subject: performance analysis Message-ID: <200303060748.h267mI025767@cbe2077.al.sw.ericsson.se> i've checked in that AXD301 performance analysis/troubleshooting tool pan in jungerl (http://sourceforge.net/projects/jungerl). it's a front end to the trace bif with some pretty intricate filters. it's changed daily to cope with different scenarios in the AXD; consequently it's quite "dense and chaotic" (tm). see the blurb below. since it comes with the Luke Gorrie Stamp of Approval it's probably worth checking out. mats ------------------------------------------------------ pan was developed to solve this common problem; what resources (CPU time and memory consumption) does a set of actions (a test case) consume? the basic idea is that you start the measurement, perform the test case and stop the measurement. this will generate a set of data files containing a wealth of information, which can then be processed to present e.g. * how much CPU time and memory each erlang process consumed * how much memory was added to each ets table * what did the call stack look like when some function was called * what messages were sent between processes at the current stage the program contains the functionality of the OTP applications dbg and fprof, the unix application top, and some extras. it is designed to run with minimal impact (which is sometimes huge) in an embedded environment. alas, it is not a product, so your mileage will vary. From Vlad.Dumitrescu@REDACTED Thu Mar 6 09:09:33 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Thu, 6 Mar 2003 09:09:33 +0100 Subject: The update R9B-1 is released Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D416@esemont203.gbg.edt.ericsson.se> > Good, although I'd have preferred a VC6 build. What do they > say...if you give them a finger they'll take a hand? ;-) > It would be nice, though -- even if I do get the point with > Cygwin, which I use to build a couple of other languages. Some of us running Windows can't afford buying VC :-) so Cygwin is the only chance. /Vlad From etxuwig@REDACTED Thu Mar 6 09:40:51 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Thu, 6 Mar 2003 09:40:51 +0100 (MET) Subject: UI, etiquette and OO phobia In-Reply-To: <4.2.2.20030305182714.00cd35d0@duomark.com> Message-ID: On Wed, 5 Mar 2003, Jay Nelson wrote: >OO may very well be the best approach for UI, but I want to >think about a different way and see what it feels like. I do not recall seeing anything in your "ramblings" that would preclude adding an OO framework (e.g. a widget library) on top of your model. The really interesting trick is of course to imagine a foundation that's elegant and general enough that you can derive different frameworks from it. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From francesco@REDACTED Thu Mar 6 10:00:08 2003 From: francesco@REDACTED (Francesco Cesarini (Erlang Consulting)) Date: Thu, 06 Mar 2003 09:00:08 +0000 Subject: Erlang Scheduled Courses US/UK/Sweden/Singapore In-Reply-To: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D416@esemont203.gbg.edt.ericsson.se> References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D416@esemont203.gbg.edt.ericsson.se> Message-ID: <3E670E18.7000701@erlang-consulting.com> Hello World. Based on your feedback from a previous mail to the group, we have now put together a schedule for Erlang/OTP courses. Please pass this on to project leaders, training managers, and any one else not on the list you think might be interested. We need all the help we can get to spread the word and make it happen. The cities we the greatest request for included London, Stockholm, Campbell (Silicon Valley) and Singapore. (If there are others, let us know) The first courses will be in May. For more information, contact me or Lennart Ohman (lennart.ohman@REDACTED) or see http://www.erlang-consulting.com/training_fs.html If there is an interest in sending someone, please express your interest as soon as possible, as we will be cancelling courses with less than four participants three weeks prior to the start date. To keep up to date with changes, new courses, dates and locations, join our training & consulting mailing list, located on the index page @ http://www.erlang-consulting.com Thanks Francesco -- http://www.erlang-consulting.com From bjorn@REDACTED Thu Mar 6 10:14:07 2003 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 06 Mar 2003 10:14:07 +0100 Subject: problem with shared heap? In-Reply-To: david wallin's message of "Wed, 05 Mar 2003 21:40:39 +0000" References: <1046900438.28550.13.camel@wintermute.csis.ul.ie> Message-ID: Shared heap is still experimental. The garbage collector is in particular needs more attention (it is basically the same garbage collector as in the separate-heap emulator). Shared heap can be better if you have an application with a lot of concurrency and message passing. Message passing will be faster (because messages are not copied) and the emulator will use less memory (because processes can share terms instead of having their own separate copies). /Bjorn david wallin writes: > When trying the new R9B-1 I decided to compile with --enable-shared-heap > to see how much faster my code would run, to my surprise the result was > quite alot slower. > > My system is a Pentium4 running Linux 2.4.18 and R9B-1 with HiPE enabled > (actually: not disabled) in both cases. > > Is this a known problem (and why shared heap is still experimental), or > is there any rule of thumb when to use or not to use shared heap ? > [...] -- Bj?rn Gustavsson Ericsson Utvecklings AB bjorn@REDACTED ?T2/UAB/F/P BOX 1505 +46 8 727 56 87 125 25 ?lvsj? From Vlad.Dumitrescu@REDACTED Thu Mar 6 10:39:22 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Thu, 6 Mar 2003 10:39:22 +0100 Subject: UI thoughts Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D419@esemont203.gbg.edt.ericsson.se> > It was mostly intended to inspire > him to forget everything he had seen and think with a > clean slate, or just to shake him up a little. And it was mostly appreciated, and it also had the intended effect. It seems on more people than only me :-) To try to expose my opinions on this, I think the ideal solution would be something like this: * the core application is completely unaware of any UI, but it has to interact with the outside world in a way or another. It can receive commands/messages/notifications and send notifications to registered observers. This is more or less the ModelView pattern. * between the core and the rest of the world a Mediator should sit and translate the application-relevant messages into something relevant to the external world. * a generic UI layer may then be one of these external observer and will then handle messages it understands and convert them to visible changes and from user interaction. It will also have to interface the generic UI to specific toolkits. Just the regular 3-layered model, it seems! :-) All is well, and I think it is a great architecture. My interest right now is concentrating at the third part: how to design a generic UI layer that is easy to plug in, that is extensible and flexible, that is easy to use by both application writer and UI designer and also how will it map onto some existing graphics API. Not easy to fullfill all this! It would be a plus if it was possible to define or change the UI dynamically. The mediator must then be also extensible and easy to extend, even at run-time. It is also important to remember that we must also have a framework to write applications in, and the middle layer too. My first choice for a graphic back-end would be OpenGL. It is standard, powerful enough for advanced use, available almost everywhere, and if only simple features are used it is not complicated. If only SDL would let one open several windows at one time! :-) I turned to X11 for basically the same reasons, and also because the GLX extension is available for XFree86 4.3. Using an existing widget toolkit (or designing one after existing models) might help use the time for the really interesting problems, but might also introduce unwanted effects. regards, Vlad From jonathan@REDACTED Thu Mar 6 11:37:35 2003 From: jonathan@REDACTED (Jonathan Coupe) Date: Thu, 6 Mar 2003 10:37:35 -0000 Subject: UI, etiquette and OO phobia References: <4.2.2.20030305182714.00cd35d0@duomark.com> Message-ID: <001201c2e3cd$656c6a80$890bfea9@mimbi> ----- Original Message ----- From: Jay Nelson To: Sent: Thursday, March 06, 2003 3:39 AM Subject: UI, etiquette and OO phobia > > I still think that Erlang, in its honourable effort to > > subvert OO-mania, is in danger of developing > > OO-phobia - but that is a more general subject > > than GUI's and I'll try to address it in a future thread. > > That definitely is a new topic. I was a big OO fan > before OO was commonly practiced. I have a tendency to > get bored and move on to new things and to be on > the fringe rather than in the pack (I like to think the > leading edge, but fringe dwellers have no global > context for relative position). I'm not OO-phobic but > I am always grasping at new approaches and new > ways of thinking, and frankly am bored with the status > quo of UIs and programming in general. I want to > rattle some cages and challenge some stagnant thinking. One of the problems with OO is that, as a single coherent way of programming, it doesn't really exist. The design, code, development tactics, and project suitability of Smalltalk are completely different from CLOS, and both are completely different from the C++, Java, and Eiffel group. E.g. one of *the* dominant issues in any project using a statically typed OO language are always going to be the struggle to design out over-tight binding. I'd argue that talking of these languages as a group is more than usually misleading, even for software engineering, and that a lot of the early project successes that drove the adoption of OO actually came from Smalltalk gui programming, while the less successful wave of projects that followed used statically typed languages in a variety of domains. Gui is certainly one of the best fits for OO - especially dynamically typed OO. But Tk manages extremely well with the dynamic typing alone, and gs, as far as the limited widget library allows, seems even more pleasant to use. - Jonathan Coupe From david.wallin@REDACTED Thu Mar 6 11:47:04 2003 From: david.wallin@REDACTED (david wallin) Date: Thu, 06 Mar 2003 10:47:04 +0000 Subject: problem with shared heap? In-Reply-To: References: <1046900438.28550.13.camel@wintermute.csis.ul.ie> Message-ID: <1046947624.28550.21.camel@wintermute.csis.ul.ie> Thanks, On Thu, 2003-03-06 at 09:14, Bjorn Gustavsson wrote: > Shared heap is still experimental. The garbage collector is > in particular needs more attention (it is basically the same garbage > collector as in the separate-heap emulator). > That makes sense since my code probably creates a lot of 'stuff' that never will be used again. > Shared heap can be better if you have an application with a lot > of concurrency and message passing. Message passing will be faster > (because messages are not copied) and the emulator will use less memory > (because processes can share terms instead of having their own separate > copies). > Yes, but when shared heap is finished, will there be cases when running a shared heap will actually perform worse than without it, or is it just now in its experimental stages that these things can occur? --david. > /Bjorn > > david wallin writes: > > > When trying the new R9B-1 I decided to compile with --enable-shared-heap > > to see how much faster my code would run, to my surprise the result was > > quite alot slower. > > > > My system is a Pentium4 running Linux 2.4.18 and R9B-1 with HiPE enabled > > (actually: not disabled) in both cases. > > > > Is this a known problem (and why shared heap is still experimental), or > > is there any rule of thumb when to use or not to use shared heap ? > > > [...] -- david wallin From raimo.niskanen@REDACTED Thu Mar 6 12:13:52 2003 From: raimo.niskanen@REDACTED (Raimo Niskanen) Date: Thu, 06 Mar 2003 12:13:52 +0100 Subject: yeah, we're just better then awk! References: <20030303141204.26137.qmail@web40803.mail.yahoo.com>, <006101c2e23f$03470c00$fcf06850@c1p4e3> Message-ID: If you just are reading from the 2d array, you could try a tuple of tuples (of elements). They kan be accesed by index (element(N, Tuple)), but if you need to change one element the whole tuple has to be rebuilt. / Raimo Niskanen, Erlang/OTP, Ericsson AB Pierpaolo BERNARDI wrote: > From: "Eric Merritt" > >> Yea the guy who did this has a comentary on Erlang >>that basically says the same think. That its a nice >>langauge and none of the tests are suited to its >>strengths. > > > Hmmm... I have been surprised by Erlang in a test > which probably is as far from its strengths as possible. > > I rewrote in Erlang a Common Lisp program which, > essentially, accesses repeatedly a big 2d array, > and does some manipulations of short lists. > > I obtain these times: > > Clisp: 11/12s > HCL: 1.5/2s > Erlang using gb_trees as arrays: 32/34s > Erlang using an ets table as array: 7/8s > > Clisp is a free CL that compiles to byte code. > HCL is a commercial CL compiling to native code. > Erlang is the byte code compiler, no Hipe. > > I was expecting much worse results for Erlang. > > Code available at http://space.tin.it/romebern/erlab.zip > > BTW, is there a better data structure to be used as an array > (i.e. a map from fixed length tuples of integers)? > > P. > From matthias@REDACTED Thu Mar 6 12:24:10 2003 From: matthias@REDACTED (Matthias Lang) Date: Thu, 6 Mar 2003 12:24:10 +0100 Subject: problem with shared heap? In-Reply-To: <1046947624.28550.21.camel@wintermute.csis.ul.ie> References: <1046900438.28550.13.camel@wintermute.csis.ul.ie> <1046947624.28550.21.camel@wintermute.csis.ul.ie> Message-ID: <15975.12250.938511.377814@antilipe.corelatus.se> david wallin writes: > Yes, but when shared heap is finished, will there be cases when running > a shared heap will actually perform worse than without it, or is it just > now in its experimental stages that these things can occur? Why would you expect the shared heap to be faster in _all_ cases? Related observations: * Native code is not necessarily faster than BEAM. * Binaries are not always faster than lists. * Tail recursive algorithms are not always faster than non-tail recursive ones. Matthias From david.wallin@REDACTED Thu Mar 6 12:39:11 2003 From: david.wallin@REDACTED (david wallin) Date: Thu, 06 Mar 2003 11:39:11 +0000 Subject: problem with shared heap? In-Reply-To: <15975.12250.938511.377814@antilipe.corelatus.se> Message-ID: <3FE8FD1D-4FC8-11D7-80F7-000393536F4E@ul.ie> You misinterpreted me, (or I didn't make myself clear). I don't expect it to be faster in all cases, but I wouldn't expect to see any cases where a shared heap performed worse than without it. Maybe on par, but not worse. Hence my question, will there be cases where using a shared heap will degrade performance? --david. On Thursday, March 6, 2003, at 11:24 AM, Matthias Lang wrote: > david wallin writes: > >> Yes, but when shared heap is finished, will there be cases when >> running >> a shared heap will actually perform worse than without it, or is it >> just >> now in its experimental stages that these things can occur? > > Why would you expect the shared heap to be faster in _all_ cases? > > Related observations: > > * Native code is not necessarily faster than BEAM. > > * Binaries are not always faster than lists. > > * Tail recursive algorithms are not always faster than non-tail > recursive ones. > > Matthias From Vlad.Dumitrescu@REDACTED Thu Mar 6 12:44:51 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Thu, 6 Mar 2003 12:44:51 +0100 Subject: problem with shared heap? Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D41C@esemont203.gbg.edt.ericsson.se> Hi, > You misinterpreted me, (or I didn't make myself clear). I > don't expect > it to be faster in all cases, but I wouldn't expect to see any cases > where a shared heap performed worse than without it. Maybe on > par, but > not worse. Hence my question, will there be cases where using > a shared > heap will degrade performance? The answer is yes. For example in cases where many processes are spawned which create a lot of garbage and then die. In the normal heap case, the cleanup is almost instantaneous. With a shared heap, garbage collections need to be done. regards, Vlad From matthias@REDACTED Thu Mar 6 12:57:01 2003 From: matthias@REDACTED (Matthias Lang) Date: Thu, 6 Mar 2003 12:57:01 +0100 Subject: problem with shared heap? In-Reply-To: <3FE8FD1D-4FC8-11D7-80F7-000393536F4E@ul.ie> References: <15975.12250.938511.377814@antilipe.corelatus.se> <3FE8FD1D-4FC8-11D7-80F7-000393536F4E@ul.ie> Message-ID: <15975.14221.855658.257039@antilipe.corelatus.se> david wallin writes: > You misinterpreted me, (or I didn't make myself clear). I don't expect > it to be faster in all cases, but I wouldn't expect to see any cases > where a shared heap performed worse than without it. Maybe on par, but > not worse. Hence my question, will there be cases where using a shared > heap will degrade performance? Yes. Matt From Erik.Stenman@REDACTED Thu Mar 6 13:47:20 2003 From: Erik.Stenman@REDACTED (Erik Stenman) Date: Thu, 6 Mar 2003 13:47:20 +0100 Subject: problem with shared heap? References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D41C@esemont203.gbg.edt.ericsson.se> Message-ID: <04c701c2e3de$86c50960$239ab280@lamppc27> Vlad Dumitrescu wrote: > Hi, > > > You misinterpreted me, (or I didn't make myself clear). I > > don't expect > > it to be faster in all cases, but I wouldn't expect to see any cases > > where a shared heap performed worse than without it. Maybe on > > par, but > > not worse. Hence my question, will there be cases where using > > a shared > > heap will degrade performance? > > The answer is yes. For example in cases where many processes are spawned which create a lot of garbage and then die. > In the normal heap case, the cleanup is almost instantaneous. With a shared heap, garbage collections need to be done. No this is not the problem. The scenarrio you describe does not cost anything extra in the shared heap, since the garbage collector is a copying one, none of the dead data needs to be visited. The problem in the current system is that if you have a process with a huge (live) data set, all this data hast to be traversed (and copied) at a major GC, even if that major GC is triggered by another process. This problem might be reduced with a new GC and GC policies that are better adapted to the shared heap. /Erik From feeley@REDACTED Thu Mar 6 14:04:10 2003 From: feeley@REDACTED (Marc Feeley) Date: Thu, 6 Mar 2003 08:04:10 -0500 Subject: problem with shared heap? In-Reply-To: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D41C@esemont203.gbg.edt.ericsson.se> (Vlad.Dumitrescu@erv.ericsson.se) References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D41C@esemont203.gbg.edt.ericsson.se> Message-ID: <200303061304.h26D4AEq020230@vor.iro.umontreal.ca> > The answer is yes. For example in cases where many processes are > spawned which create a lot of garbage and then die. In the normal > heap case, the cleanup is almost instantaneous. With a shared heap, > garbage collections need to be done. No this is a case where performance should be good. The worst case is where a lot of small processes (i.e processes which allocate very little and then die) are created AND there are lots of live objects globally (i.e. at least one process is holding on to a lot of data in the shared heap). When a good GC is used for managing the shared heap, reclaiming garbage doesn't cost anything. See my paper on the "unified heap approach" at the 2001 Erlang workshop. Marc From Vlad.Dumitrescu@REDACTED Thu Mar 6 14:11:02 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Thu, 6 Mar 2003 14:11:02 +0100 Subject: problem with shared heap? Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D41D@esemont203.gbg.edt.ericsson.se> I stand corrected. Thanks! /Vlad > -----Original Message----- > From: Erik Stenman [mailto:Erik.Stenman@REDACTED] > Sent: Thursday, March 06, 2003 1:47 PM > To: Erlang-questions (E-mail) > Subject: Re: problem with shared heap? > > > > Vlad Dumitrescu wrote: > > > > Hi, > > > > > You misinterpreted me, (or I didn't make myself clear). I > > > don't expect > > > it to be faster in all cases, but I wouldn't expect to > see any cases > > > where a shared heap performed worse than without it. Maybe on > > > par, but > > > not worse. Hence my question, will there be cases where using > > > a shared > > > heap will degrade performance? > > > > The answer is yes. For example in cases where many > processes are spawned > which create a lot of garbage and then die. > > In the normal heap case, the cleanup is almost instantaneous. With a > shared heap, garbage collections need to be done. > > No this is not the problem. > The scenarrio you describe does not cost anything extra in > the shared heap, > since the garbage collector is a copying one, none of the > dead data needs to > be visited. > > The problem in the current system is that if you have a > process with a huge > (live) data set, all this data hast to be traversed (and > copied) at a major > GC, even if that major GC is triggered by another process. > This problem might be reduced with a new GC and GC policies > that are better > adapted to the shared heap. > > > /Erik > From jay@REDACTED Thu Mar 6 16:41:30 2003 From: jay@REDACTED (Jay Nelson) Date: Thu, 06 Mar 2003 07:41:30 -0800 Subject: The Zen of UI design Message-ID: <4.2.2.20030306072348.00d07540@duomark.com> Ulf wrote: > I do not recall seeing anything in your "ramblings" that > would preclude adding an OO framework That is true. It specifically was stated to allow a separate layering. Refer back to my "seven levels of UI nirvana" posting last month: http://www.erlang.org/ml-archive/erlang-questions/200302/msg00473.html Level 5 is where "object enlightenment" occurs. That was another rambling post that attempted to put a concrete design on an amorphous discussion. Vlad wrote: > the core application is completely unaware of any UI yes! very good > This is more or less the ModelView pattern. I think this approach is more general than an OO approach and includes OO as a special case. I think with the approach you described you will come up with more interesting ideas and have a chance at defining something that feels distinctly different. > My interest right now is concentrating at the third part Hmm... you seem in a rush to get something on screen. I suppose you have a specific purpose or goal, but I would try to build the user interaction model first that maintains the internal state. The reason I say that is because once you have text boxes and other widgets, your interaction style will be constrained by how they operate. I lay awake in bed this morning imagining the user interface without a monitor. Just the keyboard and the mouse. Imagine the sound of one hand clapping... I have to say this mailing list is far too fertile for me ;-) I am thinking about things that I never intended, it interferes with my work and sleep and keeps me distracted all the time. I'll never get to the tasks I wanted to accomplish! jay From klacke@REDACTED Thu Mar 6 22:16:13 2003 From: klacke@REDACTED (Klacke) Date: Thu, 6 Mar 2003 22:16:13 +0100 Subject: Yaws 1.01 Message-ID: <20030306211613.GA22099@bluetail.com> Folks, Time for a new Yaws release. Here's the freshmeat blurb for those of you that don't know what Yaws is .... Yaws is a high performance, light-weight, threaded HTTP 1.1 Web server targeted for the generation of dynamic content. It is written in Erlang, and the server side dynamic content is generated by Erlang code embedded in the HTML code. And here are the rel notes: ----- snip ---------- This is bugfix release. Bug in ssl config passord parse found by Eric Pearson Bug in arg rewrite handling found and fixed by Taavi Talvik Bug with redir for missing trailing slash together with a query part of the url fixed, found by Erik Pearson Added the option of disabling dir_listings Added http version to access log messages Did away with the idiotic calls to id -u as well as the the broken grep in /etc/passwd. Also ensured that .yaws files with a query part don't end up in the cache. They need to be reparsed every time Fixed probles with paths that had a query part ending up in the cache Added proper support for 'if-none-match' with etag matching by Johan Bevemyr Skip empty space after an erl chunk in a .yaws file Handle broken clients that start with CRNL instead of proper request line Handle 0.9 clients ---snip---- Enjoy /klacke -- Claes Wikstrom -- Caps lock is nowhere and Alteon WebSystems -- everything is under control http://www.bluetail.com/~klacke cellphone: +46 70 2097763 From chris_pressey@REDACTED Thu Mar 6 22:23:27 2003 From: chris_pressey@REDACTED (Chris Pressey) Date: Thu, 6 Mar 2003 16:23:27 -0500 (EST) Subject: Paradigms / OO vs CO (was: UI, etiquette and OO phobia) [LONG] Message-ID: <20030306212327.44910.qmail@web20504.mail.yahoo.com> Jay Nelson wrote: > Chris Pressey: > > > I don't want to be misunderstood > > Sorry, I was trying to point out that it is possible to > throw every assumption you have made out the > window and think from a fresh point of view. When > I get stuck thinking about something, or finding the > cause of a bug, invariably a fundamental assumption > was violated which made the solution invisible to me. Yes, I probably didn't appreciate that as much as I should've - I spent a lot of time working "across paradigms" before I even encountered Erlang, so I have a tendency to come full circle. It's good - maybe critical - to discard assumptions frequently, so I've tried to make it a habit (but hopefully I've not yet taken it for granted :) One related problem that I seem to get into because of this is that I take terminology with a grain of salt - when things can't be discussed in plain language, jargon (i.e. assumptions) get in the way. So when I use words like "object", "behaviour" etc, I usually (but due to circumstances, not always) try to use them in the most informal sense. > I have a tendency to abuse metaphors against their > will. The atom / quark thing was more to say there > are differing points of view, not necessarily a > real way of breaking down the problem. The metaphor is actually quite good, and I basically agree with your suggested approach to GUI - deconstruct the problem. A widget need be no more than a loose collection of behaviours. I'm actually more concerned about a general class of implementation problems, into which the GUI approach seems to be falling. > > I still think that Erlang, in its honourable effort to > > subvert OO-mania, is in danger of developing > > OO-phobia - but that is a more general subject > > than GUI's and I'll try to address it in a future thread. > > That definitely is a new topic. I was a big OO fan > before OO was commonly practiced. I have a tendency to > get bored and move on to new things and to be on > the fringe rather than in the pack (I like to think the > leading edge, but fringe dwellers have no global > context for relative position). I'm not OO-phobic but > I am always grasping at new approaches and new > ways of thinking, and frankly am bored with the status > quo of UIs and programming in general. I want to > rattle some cages and challenge some stagnant thinking. Good :) The world needs more fringe dwellers. I think the important thing to point out is: OO itself is not a problem. Becoming entrenched in and dogmatic about OO (or any paradigm) is much more problematic. I guess to illustrate my concern, it would help to contrast OO with CO (concurrency orientation, i.e. the Erlang philosophy) OO -- How do we summarize this approach? - "Everything is an object." How do we structure an application? - We decompose it into objects. Each object has an explicit interface, with which it encapsulates some internal state. How do we organize objects? - Into classes. How do we extend existing code? - We subclass objects. How do we deal with concurrency? - We don't. Objects are dealt with synchronously (when an object method is called, the caller waits until the object returns a response.) To overcome this, perhaps we have a thread class, and we subclass it to make concurrent objects. CO -- How do we summarize this approach? - "Everything is an process." How do we structure an application? - We decompose it into processes. Each process has an explicit interface, with which it encapsulates some internal state. How do we organize processes? - At runtime, we organize them in a supervision tree; but conceptually, we don't. Typically, we try to make each module contain a function (e.g. "start") which creates the process (or processes) which handle the functionality related to that module. How do we extend existing code? - We create more processes which delegate to/from existing processes. Or, if we don't care so much about reusability, we simply alter the existing processes. How do we deal with concurrency? - Processes are concurrent. How do we deal with *NON*concurrency (sequentiality)? - If a process requires synchronization, we build a mechanism out of 2 or more asynchronous accesses (as is done in gen_server:call.) Discussion. These paradigms are actually quite similar, superficially at least: applications are structured into parts which present interfaces to other parts, behind which each part protects its own state. But from there they diverge on the issue of *control*: in CO, control is distributed amongst processes - each process has "agency". Each process can "drive" any other process that it is aware of. In OO this is basically not addressed - perhaps objects are "driven" by some "application master" object, but this is not generally specified. Which paradigm maps naturally to the real world? I would say neither - although CO comes much closer, since OO doesn't address the hard-to-dispute observation that the real world consists of diverse power centres which, operating independently or in concert, co-operate or compete for control of things. But CO also falls short, since the real world is also composed of "neutral" or "static" elements which don't have any significant "agency" - and these are often the things which are *being* controlled by the power centres. Time for some examples. Does a business have dynamic behaviour? "Of course." Does it have structure? Yes, it's composed of many entities which themselves have dynamic behaviour (employees, customers, invoices, etc) working mostly asynchronously, but in concert (i.e. with occasional synchronization.) Does a building have dynamic behaviour? "Of course not," it just exists, inert, subject to whatever operations are applied to it by other entities. Does it have structure? Yes, this is probably it's most important aspect (ask any architect.) Does a forklift have dynamic behaviour? Well, sometimes. When it's not running, no. When it is running, it has some dynamic behaviour, but this is mainly for the purpose of "amplifying" the behaviour of it's driver - but it certainly could be said to be more dynamic than the crates it's transporting, which are basically inert. How about its structure? Yes, it has one, but that's probably not of interest to you unless you're a forklift mechanic. How about a birthday party? Yes, the party itself has lots of dynamic behaviour provided by it's participants. What about the birthday cake? Not really (except for the candles, but they're short lived.) What about the presents? No, except maybe when one of them is a wind-up toy. What about the invitations? Sort of, but they're really more like messages. Structure of a party? They tend to follow a general pattern but are otherwise rather open-ended. Etc. What am I getting at in this lengthy analysis? I think there's a false dilemma between OO and CO - that there's a gap, but it could be bridged. How? I'm not entirely sure yet. But the feeling I'm getting is that there ought to be a way to deal with objects (in the informal sense, remember) regardless of whether they have dynamic behaviour or not. OO doesn't address concurrency well - it doesn't say what is granted agency and what isn't, relying on some "Grand Orchestrator"-type object (or "mainline code" if you prefer) to manage the application flow - while CO doesn't address inertness well - it requires that everything be granted agency, even things which clearly don't require it (like books and pens and fences.) One of the more appealing ideas I've had comes from the language Inform (http://www.inform-fiction.org/) in which virtual "interactive fiction" worlds can be described. In Inform, objects are basically static, reacting only when acted upon. But any object (up to 16 total IIRC :) can be assigned a "daemon" which gives it behaviour independent of the player/observer. I think this is the germ of a good model, and that, appropriately developed, it could fit between OO and CO. Decompose the problem into objects which may or may not have agency (processes.) But the hard part is making sure that objects can be treated the same by other objects, regardless of whether they are dynamic or not. I'd like to see something more transparent than "concurrent objects" or "Erlang with object extensions" - either of which seems to be a short-sighted approach where features with essentially incompatible assumptions would get slapped onto a pre-existing framework - rather than generating a smooth & novel synthesis of the two. Anyway, I should stop about now before I start repeating myself, and allow myself to give it more thought... -Chris ______________________________________________________________________ Post your free ad now! http://personals.yahoo.ca From bjarne@REDACTED Thu Mar 6 22:53:22 2003 From: bjarne@REDACTED (=?iso-8859-1?Q?Bjarne_D=E4cker?=) Date: Thu, 06 Mar 2003 22:53:22 +0100 Subject: UI, etiquette and OO phobia References: <4.2.2.20030305182714.00cd35d0@duomark.com> Message-ID: <002901c2e42a$cf303e80$642469d4@segeltorp> Gerlad Weinberg wrote of "ego-less programming". I suppose the opposite would be "subject orientated programming". Bjarne From jay@REDACTED Fri Mar 7 05:17:04 2003 From: jay@REDACTED (Jay Nelson) Date: Thu, 06 Mar 2003 20:17:04 -0800 Subject: OO vs. CO Message-ID: <4.2.2.20030306200746.00ccf790@duomark.com> > In Inform, objects are basically static, reacting only when > acted upon. But any object (up to 16 total IIRC :) can be > assigned a "daemon" which gives it behaviour independent > of the player/observer. In Symbolics Flavors (a Lisp-based object system) they had "mixins". It was a bundle of behaviours that could be used for multiple inheritance, similar to Java interfaces but not so restricted. You could mixin printable behaviour, or persistence, or anything else that was generically useful across object classes. Someone pointed out earlier there are two kinds of OO approaches, the inheritance kind and the prototype kind. With inheritance the class hierarchy is important. With prototypes, you stamp out instances of data structure and behaviour, but they are disconnected from the hierarchy but could still communicate with each other. erlang is closer to the prototype kind. Ruby tries to combine the best features of the two, allowing a class definition to be reopened and modified affecting all instances (although I forget if it is time-dynamic and does not affect prior instances), as well as allowing a single instance to have features that other members of the same class don't have. I believe the roots of prototype- based class languages come from Simula in the 70s which was used for simulation by modeling instances of independent entities. erlang would make a great simulation language (even to the level of doing something like a microprocessor emulator) because you can model the time delays, feedback loops and other interactions besides just the instances. jay From luke@REDACTED Fri Mar 7 08:22:54 2003 From: luke@REDACTED (Luke Gorrie) Date: 07 Mar 2003 08:22:54 +0100 Subject: Concurrent beam? Message-ID: Ahoy, Quite often the "the Erlang emulator doesn't exploit SMP" beef comes up, and it seems like doing a full-blown parallel Pekka-and-Tony-style emulator isn't on the cards in the near future. So what I wondered was, in Erlang style, might it be easier to write a concurrent emulator rather than a parallel one, with one thread per logically concurrent activity? For example, one thread executes erlang processes, one garbage collects, one does I/O, etc? Just a thought. Lack of SMP doesn't actually bother me in practice. Cheers, Luke From tony@REDACTED Fri Mar 7 11:10:56 2003 From: tony@REDACTED (Tony Rogvall) Date: Fri, 07 Mar 2003 11:10:56 +0100 Subject: Concurrent beam? + Erlux References: <1047023175.26763@DNS02> Message-ID: <3E687030.1080007@rogvall.com> Luke Gorrie wrote: > Ahoy, > > Quite often the "the Erlang emulator doesn't exploit SMP" beef comes > up, and it seems like doing a full-blown parallel Pekka-and-Tony-style > emulator isn't on the cards in the near future. > > So what I wondered was, in Erlang style, might it be easier to write a > concurrent emulator rather than a parallel one, with one thread per > logically concurrent activity? > > For example, one thread executes erlang processes, one garbage > collects, one does I/O, etc? > > Just a thought. Lack of SMP doesn't actually bother me in practice. > > Cheers, > Luke > Some random comments :-) The combination Executing-erlang-processes and garbage-collection is a tricky one. The simplicity in our (Pekka-Tony) approach made it, the garbage-collect at the same time as running other processes, trivial. One nice thing in our implementation was the abillity to run erlang processes in separate "kernel" threads or running them in the scheduler thread pool. That meant you could dispatch a process running free until you decided you join the "normal" scheduling again. The io/process pair also mean that you have to take care of the case when io is to be delivered from a driver to a running process. This makes the driver interface a bit slower (different anyway). In our implementation we made up a new task structure that handled both processes and ports in the same way. You could even add your own C-tasks. The main thing to do with the emulator in any case is to make the emulator fully reentrant and threadsafe. For example we implemented all process affecting bifs with async signals (like process_info, link ...) I have just started a project erlux that will run Erlang on top of the Linux kernel (without user space - well you may start a user space process if you like). This will be a patch to the kernel.org kernel replacing the init process with the emulator loop, but not leaving the kernel space. When running such a beast a SMP system will be useless unless we can run the scheduler in multiple threads. /Tony From luke@REDACTED Fri Mar 7 11:27:29 2003 From: luke@REDACTED (Luke Gorrie) Date: 07 Mar 2003 11:27:29 +0100 Subject: Concurrent beam? In-Reply-To: References: Message-ID: Ulf Wiger writes: > Separating application- and I/O processing is one of the > most efficient ways of increasing performance in I/O-bound > systems (and I believe many Erlang-based products are > I/O-bound.) Can you elaborate? My picture of an I/O-bound system is that you've run out of I/O resources, and have CPU to spare - so the application processing shouldn't affect your performance? Perhaps there are different flavours of "I/O bound" - are you I/O or CPU bound when your select()-loop or kernel is overloading the CPU while performing I/O? The whole "I/O-bound" concept if very attractive, from the "no use doing this in C instead" perspective ;-) Cheers, Luke From vlad_dumitrescu@REDACTED Fri Mar 7 13:38:38 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Fri, 07 Mar 2003 13:38:38 +0100 Subject: Concurrent beam? + Erlux Message-ID: >I have just started a project erlux that will run Erlang on top of the >Linux kernel (without user space - well you may start a user space process >if you like). Hey, that was _my_ dream! :-D But since my knowledge about hacking Linux kernels amounts to zero, I think it's safer to let you handle it. I didn't even succeeded upgrading from 2.4.18 to 2.4.20... :-) BTW, what happened with the parallel "Pekka-Tony" implementation? regards, Vlad _________________________________________________________________ Skaffa fler messengerkontakter - Vinn 10.000 i resecheckar! http://messenger.msn.se/promo From mickael.remond@REDACTED Fri Mar 7 14:18:41 2003 From: mickael.remond@REDACTED (Mickael Remond) Date: Fri, 7 Mar 2003 14:18:41 +0100 Subject: Erlux In-Reply-To: <3E687030.1080007@rogvall.com> References: <1047023175.26763@DNS02> <3E687030.1080007@rogvall.com> Message-ID: <1047043121.fa48d3e297c2f@webmail.spamcop.net> Tony Rogvall : > I have just started a project erlux that will run Erlang on top of the > Linux kernel (without user space - well you may start a user space > process if you like). This will be a patch to the kernel.org kernel > replacing the init process with the emulator loop, but not leaving the > kernel space. When running such a beast a SMP system will be useless > unless we can run the scheduler in multiple threads. Yuhm ! Sounds very good :-) I do not know a lot of thing about Linux Kernel development, but what are the implication ? Does this mean you are booting the system directly to the Erlang virtual machine ? How will this be related to the Erlang boot process ? Is your project hosted on Sourceforge ? It might be the right time to update the Erwolf project, an Erlang-Linux based distribution :-) -- Micka?l R?mond From jay@REDACTED Fri Mar 7 15:56:26 2003 From: jay@REDACTED (Jay Nelson) Date: Fri, 07 Mar 2003 06:56:26 -0800 Subject: Erlux Message-ID: <4.2.2.20030307065237.00d08c80@duomark.com> Tony Rogvall : > I have just started a project erlux that > will run Erlang on top of the Linux kernel Micka?l R?mond > It might be the right time to update the > Erwolf project, an Erlang-Linux based > distribution :-) Now we're talking! I want an all erlang embedded system-on-a-chip so I can have an erlang keyboard, PDA, server appliance, network attached storage, etc. Anywhere I go I can tap a node into my own network. Just stick my erlang-os USB key into any computer that is handy. jay From jay@REDACTED Fri Mar 7 15:59:43 2003 From: jay@REDACTED (Jay Nelson) Date: Fri, 07 Mar 2003 06:59:43 -0800 Subject: OO vs. CO In-Reply-To: References: <4.2.2.20030306200746.00ccf790@duomark.com> Message-ID: <4.2.2.20030307065641.00d0d200@duomark.com> > >erlang would make a great simulation language Ulf wrote: > > If I'm not mistaken, the ECOMP (Erlang Processor) exists in > > two fully simulated versions: one traditional VHDL > > simulator, and one Erlang-based simulator. The Erlang-based > > simulator was the easiest to implement and the easiest to > > work with. What is the "Erlang Processor"? When can I get one at Radio Shack? jay From tony@REDACTED Fri Mar 7 17:58:55 2003 From: tony@REDACTED (Tony Rogvall) Date: Fri, 07 Mar 2003 17:58:55 +0100 Subject: Concurrent beam? + Erlux References: <1047042030.29947@DNS02> Message-ID: <3E68CFCF.3000700@rogvall.com> Vlad Dumitrescu wrote: > >> I have just started a project erlux that will run Erlang on top of the >> Linux kernel (without user space - well you may start a user space >> process if you like). > > > Hey, that was _my_ dream! :-D > But since my knowledge about hacking Linux kernels amounts to zero, I > think it's safer to let you handle it. I didn't even succeeded upgrading > from 2.4.18 to 2.4.20... :-) > > BTW, what happened with the parallel "Pekka-Tony" implementation? > Down the drain, I guess, like many of the Ericsson projects :-) But how knows I may raise again ... /Tony From Sean.Hinde@REDACTED Fri Mar 7 18:57:55 2003 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Fri, 7 Mar 2003 17:57:55 -0000 Subject: Concurrent beam? + Erlux Message-ID: > > BTW, what happened with the parallel "Pekka-Tony" implementation? > > > > Down the drain, I guess, like many of the Ericsson projects :-) And the source? > But how knows I may raise again ... It would be truly awesome to have a linearly scalable SMP erlang node. Sean NOTICE AND DISCLAIMER: This email (including attachments) is confidential. If you have received this email in error please notify the sender immediately and delete this email from your system without copying or disseminating it or placing any reliance upon its contents. We cannot accept liability for any breaches of confidence arising through use of email. Any opinions expressed in this email (including attachments) are those of the author and do not necessarily reflect our opinions. We will not accept responsibility for any commitments made by our employees outside the scope of our business. We do not warrant the accuracy or completeness of such information. From vlad_dumitrescu@REDACTED Fri Mar 7 20:53:47 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Fri, 7 Mar 2003 20:53:47 +0100 Subject: Fw: Paradigms / OO vs CO [LONG] Message-ID: * Sorry if this gets to be a duplicate, the earlier copy seems to be stuck in cyberspace... > I think this is the germ of a good model, and that, appropriately > developed, it could fit between OO and CO. Decompose the problem into > objects which may or may not have agency (processes.) But the hard > part is making sure that objects can be treated the same by other > objects, regardless of whether they are dynamic or not. I'd like to > see something more transparent than "concurrent objects" or "Erlang > with object extensions" - either of which seems to be a short-sighted > approach where features with essentially incompatible > assumptions would > get slapped onto a pre-existing framework - rather than generating a > smooth & novel synthesis of the two. I have been thinking along those lines too, although not as much to the point. I am not sure what you mean by "something transparent" when handling dynamic and static objects (or things). IMHO, if one uses the usual pattern of wrapping gen_server calls in function calls, then just the same thing can be done for an inert object, like for example a record. We have a module that defines some static data, and also the way it is accessed. The first argument will be the data, instead of a Pid when processes are involved. If one agrees to use this first argument as an opaque reference, then it is as transparent as it can be, with no changes to the language or VM. However, I think it was you Chris that wanted the message passing to be more visible. Then transparency would mean that writing "Not_a_pid_or_atom ! Term" will have to translate into a regular function call (supposedly the Not_a_pid_or_atom data will have information about which module and so). Then again it will be transparent, with some changes. (However having a static_thing:start() might be confusing) Or am I missing something here? *** *** Is it a good thing to hide the difference, or is it important to know apart dynamic from static entities? I don't know, but my gut feeling is in favor of the latter. *** *** A note about static objects, one question would be how to handle extending their functionality, instead of a class hierarchy. I think this can be done easily, and without disturbing too much. One simple (simplistic?) way might be using delegation to another module. Syntactic sugar can make it as simple as -delegate(other_module, [fun1/3, fun2/0]). which will automatically create function definitions for fun1 and fun2. I think I can already hear voices saying "It's not good, you're spreading the functionality over several modules, and we want to be able to see what's happening by reading just one". To that I'd answer that in practice one-module-only functionality is quite rare for less-than-most-simple cases. There are implied dependencies in complex cases and they aren't visible in the code. Take Joe's femto-web-server for example: the three modules are indeed separate, but they are meant to work together (except for tcp_server which is generic). best regards, Vlad From etxuwig@REDACTED Fri Mar 7 09:49:22 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Fri, 7 Mar 2003 09:49:22 +0100 (MET) Subject: OO vs. CO In-Reply-To: <4.2.2.20030306200746.00ccf790@duomark.com> Message-ID: On Thu, 6 Mar 2003, Jay Nelson wrote: >erlang would make a great simulation language (even to the >level of doing something like a microprocessor emulator) >because you can model the time delays, feedback loops and >other interactions besides just the instances. If I'm not mistaken, the ECOMP (Erlang Processor) exists in two fully simulated versions: one traditional VHDL simulator, and one Erlang-based simulator. The Erlang-based simulator was the easiest to implement and the easiest to work with. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From etxuwig@REDACTED Fri Mar 7 09:53:01 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Fri, 7 Mar 2003 09:53:01 +0100 (MET) Subject: Concurrent beam? In-Reply-To: Message-ID: On 7 Mar 2003, Luke Gorrie wrote: >So what I wondered was, in Erlang style, might it be easier >to write a concurrent emulator rather than a parallel one, >with one thread per logically concurrent activity? > >For example, one thread executes erlang processes, one >garbage collects, one does I/O, etc? I believe it could be a big win for some projects (don't ask me for examples) just to be able to locate members of the thread pool onto a different (or several different) CPU. Separating application- and I/O processing is one of the most efficient ways of increasing performance in I/O-bound systems (and I believe many Erlang-based products are I/O-bound.) /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From bjorn@REDACTED Fri Mar 7 10:36:02 2003 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 07 Mar 2003 10:36:02 +0100 Subject: Concurrent beam? In-Reply-To: Luke Gorrie's message of "07 Mar 2003 08:22:54 +0100" References: Message-ID: Luke Gorrie writes: > So what I wondered was, in Erlang style, might it be easier to write a > concurrent emulator rather than a parallel one, with one thread per > logically concurrent activity? > > For example, one thread executes erlang processes, one garbage > collects, one does I/O, etc? It is already possible to use threads for file I/O. We have discussed introducing threads for garbage collection. We think that would be doable. /Bjorn -- Bj?rn Gustavsson Ericsson Utvecklings AB bjorn@REDACTED ?T2/UAB/F/P BOX 1505 +46 8 727 56 87 125 25 ?lvsj? From kent@REDACTED Fri Mar 7 23:24:51 2003 From: kent@REDACTED (Kent Boortz) Date: 07 Mar 2003 23:24:51 +0100 Subject: Compiling R9B-0 on SuSE Linux Linux 8.1 In-Reply-To: References: Message-ID: Roger Price writes: > In function `start_termcap': > /mnt/home/erlang/otp_src_R9B-0/erts/emulator/drivers/unix/ttsl_drv.c:599: > undefined reference to `tgetent' This is a configure bug. You need the development package for ncurses library. After that you need to remove config.cache and configure again, kent From rprice@REDACTED Sat Mar 8 00:14:31 2003 From: rprice@REDACTED (Roger Price) Date: Sat, 8 Mar 2003 00:14:31 +0100 (CET) Subject: Compiling R9B-0 on SuSE Linux Linux 8.1 In-Reply-To: Message-ID: On 5 Mar 2003, Kent Boortz wrote: > You could try to remove the "config.cache" file and rerun configure. Hello Kent, I removed "config.cache", and successfully ran ./configure. I then ran make clean; make and got the following message: gcc -o /mnt/home/erlang/otp_src_R9B-0/bin/i686-pc-linux-gnu/beam.instr \ -Wl,-export-dynamic /mnt/home/erlang/otp_src_R9B-0/erts/ obj.instr.beam/i686-pc-linux-gnu/erl_main.o ...... lots of .o's removed........ -lresolv -ldl -lm -L/mnt/home/erlang/otp_src_R9B-0/erts/obj/i686-pc-linux-gnu -lz /mnt/home/erlang/otp_src_R9B-0/erts/obj.instr.beam/i686-pc-linux-gnu/ttsl_drv.o: In function `start_termcap': /mnt/home/erlang/otp_src_R9B-0/erts/emulator/drivers/unix/ttsl_drv.c:599: undefined reference to `tgetent' ...... similar messages removed........ /mnt/home/erlang/otp_src_R9B-0/erts/obj.instr.beam/i686-pc-linux-gnu/ttsl_drv.o: In function `move_left': /mnt/home/erlang/otp_src_R9B-0/erts/emulator/drivers/unix/ttsl_drv.c:611: undefined reference to `tputs' ...... similar messages removed........ collect2: ld returned 1 exit status make[2]: *** [/mnt/home/erlang/otp_src_R9B-0/bin/i686-pc-linux-gnu/beam.instr] Error 1 make[2]: Leaving directory `/mnt/home/erlang/otp_src_R9B-0/erts/emulator' make[1]: *** [instr] Error 2 make[1]: Leaving directory `/mnt/home/erlang/otp_src_R9B-0/erts/emulator' make: *** [emulator.instr] Error 2 It looks as if function tgetent is called in ttsl.drv which has been compiled twice. The first time, in erts/obj, the linking was ok, but then in erts/obj.instr it failed. Any suggestions would be much appreciated. Best Regards, Roger ________________________________________________________________________ > If it still doesn't work, could you please send me the output from > the program > > #include > > int main() > { > printf("void * = %d\n", sizeof(void *)); > printf("size_t = %d\n",sizeof(size_t)); > printf("int = %d\n",sizeof(int)); > printf("long = %d\n",sizeof(long)); > exit(0); > } void * = 4 size_t = 4 int = 4 long = 4 From etxuwig@REDACTED Sat Mar 8 00:23:10 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Sat, 8 Mar 2003 00:23:10 +0100 (MET) Subject: OO vs. CO In-Reply-To: <4.2.2.20030307065641.00d0d200@duomark.com> Message-ID: On Fri, 7 Mar 2003, Jay Nelson wrote: >Ulf wrote: > > >> > If I'm not mistaken, the ECOMP (Erlang Processor) exists in >> > two fully simulated versions: one traditional VHDL >> > simulator, and one Erlang-based simulator. The Erlang-based >> > simulator was the easiest to implement and the easiest to >> > work with. > >What is the "Erlang Processor"? When can I get one at >Radio Shack? http://www.erlang.se/euc/00/processor.ppt Unfortunately, this project has not been moving much since then (some additional work was done, and very little now remains before one could start testing an FPGA version.) Perhaps it will spring to life again someday... (There seems to be reluctance towards releasing hardware designs as Open Source -- I don't know why.) /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From Vlad.Dumitrescu@REDACTED Fri Mar 7 11:54:17 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Fri, 7 Mar 2003 11:54:17 +0100 Subject: Paradigms / OO vs CO [LONG] Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D424@esemont203.gbg.edt.ericsson.se> > I think this is the germ of a good model, and that, appropriately > developed, it could fit between OO and CO. Decompose the problem into > objects which may or may not have agency (processes.) But the hard > part is making sure that objects can be treated the same by other > objects, regardless of whether they are dynamic or not. I'd like to > see something more transparent than "concurrent objects" or "Erlang > with object extensions" - either of which seems to be a short-sighted > approach where features with essentially incompatible > assumptions would > get slapped onto a pre-existing framework - rather than generating a > smooth & novel synthesis of the two. I have been thinking along those lines too, although not as much to the point. I am not sure what you mean by "something transparent" when handling dynamic and static objects (or things). IMHO, if one uses the usual pattern of wrapping gen_server calls in function calls, then just the same thing can be done for an inert object, like for example a record. We have a module that defines some static data, and also the way it is accessed. The first argument will be the data, instead of a Pid when processes are involved. If one agrees to use this first argument as an opaque reference, then it is as transparent as it can be, with no changes to the language or VM. However, I think it was you Chris that wanted the message passing to be more visible. Then transparency would mean that writing "Not_a_pid_or_atom ! Term" will have to translate into a regular function call (supposedly the Not_a_pid_or_atom data will have information about which module and so). Then again it will be transparent, with some changes. (However having a static_thing:start() might be confusing) Or am I missing something here? *** *** Is it a good thing to hide the difference, or is it important to know apart dynamic from static entities? I don't know, but my gut feeling is in favor of the latter. *** *** A note about static objects, one question would be how to handle extending their functionality, instead of a class hierarchy. I think this can be done easily, and without disturbing too much. One simple (simplistic?) way might be using delegation to another module. Syntactic sugar can make it as simple as -delegate(other_module, [fun1/3, fun2/0]). which will automatically create function definitions for fun1 and fun2. I think I can already hear voices saying "It's not good, you're spreading the functionality over several modules, and we want to be able to see what's happening by reading just one". To that I'd answer that in practice one-module-only functionality is quite rare for less-than-most-simple cases. There are implied dependencies in complex cases and they aren't visible in the code. Take Joe's femto-web-server for example: the three modules are indeed separate, but they are meant to work together (except for tcp_server which is generic). best regards, Vlad From etxuwig@REDACTED Fri Mar 7 12:55:09 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Fri, 7 Mar 2003 12:55:09 +0100 (MET) Subject: Concurrent beam? In-Reply-To: Message-ID: On 7 Mar 2003, Luke Gorrie wrote: >Ulf Wiger writes: > >> Separating application- and I/O processing is one of the >> most efficient ways of increasing performance in I/O-bound >> systems (and I believe many Erlang-based products are >> I/O-bound.) > >Can you elaborate? > >My picture of an I/O-bound system is that you've run out of >I/O resources, and have CPU to spare - so the application >processing shouldn't affect your performance? > >Perhaps there are different flavours of "I/O bound" - are >you I/O or CPU bound when your select()-loop or kernel is >overloading the CPU while performing I/O? You could for example offload the processor running erlang code by putting protocol stacks (e.g. TCP/IP, SCTP, SAAL, MTP3, etc) on a different CPU -- unless of course those protocols are implemented in Erlang... ;) /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From wwasilev@REDACTED Sat Mar 8 01:08:27 2003 From: wwasilev@REDACTED (Wwas) Date: Fri, 7 Mar 2003 19:08:27 -0500 Subject: OO vs. CO References: Message-ID: <002701c2e506$d8de3180$0a7ba8c0@was> ----- Original Message ----- From: "Ulf Wiger" To: "Jay Nelson" Cc: Sent: Friday, March 07, 2003 6:23 PM Subject: Re: OO vs. CO > On Fri, 7 Mar 2003, Jay Nelson wrote: > > >Ulf wrote: > > > > > >> > If I'm not mistaken, the ECOMP (Erlang Processor) exists in > >> > two fully simulated versions: one traditional VHDL > >> > simulator, and one Erlang-based simulator. The Erlang-based > >> > simulator was the easiest to implement and the easiest to > >> > work with. > > > >What is the "Erlang Processor"? When can I get one at > >Radio Shack? > > > http://www.erlang.se/euc/00/processor.ppt > > Unfortunately, this project has not been moving much since > then (some additional work was done, and very little now > remains before one could start testing an FPGA version.) > > Perhaps it will spring to life again someday... > (There seems to be reluctance towards releasing hardware > designs as Open Source -- I don't know why.) > > /Uffe > -- > Ulf Wiger, Senior Specialist, > / / / Architecture & Design of Carrier-Class Software > / / / Strategic Product & System Management > / / / Ericsson AB, Connectivity and Control Nodes http://www.opencores.com/ has a nice collection of open-source hardware designs. -was From vances@REDACTED Sat Mar 8 01:39:10 2003 From: vances@REDACTED (Vance Shipley) Date: Fri, 7 Mar 2003 19:39:10 -0500 Subject: Concurrent beam? In-Reply-To: References: Message-ID: <20030308003910.GK9996@frogman.motivity.ca> On Fri, Mar 07, 2003 at 12:55:09PM +0100, Ulf Wiger wrote: } } You could for example offload the processor running erlang } code by putting protocol stacks (e.g. TCP/IP, SCTP, SAAL, } MTP3, etc) on a different CPU -- unless of course those } protocols are implemented in Erlang... ;) Unless of course those protocols are implemented in Erlang and are running on their own Erlang node(s). :) -Vance From matthias@REDACTED Fri Mar 7 16:52:49 2003 From: matthias@REDACTED (Matthias Lang) Date: Fri, 7 Mar 2003 16:52:49 +0100 Subject: OO vs. CO In-Reply-To: <4.2.2.20030307065641.00d0d200@duomark.com> References: <4.2.2.20030306200746.00ccf790@duomark.com> <4.2.2.20030307065641.00d0d200@duomark.com> Message-ID: <15976.49233.177256.494264@antilipe.corelatus.se> Jay Nelson writes: > What is the "Erlang Processor"? When can I get one at > Radio Shack? See: http://www.erlang.se/euc/00/processor.ppt google has an HTML approximation, ask google about "ECOMP Erlang Processor" and click on the "show as HTML" link. Matthias From victoriak@REDACTED Sat Mar 8 00:17:15 2003 From: victoriak@REDACTED (Victoria Kulikou) Date: Fri, 7 Mar 2003 17:17:15 -0600 Subject: How to convert string representation of Date and Time to integer in Erlang and vice versa? Message-ID: <002b01c2e4ff$b11a9d20$10c3cf0a@victoriaXP> Is there a library in Erlang that provides conversion of Date and Time from string to integer and from integer to string? Sincerely, Victoria. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bjarne@REDACTED Sat Mar 8 10:04:15 2003 From: bjarne@REDACTED (=?iso-8859-1?Q?Bjarne_D=E4cker?=) Date: Sat, 08 Mar 2003 10:04:15 +0100 Subject: Paradigms / OO vs CO References: <20030306212327.44910.qmail@web20504.mail.yahoo.com> Message-ID: <002f01c2e551$b5065d00$092069d4@segeltorp> Hello > I think the important thing to point out is: OO itself is not a > problem. Becoming entrenched in and dogmatic about OO (or any > paradigm) is much more problematic. Engineers in all fields think in terms of the basic abstractions they have learnt, like resistors, capacitors, impedances etc or in software data types, functions, processes etc. The idea with OO seems to be to reduce everything down to just *one* abstraction, which would make software a very unique engieering science. I think that the reason for this is its attractions to management. To them software is just an amorphous mass so objects seem to create some form of order or structure. Bjarne From tony@REDACTED Sat Mar 8 14:30:24 2003 From: tony@REDACTED (Tony Rogvall) Date: Sat, 08 Mar 2003 14:30:24 +0100 Subject: Erlux References: <1047023175.26763@DNS02> <3E687030.1080007@rogvall.com> <1047044407.24742@DNS02> Message-ID: <3E69F070.1040904@rogvall.com> Mickael Remond wrote: > Tony Rogvall : > > >>I have just started a project erlux that will run Erlang on top of the >>Linux kernel (without user space - well you may start a user space >>process if you like). This will be a patch to the kernel.org kernel >>replacing the init process with the emulator loop, but not leaving the >>kernel space. When running such a beast a SMP system will be useless >>unless we can run the scheduler in multiple threads. > > > Yuhm ! > Sounds very good :-) > I do not know a lot of thing about Linux Kernel development, but what are the > implication ? > Does this mean you are booting the system directly to the Erlang virtual machine ? Yes. > How will this be related to the Erlang boot process ? Not much, the normal boot will read from /lib/modules/erlang/lib/... from the root file system. The emulator it self is compiled with the kernel. As soon as I/We get the basic system running (i.e prompt at the console) then it's time to start think about: - Bringing the network up (dhcp-client or manual config), addding routes... - Utility for mounting (auto?) filesystems. - Adding login, users and permissions (per process perhaps, "flame warning" :-) telnetd, sshd. - Port hotplug stuff for usb/pcmcia ... ... And plenty of nice utiltities, of course the linux hardware drivers remain as is, and some erlang driver for force loading them (insmod) is needed (could perhaps be the same as erl_ddll, when compiling loadable drivers one could compile them as kernel modules? Possibly the linux kernel should be patched with the kpoll (for inproved polling, yes this is the case even when running in kernel space, the kpoll will add "notifications" of io events) and some kind of file-changed-events-patch for monitoring files? > > Is your project hosted on Sourceforge ? > No, not yet. I am not sure how the structure should look like, I am just poking around at the moment. > It might be the right time to update the Erwolf project, an Erlang-Linux based > distribution :-) > /Tony From lennart.ohman@REDACTED Sat Mar 8 17:22:01 2003 From: lennart.ohman@REDACTED (=?ISO-8859-1?Q?Lennart_=D6hman?=) Date: Sat, 08 Mar 2003 17:22:01 +0100 Subject: How to convert string representation of Date and Time to integer in Erlang and vice versa? References: <002b01c2e4ff$b11a9d20$10c3cf0a@victoriaXP> Message-ID: <3E6A18A9.1070600@st.se> There is a library in stdlib (calendar) which deals with the more complicated issues related to date and time, like adding a certain number of days to a date and finding out what correct date the result will be etc etc. Date and time are usually represented as a tuples of three integers. And if date and time are given together, offen as a tuple containing two tuples, e.g {{2002,3,19},{23,50,59}}. Converting the basic data types integers and strings (list of ascii values) is done with the BIFs integer_to_list/1 and list_to_integer/1. See documentation on kernal application -> erlang module for details. With this it should be pretty simple to write the functionality you are looking for. /Lennart Victoria Kulikou wrote: > Is there a library in Erlang that provides conversion of Date and Time > from string to integer and from integer to string? > > > > Sincerely, > > Victoria. > ------------------------------------------------------------- Lennart Ohman phone : +46-8-587 623 27 Sjoland & Thyselius Telecom AB cellular: +46-70-552 6735 Sehlstedtsgatan 6 fax : +46-8-667 8230 SE-115 28 STOCKHOLM, SWEDEN email : lennart.ohman@REDACTED From ulf.wiger@REDACTED Sat Mar 8 17:30:57 2003 From: ulf.wiger@REDACTED (Wiger Ulf) Date: Sat, 8 Mar 2003 17:30:57 +0100 Subject: How to convert string representation of Date and Time to integer in Erlang and vice versa? References: <002b01c2e4ff$b11a9d20$10c3cf0a@victoriaXP> Message-ID: <000b01c2e590$1915b6e0$fd7a40d5@telia.com> There are some helper functions, but whether they do what you need is another question. That depends on your specific problem. See the documentation for httpd_util and calendar, for example. http://www.erlang.org/doc/r9b/lib/inets-3.0/doc/html/httpd_util.html http://www.erlang.org/doc/r9b/lib/stdlib-1.11.0/doc/html/calendar.html /Uffe Erlang (BEAM) emulator version 5.2 [threads:0] Eshell V5.2 (abort with ^G) 1> httpd_util:rfc1123_date(). "Sat, 08 Mar 2003 16:19:58 GMT" 2> httpd_util:rfc1123_date({{1888,05,17},{08,15,34}}). "Thu, 17 May 1888 08:15:34 GMT" 3> httpd_util:convert_request_date("Sun Nov 6 08:49:37 1994"). {{1994,11,6},{8,49,37}} 4> calendar:date_to_gregorian_days(date()). 731647 5> calendar:datetime_to_gregorian_seconds({date(),time()}). 63214363500 ----- Original Message ----- From: Victoria Kulikou To: erlang-questions@REDACTED Sent: den 8 mars 2003 00:17 Subject: How to convert string representation of Date and Time to integer in Erlang and vice versa? Is there a library in Erlang that provides conversion of Date and Time from string to integer and from integer to string? Sincerely, Victoria. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay@REDACTED Sat Mar 8 17:41:02 2003 From: jay@REDACTED (Jay Nelson) Date: Sat, 08 Mar 2003 08:41:02 -0800 Subject: Paradigms / OO vs CO Message-ID: <4.2.2.20030308080124.00d1c510@duomark.com> > I think this is the germ of a good model, and that, appropriately > developed, it could fit between OO and CO. Decompose the problem into > objects which may or may not have agency (processes.) But the hard > part is making sure that objects can be treated the same by other > objects, regardless of whether they are dynamic or not. I'd like to > see something more transparent than "concurrent objects" or "Erlang > with object extensions" - either of which seems to be a short-sighted > approach where features with essentially incompatible > assumptions would > get slapped onto a pre-existing framework - rather than generating a > smooth & novel synthesis of the two. I haven't used ocaml or any other "object-oriented" functional language so I may be way off here, but thinking about it raised some issues for me. Chris Okasaki talks about persistence in "Purely Functional Data Structures". Functional data structures are persistent, meaning that multiple versions can exist simultaneously, whereas imperative data structures are ephemeral meaning that only one version exists at a time. All the OO paradigms I've seen are designed around ephemeral objects, with the exception of versioning OO databases which are generally approximations since only the DB saved versions exist, not the temporary versions that were used to get to a save state. In OO you don't have to deal with outdated copies of objects, every instance is ephemeral. In erlang if you were to make some sort of static object, you would have to make sure that it is not modified in more than one process, or stashed inside some list, or else you have to serialize it in a server or store it in an ets table and always get a fresh copy (well, I guess the ets approach isn't even guaranteed to work). The safest thing is to have an object pool, with unique ids, that is managed as a separate process. When you need to deal with an object you ask for it from the pool by sending a message. You could try to lock it and use synchronization to allow modification and check-in of the new version, but you would run into deadlock issues. So instead you make each object a process -- even if it is a static object (if it truly never changes, you might not have to but...). And all is good. Use messaging to get objects to respond, rely on the message queue for serialization and the object pool for synchronization. Step back and look at it. You have implemented pure Smalltalk, everything is an object (process) and all work is accomplished via message sending, but it looks just like the erlang process register namespace. How do you do inheritance in this scheme? Inheritance in my mind grows up rather than down. Create a new process that delegates to other processes as Vlad said. It has a new interface, looks and acts like a new object, but relies on existing behaviour for implementation. It is not at all static, though. You could remove or inhibit delegation, kill the process and replace it with a different collection of behaviours; it appears more like a prototype instance that can be modified after it is created and can violate the strict inheritance. If you kill and create a new instance in an OO environment your choices are limited to the strictly defined parent class hierarchy; in erlang you can combine any modules or subsets of modules you want. What would you be trying to accomplish by using an OO approach? I think that at the fundamental roots of the language, erlang contains versioned data and OO is antithetical to that. Suppose you have an erlang textbox UI record structure in your internal model. Every time a character is added you create a new copy of the structure and throw away the old one. Undo would be very easy if you keep all the old versions of the data. The mixin approach of adding behaviour to display the data would work well (just call functions in a display textbox module or delegate to a single process), but the inheritance approach of statically structured OO wouldn't work as well because you would end up with multiple processes delegating to each other depending on the depth of the inheritance hierarchy just to draw the characters in the right place, and then you would have to communicate each version of the data when implementing undo, or else repeating the data versioning edit in all processes in the delegation chain whenever a character came in. I guess my thinking is to do two things: 1) push erlang in the erlang-y direction as far as I can to see what problems it is suitable for, and 2) state a problem and see how many approaches I can think of for implementing it in erlang. Use OO is not a problem, it is a solution. What problem are you trying to solve? Right now for UI I have taken the #2 step and am thinking hard about the #1 step. jay From Marc.Vanwoerkom@REDACTED Sat Mar 8 21:59:36 2003 From: Marc.Vanwoerkom@REDACTED (Marc Ernst Eddy van Woerkom) Date: Sat, 8 Mar 2003 21:59:36 +0100 (MET) Subject: Judy, a datastructure taylored for modern CPUs Message-ID: <200303082059.h28KxaR21623@bonsai.fernuni-hagen.de> Hi, reading about functional datastructures, below is something that is opposite in spirit. :) A datastructure that is designed to take advantage of the architecture of modern CPUs. BTW are associative arrays are used deep within the Erlang implementation? :) Regards, Marc ------- Start of forwarded message ------- http://judy.sourceforge.net/ Judy is an implementation of a sorted associative array in C. All reasonable associative array implementations have O(log N) insert and lookup complexity, but the constant factor for Judy is very much smaller than other widely used implementations (several times faster than STL's "map" and twice as fast as SGI's "hash_map", in my trivial benchmarks). The designer explains why here ; most of the improvement comes from awareness of the characteristics of modern memory architectures. _______________________________________________ sweetcode mailing list http://lists.ofb.net/listinfo/sweetcode http://sweetcode.org/ ------- End of forwarded message ------- From rprice@REDACTED Sun Mar 9 01:37:27 2003 From: rprice@REDACTED (Roger Price) Date: Sun, 9 Mar 2003 01:37:27 +0100 (CET) Subject: Compiling R9B-0 on SuSE Linux Linux 8.1 In-Reply-To: Message-ID: On 7 Mar 2003, Kent Boortz wrote: > This is a configure bug. You need the development package for > ncurses library. After that you need to remove config.cache and > configure again, Hello Kent, Done! I also loaded the openssl development package. I now have Erlang R9B-0 running on SuSE Linux 8.1 (kernel 2.4.19). Thanks for your help. I would like to suggest a change in Makefile.in, to make it easier to have several Erlang releases installed at the same time: Add DISTRIBUTION = R9B-0 Replace ERLANG_LIBDIR = $(INSTALL_PREFIX)@libdir@/erlang ERLANG_ILIBDIR = @libdir@/erlang by ERLANG_LIBDIR = $(INSTALL_PREFIX)@libdir@/erlang_$(DISTRIBUTION) ERLANG_ILIBDIR = @libdir@/erlang_$(DISTRIBUTION) Best Regards, Roger From mickael.remond@REDACTED Sun Mar 9 15:31:25 2003 From: mickael.remond@REDACTED (Mickael Remond) Date: Sun, 9 Mar 2003 15:31:25 +0100 Subject: EML has disappered in DIA Message-ID: <20030309143125.GA3776@erlang.dyndns.org> Hello, Does someone know what happened to the EML (Event Modeling Language) plugin in latest versions of DIA ? I launched it today and the plugin does not seem to be available (at least on my Mandrake Linux distribution 9.0) This is really annoying because I am using the EML formalism to document my applications. -- Micka?l R?mond From david.wallin@REDACTED Sun Mar 9 16:18:04 2003 From: david.wallin@REDACTED (david wallin) Date: Sun, 09 Mar 2003 15:18:04 +0000 Subject: Compiling R9B-0 on SuSE Linux Linux 8.1 In-Reply-To: Message-ID: <5347CA8A-5242-11D7-ACCC-000393536F4E@ul.ie> On Sunday, March 9, 2003, at 12:37 AM, Roger Price wrote: > > I would like to suggest a change in Makefile.in, to make it easier to > have several Erlang releases installed at the same time: > I use GNU Stow (www.gnu.org/software/stow) for that. There's also a xstow (xstow.sourceforge.net) if you want to perl free version. (I haven't tried xstow myself so I can't recommend it). cheers, --david. From svg@REDACTED Sat Mar 8 16:32:10 2003 From: svg@REDACTED (Vladimir Sekissov) Date: Sat, 08 Mar 2003 20:32:10 +0500 (YEKT) Subject: EML has disappered in DIA In-Reply-To: <20030309143125.GA3776@erlang.dyndns.org> References: <20030309143125.GA3776@erlang.dyndns.org> Message-ID: <20030308.203210.74744244.svg@surnet.ru> Good day, I'd stopped EML plugin development a year ago because nobody was interested here in EML and Dia team dropped it when Dia switched to new API in next release. If my decision was wrong I'm ready to continue work on it. Best Regards, Vladimir Sekissov mickael.remond> Does someone know what happened to the EML (Event Modeling Language) mickael.remond> plugin in latest versions of DIA ? mickael.remond> I launched it today and the plugin does not seem to be available (at mickael.remond> least on my Mandrake Linux distribution 9.0) mickael.remond> mickael.remond> This is really annoying because I am using the EML formalism to document mickael.remond> my applications. mickael.remond> mickael.remond> -- mickael.remond> Micka?l R?mond From david.wallin@REDACTED Sun Mar 9 19:10:26 2003 From: david.wallin@REDACTED (david wallin) Date: Sun, 09 Mar 2003 18:10:26 +0000 Subject: Erlang & Robotics Message-ID: <671D51F0-525A-11D7-ACCC-000393536F4E@ul.ie> I've been interested in doing something with robotics, and would hate to give up on Erlang because of that. I know there's been others who has shared this interest in the past and hoped to make the Erlang runtime small enough for the processors (+memory) found in these devices (in the affordable segment of the market. Think Lego Mindstorms). Did anyone succeed in doing this ? Could Erlang be 'pruned' of some of it's features to make this happen (Erlang Lite?), and in that case, what would that be ? Another fundamentally different approach would be "Erlang Mindstorms": A programmable brick using the almost existing Erlang processor combined with Bluetooth. This would be extremely exciting stuff, unfortunately, I fear this won't be realized. (Feel free to prove me wrong). cheers, --david. From vances@REDACTED Sun Mar 9 19:17:42 2003 From: vances@REDACTED (Vance Shipley) Date: Sun, 9 Mar 2003 13:17:42 -0500 Subject: EML has disappered in DIA In-Reply-To: <20030308.203210.74744244.svg@surnet.ru> References: <20030309143125.GA3776@erlang.dyndns.org> <20030308.203210.74744244.svg@surnet.ru> Message-ID: <20030309181742.GE9996@frogman.motivity.ca> I was asking about both EML and the plugin for Dia exactly one year ago but no one had anything to say about either. http://www.erlang.org/ml-archive/erlang-questions/200202/msg00058.html I wrote to you as well but received no response. The Dia maintainers actually pulled the EML plugin because they couldn't reach you to get a statement on Copyright. It does also need to be rewritten to be put into the new franework. I was a few months ago going to write a new one as I would very much like to see it working. I gotted bogged down in porting the new Dia in my environment and the project stalled. In any event I'd really like to see this. I like the EML and find it useful. -Vance From etxuwig@REDACTED Sun Mar 9 19:53:43 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Sun, 9 Mar 2003 19:53:43 +0100 (MET) Subject: Erlang & Robotics In-Reply-To: <671D51F0-525A-11D7-ACCC-000393536F4E@ul.ie> Message-ID: On Sun, 9 Mar 2003, david wallin wrote: >I've been interested in doing something with robotics, and >would hate to give up on Erlang because of that. I know >there's been others who has shared this interest in the >past and hoped to make the Erlang runtime small enough for >the processors (+memory) found in these devices (in the >affordable segment of the market. Think Lego Mindstorms). I've figured that the Erlang programming model would be ideal for robotics programming. >Did anyone succeed in doing this ? Could Erlang be 'pruned' >of some of it's features to make this happen (Erlang >Lite?), and in that case, what would that be ? > >Another fundamentally different approach would be "Erlang >Mindstorms": A programmable brick using the almost >existing Erlang processor combined with Bluetooth. This >would be extremely exciting stuff, unfortunately, I fear >this won't be realized. (Feel free to prove me wrong). The Erlang Processor was certainly aimed at environments similar to this: where you'd need a dirt cheap, low-power(*) chip with a very lightweight "device OS" (like the Erlang kernel). Another plus should be the garbage collection design, which relied on sub-instructions to increment/decrement references, and where the actual release of garbage didn't steal CPU cycles from the application (i.e. no GC freezes). /Uffe (*) The Erlang Process used about 30x fewer machine instructions than BEAM to run an average Erlang program. This can be used either to speed up execution, or to build simpler (=cheaper) chips. -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From spearce@REDACTED Mon Mar 10 07:48:52 2003 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 10 Mar 2003 01:48:52 -0500 Subject: ets:select_count/2 undef? Message-ID: <20030310064852.GA21274@spearce.org> I'm getting this: 58> ets:select(aui_data, [{{aui_datum,pid(0,108,0),'_','_'},[],['$_']}]). [] 57> ets:select_count(aui_data, [{{aui_datum,pid(0,108,0),'_','_'},[],['$_']}]). ** exited: {undef,[{ets,select_count, [aui_data,[{{aui_datum,<0.108.0>,'_','_'},[],['$_']}]]}, {erl_eval,expr,3}, {erl_eval,exprs,4}, {shell,eval_loop,2}]} ** The table aui_data exists, but the function ets:select_count/2 doesn't? This is R9B-0. -- Shawn. He is now rising from affluence to poverty. -- Mark Twain From francesco@REDACTED Mon Mar 10 08:54:00 2003 From: francesco@REDACTED (Francesco Cesarini (Erlang Consulting)) Date: Mon, 10 Mar 2003 07:54:00 +0000 Subject: Erlang & Robotics In-Reply-To: References: Message-ID: <3E6C4498.6050209@erlang-consulting.com> http://www.robotics.com/arobot/andy.html was built as a Master's thesis project using Erlang and a Lego robot. I never got my hands on the thesis, as the page containing it was taken down. But from the above page, you find out that Andy Allen used a 486SLC2-50 with 16 Meg of Ram running off of batteries with the help of DC/DC converters. Real Time Linux, Erlang, and Improv comprise the software, along with low level parallel port drivers. The 486 communicates with the ARobot's Basic Stamp through an RS-232 connection. The 486 is simply a vision coprocessor, subordinate to the Basic Stamp. This basic system of an x86 on top can be used for many other tasks as well. Cheers, Francesco -- http://www.erlang-consulting.com Ulf Wiger wrote: >On Sun, 9 Mar 2003, david wallin wrote: > > > >>I've been interested in doing something with robotics, and >>would hate to give up on Erlang because of that. I know >>there's been others who has shared this interest in the >>past and hoped to make the Erlang runtime small enough for >>the processors (+memory) found in these devices (in the >>affordable segment of the market. Think Lego Mindstorms). >> >> > >I've figured that the Erlang programming model would be >ideal for robotics programming. > > > >>Did anyone succeed in doing this ? Could Erlang be 'pruned' >>of some of it's features to make this happen (Erlang >>Lite?), and in that case, what would that be ? >> >>Another fundamentally different approach would be "Erlang >>Mindstorms": A programmable brick using the almost >>existing Erlang processor combined with Bluetooth. This >>would be extremely exciting stuff, unfortunately, I fear >>this won't be realized. (Feel free to prove me wrong). >> >> > >The Erlang Processor was certainly aimed at environments >similar to this: where you'd need a dirt cheap, low-power(*) >chip with a very lightweight "device OS" (like the Erlang >kernel). Another plus should be the garbage collection >design, which relied on sub-instructions to >increment/decrement references, and where the actual release >of garbage didn't steal CPU cycles from the application >(i.e. no GC freezes). > >/Uffe > >(*) The Erlang Process used about 30x fewer machine >instructions than BEAM to run an average Erlang program. >This can be used either to speed up execution, or to build >simpler (=cheaper) chips. > > From eleberg@REDACTED Mon Mar 10 09:18:13 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Mon, 10 Mar 2003 09:18:13 +0100 (MET) Subject: Concurrent beam? + Erlux Message-ID: <200303100818.h2A8IDH21400@cbe.ericsson.se> > X-Original-Recipient: erlang-questions@REDACTED > Date: Fri, 07 Mar 2003 11:10:56 +0100 > From: Tony Rogvall ...deleted > I have just started a project erlux that will run Erlang on top of the > Linux kernel (without user space - well you may start a user space is this easier/better than using OSKit? (http://www.cs.utah.edu/flux/oskit/). bengt From eleberg@REDACTED Mon Mar 10 09:48:09 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Mon, 10 Mar 2003 09:48:09 +0100 (MET) Subject: Erlux Message-ID: <200303100848.h2A8m9H23508@cbe.ericsson.se> > X-Original-Recipient: erlang-questions@REDACTED > Date: Sat, 08 Mar 2003 14:30:24 +0100 > From: Tony Rogvall ...deleted > - Adding login, users and permissions (per process perhaps, "flame > warning" :-) telnetd, sshd. what is wrong with a per process namespace? plan9 has had it for 15 years. (there is also a unix clustering software that has it, but i have not been able to remember where i saw it). bengt From tony@REDACTED Mon Mar 10 10:14:13 2003 From: tony@REDACTED (Tony Rogvall) Date: Mon, 10 Mar 2003 10:14:13 +0100 Subject: Concurrent beam? + Erlux References: <1047285035.18872@DNS02> Message-ID: <3E6C5765.8050801@rogvall.com> Bengt Kleberg wrote: > >>X-Original-Recipient: erlang-questions@REDACTED >>Date: Fri, 07 Mar 2003 11:10:56 +0100 >>From: Tony Rogvall > > ....deleted > > >>I have just started a project erlux that will run Erlang on top of the >>Linux kernel (without user space - well you may start a user space > > > is this easier/better than using OSKit? (http://www.cs.utah.edu/flux/oskit/). > > I dont know. But linux has been around for some time now, of course the internal API's are chaninging over time. But to spend a lot time looking into different ways of doing it is an academic issue. To get something done, you actually have to DO IT!!!! Regards /Tony From Vlad.Dumitrescu@REDACTED Mon Mar 10 11:02:53 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Mon, 10 Mar 2003 11:02:53 +0100 Subject: Erlang & Robotics Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D429@esemont203.gbg.edt.ericsson.se> > I've been interested in doing something with robotics, and would hate > to give up on Erlang because of that. I know there's been others who > has shared this interest in the past and hoped to make the Erlang > runtime small enough for the processors (+memory) found in these > devices (in the affordable segment of the market. Think Lego > Mindstorms). > Did anyone succeed in doing this ? Could Erlang be 'pruned' > of some of > it's features to make this happen (Erlang Lite?), and in that case, > what would that be ? Hi, I have been looking into this, but that's about it. From what I could see, this would require an almost complete rewrite of the runtime (if I remember correctly the old pointer tagging scheme allowed only 4k of RAM to be used with an 8 bit processor, which is a bit low :-) The new tagging scheme is much better but I have no figures. Another issue is that the Erlang runtime should be part of the kernel. BrickOS might be used as a base for this: http://brickos.sourceforge.net/. My first idea was to try to run Erlang on a regular PC and let it communicate with the Mindstorms brick via the serial interface. Two years ago there were a lot of problems with it, and I couldn't make it work, but since then things have improved a lot. best regards, Vlad From spearce@REDACTED Mon Mar 10 11:14:34 2003 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 10 Mar 2003 05:14:34 -0500 Subject: Unaccounted memory usage... Message-ID: <20030310101434.GB21274@spearce.org> Can someone help me explain this a little? My beam process is currently at a little over 200 MB resident heap size. I have approx 1700 processes running in the node. Only 19 are registered. This is R9B-0, 32 bit (Linux). I'm not running distributed, so no epmd, no connected nodes. i() in the shell reports I'm using 2430190 words heap, 19828 words stack, for a total of 2,450,018 = 9.57 MB. ets:i() reports 16 tables are allocated. Most of them aren't interesting, as they are the standard erts/OTP tables, and aren't of an obscene size. The 7 application tables report a total memory usage of 234,183 words = 915 KB. Thus I figure my total application memory usage at about 11 MB. Yet I have a 200 MB heap size. 41> statistics(garbage_collection). {152876,298095162,0} 42> (298095162*4)/(1024*1024). 1137.14 Clearly with only 200 MB of actual process heap, we don't have 1.1 GB currently free, but have made 1.1 GB of junk overall. That's fine, but where is my ~180 MB? 43> erlang:system_info(allocated_areas). [{definite_alloc,2097152,1529816}, {static,402553}, {atom_space,65544,36019}, {binary,2776510}, {atom_table,25317}, {module_table,824}, {export_table,14864}, {register_table,144}, {loaded_code,1100740}, {process_desc,516800,503120}, {table_desc,1520,1444}, {link_desc,240480,236520}, {atom_desc,93120,93096}, {export_desc,98880,98784}, {module_desc,4000,3320}, {preg_desc,400,380}, {mesg_desc,56400,0}, {plist_desc,0,0}, {fixed_deletion_desc,0,0}, {bif_timer_rec_desc,1280,64}, {fun_desc,14560,13608}] Manual says these are in bytes. I don't see my 180 MB here. :( How can I get the amount of memory that is free within erts, but that can't be reclaimed by the OS? I can only come up with two explanations for the widely different memory information: - My handful of transient processes that were created used more memory than the others, and pushed the heap up. (The 1700 is what is left after about 850 transients were created and shutdown.) - The number of monitors I have in 1 process (~ 850) is eating a large amount of memory. Or I'm leaking monitors at some point. Does one have to demonitor a monitor if we get a 'DOWN' message noting the process has exited? I'm putting money on the first one being the problem. -- Shawn. FORTUNE PROVIDES QUESTIONS FOR THE GREAT ANSWERS: #4 A: Go west, young man, go west! Q: What do wabbits do when they get tiwed of wunning awound? From Vlad.Dumitrescu@REDACTED Mon Mar 10 11:34:04 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Mon, 10 Mar 2003 11:34:04 +0100 Subject: Extending functionality Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D42A@esemont203.gbg.edt.ericsson.se> Good morning everyone, I sat and thought about which way is best for extending existing functionality in Erlang, without touching the original source code. There are two issues (not sure if they are very different): extending a module's functionality and extending a process' functionality. An example might be best: let's say I have found a way to improve the "strings" module, only some parts of it. Let's also suppose the source for "strings" isn't available. I would like to write a module called "better-strings" where my improvements are implemented, and what's unchanged should be directed to the regular "strings". This is because I don't want to be forced to remember which function is in which module when working with the strings. Later on, someone else might improve more stuff, but maybe some is from "strings" and some is from "better-strings" - and would like to write "even-better-strings" to transparently extend "strings" and "better-strings". A similar question can be applied to processes: I have a server and I'd like to add some functionality without recompiling it. The change might involve handling new requests and/or modifying existing request handling. It should work with plain servers and also with gen_servers. One example is instrumenting the server so that it logs every request made. There is also a third case: extending a function with more clauses, even if this function is defined in another module: generic functions. These I'm not sure if they are really useful alone, I took them here just for completness. Is this a real problem, or am I just being too academic? How are these issues handled today? Any thoughts stirred by my questions will be appreciated. I don't see any way that doesn't involve either writing plenty of functions that delegate to the other module(s) [with a lot of redundancy and error-prone], or changing the runtime and compiler in a non-trivial way. These extensions might also come in two different flavors: static (affecting the source code) and dynamic (run-time instrumentation), which will probably need to be handled in vey different ways. best regards, Vlad From tony@REDACTED Mon Mar 10 11:49:52 2003 From: tony@REDACTED (Tony Rogvall) Date: Mon, 10 Mar 2003 11:49:52 +0100 Subject: Erlux References: <1047286791.11442@DNS02> Message-ID: <3E6C6DD0.10701@rogvall.com> Bengt Kleberg wrote: > >>X-Original-Recipient: erlang-questions@REDACTED >>Date: Sat, 08 Mar 2003 14:30:24 +0100 >>From: Tony Rogvall > > ....deleted > > >>- Adding login, users and permissions (per process perhaps, "flame >>warning" :-) telnetd, sshd. > > > what is wrong with a per process namespace? plan9 has had it for 15 > years. (there is also a unix clustering software that has it, but i > have not been able to remember where i saw it). > I do not understand what you mean, could please explain. What namespace? unixprocess? /Tony From eleberg@REDACTED Mon Mar 10 12:20:35 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Mon, 10 Mar 2003 12:20:35 +0100 (MET) Subject: Erlux Message-ID: <200303101120.h2ABKZH08137@cbe.ericsson.se> > X-Original-Recipient: eleberg@REDACTED > Date: Mon, 10 Mar 2003 11:49:52 +0100 > From: Tony Rogvall ...deleted > I do not understand what you mean, could please explain. What namespace? > unixprocess? yes. operating system processes. the idea is to let each process have its own ''namespace'', which is its own view of everything that can be interface via the file system. see http://plan9.bell-labs.com/sys/doc/names.html . i mistakenly thought you where talking about this kind of possibilities for erlux (since there is a limited version of this concept as of linux 2.5). sorry for the confusion. please accept my apology. bengt From thomasl_erlang@REDACTED Mon Mar 10 13:02:31 2003 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Mon, 10 Mar 2003 04:02:31 -0800 (PST) Subject: Concurrent beam? + Erlux In-Reply-To: <200303100818.h2A8IDH21400@cbe.ericsson.se> Message-ID: <20030310120231.30233.qmail@web13307.mail.yahoo.com> --- Bengt Kleberg wrote: > > > X-Original-Recipient: erlang-questions@REDACTED > > Date: Fri, 07 Mar 2003 11:10:56 +0100 > > From: Tony Rogvall > ...deleted > > > I have just started a project erlux that will run > Erlang on top of the > > Linux kernel (without user space - well you may > start a user space > > is this easier/better than using OSKit? > (http://www.cs.utah.edu/flux/oskit/). My impression from playing with the OSkit is that it works fairly well; you can at least build and boot example kernels very quickly. It also seems to work well in practice: there are a handful of research OS:es of varying complexity built w. OSkit. The OSkit uses GPL v2 as a license. The impact of that depends on what you're going to do, I guess (from their summary, it seems you have to make the files linked with the OSkit open source). Likely not an issue? The Linux advantage is that the groundwork is done and the architecture is already there (and might be familiar). Probably "future proof" due to the user community. The code license is not an issue, AFAIK. (But then I'm not a lawyer :-) Best, Thomas __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - forms, calculators, tips, more http://taxes.yahoo.com/ From vances@REDACTED Mon Mar 10 16:20:28 2003 From: vances@REDACTED (Vance Shipley) Date: Mon, 10 Mar 2003 10:20:28 -0500 Subject: Erlang vs Linux In-Reply-To: <20030226180602.GB76188@frogman.motivity.ca> Message-ID: <20030310152028.GI9996@frogman.motivity.ca> At the risk of opening a dead and very off topic thread ... It seems SCO is now suing IBM for $1 billion because they may have let Linux become contanimated with SYSV source licensed to them for AIX by SCO. http://www.informationweek.com/story/IWK20030307S0005 This would be an interesting turn of events. Linux becoming mired down in the same legal quagmire that stymied *BSD adoption and gave it the headstart. Maybe SCO have finally found a way to be profitable. :) -Vance From matthias@REDACTED Mon Mar 10 17:46:43 2003 From: matthias@REDACTED (Matthias Lang) Date: Mon, 10 Mar 2003 17:46:43 +0100 Subject: Unaccounted memory usage... In-Reply-To: <20030310101434.GB21274@spearce.org> References: <20030310101434.GB21274@spearce.org> Message-ID: <15980.49523.682650.103902@antilipe.corelatus.se> Shawn Pearce writes: > Can someone help me explain this a little? My beam process is > currently at a little over 200 MB resident heap size. Nice to see a real problem concerning code which actually exists. Just for a change. It's reasonably easy to see where CPU time is going in Erlang, but sometimes it's frustratingly difficult to figure out where the memory is going. Gut feeling tends to be misleading. Something which often helps is using an instrumented emulator (start it with -instr) to figure out where memory is going. Take a look at http://www.erlang.org/doc/r9b/lib/tools-2.1/doc/html/instrument.html Don't be afraid to hack instrument.erl to help you figure out what's going on, e.g. you may want to sum memory areas by type. Here's a hack I needed to diagnose my previous problem---memory fragmentation. It gives you a list you can sum instead of just printing out holes: holes([]) -> ok; holes([E | L]) -> holes(E, L). holes(E1, []) -> []; holes(E1, [E2 | Rest]) -> {_,P1,S1,_} = E1, {_,P2,S2,_} = E2, End = P1+S1, Hole = P2 - (End + ?INFO_SIZE), if Hole =< 7 -> holes(E2, Rest); true -> [Hole|holes(E2, Rest)] end. Matt From david.wallin@REDACTED Mon Mar 10 19:48:58 2003 From: david.wallin@REDACTED (david wallin) Date: Mon, 10 Mar 2003 18:48:58 +0000 Subject: ECOMP (was:Re: OO vs. CO) In-Reply-To: Message-ID: On Friday, March 7, 2003, at 11:23 PM, Ulf Wiger wrote: > > > http://www.erlang.se/euc/00/processor.ppt > > Unfortunately, this project has not been moving much since > then (some additional work was done, and very little now > remains before one could start testing an FPGA version.) > Is FPGA hardware ? > Perhaps it will spring to life again someday... Where's the petition to sign ? :-) > (There seems to be reluctance towards releasing hardware > designs as Open Source -- I don't know why.) > I think partly this is because the benefit isn't nearly as obvious as with software. One of the key benefits with open source is that more people gets involved and find bugs, I don't know, maybe there is a huge number of hardware guys who likes to simulate hardware designs, but in the end you still need someone to produce the actual thing. Maybe one day when we can all make our chips with the printer open-sourced hardware designs might become interesting. Just out of curiosity, I know practically nothing about this, but suppose the design was open-sourced, what would it take to get someone to build it ? What quantities of the chip need to be produced to make it feasible? > /Uffe > -- > Ulf Wiger, Senior Specialist, > / / / Architecture & Design of Carrier-Class Software > / / / Strategic Product & System Management > / / / Ericsson AB, Connectivity and Control Nodes > --david. From vances@REDACTED Mon Mar 10 20:43:47 2003 From: vances@REDACTED (Vance Shipley) Date: Mon, 10 Mar 2003 14:43:47 -0500 Subject: ECOMP (was:Re: OO vs. CO) In-Reply-To: References: Message-ID: <20030310194347.GE20416@frogman.motivity.ca> I know nothing of such things but I am left wondering after someone commented on the list about the possibility of using the Crusoe chip to make an Erlang processor. Would that "just require software"? -Vance From chris_pressey@REDACTED Mon Mar 10 21:22:33 2003 From: chris_pressey@REDACTED (Chris Pressey) Date: Mon, 10 Mar 2003 15:22:33 -0500 (EST) Subject: Process Wasting (was: OO vs CO) Message-ID: <20030310202233.44974.qmail@web20501.mail.yahoo.com> (right now I'm having to resort to webmail, so, apologies if the formatting on this message turns out a bit munged) Vlad Dumitrescu wrote: > > [me] > > I think this is the germ of a good model, and that, appropriately > > developed, it could fit between OO and CO. Decompose the problem into > > objects which may or may not have agency (processes.) But the hard > > part is making sure that objects can be treated the same by other > > objects, regardless of whether they are dynamic or not. I'd like to > > see something more transparent than "concurrent objects" or "Erlang > > with object extensions" - either of which seems to be a short-sighted > > approach where features with essentially incompatible > > assumptions would > > get slapped onto a pre-existing framework - rather than generating a > > smooth & novel synthesis of the two. > > I have been thinking along those lines too, although not as much to the > point. I am not sure what you mean by "something transparent" when handling > dynamic and static objects (or things). Neither do I. Damn. Sorry. I typed that too quickly. Actually, I've found that term "transparent" to be one of the more misused, so I'm REALLY kicking myself for that one. In this industry people have a tendency to say "transparent" when they mean "seamless" (which is really semantically closer to "opaque"...) So I think I meant seamless there. So, no, you're not missing anything. > [...] > *** *** > Is it a good thing to hide the difference, or is it important to know apart > dynamic from static entities? I don't know, but my gut feeling is in favor > of the latter. > *** *** It's a double-edged sword. You lose some, you gain some... Actually, something I meant to address, but didn't really, was that an object can go from static to dynamic back to static (like the forklift, when you turn it on or off, or the candles, when they're lit then extinguished.) I'd hate to have to remodel/rewrite something, after deciding that it should be the other. Of course, if you take a longer view, I guess the problem disappears; an object that goes from static to dynamic, is in the overall analysis - dynamic. In other words - it's easier to simulate object-ness with a process, than it is to simulate process-ness with an object. If you want an "inert process" with no dynamic behaviour at all, you can just say listen() -> receive _ -> listen() end. I guess my real contention is with the fact that this is a waste - even if an Erlang node *can* happily handle 7000 concurrent processes - why push it that far, if 60% of those processes aren't really doing squat? That's probably my own hang-up at this point, though - wasting processes is probably justifiable, if it makes the model more cohesive - which it does, here. > A note about static objects, one question would be how to handle extending > their functionality, instead of a class hierarchy. I think this can be done > easily, and without disturbing too much. One simple (simplistic?) way might > be using delegation to another module. Syntactic sugar can make it as simple > as > -delegate(other_module, [fun1/3, fun2/0]). > which will automatically create function definitions for fun1 and fun2. Delegate, inherit, override, whatever you want to call it, I think it'd be a good thing to have. Just to stress it - I imagine it would be syntactic sugar for default(Function, Args) -> apply(other_module, Function, Args). Where default/2 is a function that is called in a module, when an undefined function is specified to be called in that module, instead of raising an exception. Again, not very original perhaps - many of the ideas for things that I think would be good in Erlang, show up in Perl in some form - but flexible and very much in tune with the "you have complete control over error handling" tenet. Mainly I like this because it seems to address the biggest process waste that I can forsee: specialization. It hardly seems worth it to use processes for "front-ends" which simply redirect "traffic" - when we can do that in a much simpler way. Seems to have something to do with what I said before, how a process which is just translating CR's to LF's isn't very interesting (therefore, why is it a process?) - but one which accepts arbitrary chunks of text and repackages it into lines, it's very easy to see how making it a process increases clarity and organization, well, phenomenally really... > I think I can already hear voices saying "It's not good, you're spreading > the functionality over several modules, and we want to be able to see what's > happening by reading just one". But we also want modules to be small, and "self-contained"... there's only so much you can expect. Modules are modular (duh? :) so they'll always have external references. > To that I'd answer that in practice > one-module-only functionality is quite rare for less-than-most-simple cases. > There are implied dependencies in complex cases and they aren't visible in > the code. Take Joe's femto-web-server for example: the three modules are > indeed separate, but they are meant to work together (except for tcp_server > which is generic). Exactly. > best regards, > Vlad -Chris ______________________________________________________________________ Post your free ad now! http://personals.yahoo.ca From chris_pressey@REDACTED Mon Mar 10 21:49:47 2003 From: chris_pressey@REDACTED (Chris Pressey) Date: Mon, 10 Mar 2003 15:49:47 -0500 (EST) Subject: OO (was: OO vs CO) Message-ID: <20030310204947.91466.qmail@web20512.mail.yahoo.com> Bjarne D?cker wrote: > Hello Hello! > > I think the important thing to point out is: OO itself is not a > > problem. Becoming entrenched in and dogmatic about OO (or any > > paradigm) is much more problematic. > > Engineers in all fields think in terms > of the basic abstractions they have > learnt, like resistors, capacitors, > impedances etc or in software data > types, functions, processes etc. > > The idea with OO seems to be to > reduce everything down to just *one* > abstraction, which would make software > a very unique engieering science. > > I think that the reason for this is its > attractions to management. To them > software is just an amorphous mass > so objects seem to create some form > of order or structure. I agree, this is part of the desire for objects. (Although - perhaps this goes without saying - I don't think it's best idea. It shocks me how quickly it can complexify a problem. If you try to reduce everything to a single abstraction, then that abstraction is almost surely going to be more powerful than useful - you start with objects, soon you have to deal with relationships, properties, methods, singletons, homomorphisms, and who-knows-what-else...) I think the other part of the desire for objects is that, to most people, an object is something physical that you can see and hold (like a book or a spoon) unlike a function or a rule or a process. I think this is a very comforting idea to managers, even if it turns out to be an illusion when applied to software engineering. > Bjarne -Chris ______________________________________________________________________ Post your free ad now! http://personals.yahoo.ca From jabba@REDACTED Mon Mar 10 22:01:16 2003 From: jabba@REDACTED (Jani Launonen) Date: Mon, 10 Mar 2003 23:01:16 +0200 (EET) Subject: ECOMP (was:Re: OO vs. CO) In-Reply-To: <20030310194347.GE20416@frogman.motivity.ca> References: <20030310194347.GE20416@frogman.motivity.ca> Message-ID: On Mon, 10 Mar 2003, Vance Shipley wrote: > >I know nothing of such things but I am left wondering after >someone commented on the list about the possibility of using the >Crusoe chip to make an Erlang processor. Would that "just require >software"? > > -Vance This is something that I've been thinking too. The rumour says that it would make one great JVM on top of the Crusoe, so why not EVM too? :) I just wonder, if Transmeta would be interest in licencing it's technology or Ericsson interest in developing such technology. Anyways, it would be rather interesting if Crusoe could run X86 and Erlang simultaneusly on VLIW core. Cheers, -+-+-+- Jani Launonen Student. . . . . . . . . .University of Oulu, Dept. of EE Assistant Researcher . . .Apricot Project "Computing is a field which has one of the shortest collective memories of any engineering or scientific discipline." - Marty Fouts, comp.distributed From matthias@REDACTED Mon Mar 10 22:27:01 2003 From: matthias@REDACTED (Matthias Lang) Date: Mon, 10 Mar 2003 22:27:01 +0100 Subject: ECOMP (was:Re: OO vs. CO) In-Reply-To: <20030310194347.GE20416@frogman.motivity.ca> References: <20030310194347.GE20416@frogman.motivity.ca> Message-ID: <15981.805.944193.699810@antilipe.corelatus.se> David Wallin writes: > > then (some additional work was done, and very little now > > remains before one could start testing an FPGA version.) > Is FPGA hardware ? Is a Lisp program data? ;-) An ASIC is a bunch of gates which you lay out at a chip fab by using lithographic techniques. Its function is set in stone. An FPGA is a bunch of gates which you can "wire up" any way you like by programming it. Roughly, you write a file like this: Pin A1 is connected to NAND-gate 7, input 1 NAND-gate 7's output is connected to flipflop 9 Flipflip 9 is connected to .... and use it to program the FPGA. Once programmed, the FPGA behaves exactly like an ASIC. When you pull the power plug, the FPGA forgets what it was programmed as, so next time you can program it as something else. It can be an ECOMP one minute and a Java CPU the next. FPGAs can do everything ASICs can. In theory. In practice, FPGAs are slower, use more power and have lower gate density than ASICs. ECOMP probably just fits in a large-ish FPGA, which means it would sit in a small corner of an ASIC. That last part is important. If your product contains custom ASICs, then maybe one of the ASICs has a 'spare' corner and a bunch of spare pins. Then you could put ECOMP there "for free". > What quantities of the chip need to be produced to make it feasible? There are many ways to turn a design into hardware and they're all different tradeoffs between speed, cost-per-gate, cost-per-device, ... _Very_ roughly, an FPGA costs maybe $100 per device and you can probably get a development board with a compiler for not much more. An ASIC costs maybe $5 per device and getting the manufacturing set up costs perhaps $200k. Matt From chris_pressey@REDACTED Tue Mar 11 00:08:29 2003 From: chris_pressey@REDACTED (Chris Pressey) Date: Mon, 10 Mar 2003 18:08:29 -0500 (EST) Subject: OO vs Erlang Message-ID: <20030310230829.19290.qmail@web20510.mail.yahoo.com> Jay Nelson wrote: > I haven't used ocaml or any other "object-oriented" functional > language so I may be way off here, but thinking about it raised > some issues for me. > > Chris Okasaki talks about persistence in "Purely Functional Data > Structures". Functional data structures are persistent, meaning > that multiple versions can exist simultaneously, whereas imperative > data structures are ephemeral meaning that only one version exists > at a time. > > All the OO paradigms I've seen are designed around ephemeral objects, > with the exception of versioning OO databases which are generally > approximations since only the DB saved versions exist, not the > temporary versions that were used to get to a save state. In OO > you don't have to deal with outdated copies of objects, every > instance is ephemeral. In erlang if you were to make some sort of > static object, you would have to make sure that it is not modified > in more than one process, or stashed inside some list, or else you > have to serialize it in a server or store it in an ets table and > always get a fresh copy (well, I guess the ets approach isn't > even guaranteed to work). Yep, the serialization problem draws you towards using one process per object, so to speak - or, to start thinking in terms of servers rather than objects. I dunno, though - sorry if this is getting too abstract for the Erlang list (I know of at least one other list where this would be more apropos, and if this list is really getting too fertile, I'll happily move it there,) but - at the risk of introducing weird concepts like metaparadigms, I think it comes down to how the buzzwords cloud our perceptions regarding how these various schools of programming come to be. Heresy follows (lovable kook that I am, I'm practically expected to have a controversial theory or two, right?) My current opinion is that there are really only two computational paradigms that humanity has discovered so far - commonly called imperative and functional, although those names aren't very descriptive, and you almost might as well call them the Turing approach and the Church approach - or destructive and derivational, or persistent and emphemeral, or updatable and single-assignment. The basic idea is that, in a functional language, a symbol cannot take on more than one value in a single scope, while in an imperative language, it can. This generally means that repetition (actually 'rechecking', which I would claim is required for computation, although I probably can't prove that) is done with iteration in an imperative language (i.e. 'while', 'if-then-goto', etc), while it must be done with recursion in a functional language (since you cannot update a counter variable - you must enter a new scope instead.) Further, we tend to think of object-oriented programming, concurrency-oriented programming, logic programming, rewriting, dataflow, automata, and the like, as seperate paradigms on par with those two computational models, but I think they are actually breakdowns along a different dimension, perhaps several different dimensions. That is to say - objects and processes don't really have ANYTHING to do with computation. They're not computational models - they're *communication* models. For that reason, you can have OO+imperative (Java,) OO+functional (O'Caml,) CO+functional (Erlang), CO+imperative (??? i can't think of an example offhand) and so on. (Logic programming, OTOH, looks like a subset of functional programming, while rewriting looks like a subset of imperative programming - even though they otherwise seem fairly similar. I have yet to delve into that question very deeply.) This also means that most of the "special" features associated strongly with a given paradigm have little or nothing to do with that paradigm - for example, lambdas aren't something that must exist solely in a functional framework - an imperative language ought to be able to have lambda procedures along the same lines. But back to objects. In OO, objects are often attributed with "identity", and this directly relates to ephemeral vs persistent (identity implies persistence.) But while this can be useful, it's also not strictly necessary - I don't think it's an issue in OO+functional languages like O"Caml. In other words, I think "object identity" is an artefact stemming from most OO languages being OO+imperative - and is, at it's root, more of an imperative vs. functional issue, than anything to do with OO. (Hell, I'm tempted to think it has more to do with databases than anything, but after making a wild claim like there being seperate computational and communication paradigms, I'm a bit wary about introducing a topic like data storage paradigms...) > [...] > What would you be trying to accomplish by using an OO approach? > I think that at the fundamental roots of the language, erlang > contains versioned data and OO is antithetical to that. Suppose > you have an erlang textbox UI record structure in your internal > model. Every time a character is added you create a new copy of the > structure and throw away the old one. Undo would be very easy > if you keep all the old versions of the data. The mixin approach of > adding behaviour to display the data would work well (just call > functions in a display textbox module or delegate to a single > process), but the inheritance approach of statically structured OO > wouldn't work as well because you would end up with multiple > processes delegating to each other depending on the depth of the > inheritance hierarchy just to draw the characters in the right place, > and then you would have to communicate each version of the data > when implementing undo, or else repeating the data versioning edit > in all processes in the delegation chain whenever a character came > in. Hmm, the strength of Erlang here would seem to be how easily Erlang can encapsulate ephemeral data (the function arguments) within a persistent entity (the server). Thinking about it a bit, I'm not actually convinced that undo does become so much easier, because anything should be able to query the value of the textbox at any time - the textbox is persistent. If it comes down to how I'd code it, the textbox would be a server, which would still have to keep a list of all previous values the textbox had, as its state - it would be nice to be able to leverage the recursive nature of functions to implicitly store those old values, but I don't think it could be done if that textbox could be arbitrarily addressed by other processes (sorry, I can't think of a good way to explain it right now, I'll have to think about it more.) > I guess my thinking is to do two things: 1) push erlang in the > erlang-y direction as far as I can to see what problems it is > suitable for, and 2) state a problem and see how many approaches > I can think of for implementing it in erlang. > > Use OO is not a problem, it is a solution. What problem are you > trying to solve? Honestly... although I like hacking (er I mean systems engineering, right,) in Erlang, my interest has always been in language design. While I support the idea of "choose the right language for the problem" in theory (like I support the idea of reusable code - in theory -) in practice it doesn't pan out as well as it should. I think humanity has been searching for a general-purpose programming language since, well, FORTRAN, and every attempt (Algol, PL/I, BASIC, Java et al) seems to fall way short and "niche-ify or die" quite quickly (frighteningly enough, C, which was never intended to be anything except a systems-construction language, seems to dominate through sheer ubiquity) My feeling is that Erlang, appropriately specialized though it is, is as close to a well-designed general-purpose language as any other; probably closer. It has much appeal by being sheer fun to code in. The "problem" is that Erlang still has it's weaknesses, as would be expected, and for it (or a descendant of it) to be applied to a greater range of problems (such as UI perhaps), it should be open to adopting the best features of other languages, while avoiding their weaknesses. (So there's really no problem per se. I'm just a nuisance. :) When learning Erlang - yes, throw OO out the window. It'll just mess you up. But don't *abandon* OO - when you begin to master Erlang, I think you find that, naturally, there are some things that it doesn't do so well, that some OO languages have addressed - and it's silly to be dismissive of something that does work, just because it's "not from our school". Surely the schools still have something to learn from each other - and from schools yet to be discovered? > Right now for UI I have taken the #2 step and am thinking hard about > the #1 step. > > jay I guess my feeling is that #1 is probably going to happen anyway, so I'd like to promote #2 insofar as it actually results in something useful (and isn't just a result of wanting to imitate Java/Haskell/etc.) More on this later, inevitably - I think it'll happen more along the lines of small changes which make small things easier - like Vlad's -delegate(...) proposal, rather than any Grand Reorganization Into Objects... and I still have a whole lot of thinking about it to do... -Chris ______________________________________________________________________ Post your free ad now! http://personals.yahoo.ca From enano@REDACTED Mon Mar 10 21:36:56 2003 From: enano@REDACTED (Miguel Barreiro Paz) Date: Mon, 10 Mar 2003 21:36:56 +0100 (CET) Subject: ECOMP (was:Re: OO vs. CO) In-Reply-To: <20030310194347.GE20416@frogman.motivity.ca> References: <20030310194347.GE20416@frogman.motivity.ca> Message-ID: > I know nothing of such things but I am left wondering after > someone commented on the list about the possibility of using the > Crusoe chip to make an Erlang processor. Would that "just require > software"? As far as I know, even if the Crusoe instruction set can be software-redefined, the interface to do so is not published. From kent@REDACTED Tue Mar 11 01:30:37 2003 From: kent@REDACTED (Kent Boortz) Date: 11 Mar 2003 01:30:37 +0100 Subject: OTP Article In-Reply-To: <200302111329.h1BDT3p17455@bonsai.fernuni-hagen.de> References: <200302111329.h1BDT3p17455@bonsai.fernuni-hagen.de> Message-ID: Marc Ernst Eddy van Woerkom writes: > BTW I can't access the OTP Article link on > > http://www.erlang.org/doc.html > > and the other Ericsson articles neither. Thank your for reporting this. This is now corrected, kent From blitzfeuer@REDACTED Tue Mar 11 04:50:27 2003 From: blitzfeuer@REDACTED (Walter C. Reel III) Date: Mon, 10 Mar 2003 22:50:27 -0500 Subject: Remote connect problems. Message-ID: Hello, I'm currently looking into creating distributed, reliable information base. I read the Erlang white paper, saw the FP foundation, hot swappable capability and built-in database system and thought this was perfect. So I've decided to check it out. I have two hosts running Erlang in an internal network. One is a win32 machine and the other is linux. After I start up erlang on each system I can't ping the win32 from linux, but as soon as I ping the linux machine from the win32 host the systems connect. Both are the same version (5.2.3.3), both can resolve name lookups to each other and both have the same cookie set and 'epmd.exe -d -d' doesn't report anything when I try to 'net_adm:ping(Node)' from the linux machine. Does anyone know what am I doing wrong? I'm really stuck on this. - Walter From Bruce@REDACTED Tue Mar 11 06:09:44 2003 From: Bruce@REDACTED (Bruce Fitzsimons) Date: Tue, 11 Mar 2003 18:09:44 +1300 Subject: TZ determination Message-ID: <04bb01c2e78c$6dcacc40$4021970a@norris> Can anyone suggest some cleaner, more efficient code than this for determining the offset from UTC/GMT? I *know* the bif's have access to this information, but I can't see any way to get it out. It just seems awful to have to reverse-engineer the difference, and its certainly inefficient. Suggestions on how to better drive io_lib would be appreciated too - I ended up with 0-100 under some formatting/padding combinations, which seemed like a bug. zone() -> Time = erlang:universaltime(), LocalTime = calendar:universal_time_to_local_time(Time), DiffSecs = calendar:datetime_to_gregorian_seconds(LocalTime) - calendar:datetime_to_gregorian_seconds(Time), zone((DiffSecs/3600)*100). %% Ugly reformatting code to get times like +0000 and -0200 zone(Val) when Val < 0 -> io_lib:format("-~4..0w", [trunc(abs(Val))]); zone(Val) when Val >= 0 -> io_lib:format("+~4..0w", [trunc(abs(Val))]). Thanks, Bruce From jay@REDACTED Tue Mar 11 07:55:41 2003 From: jay@REDACTED (Jay Nelson) Date: Mon, 10 Mar 2003 22:55:41 -0800 Subject: Erlux Message-ID: <4.2.2.20030310225455.00d17d30@duomark.com> Here's a link to an RTAI Linux setup on a system on a chip configuration. http://www.linuxdevices.com/articles/AT6416763926.html jay From matthias@REDACTED Tue Mar 11 08:42:09 2003 From: matthias@REDACTED (Matthias Lang) Date: Tue, 11 Mar 2003 08:42:09 +0100 Subject: Remote connect problems. In-Reply-To: References: Message-ID: <15981.37713.413881.422852@antilipe.corelatus.se> A first step is to try the whole experiment with two nodes on the same linux machine. I.e. start two xterms. In one: matthias >erl -sname hokus -setcookie nocookie Erlang (BEAM) emulator version 5.1.2 [source] (hokus@REDACTED)1> and in the other matthias >erl -sname pokus -setcookie nocookie Erlang (BEAM) emulator version 5.1.2 [source] (pokus@REDACTED)1> net:ping(hokus@REDACTED). pong Note the 'pong'. A next step could be to use numeric host-ids, i.e. on linux: erl -name 'hokus@REDACTED' -setcookie nocookie and on windows erl -name 'pokus@REDACTED' -setcookie nocookie (pokus@REDACTED)1> net:ping('hokus@REDACTED'). pong Note the '-name' instead of '-sname'. Let the list know how it goes. And next time you report a problem, please include a cut and paste of what you actually did, my ESP isn't what it used to be. Matthias Walter C. Reel III writes: > Hello, > > I'm currently looking into creating distributed, reliable information base. > I read the Erlang white paper, saw the FP foundation, hot swappable > capability and built-in database system and thought this was perfect. So > I've decided to check it out. > > I have two hosts running Erlang in an internal network. One is a win32 > machine and the other is linux. After I start up erlang on each system I > can't ping the win32 from linux, but as soon as I ping the linux machine > from the win32 host the systems connect. Both are the same version > (5.2.3.3), both can resolve name lookups to each other and both have the > same cookie set and 'epmd.exe -d -d' doesn't report anything when I try to > 'net_adm:ping(Node)' from the linux machine. Does anyone know what am I > doing wrong? I'm really stuck on this. > > - Walter > > From eleberg@REDACTED Tue Mar 11 09:15:40 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Tue, 11 Mar 2003 09:15:40 +0100 (MET) Subject: Erlang vs Linux Message-ID: <200303110815.h2B8FeH20485@cbe.ericsson.se> > Date: Mon, 10 Mar 2003 10:20:28 -0500 > From: Vance Shipley > It seems SCO is now suing IBM for $1 billion because they may > have let Linux become contanimated with SYSV source licensed to > them for AIX by SCO. > > http://www.informationweek.com/story/IWK20030307S0005 > > This would be an interesting turn of events. Linux becoming mired > down in the same legal quagmire that stymied *BSD adoption and gave > it the headstart. you might be right. however, i think that linux has something bsd did not have, a sponsor. it is not suse that is beeing sued, but ibm. imho the legal system in the usa awards the victory to either party after who has the most money. bengt From bjarne@REDACTED Tue Mar 11 09:57:00 2003 From: bjarne@REDACTED (=?iso-8859-1?Q?Bjarne_D=E4cker?=) Date: Tue, 11 Mar 2003 09:57:00 +0100 Subject: OO (was: OO vs CO) References: <20030310204947.91466.qmail@web20512.mail.yahoo.com> Message-ID: <002e01c2e7ac$2e74e880$100969d4@segeltorp> Hi >I think the other part of the desire for objects is that, to most >people, an object is something physical that you can see and hold (like >a book or a spoon) unlike a function or a rule or a process. I think >this is a very comforting idea to managers, even if it turns out to be >an illusion when applied to software engineering. Agree! Bjarne From Vlad.Dumitrescu@REDACTED Tue Mar 11 12:22:27 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Tue, 11 Mar 2003 12:22:27 +0100 Subject: Extending functionality: a practical case Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D433@esemont203.gbg.edt.ericsson.se> Hi again, I thought a more practical approach would be more, erm... practical :-) so I set up to tweak gen_server.erl in order to allow for an implementation spread across several modules. It wasn't very difficult, even if I didn't make it backwards compatible with this quick hack. In short, the change allows a gen_server_2 to be started with a _list_ of modules that implement the callbacks. The type of the State argument to all callbacks was modified to be {OldState, ModuleList}. See attached demo.erl. gen_server_2 handles the new type of State and also provides some new functions: next_call, next_cast, next_init, next_terminate, next_info and next_code_change. These will retrieve the name of the next module to call from the NewState, and call the respective handle_xxx function after stripping down the ModuleList. If the Module list is to be stored in the process dictionary, the new gen_server implementation will be backwards compatible from a callback module's point of view. Also, it isn't difficult to add functionality for modifying the ModuleList at run-time, thus making this ultimately dynamic. Now back to the main questions: Is this functionality needed? Did anyone feel at some time that it would be nice to be able to do this? Now that it's here, does anyone think it can be useful? Or is it just a toy feature? best regards, Vlad -------------- next part -------------- A non-text attachment was scrubbed... Name: demo.erl Type: application/octet-stream Size: 4175 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: gen_server_2.tar.gz Type: application/octet-stream Size: 6040 bytes Desc: not available URL: From per@REDACTED Tue Mar 11 13:31:48 2003 From: per@REDACTED (Per Hedeland) Date: Tue, 11 Mar 2003 13:31:48 +0100 (CET) Subject: TZ determination In-Reply-To: <04bb01c2e78c$6dcacc40$4021970a@norris> Message-ID: <200303111231.h2BCVmh18019@tordmule.bluetail.com> "Bruce Fitzsimons" wrote: > >Can anyone suggest some cleaner, more efficient code than this for >determining the offset from UTC/GMT? I *know* the bif's have access to this >information, but I can't see any way to get it out. It just seems awful to >have to reverse-engineer the difference, and its certainly inefficient. Hm, why the sudden interest in time zones (well, second question in two weeks:-)? But anyway, no, there is no easier way to access this info AFAIK, and it's not Erlang's fault - see below for how it's done with "all the power of C" in a rather well-known open-source program that needs to do such things... You want to watch out for non-integral-hours offsets though: $ env TZ=Australia/Adelaide date +%z +1030 $ env TZ=Australia/Adelaide erl -noshell -s foo przone -s erlang halt +1050 :-) >Suggestions on how to better drive io_lib would be appreciated too - I ended >up with 0-100 under some formatting/padding combinations, which seemed like >a bug. Doesn't seem to happen with what you have now - though maybe io*:format() is "overkill", you could do something like L = integer_to_list(trunc(abs(Val))), "+" ++ lists:nthtail(length(L), "0000") ++ L. (at least you don't have to read the io man page to figure out what it does:-). --Per Hedeland ------------- gmt = *gmtime(&t); lt = localtime(&t); off = (lt->tm_hour - gmt.tm_hour) * 60 + lt->tm_min - gmt.tm_min; /* assume that offset isn't more than a day ... */ if (lt->tm_year < gmt.tm_year) off -= 24 * 60; else if (lt->tm_year > gmt.tm_year) off += 24 * 60; else if (lt->tm_yday < gmt.tm_yday) off -= 24 * 60; else if (lt->tm_yday > gmt.tm_yday) off += 24 * 60; From wwsprague@REDACTED Tue Mar 11 17:28:28 2003 From: wwsprague@REDACTED (Webb Sprague) Date: Tue, 11 Mar 2003 08:28:28 -0800 Subject: Reloading modules References: <200303110815.h2B8FeH20485@cbe.ericsson.se> Message-ID: <3E6E0EAC.3000605@ucdavis.edu> First--greetings, and thanks to all the people that made Erlang happen. It is *really* cool. Is there a way to reload modules that you change in the shell. Basically, I just want to test them, change, test, etc. If I need to write something a function, that would be fine, but this would help me out a lot. I did search the archives a little bit, but I couldn't find anything. Thanks W From paf@REDACTED Tue Mar 11 17:31:36 2003 From: paf@REDACTED (Paulo Ferreira) Date: Tue, 11 Mar 2003 16:31:36 +0000 Subject: ECOMP (was:Re: OO vs. CO) Message-ID: >> I know nothing of such things but I am left wondering after >> someone commented on the list about the possibility of using the >> Crusoe chip to make an Erlang processor. Would that "just require >> software"? > > As far as I know, even if the Crusoe instruction set can be >software-redefined, the interface to do so is not published. Sad, very sad..... Now, some crazy ideas: Mildly crazy: If the Beam specification matches well a virtual stack machine, why not use a real stack machine like the PTSC IGNITE ( http://www.ptsc.com )? Those guys sell the processor and the "IP" to put the processor on your own FPGA. BTW is there something like "Beam specification for dummies"? Really really crazy: :-) :-) Why not "compile erlang directly into Hardware" ? We have usually lots of processes, that could be "mapped" into different areas/blocks of the FPGA. Each process has its own hardware, enough to do its own tasks, and comunicates with other "processes/hardware blocks" by message passing. Things like this loop are simple and fast in Hardware. loop(Counter)-> receive {up,Pid} -> loop(Counter+1); {down,Pid} -> loop(Counter-1); {query,Pid} -> Pid ! {value,Counter}, loop(Counter) end. Variants: a) At startup, all "processes/hardware blocks" are created and start "processing" the messages they receive. b) The "hardware blocks/processes" are "created" at runtime reconfiguring dynamically the FPGA. So instead of making hardware that "paralelizes" serial software with things like "sliding registers", why not start with software that is already paralell like Erlang, and put it into Hardware ? Greetings Paulo Ferreira ------------------------------------------------ Paulo Ferreira paf@REDACTED From luke@REDACTED Tue Mar 11 17:29:08 2003 From: luke@REDACTED (Luke Gorrie) Date: 11 Mar 2003 17:29:08 +0100 Subject: Reloading modules In-Reply-To: <3E6E0EAC.3000605@ucdavis.edu> References: <200303110815.h2B8FeH20485@cbe.ericsson.se> <3E6E0EAC.3000605@ucdavis.edu> Message-ID: Webb Sprague writes: > Is there a way to reload modules that you change in the > shell. Basically, I just want to test them, change, test, etc. If I > need to write something a function, that would be fine, but this would > help me out a lot. If you compile with "c(mymodule)", it automatically gets reloaded. Otherwise, you can do "l(mymodule)" to do the reload. NB: you can find all these builtin shell functions in the 'c' module in stdlib (it has a manpage too.) Cheers, Luke From Vlad.Dumitrescu@REDACTED Tue Mar 11 17:39:32 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Tue, 11 Mar 2003 17:39:32 +0100 Subject: Reloading modules Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D444@esemont203.gbg.edt.ericsson.se> Hi and welcome! :-) You can use "c(module)." to compile and load, or "l(module)." to just load the compiled new code. This will do a Code:purge first, and then a code:load. See code module docs for details. Check the c module, it has a lot of goodies to be used from the shell. regards, Vlad > -----Original Message----- > From: Webb Sprague [mailto:wwsprague@REDACTED] > Sent: Tuesday, March 11, 2003 5:28 PM > Cc: erlang-questions@REDACTED > Subject: Reloading modules > > > First--greetings, and thanks to all the people that made > Erlang happen. > It is *really* cool. > > Is there a way to reload modules that you change in the shell. > Basically, I just want to test them, change, test, etc. If > I need to > write something a function, that would be fine, but this > would help me > out a lot. > > I did search the archives a little bit, but I couldn't find anything. > > Thanks > W > > From wwsprague@REDACTED Tue Mar 11 17:45:23 2003 From: wwsprague@REDACTED (Webb Sprague) Date: Tue, 11 Mar 2003 08:45:23 -0800 Subject: Reloading modules References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D444@esemont203.gbg.edt.ericsson.se> Message-ID: <3E6E12A3.2040503@ucdavis.edu> Thanks everybody! It looks like "c()" should work fine, but Luke Gorrie also told me how to check to see if the module is stale. This should be enough to work with now. W Vlad Dumitrescu (EAW) wrote: >Hi and welcome! :-) > >You can use "c(module)." to compile and load, or "l(module)." to just load the compiled new code. This will do a Code:purge first, and then a code:load. See code module docs for details. > >Check the c module, it has a lot of goodies to be used from the shell. > >regards, >Vlad > > > >>-----Original Message----- >>From: Webb Sprague [mailto:wwsprague@REDACTED] >>Sent: Tuesday, March 11, 2003 5:28 PM >>Cc: erlang-questions@REDACTED >>Subject: Reloading modules >> >> >>First--greetings, and thanks to all the people that made >>Erlang happen. >> It is *really* cool. >> >>Is there a way to reload modules that you change in the shell. >> Basically, I just want to test them, change, test, etc. If >>I need to >>write something a function, that would be fine, but this >>would help me >>out a lot. >> >>I did search the archives a little bit, but I couldn't find anything. >> >>Thanks >>W >> >> >> >> From rasmus_jonsson@REDACTED Tue Mar 11 19:26:39 2003 From: rasmus_jonsson@REDACTED (=?iso-8859-1?q?Rasmus=20Jonsson?=) Date: Tue, 11 Mar 2003 19:26:39 +0100 (CET) Subject: jinterface problems Message-ID: <20030311182639.2854.qmail@web20510.mail.yahoo.com> I and a friend are trying out the jinterface functions. My friend created a java program that tried to create a new instance of the class OtpNode on his machine with the full name of my erlang node xxx@REDACTED and my erlang security cookie (on my machine half a world away, him Sidney, me Sweden). OtpNode node = new OtpNode ("xxx@REDACTED","mycookie"); Every time he tried to do this he got an exception thrown at him. I ran exactly the same java program on my machine (where the erlang node is running) but for me the creation of the OtpNode went ok. This got me to wonder if the jinterface can be used this way or if there is another error we are doing. Maybe it is delay sensitive even if this sounds unlikely. My friend has R9B-1 and I have R9B-0. Please help me if you have experience of jinterface. Rasmus _____________________________________________________ G? f?re i k?n och f? din sajt v?rderad p? nolltid med Yahoo! Express Se mer p?: http://se.docs.yahoo.com/info/express/help/index.html From spearce@REDACTED Tue Mar 11 20:04:35 2003 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 11 Mar 2003 14:04:35 -0500 Subject: jinterface problems In-Reply-To: <20030311182639.2854.qmail@web20510.mail.yahoo.com> References: <20030311182639.2854.qmail@web20510.mail.yahoo.com> Message-ID: <20030311190435.GA26601@spearce.org> Is it possible there is a firewall between you and your friend? He must be able to contact both the epmd process running on the machine as your Erlang node, as well as the Erlang node itself. Rasmus Jonsson wrote: > I and a friend are trying out the jinterface > functions. > My friend created a java program that tried to create > a new instance of the class OtpNode on his machine > with the full name of my erlang node xxx@REDACTED and my > erlang security cookie (on my machine half a world > away, him Sidney, me Sweden). > > OtpNode node = new OtpNode ("xxx@REDACTED","mycookie"); > > Every time he tried to do this he got an exception > thrown at him. I ran exactly the same java program on > my machine (where the erlang node is running) but for > me the creation of the OtpNode went ok. > > This got me to wonder if the jinterface can be used > this way or if there is another error we are doing. > Maybe it is delay sensitive even if this sounds > unlikely. My friend has R9B-1 and I have R9B-0. > > Please help me if you have experience of jinterface. > > Rasmus > > > _____________________________________________________ > G? f?re i k?n och f? din sajt v?rderad p? nolltid med Yahoo! Express > Se mer p?: http://se.docs.yahoo.com/info/express/help/index.html -- Shawn. The man who sets out to carry a cat by its tail learns something that will always be useful and which never will grow dim or doubtful. -- Mark Twain From spearce@REDACTED Tue Mar 11 20:06:30 2003 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 11 Mar 2003 14:06:30 -0500 Subject: ets vs. mnesia ram_copies Message-ID: <20030311190630.GB26601@spearce.org> Does anyone have any tests they've put together comparing the performance of mnesia ram_copies (ram only tables, non replicated) and ets? I'm trying to get an idea of the loss I'll have in performance by moving from ets to mnesia. I realize it'll be slower. And my case isn't necessarily what others tested, blah, blah, blah. I just thought I'd seen a message about it a while ago, but couldn't find it in the archives. -- Shawn. Q: What's tan and black and looks great on a lawyer? A: A doberman. From vlad_dumitrescu@REDACTED Tue Mar 11 20:11:08 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Tue, 11 Mar 2003 20:11:08 +0100 Subject: jinterface problems References: <20030311182639.2854.qmail@web20510.mail.yahoo.com> Message-ID: Hi, > My friend created a java program that tried to create > a new instance of the class OtpNode on his machine > with the full name of my erlang node xxx@REDACTED and my > erlang security cookie (on my machine half a world > away, him Sidney, me Sweden). > > OtpNode node = new OtpNode ("xxx@REDACTED","mycookie"); is yyy.zz your machine or his? The node should be called xxx@REDACTED's_name because it isn't the name of a node to connect to, but the name of the node tha Java program is starting. From there you can connect to the Erlang node on your machine. That's my guess, since I don't know what the thrown exception is. Hope it helps. regards, Vlad From Sean.Hinde@REDACTED Tue Mar 11 20:17:29 2003 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Tue, 11 Mar 2003 19:17:29 -0000 Subject: ets vs. mnesia ram_copies Message-ID: > Does anyone have any tests they've put together comparing the > performance of mnesia ram_copies (ram only tables, non replicated) > and ets? I'm trying to get an idea of the loss I'll have in > performance by moving from ets to mnesia. > > I realize it'll be slower. And my case isn't necessarily what > others tested, blah, blah, blah. I just thought I'd seen a > message about it a while ago, but couldn't find it in the > archives. I did some a long time ago, with old versions of erts and mnesia, and it was indeed slower. I do seem to recall noticing that the number of hops from mnesia:dirty_read to ets:lookup was reduced since then to almost nothing for a local node, so I guess nowadays there is not much difference. My test was a 10 liner which just inserted and read 100,000 rows or so - not hard to recreate and not very sophisticated. Sean NOTICE AND DISCLAIMER: This email (including attachments) is confidential. If you have received this email in error please notify the sender immediately and delete this email from your system without copying or disseminating it or placing any reliance upon its contents. We cannot accept liability for any breaches of confidence arising through use of email. Any opinions expressed in this email (including attachments) are those of the author and do not necessarily reflect our opinions. We will not accept responsibility for any commitments made by our employees outside the scope of our business. We do not warrant the accuracy or completeness of such information. From rasmus_jonsson@REDACTED Tue Mar 11 20:35:33 2003 From: rasmus_jonsson@REDACTED (=?iso-8859-1?q?Rasmus=20Jonsson?=) Date: Tue, 11 Mar 2003 20:35:33 +0100 (CET) Subject: jinterface problems In-Reply-To: Message-ID: <20030311193533.3248.qmail@web20511.mail.yahoo.com> The javaprogram in Australia tried to do new OtpNode giving the adress of the E-node on my machine in Sweden. (the jinterface UG is not explicit on this point) Another response I got, said that the empd has to run on the java klient machine for it to work. What we actually are trying to accomplish is to let any client (anywhere) download an java applet over http from a inets server on the erlang node, and then we want the java applet and the e-node to start communica- ting. (here we cannot require any empd running on the client!) >From the responses, I have got so far, it seems like jinterface is the wrong way to go to get this working. Is this correctly understood? Is there any other library/package that is better suited for e-node/java applet communication? Thanks, Rasmus --- Vlad Dumitrescu skrev: > Hi, > > > My friend created a java program that tried to > create > > a new instance of the class OtpNode on his machine > > with the full name of my erlang node xxx@REDACTED > and my > > erlang security cookie (on my machine half a world > > away, him Sidney, me Sweden). > > > > OtpNode node = new OtpNode > ("xxx@REDACTED","mycookie"); > > is yyy.zz your machine or his? The node should be > called > xxx@REDACTED's_name because it isn't the name > of a node to connect to, > but the name of the node tha Java program is > starting. From there you can > connect to the Erlang node on your machine. > > That's my guess, since I don't know what the thrown > exception is. Hope it > helps. > regards, > Vlad _____________________________________________________ G? f?re i k?n och f? din sajt v?rderad p? nolltid med Yahoo! Express Se mer p?: http://se.docs.yahoo.com/info/express/help/index.html From luke@REDACTED Tue Mar 11 20:40:28 2003 From: luke@REDACTED (Luke Gorrie) Date: 11 Mar 2003 20:40:28 +0100 Subject: jinterface problems In-Reply-To: <20030311193533.3248.qmail@web20511.mail.yahoo.com> References: <20030311193533.3248.qmail@web20511.mail.yahoo.com> Message-ID: Rasmus Jonsson writes: > What we actually are trying to accomplish is to let any client > (anywhere) download an java applet over http from a inets server on > the erlang node, and then we want the java applet and the e-node to > start communica- ting. (here we cannot require any empd running on > the client!) I think that jinterface is the right way, but I would suggest using your own protocol instead of distributed Erlang. You can do this by opening a regular TCP socket and the Otp{Input,Output}Stream in Java and term_to_binary/binary_to_term in Erlang to translate between Erlang terms and binary data (for sending over sockets.) Two good things about this approach: the networking part is simple and predictable (you open the socket however you like), and you have control over what messages are sent and how they are processed. Security-wise, giving someone access to your Erlang node via distribution is equivalent to giving them a shell on your machine, so if you used distributed Erlang you should be very careful about who you let run the applet. The other main option for Java<->Erlang communication is UBF: http://www.sics.se/~joe/ubf/site/home.html (more experimental, but generally simpler.) Cheers, Luke From jocke@REDACTED Tue Mar 11 21:17:10 2003 From: jocke@REDACTED (Joakim G.) Date: Tue, 11 Mar 2003 21:17:10 +0100 Subject: jinterface problems In-Reply-To: References: <20030311193533.3248.qmail@web20511.mail.yahoo.com> Message-ID: <3E6E4446.9080506@bluetail.com> XML-RPC could be an alternative as well: An Erlang XML-RPC lib: http://www.gleipnir.com/xmlrpc/ A Java XML-RPC lib: http://ws.apache.org/xmlrpc/ An example Fibonacci XML-RPC server in Erlang: http://www.gleipnir.com/xmlrpc/unpacked/LATEST/examples/fib_server.erl A Java XML-RPC client using the above example Erlang server: http://www.gleipnir.com/xmlrpc/unpacked/LATEST/examples/FibClient.java Cheers /Jocke Luke Gorrie wrote: >Rasmus Jonsson writes: > > > >>What we actually are trying to accomplish is to let any client >>(anywhere) download an java applet over http from a inets server on >>the erlang node, and then we want the java applet and the e-node to >>start communica- ting. (here we cannot require any empd running on >>the client!) >> >> > >I think that jinterface is the right way, but I would suggest using >your own protocol instead of distributed Erlang. You can do this by >opening a regular TCP socket and the Otp{Input,Output}Stream in Java >and term_to_binary/binary_to_term in Erlang to translate between >Erlang terms and binary data (for sending over sockets.) > >Two good things about this approach: the networking part is simple and >predictable (you open the socket however you like), and you have >control over what messages are sent and how they are >processed. Security-wise, giving someone access to your Erlang node >via distribution is equivalent to giving them a shell on your machine, >so if you used distributed Erlang you should be very careful about who >you let run the applet. > >The other main option for Java<->Erlang communication is UBF: >http://www.sics.se/~joe/ubf/site/home.html (more experimental, but >generally simpler.) > >Cheers, >Luke > > From spearce@REDACTED Tue Mar 11 21:13:17 2003 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 11 Mar 2003 15:13:17 -0500 Subject: jinterface problems In-Reply-To: <20030311193533.3248.qmail@web20511.mail.yahoo.com> References: <20030311193533.3248.qmail@web20511.mail.yahoo.com> Message-ID: <20030311201317.GC26601@spearce.org> Rasmus Jonsson wrote: > What we actually are trying to accomplish is to let > any client (anywhere) download an java applet over > http > from a inets server on the erlang node, and then we > want the java applet and the e-node to start > communica- > ting. (here we cannot require any empd running on the > client!) That might be a dangerous operation, as any connected node can send any message to any process in any other node on the network. Thus the java applet (or anyone else with the cookie and an OTP node) can send a message to the RPC server to ask it to run say: os:cmd("rm -rf /") and have it succeed. The best idea would be to form a protocol between the applet and the Erlang server, which responds to clients using gen_tcp. Set {packet, 4} in gen_tcp and use the jinterface classes to serialize messages in java and send them with 4 byte length headers over a TCP socket. In Erlang you can use term_to_binary and binary_to_term to convert back and forth. This is essentially all the distribution system does, it just also automatically relays the message to the destination pid, as well as provide for linking and whatnot. -- Shawn. Avoid reality at all costs. From ulf.wiger@REDACTED Tue Mar 11 21:15:18 2003 From: ulf.wiger@REDACTED (Wiger Ulf) Date: Tue, 11 Mar 2003 21:15:18 +0100 Subject: ets vs. mnesia ram_copies References: <20030311190630.GB26601@spearce.org> Message-ID: <007101c2e80a$ef86c8a0$fd7a40d5@telia.com> I guess we're comparing dirty_read() to ets:lookup() and dirty_write() to ets:insert()? Transactions will of course be much slower, but it's not really fair to compare that to ets, since the semantics differ. First of all, you can get *almost* ets performance by writing like this: mnesia:activity( Type = ets, fun() -> [#obj{value = Val} = Obj] = mnesia:read({obj, Key}), mnesia:write(Obj#obj{val = foo(Val)}) end). where Type can be ets | dirty | sync_dirty | transaction | sync_transaction When Type == ets, the mnesia:read() and mnesia:write() functions are translated to ets:lookup() and ets:insert(), with minimal overhead (basically a get() and a couple of external function calls for each and a get_env() (an ets:lookup() to determine the access module for mnesia -- can be avoided if you provide it explicitly.) If you're doing dirty_write (e.g. with Type=dirty), mnesia will have to perform some checks, each being basically an ets:lookup(): 1) record validation (proper record name and attributes) 2) where_to_read (finding out where the physical table is) 3) sending the request to mnesia_tm process and awaiting the result 4) a number of other meta-data lookups (indeces, storage_type, replication) /Uffe ----- Original Message ----- From: "Shawn Pearce" To: Sent: den 11 mars 2003 20:06 Subject: ets vs. mnesia ram_copies > Does anyone have any tests they've put together comparing the > performance of mnesia ram_copies (ram only tables, non replicated) > and ets? I'm trying to get an idea of the loss I'll have in > performance by moving from ets to mnesia. > > I realize it'll be slower. And my case isn't necessarily what > others tested, blah, blah, blah. I just thought I'd seen a > message about it a while ago, but couldn't find it in the > archives. > > -- > Shawn. > > Q: What's tan and black and looks great on a lawyer? > A: A doberman. From spearce@REDACTED Tue Mar 11 21:27:08 2003 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 11 Mar 2003 15:27:08 -0500 Subject: ets vs. mnesia ram_copies In-Reply-To: <007101c2e80a$ef86c8a0$fd7a40d5@telia.com> References: <20030311190630.GB26601@spearce.org> <007101c2e80a$ef86c8a0$fd7a40d5@telia.com> Message-ID: <20030311202708.GD26601@spearce.org> Thanks, that was basically what I was looking for, I guess. :) My intent is to do writes through a normal transaction, as right now all writes are serialized anyway through a server process. I would rather to have the transaction semantic of being able to rollback and have it be slower, then not have it. The writes aren't my problem. Its the reads. :) If I went with Mnesia, I'd pretty much have to use a dirty read of some sort. As it is, I really need a couple of indexes defined on my data, so writes aren't that fast to begin with, and won't be that fast with Mnesia. I'm all about read speed. :) Wiger Ulf wrote: > I guess we're comparing dirty_read() to ets:lookup() and > dirty_write() to ets:insert()? Transactions will of course be much > slower, but it's not really fair to compare that to ets, since the > semantics differ. > > First of all, you can get *almost* ets performance by writing > like this: > > mnesia:activity( > Type = ets, > fun() -> > [#obj{value = Val} = Obj] = mnesia:read({obj, Key}), > mnesia:write(Obj#obj{val = foo(Val)}) > end). > > where Type can be ets | dirty | sync_dirty | transaction | sync_transaction > > When Type == ets, the mnesia:read() and mnesia:write() functions are > translated to ets:lookup() and ets:insert(), with minimal overhead > (basically > a get() and a couple of external function calls for each and a get_env() > (an ets:lookup() to determine the access module for mnesia -- can be avoided > if you provide it explicitly.) > > If you're doing dirty_write (e.g. with Type=dirty), mnesia will have to > perform some checks, each being basically an ets:lookup(): > > 1) record validation (proper record name and attributes) > 2) where_to_read (finding out where the physical table is) > 3) sending the request to mnesia_tm process and awaiting the result > 4) a number of other meta-data lookups (indeces, storage_type, replication) -- Shawn. Your reasoning powers are good, and you are a fairly good planner. From vances@REDACTED Tue Mar 11 21:47:04 2003 From: vances@REDACTED (Vance Shipley) Date: Tue, 11 Mar 2003 15:47:04 -0500 Subject: jinterface problems In-Reply-To: <20030311201317.GC26601@spearce.org> References: <20030311193533.3248.qmail@web20511.mail.yahoo.com> <20030311201317.GC26601@spearce.org> Message-ID: <20030311204704.GS27264@frogman.motivity.ca> On Tue, Mar 11, 2003 at 03:13:17PM -0500, Shawn Pearce wrote: } Rasmus Jonsson wrote: } > What we actually are trying to accomplish is to let } > any client (anywhere) download an java applet over } > http } > from a inets server on the erlang node, and then we } > want the java applet and the e-node to start } > communica- } > ting. (here we cannot require any empd running on the } > client!) } } That might be a dangerous operation, as any connected node It may be but it's actually pretty cool. :) I'm tempted to learn some Java just so I can play too. -Vance From spearce@REDACTED Tue Mar 11 21:48:21 2003 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 11 Mar 2003 15:48:21 -0500 Subject: binary_to_term atom table overflow threat Message-ID: <20030311204821.GE26601@spearce.org> So what is the best way to deal with the binary_to_term/1 atom table overflow problem (you know, 1 million atom limit, binary_to_term/1 can make any atoms it pleases)? Any chance we might see a binary_to_term/2 where if the second argument is false term's which are atoms in the input binary and are not already in the atom table are returned as strings (lists)? Might not make sense to do though, given that UBF exists... -- Shawn. Your lucky number has been disconnected. From spearce@REDACTED Tue Mar 11 21:56:11 2003 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 11 Mar 2003 15:56:11 -0500 Subject: Unaccounted memory usage... In-Reply-To: <15980.49523.682650.103902@antilipe.corelatus.se> References: <20030310101434.GB21274@spearce.org> <15980.49523.682650.103902@antilipe.corelatus.se> Message-ID: <20030311205611.GF26601@spearce.org> Just an interesting note, R9B-0 on Windows XP with the same test case uses 24 MB, peak memory. Odd how the Linux code uses so much, but the Windows code doesn't. Of course, Windows didn't have a large enough backlog on the socket with {backlog, 5} to handle more than 64 simultaneous incoming connections (Linux did). :( Shawn Pearce writes: > Can someone help me explain this a little? My beam process is > currently at a little over 200 MB resident heap size. -- Shawn. You'll feel much better once you've given up hope. From spearce@REDACTED Tue Mar 11 22:36:13 2003 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 11 Mar 2003 16:36:13 -0500 Subject: jinterface problems In-Reply-To: <20030311204704.GS27264@frogman.motivity.ca> References: <20030311193533.3248.qmail@web20511.mail.yahoo.com> <20030311201317.GC26601@spearce.org> <20030311204704.GS27264@frogman.motivity.ca> Message-ID: <20030311213613.GG26601@spearce.org> I found the jinterface to be useful when I wanted to talk to Java for JDBC. jinterface rocks just like Erlang distribution and CORBA support in Erlang works: lets you talk to external systems (which may be new legacy) pretty easily. Probably one of Erlang's best strengths is how much it has included, and how many things it can talk to as a result. I think the last thing missing is very good access to commerical SQL DBMSs, aka Oracle, Sybase, Informix, DB2, and by means of something other than ODBC. :) But with jinterface and corba, you have the ability to at least talk to a pehaps already-existing system to do that access for you. My one problem was jinterface (thanks to the JVM) was slower than I wanted to access Oracle. So I'm doing OTL and a c-node or an external port process to connect to Oracle. Need to start building that this week actually. :) But jinterface isn't cool enough to justify the pain and torture an Erlang developer would face learning and programming in Java. This Erlang project let me pull out of the New York winter doldrums and start to enjoy programming again. (Up until last week I was doing Java only, and hating it.) Of course, I'm so much more productive in Erlang, I've already surpassed 6 months of Java development in a pretty solid Erlang prototype. Vance Shipley wrote: > On Tue, Mar 11, 2003 at 03:13:17PM -0500, Shawn Pearce wrote: > } Rasmus Jonsson wrote: > } > What we actually are trying to accomplish is to let > } > any client (anywhere) download an java applet over > } > http > } > from a inets server on the erlang node, and then we > } > want the java applet and the e-node to start > } > communica- > } > ting. (here we cannot require any empd running on the > } > client!) > } > } That might be a dangerous operation, as any connected node > > > It may be but it's actually pretty cool. :) > > I'm tempted to learn some Java just so I can play too. > > -Vance -- Shawn. The last thing one knows in constructing a work is what to put first. -- Blaise Pascal From luke@REDACTED Tue Mar 11 22:33:36 2003 From: luke@REDACTED (Luke Gorrie) Date: 11 Mar 2003 22:33:36 +0100 Subject: jinterface problems In-Reply-To: <20030311213613.GG26601@spearce.org> References: <20030311193533.3248.qmail@web20511.mail.yahoo.com> <20030311201317.GC26601@spearce.org> <20030311204704.GS27264@frogman.motivity.ca> <20030311213613.GG26601@spearce.org> Message-ID: Shawn Pearce writes: > But jinterface isn't cool enough to justify the pain and torture > an Erlang developer would face learning and programming in Java. Yeah. If you want to delete your disk from a foreign language, Emacs Lisp is surely the tool of choice: (erl-send-rpc 'mynode@REDACTED 'os 'cmd '("rm -rf /")) ;-) Cheers, Luke From jay@REDACTED Wed Mar 12 08:31:24 2003 From: jay@REDACTED (Jay Nelson) Date: Tue, 11 Mar 2003 23:31:24 -0800 Subject: OO vs. Erlang Message-ID: <4.2.2.20030311212738.00d0d570@duomark.com> I had to do some driving this weekend, so I got a lot of thinking done. Unfortunately it would take me days to post what I have been thinking about so it will have to come out over the next week or so little by little. Paraphrasing Chris: > imperative and functional > = destructive and derivational, > or = persistent and emphemeral > or = updatable and single-assignment > In OO, objects are often attributed with "identity", and > this directly relates to ephemeral vs persistent > (identity implies persistence.) > Erlang can encapsulate ephemeral data (the > function arguments) within a persistententity (the server) When I mentioned Okasaki's term "persistence" it means something very different than the same term applied to OO instances. I suppose it is unfortunate that he chose that term because it has such a history as a term for storing objects in a database across invocations of a process. In erlang: #state{a = 1, b = 2} = State1. State2 = State1#{a = 3}. creates two versions of a #state object. The data structure is called "persistent" because it _cannot_ be modified and so must always be copied leaving both versions accessible _simultaneously_. In C++ or OO languages, modifying the instance automatically changes all references to it to give only the new value of the state. One has to explicitly copy the object if the old version is needed, something we are taught to avoid doing unnecessarily. It is not "persistent" because a single change destroys the old version. > I'm not actually convinced that undo does become so > much easier, because anything should be able to query > the value of the textbox at any time - the textbox is persistent. See above. In an X-windows or other implementation, the textbox is not persistent in the Functional sense because it is destructively modified thus changing its state. The undo information in X-windows is not associated with the textbox but must be cached somewhere else and the internal state of the textbox requested to be replaced (I believe that is how it is done). > If it comes down to how I'd code it, the textbox would be > a server, which would still have to keep a list of all previous > values the textbox had, as its state - it would be nice to be > able to leverage the recursive nature of functions to implicitly > store those old values, but I don't think it could be done if > that textbox could be arbitrarily addressed by other processes The code would work like this: textbox:new() -> #charset{ version = [], data = [], redo = [] } add_char(Char, #charset{ version = OldVsns, data = String }) -> NewString = [ Char | String ], #charset{ version = [ NewString | OldVsns ], data = NewString }. del_char(#charset{ version = OldVsns, data = [ Char | Rest ] }) -> #charset{ version = [ Rest | OldVsns ], data = Rest}; del_char(#charset{ data = [] } = TextBox) -> beep(), TextBox. ins_char(Char, Pos, #charset{ version = OldVsns, data = String }) -> InsPos = length(String) - Pos, NewString = lists:sublist(String, InsPos) ++ [ Char ] ++ lists:nthtail(InsPos, String), #charset{ version = [ NewString | OldVsns ], data = NewString }. undo(#charset{ version = [ CurrVsn | OldVsns ], data = String, redo = Redo }) -> case OldVsns of [ Prev | _Older ] -> #charset{ version = OldVsns, data = Prev, redo = [ CurrVsn | Redo ] }; [] -> #charset{ version = [], data = [], redo = [ CurrVsn | Redo ] } end; undo(#charset{ version = [] } = TextBox) -> beep(), TextBox. redo(#charset{ version = OldVsns, data = String, redo = [ Redo | Rest] }) -> #charset{ version = [ Redo | OldVsns ], data = Redo, redo = Rest }; redo(#charset{ redo = [] } = TextBox) -> beep(), TextBox. [Warning: the above code is untested and typed in for the first time in this message, but is approximately what you want. Try it out and then print out the version field with one entry per line to see the entire typo-prone history of the textbox.] First note that paying attention to the internals without regard to the display leads to an efficient and understandable data structure that is completely unexpected when compared to the imperative approach used by X-windows, et al. The string in the textbox is maintained as a _reverse_ list of characters, because typically characters are added or removed one at a time. You would need to add functions for cut and paste, but they look the same except for working on sublists at a time. Second, the code uses the nature of functional data structure versions that comes automatically to allow undo and redo. The internal implementation shares sublists to provide the most efficient memory utilization that records all versions of the string ever created. (I would replace ins_char with a call to a function that creates the inserted list recursively in an efficient way rather than using append as I did above for clarity.) The undo and redo should still work regardless of the type of edit performed (even removing every other letter in one shot or some other strange transmogrification). To do this in an imperative language you would have to introduce lists and explicitly copy the string every time (and I'll bet you wouldn't have stored it backwards because you probably pre- allocated the memory and used a pointer -- it wouldn't even occur to you that backwards storage might be beneficial) so I would wager the imperative implementation would be less efficient. On top of that you would have to make new instances with different length pre-allocated buffers for each textbox you wanted, or else make it really big and hope you never overrun it (probably the most commonly occurring and most insecure bug in all of software) or some complicated realloc refinement would have to be introduced (which of course would triple the memory use because you would realloc at double size, copy memory and then free). In erlang, manipulating every version of the data structure that ever existed is more natural and fairly straight-forward. The textbox behaviour above could be in a separate process so no other code could get at the internals other than using the message interface (strong encapsulation). If a pointer to a particular version of the textbox internals were obtained outside the process, it couldn't be changed in a way that would affect the textbox or undo / redo. Also you get concurrent execution with all the other textboxes (think of scrolling stock tickers for different stock market exchanges instead of text type-in boxes). In fact, other processes could arbitrarily ask for _any_ version of the textbox internals if you provided an message interface to do so. jay From ulf.wiger@REDACTED Wed Mar 12 08:40:04 2003 From: ulf.wiger@REDACTED (Wiger Ulf) Date: Wed, 12 Mar 2003 08:40:04 +0100 Subject: binary_to_term atom table overflow threat References: <20030311204821.GE26601@spearce.org> Message-ID: <002c01c2e86a$98ef6b40$fd7a40d5@telia.com> For the record, UBF is pretty good at creating atoms as well. (: (In UBF, they're called "constants", but of course, when you type-specify your protocol, you can avoid using them...) /Uffe ----- Original Message ----- From: "Shawn Pearce" To: Sent: den 11 mars 2003 21:48 Subject: binary_to_term atom table overflow threat > So what is the best way to deal with the binary_to_term/1 > atom table overflow problem (you know, 1 million atom > limit, binary_to_term/1 can make any atoms it pleases)? > > Any chance we might see a binary_to_term/2 where if the > second argument is false term's which are atoms in the > input binary and are not already in the atom table are > returned as strings (lists)? Might not make sense to > do though, given that UBF exists... > > -- > Shawn. > > Your lucky number has been disconnected. From eleberg@REDACTED Wed Mar 12 09:07:52 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Wed, 12 Mar 2003 09:07:52 +0100 (MET) Subject: ets vs. mnesia ram_copies Message-ID: <200303120807.h2C87qH20180@cbe.ericsson.se> > Date: Tue, 11 Mar 2003 14:06:30 -0500 > From: Shawn Pearce > To: erlang-questions@REDACTED > Subject: ets vs. mnesia ram_copies > Mail-Followup-To: erlang-questions@REDACTED > Mime-Version: 1.0 > Content-Disposition: inline > User-Agent: Mutt/1.4i > > Does anyone have any tests they've put together comparing the > performance of mnesia ram_copies (ram only tables, non replicated) > and ets? I'm trying to get an idea of the loss I'll have in as an aside: it is possible to create a mnesia table, and use it from ets. this might be handy if there is a problem with the persistance of ets tables (the process owning the ets table dies, but the users of the table lives on). bengt From matthias@REDACTED Wed Mar 12 11:16:42 2003 From: matthias@REDACTED (Matthias Lang) Date: Wed, 12 Mar 2003 11:16:42 +0100 Subject: OO vs. CO In-Reply-To: <4.2.2.20030306200746.00ccf790@duomark.com> References: <4.2.2.20030306200746.00ccf790@duomark.com> Message-ID: <15983.2314.315559.110704@antilipe.corelatus.se> Jay Nelson writes: > entities. erlang would make a great simulation language (even > to the level of doing something like a microprocessor emulator) > because you can model the time delays, feedback loops and > other interactions besides just the instances. In simulation, Erlang's concurrency is a double-edged sword. If you model each real-world concurrent item as an Erlang process and simulate delays by letting processes sleep, Erlang takes care of scheduling and everything looks clean and simple. The downside is that the simulator's execution time gets included in the simulation. Sometimes that is desirable, often it isn't---having the two runs of the same simulation return different results can be an unpleasant "a-ha" experience. And if you scale time to get the simulation to run faster than real-time you increase the relative effect of the simulator's execution time. It is possible to take measures to avoid this at the expense of simplicity. Matt From quintela@REDACTED Wed Mar 12 12:11:39 2003 From: quintela@REDACTED (Juan Quintela) Date: Wed, 12 Mar 2003 12:11:39 +0100 Subject: ECOMP In-Reply-To: (Miguel Barreiro Paz's message of "Mon, 10 Mar 2003 21:36:56 +0100 (CET)") References: <20030310194347.GE20416@frogman.motivity.ca> Message-ID: <86u1e8alg4.fsf@trasno.mitica> >>>>> "miguel" == Miguel Barreiro Paz writes: >> I know nothing of such things but I am left wondering after >> someone commented on the list about the possibility of using the >> Crusoe chip to make an Erlang processor. Would that "just require >> software"? miguel> As far as I know, even if the Crusoe instruction set can be miguel> software-redefined, the interface to do so is not published. It can be redefined. Their presentation was I think it was quake or something like that, running on a JVM on bare hardware inside of an x86 image. But as far as I know, the interface is not publised, nor there is any plan to publish it. Later, Juan. -- In theory, practice and theory are the same, but in practice they are different -- Larry McVoy From joe@REDACTED Wed Mar 12 12:40:09 2003 From: joe@REDACTED (Joe Armstrong) Date: Wed, 12 Mar 2003 12:40:09 +0100 (CET) Subject: ANNOUNCE: erlguten Message-ID: ErlGuten is now available at http://www.sics.se/~joe/erlguten-2.0/erlguten.html ErlGuten aims to produce typographic quality PDF from XML or a Erlang program. The release includes a library pdf.erl which can be used to create PDF directly from an ERlang program. ErlGuten emplements the first part of the "grand plan" for unifying GUIs and text production systems that I brain dumped earlier. Comments, errors and all feedback is welcome, as are volunteers /Joe From etxuwig@REDACTED Wed Mar 12 13:14:03 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Wed, 12 Mar 2003 13:14:03 +0100 (MET) Subject: OO vs. CO In-Reply-To: <15983.2314.315559.110704@antilipe.corelatus.se> Message-ID: On Wed, 12 Mar 2003, Matthias Lang wrote: >The downside is that the simulator's execution time gets >included in the simulation. Sometimes that is desirable, >often it isn't---having the two runs of the same simulation >return different results can be an unpleasant "a-ha" >experience. And if you scale time to get the simulation to >run faster than real-time you increase the relative effect >of the simulator's execution time. When we've performed benchmark tests in a sandbox environment, we've used timestamped 'proc' trace on the processes that are running the 'interesting' code. This gives us 'in' and 'out' trace events with timestamps, and allows us to calculate the effective time used by individual processes. (Some timeslices may show up as unrealistically long. This is probably due to the entire VM being scheduled out. One may have to do multiple test runs to get a good estimate.) /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From etxuwig@REDACTED Wed Mar 12 13:24:23 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Wed, 12 Mar 2003 13:24:23 +0100 (MET) Subject: ANNOUNCE: erlguten In-Reply-To: Message-ID: On Wed, 12 Mar 2003, Joe Armstrong wrote: >ErlGuten is now available at > > http://www.sics.se/~joe/erlguten-2.0/erlguten.html > >ErlGuten aims to produce typographic quality PDF from XML >or a Erlang program. Very nice! But is the word "AWAY" really correctly kerned in your sample document? (: (it looks a bit funny, at least on my PC) /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From joe@REDACTED Wed Mar 12 13:36:50 2003 From: joe@REDACTED (Joe Armstrong) Date: Wed, 12 Mar 2003 13:36:50 +0100 (CET) Subject: ANNOUNCE: erlguten In-Reply-To: Message-ID: Sorry - finger trouble the space between the A and W was correct but not the W and A - I've re-built everything - (with the same version numbers) just to confuse everbody. /Joe On Wed, 12 Mar 2003, Ulf Wiger wrote: > On Wed, 12 Mar 2003, Joe Armstrong wrote: > > >ErlGuten is now available at > > > > http://www.sics.se/~joe/erlguten-2.0/erlguten.html > > > >ErlGuten aims to produce typographic quality PDF from XML > >or a Erlang program. > > Very nice! But is the word "AWAY" really correctly kerned in > your sample document? (: (it looks a bit funny, at least on > my PC) > > /Uffe > From etxuwig@REDACTED Wed Mar 12 13:44:52 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Wed, 12 Mar 2003 13:44:52 +0100 (MET) Subject: ANNOUNCE: erlguten In-Reply-To: Message-ID: Ah, much better now. (: (: (: /Uffe On Wed, 12 Mar 2003, Joe Armstrong wrote: >Sorry - finger trouble the space between the A and W was >correct but not the W and A - > >I've re-built everything - (with the same version numbers) >just to confuse everbody. > >/Joe > > >On Wed, 12 Mar 2003, Ulf Wiger wrote: > >> On Wed, 12 Mar 2003, Joe Armstrong wrote: >> >> >ErlGuten is now available at >> > >> > http://www.sics.se/~joe/erlguten-2.0/erlguten.html >> > >> >ErlGuten aims to produce typographic quality PDF from XML >> >or a Erlang program. >> >> Very nice! But is the word "AWAY" really correctly kerned in >> your sample document? (: (it looks a bit funny, at least on >> my PC) >> >> /Uffe >> > > -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From Vlad.Dumitrescu@REDACTED Wed Mar 12 14:26:30 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Wed, 12 Mar 2003 14:26:30 +0100 Subject: ANNOUNCE: erlguten Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D44B@esemont203.gbg.edt.ericsson.se> > ErlGuten is now available at > > http://www.sics.se/~joe/erlguten-2.0/erlguten.html Way cool!! Just some quick questions (for now :-) I tried to check the code, but it's too much at once. -- how is flow between boxes handled? I tried to set a "continue" parameter to another box, but it didn't work. Or is it still on the ToDo list? -- is automatic page flow implemented? -- when outputting XML, I see the demos have nice precomputed galley boxes - how is it done when text doesn't fit the box? best regards, Vlad From urfaust@REDACTED Wed Mar 12 14:34:25 2003 From: urfaust@REDACTED (Faust) Date: Thu, 13 Mar 2003 00:34:25 +1100 Subject: ANNOUNCE: erlguten In-Reply-To: (Joe Armstrong's message of "Wed, 12 Mar 2003 12:40:09 +0100 (CET)") References: Message-ID: Joe Armstrong writes: > ErlGuten aims to produce typographic quality PDF from XML or > a Erlang program. Very nice indeed. So far I have been using Latex for my wordprocessing. It will be nice to use erlang instead ! -- natsu-gusa ya / tsuwamono-domo-ga / yume no ato summer grasses / strong ones / dreams site Summer grasses, All that remains Of soldier's dreams (Basho trans. Stryk) From joe@REDACTED Wed Mar 12 14:36:22 2003 From: joe@REDACTED (Joe Armstrong) Date: Wed, 12 Mar 2003 14:36:22 +0100 (CET) Subject: ANNOUNCE: erlguten In-Reply-To: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D44B@esemont203.gbg.edt.ericsson.se> Message-ID: On Wed, 12 Mar 2003, Vlad Dumitrescu (EAW) wrote: > > ErlGuten is now available at > > > > http://www.sics.se/~joe/erlguten-2.0/erlguten.html > > Way cool!! > > Just some quick questions (for now :-) I tried to check the code, but it's too much at once. > > -- how is flow between boxes handled? I tried to set a "continue" parameter to another box, but it didn't work. Or is it still on the ToDo list? To do > -- is automatic page flow implemented? To do - also I'm unsure about this. > -- when outputting XML, I see the demos have nice precomputed galley boxes - how is it done when text doesn't fit the box? > The text that won't fit goes into the black hole > best regards, > Vlad > /Joe From hp@REDACTED Wed Mar 12 15:17:25 2003 From: hp@REDACTED (HP Wei) Date: Wed, 12 Mar 2003 09:17:25 -0500 (EST) Subject: ANNOUNCE: erlguten Message-ID: <200303121417.h2CEHP6n007004@wren.rentec.com> >Very nice indeed. >So far I have been using Latex for my wordprocessing. > >It will be nice to use erlang instead ! I just want to know the reason for this. Is erlguten going to be 'Latex' plus more ?? hp From joe@REDACTED Wed Mar 12 16:07:18 2003 From: joe@REDACTED (Joe Armstrong) Date: Wed, 12 Mar 2003 16:07:18 +0100 (CET) Subject: ANNOUNCE: erlguten In-Reply-To: <200303121417.h2CEHP6n007004@wren.rentec.com> Message-ID: ErlGuten is a system for transforming XML -> PDF It also provides a nice way of doing 'on the fly' transformations from XML like parse trees into PDF. In ErlGuten a document has threee parts, a layout, content and a map which maps content onto layout boxes. In LaTeX layout it is almost impossibly difficult - you type in your stuff and LaTeX figures out where to put it on the page - ErlGuten is the other way around - you start by defining precisely where all the boxes on a page are to be, and all the fonts etc. and then you say what text is to be put into which box etc. ErlGuten combines several technologies - XML, Postscript/PDF and Erlang. XML is a wide spread and easy to use mark-up language Postscript/PDF is freely available and there are many beautiful Type1 postscript fonts Erlang is used for writing plug-ins and extensions. It is my hope that I will be able to replace LaTeX with ErlGuten and achieve better quality results with less effort. /Joe On Wed, 12 Mar 2003, HP Wei wrote: > > >Very nice indeed. > >So far I have been using Latex for my wordprocessing. > > > >It will be nice to use erlang instead ! > > I just want to know the reason for this. > Is erlguten going to be 'Latex' plus more ?? > > hp > From erlang@REDACTED Wed Mar 12 15:03:49 2003 From: erlang@REDACTED (Peter-Henry Mander) Date: Wed, 12 Mar 2003 14:03:49 +0000 Subject: ANNOUNCE: erlguten References: <200303121417.h2CEHP6n007004@wren.rentec.com> Message-ID: <3E6F3E45.3040801@manderp.freeserve.co.uk> I think the appeal is in being able to generate elaborate, presentation quality documents directly from changable/dynamic data, with charts, graphs, tables, links etc... I intend to use it to generate printable reports directly from and within a product testing framework and is accessible from a web page. Thanks Joe, btw, for doing this. I've now got all the tools (pdf,web) I need in Erlang, and in the form of tutorials no less. I owe you quite a few beers :-) Pete. HP Wei wrote: >>Very nice indeed. >>So far I have been using Latex for my wordprocessing. >> >>It will be nice to use erlang instead ! > > > I just want to know the reason for this. > Is erlguten going to be 'Latex' plus more ?? > > hp > > > From blitzfeuer@REDACTED Wed Mar 12 12:15:47 2003 From: blitzfeuer@REDACTED (Walter C. Reel III) Date: Wed, 12 Mar 2003 11:15:47 +0000 Subject: Remote connect problems. In-Reply-To: <15981.37713.413881.422852@antilipe.corelatus.se> References: <15981.37713.413881.422852@antilipe.corelatus.se> Message-ID: <200303121115.47960.blitzfeuer@sc.rr.com> On Tuesday 11 March 2003 07:42 am, Matthias Lang wrote: > A first step is to try the whole experiment with two nodes on the > same linux machine. I.e. start two xterms. In one: > > matthias >erl -sname hokus -setcookie nocookie > Erlang (BEAM) emulator version 5.1.2 [source] > (hokus@REDACTED)1> > > and in the other > > matthias >erl -sname pokus -setcookie nocookie > Erlang (BEAM) emulator version 5.1.2 [source] > (pokus@REDACTED)1> net:ping(hokus@REDACTED). > pong > > Note the 'pong'. A next step could be to use numeric host-ids, i.e. on > linux: > > erl -name 'hokus@REDACTED' -setcookie nocookie > > and on windows > > erl -name 'pokus@REDACTED' -setcookie nocookie > (pokus@REDACTED)1> net:ping('hokus@REDACTED'). > pong > > Note the '-name' instead of '-sname'. Let the list know how it > goes. And next time you report a problem, please include a cut and > paste of what you actually did, my ESP isn't what it used to be. > > Matthias With the fully qualified name provided neither of the machines can talk to each other now. $ erl -name 'kermit@REDACTED' -setcookie nocookie Erlang (BEAM) emulator version 5.2.3.3 [source] [hipe] [threads:0] Eshell V5.2.3.3 (abort with ^G) (kermit@REDACTED)1> nodes(). [] (kermit@REDACTED)2> net_adm:ping('piggy@REDACTED'). pang (kermit@REDACTED)3> The results are the same on 'piggy'. The fully qualified name with the IP address should work regardless right? Two nodes on the same host will talk to each other with no problems. $ erl -name 'fozzie@REDACTED' -setcookie nocookie Erlang (BEAM) emulator version 5.2.3.3 [source] [hipe] [threads:0] Eshell V5.2.3.3 (abort with ^G) (fozzie@REDACTED)1> nodes(). [] (fozzie@REDACTED)2> net_adm:ping('kermit@REDACTED'). pong (fozzie@REDACTED)3> $ erl -name 'kermit@REDACTED' -setcookie nocookie Erlang (BEAM) emulator version 5.2.3.3 [source] [hipe] [threads:0] Eshell V5.2.3.3 (abort with ^G) (kermit@REDACTED)1> nodes(). ['fozzie@REDACTED'] > > Walter C. Reel III writes: > > Hello, > > > > I'm currently looking into creating distributed, reliable information > > base. I read the Erlang white paper, saw the FP foundation, hot > > swappable capability and built-in database system and thought this was > > perfect. So I've decided to check it out. > > > > I have two hosts running Erlang in an internal network. One is a win32 > > machine and the other is linux. After I start up erlang on each system > > I can't ping the win32 from linux, but as soon as I ping the linux > > machine from the win32 host the systems connect. Both are the same > > version (5.2.3.3), both can resolve name lookups to each other and both > > have the same cookie set and 'epmd.exe -d -d' doesn't report anything > > when I try to 'net_adm:ping(Node)' from the linux machine. Does anyone > > know what am I doing wrong? I'm really stuck on this. > > > > - Walter From joe@REDACTED Wed Mar 12 16:39:29 2003 From: joe@REDACTED (Joe Armstrong) Date: Wed, 12 Mar 2003 16:39:29 +0100 (CET) Subject: ANNOUNCE: erlguten In-Reply-To: <3E6F3E45.3040801@manderp.freeserve.co.uk> Message-ID: On Wed, 12 Mar 2003, Peter-Henry Mander wrote: > I think the appeal is in being able to generate elaborate, presentation > quality documents directly from changable/dynamic data, with charts, > graphs, tables, links etc... Actually I started writing it because am *appalled* at the quality of modern typesetting. IMHO desktop publishing has destroyed high quality typesetting - for example Times Roman was *designed* for setting narrow columns of newspaper print - it is commonly used to print wide columns on A4 paper - the result is a mess. TeX/LaTeX also are flawed - TeX can't line up rows in two parallel columns. Just look at LaTeX papers done with two columns - you'll see that the text in the individual lines are usually misaligned. The use of LaTeX in producing scientific documents has resulted in virtually all publications looking identical - the typography is often awful as are the fonts - believe me there are some really *beautiful* type 1 postscript fonts which deserve to get used in scientific publications. Many magazines get this wrongs - newspapers are much better. If you look at a newspaper the overall design is based on a smallish number of templates - where each template is a set of rectangular boxes (I guess most papers use less than 20 templates) - indeed there should only be a small number of templates if the work as a whole is to have a consistent look and feel. Erlguten design will reflect this - the idea (not yet implemented) is to have a small number of templates + a large database of articles. Making a document consists then of choosing a template and dropping an article into it. I imagine generating these (content -> template) map on the fly and producing personalized content. The other point is *quality* I want to achieved the highest possibly quality - MS word etc. get character kerning *wrong* and miss out ligatures - they make typographically crazy decisions - setting up fixed columns (a la newspaper) is terribly difficult. The next level of programs quark-express - InDesign2 etc. can produce better quality output but are literally *painful* to use (it probably takes ten thousand mouse clicks to no anything - by which time your arm wants to drop off). There seems to be no good free software to produce high quality PDF from XML (I looked) the industry "standard" way of doing this is to use XSLT to transform XML to the FOSSI XML DTD and then transform this to a subset of TeX and then transform this to PDF. This method is extremely complicated and incredibly difficult to produce any good results (I've tried). The direct transformation of XML -> PDF *in one step* is much better and easier to program - all the Adobe documentation is freely available and is of surprisingly high quality (well done Adobe) - IMHO PDF is extremely well designed as is Postscript. > I intend to use it to generate printable reports directly from and > within a product testing framework and is accessible from a web page. Now make me happy by getting the typography right - choose *beautiful* typefaces - and get the layout right - try reading a few books on typography first :-) ((seriously)) - things got better and better from 1445 until about 1985 and then got worse ... I read that a typesetter setting newsprint on a Linotype machine could enter properly formatted text 4 times faster than with a modern desk top publishing system. This was *not* WYSIWYG but all done single key type setting commands ... If anybody knows how to get a Linotype manual can they mail me :-) So let's try to make things better ... > > Thanks Joe, btw, for doing this. I've now got all the tools (pdf,web) I > need in Erlang, and in the form of tutorials no less. I owe you quite a > few beers :-) Great - which bar?? /Joe > > Pete. > > HP Wei wrote: > >>Very nice indeed. > >>So far I have been using Latex for my wordprocessing. > >> > >>It will be nice to use erlang instead ! > > > > > > I just want to know the reason for this. > > Is erlguten going to be 'Latex' plus more ?? > > > > hp > > > > > > > > > From Marc.Vanwoerkom@REDACTED Wed Mar 12 16:41:03 2003 From: Marc.Vanwoerkom@REDACTED (Marc Ernst Eddy van Woerkom) Date: Wed, 12 Mar 2003 16:41:03 +0100 (MET) Subject: ANNOUNCE: erlguten In-Reply-To: (message from Joe Armstrong on Wed, 12 Mar 2003 12:40:09 +0100 (CET)) Message-ID: <200303121541.h2CFf3U28629@bonsai.fernuni-hagen.de> > ErlGuten is now available at > > http://www.sics.se/~joe/erlguten-2.0/erlguten.html > > ErlGuten aims to produce typographic quality PDF from XML or > a Erlang program. > (..) > Comments, errors and all feedback is welcome, as are volunteers My eye hung on di-fferent. I interpret http://www.xs4all.nl/~talo/talo/e_rules.html that diff counts as one sylable and should be hyphenated after the consonant (the "ff"). > Viewers - I'd like to connect ErlGuten to the freetype project > and make a GUI with the same interface as provided by the pdf module I don't understand this. Do you mean writing an Erlang version of a PDF reader or something different? In General I would like to know more about the project. If you want to clone or surpass TeX or just have a reasonable layout enginge. If you will take ideas from METAPOST etc. Regards, Marc From joe@REDACTED Wed Mar 12 16:53:31 2003 From: joe@REDACTED (Joe Armstrong) Date: Wed, 12 Mar 2003 16:53:31 +0100 (CET) Subject: ANNOUNCE: erlguten In-Reply-To: <200303121541.h2CFf3U28629@bonsai.fernuni-hagen.de> Message-ID: On Wed, 12 Mar 2003, Marc Ernst Eddy van Woerkom wrote: > > ErlGuten is now available at > > > > http://www.sics.se/~joe/erlguten-2.0/erlguten.html > > > > ErlGuten aims to produce typographic quality PDF from XML or > > a Erlang program. > > (..) > > Comments, errors and all feedback is welcome, as are volunteers > > My eye hung on di-fferent. > > I interpret > > http://www.xs4all.nl/~talo/talo/e_rules.html > > that diff counts as one sylable and should be hyphenated after > the consonant (the "ff"). > I've just use'd the TeX hyphenation tables and the algorithm from Tex re-implement in Erlang. > > > Viewers - I'd like to connect ErlGuten to the freetype project > > and make a GUI with the same interface as provided by the pdf module > > I don't understand this. > Do you mean writing an Erlang version of a PDF reader or something > different? Yes - I'd like a PDF reader in Erlang - and I'd like to write GUIs with the *same* layout language as used for creating PDF (like go 'ol display postscript) > > > In General I would like to know more about the project. > If you want to clone or surpass TeX or just have a reasonable > layout enginge. If you will take ideas from METAPOST etc. > I want the layout language to be XML The programming extension language to be Erlang The fonts to be Postscript Type 1 The output to be PDF I aim (of course) at better quality than TeX - whether I can do this remains to be seen. I have been reading books on Typography and there are a lot of neat ideas around that seem never to have been implemented, like for example: Hermann Zapfs optimization which is: Add an extra blank at the start (end) of a line - kern against the blank and throw away the extra blank - this is said to produce better optical alignment of the margins. Also do what Gutenberg did in the 42 line bible - move right hand punctuation slightly into the margin - this is only node in PDFTeX as far as I know (and with pleasing results) I also want to bring some common sense typography into documents - please don't set wide A4 columns in 11/11 TimesRoman :-) /Joe > Regards, > Marc > From etxuwig@REDACTED Wed Mar 12 17:05:57 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Wed, 12 Mar 2003 17:05:57 +0100 (MET) Subject: ANNOUNCE: erlguten In-Reply-To: Message-ID: On Wed, 12 Mar 2003, Joe Armstrong wrote: > If you look at a newspaper the overall design is based on >a smallish number of templates - where each template is a >set of rectangular boxes (I guess most papers use less than >20 templates) - indeed there should only be a small number >of templates if the work as a whole is to have a consistent >look and feel. Working for a Big Company (albeit smaller than it used to be...), where you're supposed to write technical documentation in FrameMaker, using some predefined templates (technicians write docs in FrameMaker, product managers and marketing people use MS Word, making things even better), I would _love_ to see a shift towards writing simple XML documents and then transforming XML -> HTML, and XML -> PDF. Not all documents we write need to be pretty (some do), but all of them should be eminently searchable. Also, they need to be version-controlled (and version control systems tend to like text best of all.) What I guess is needed to convince those of my colleagues who are not vi or emacs fanatics, is some input tool that gives at least a decent approximation of what the output is going to look like (WYSINWYWGBCEFW*) and some simple graphical aide that hides those scary XML tags. (: /Uffe (*) What You See Is Not What You Will Get, But Close Enough For Government Work. -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From erlang@REDACTED Wed Mar 12 17:01:38 2003 From: erlang@REDACTED (Peter-Henry Mander) Date: Wed, 12 Mar 2003 16:01:38 +0000 Subject: ANNOUNCE: erlguten References: Message-ID: <3E6F59E2.8010005@manderp.freeserve.co.uk> Joe Armstrong wrote: > >>I think the appeal is in being able to generate elaborate, >>presentation >>quality documents directly from changeable/dynamic data, with charts, >>graphs, tables, links etc... > > > Actually I started writing it because am *appalled* at the quality > of modern typesetting. ... > If you look at a newspaper the overall design is based on a smallish > number of templates - where each template is a set of rectangular > boxes (I guess most papers use less than 20 templates) - indeed there > should only be a small number of templates if the work as a whole is > to have a consistent look and feel. > That echos what my typography and graphic design teachers told us back in 1989(?). You obviously have a pronounced sense of aesthetics (it shows in your Erlang tutorials too :-). I did a two year graphic design course, but didn't find work and ended up studying computer science & cybernetics instead. I digress. Yes, I agree that the current tools aren't really designed with good typographic practice in mind. But I think that good typography also requires some guidance, teaching and experience. The reason most scientific documents look appallingly similar isn't just because of LaTeX. People generally don't have aesthetic flair (maybe the reason I couldn't get a job in graphic design?:-)) Following your example of inappropriate type faces, would a template offer recommended type faces? Would other graphical elements be incorporated, such as styles for graphics and tables? > Erlguten design will reflect this - the idea (not yet implemented) > is to have a small number of templates + a large database of articles. > > Making a document consists then of choosing a template and dropping > an article into it. > Supplying a limited selection of excellent templates would help enormously. I don't underestimate how hard it is to do this, but at least it would give some guidance. It may not be possible to automate the teaching and experience, though. > I imagine generating these (content -> template) map on the fly and > producing personalized content. > > The other point is *quality* I want to achieved the highest possibly > quality - MS word etc. get character kerning *wrong* and miss out > ligatures - they make typographically crazy decisions - setting up > fixed columns (a la newspaper) is terribly difficult. > > The next level of programs quark-express - InDesign2 etc. can > produce better quality output but are literally *painful* to use (it > probably takes ten thousand mouse clicks to no anything - by which > time your arm wants to drop off). > I agree again, I've suffered both, and I'm equally sick of both. > There seems to be no good free software to produce high quality PDF > from XML (I looked) the industry "standard" way of doing this is to > use XSLT to transform XML to the FOSSI XML DTD and then transform this > to a subset of TeX and then transform this to PDF. This method is > extremely complicated and incredibly difficult to produce any good > results (I've tried). > > The direct transformation of XML -> PDF *in one step* is much better > and easier to program - all the Adobe documentation is freely available > and is of surprisingly high quality (well done Adobe) - IMHO PDF is > extremely well designed as is Postscript. > Hmm. Would display postscript be in the pipeline? The GNUstep project (gnustep.org) is working on something there. I'm interested in using GNUstep for developing GUIs. I was very interested when Next Inc. introduced their black cube. I hope to play with it at last after almost 15-20 years! > >>I intend to use it to generate printable reports directly from and >>within a product testing framework and is accessible from a web page. > > Now make me happy by getting the typography right - choose > *beautiful* typefaces - and get the layout right - try reading a few > books on typography first :-) ((seriously)) - things got better and > better from 1445 until about 1985 and then got worse ... > Yup, the typography teacher was dismayed at the downward trend in quality at the time. It probably coincides with the emergence of DTP, and everyone believing they could match the professionals with the new technology. They always referred back to very early typographical examples, Gutenberg's bible for one. The problem is that good quality can easily be appreciated, but not easily created. I'll read my course notes and try my best, I've got a couple of day off soon... > I read that a typesetter setting newsprint on a Linotype machine > could enter properly formatted text 4 times faster than with a modern > desk top publishing system. This was *not* WYSIWYG but all done single > key type setting commands ... If anybody knows how to get a Linotype > manual can they mail me :-) > > So let's try to make things better ... > Maybe going *slower* would improve things? Taking time to polish would do wonders to the result. But we're all racing to produce stuff too quickly I think. > >>Thanks Joe, btw, for doing this. I've now got all the tools (pdf,web) I >>need in Erlang, and in the form of tutorials no less. I owe you quite a >>few beers :-) > > > Great - which bar?? > Hopefully one east of London? > /Joe From Sean.Hinde@REDACTED Wed Mar 12 18:26:27 2003 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Wed, 12 Mar 2003 17:26:27 -0000 Subject: ANNOUNCE: erlguten Message-ID: > Hmm. Would display postscript be in the pipeline? The GNUstep project > (gnustep.org) is working on something there. I'm interested in using > GNUstep for developing GUIs. I was very interested when Next Inc. > introduced their black cube. I hope to play with it at last > after almost > 15-20 years! AKAIK Apple originally wanted to use display postscript for OS X but they couldn't agree licencing with Adobe. They fell back to display PDF as second choice, but I remember reading that this caused them quite a performance hit. > > Great - which bar?? > > > > Hopefully one east of London? Or West of London?? Sean NOTICE AND DISCLAIMER: This email (including attachments) is confidential. If you have received this email in error please notify the sender immediately and delete this email from your system without copying or disseminating it or placing any reliance upon its contents. We cannot accept liability for any breaches of confidence arising through use of email. Any opinions expressed in this email (including attachments) are those of the author and do not necessarily reflect our opinions. We will not accept responsibility for any commitments made by our employees outside the scope of our business. We do not warrant the accuracy or completeness of such information. From Gosta.Ask@REDACTED Wed Mar 12 18:42:39 2003 From: Gosta.Ask@REDACTED (=?ISO-8859-1?Q?=22G=F6sta_Ask_=28EAB=29=22?=) Date: Wed, 12 Mar 2003 18:42:39 +0100 Subject: ANNOUNCE: erlguten References: Message-ID: <3E6F718F.4030402@etx.ericsson.se> Ulf Wiger wrote: > [ ... ] >, I would _love_ to see a shift towards writing simple XML > documents and then transforming XML -> HTML, and XML -> PDF. > > Not all documents we write need to be pretty (some do), but > all of them should be eminently searchable. Also, they need > to be version-controlled (and version control systems tend > to like text best of all.) > > What I guess is needed to convince those of my colleagues > who are not vi or emacs fanatics, is some input tool that > gives at least a decent approximation of what the output is > going to look like (WYSINWYWGBCEFW*) and some simple > graphical aide that hides those scary XML tags. (: > > /Uffe > (*) What You See Is Not What You Will Get, But Close Enough > For Government Work. > There is actually a good foundation for XML-based document handling inside the Big Company, although it has fallen from grace lately; the Powers that Rule seem to view MS Word as the end of the development ladder. And I suppose it is (turned upside down). Quite a few Customer Documents are still being written using Docware (the internal name for SGML/XML-based documentation). The key is the XSEIF DTD. From the internal Big-Company page I cut: "The new XSEIF-DTD was first released in the STD environment in TaGtool R8/R3 (released fall 2000). XSEIF is a modification of SEIF which is being phased out. Here is some of the highlights for the XSEIF-DTD. For more information we refer to the XSEIF User Guide and the Developer's Guide. * XML Compliant DTD XSEIF can be used both in SGML and XML tools. * XLink based linking system XSEIF provides a powerful linking system, designed to scale with emerging XLink based tools and infrastructures. [...]" The Xlink thing is in http://www.w3.org/TR/xlink/ I used to write quite a few documents using SEIF; always preferred it to Frame and the other alternatives. Version handling was good and the filters to produce html were straightforward. Easy to link in pictures from IslandDraw. Platform independence. The licensing from ArborText was the scary part. G?sta Ask System Test AXD301 From Marc.Vanwoerkom@REDACTED Wed Mar 12 19:00:57 2003 From: Marc.Vanwoerkom@REDACTED (Marc Ernst Eddy van Woerkom) Date: Wed, 12 Mar 2003 19:00:57 +0100 (MET) Subject: ANNOUNCE: erlguten In-Reply-To: (message from Joe Armstrong on Wed, 12 Mar 2003 16:07:18 +0100 (CET)) Message-ID: <200303121800.h2CI0vE15718@bonsai.fernuni-hagen.de> > In LaTeX layout it is almost impossibly difficult - you type in your > stuff and LaTeX figures out where to put it on the page. That is a feature not a bug. In LaTeX you choose a style and settle the big layout decisions by that choice and after this you can only layout in a constrained way. > - ErlGuten is > the other way around - you start by defining precisely where all the > boxes on a page are to be, and all the fonts etc. and then you say > what text is to be put into which box etc. So you code the style for that doc (in LaTeX terminology). > It is my hope that I will be able to replace LaTeX with ErlGuten and > achieve better quality results with less effort. And I already hoped ConTeXt would do that .. :) http://www.berenddeboer.net/tex/#from_latex_to_context .. ok it is already 10 years old. A very ambitious and exciting project! Regards, Marc From mikael.karlsson@REDACTED Wed Mar 12 17:59:15 2003 From: mikael.karlsson@REDACTED (Mikael Karlsson) Date: Wed, 12 Mar 2003 17:59:15 +0100 Subject: ANNOUNCE: erlguten In-Reply-To: References: Message-ID: <200303121759.15891.mikael.karlsson@creado.com> I recall that XML editors from Arbortext and Excosoft are (were?) also used within Ericsson. They provide some approximation of the end result. /Mikael onsdag 12 mars 2003 17:05 skrev Ulf Wiger: > On Wed, 12 Mar 2003, Joe Armstrong wrote: > > If you look at a newspaper the overall design is based on > >a smallish number of templates - where each template is a > >set of rectangular boxes (I guess most papers use less than > >20 templates) - indeed there should only be a small number > >of templates if the work as a whole is to have a consistent > >look and feel. > > Working for a Big Company (albeit smaller than it used to > be...), where you're supposed to write technical > documentation in FrameMaker, using some predefined templates > (technicians write docs in FrameMaker, product managers and > marketing people use MS Word, making things even better), I > would _love_ to see a shift towards writing simple XML > documents and then transforming XML -> HTML, and XML -> PDF. > > Not all documents we write need to be pretty (some do), but > all of them should be eminently searchable. Also, they need > to be version-controlled (and version control systems tend > to like text best of all.) > > What I guess is needed to convince those of my colleagues > who are not vi or emacs fanatics, is some input tool that > gives at least a decent approximation of what the output is > going to look like (WYSINWYWGBCEFW*) and some simple > graphical aide that hides those scary XML tags. (: > > /Uffe > (*) What You See Is Not What You Will Get, But Close Enough > For Government Work. From bernardp@REDACTED Wed Mar 12 19:03:14 2003 From: bernardp@REDACTED (Pierpaolo BERNARDI) Date: Wed, 12 Mar 2003 19:03:14 +0100 Subject: ANNOUNCE: erlguten References: Message-ID: <035601c2e8c1$c7a4e580$4cf36850@c1p4e3> From: "Joe Armstrong" > TeX/LaTeX also are flawed - TeX can't line up rows in two parallel > columns. Have you looked at Lout? Lout is a text formatter TeX style, but better. Its author, Jeff Kingston (jeff at cs.usyd.edu.au, being CC'ed), has started working on a new functional language called Nonpareil to be used for the implementation of Lout's successor. There's a thesis and other papers with a roadmap for this new system. I don't have URL's handy, I hope Jeff will supply them. Perhaps there's ground for a fertile exchange of ideas. To Jeff Kingston: Joe Armstrong just released a system and announced a plan which I think has much in common with your plan and view for a typesetting system. Here's Joe's announce: ================================ ErlGuten is now available at http://www.sics.se/~joe/erlguten-2.0/erlguten.html ErlGuten aims to produce typographic quality PDF from XML or a Erlang program. The release includes a library pdf.erl which can be used to create PDF directly from an ERlang program. ErlGuten emplements the first part of the "grand plan" for unifying GUIs and text production systems that I brain dumped earlier. Comments, errors and all feedback is welcome, as are volunteers /Joe ================================ P. From daniel.dudley@REDACTED Wed Mar 12 19:09:31 2003 From: daniel.dudley@REDACTED (Daniel Dudley) Date: Wed, 12 Mar 2003 19:09:31 +0100 Subject: ANNOUNCE: erlguten References: Message-ID: <006301c2e8c2$879edcb0$a3d3b33e@dld2000> Joe Armstrong wrote: > ErlGuten is now available at > > http://www.sics.se/~joe/erlguten-2.0/erlguten.html > > ErlGuten aims to produce typographic quality PDF from XML > or a Erlang program. > > The release includes a library pdf.erl which can be used to > create PDF directly from an ERlang program. > > ErlGuten emplements the first part of the "grand plan" for > unifying GUIs and text production systems that I brain > dumped earlier. > > Comments, errors and all feedback is welcome, as are > volunteers Just so that some of the downsides of Joe's arguments get to see some light ;-), I thought the following http://www.complang.tuwien.ac.at/anton/why-not-pdf.html might interest the many posters to this thread. Check out the links at the bottom of that webpage, too. This just might generate a more balanced critique of Joe's work in this area. As a matter of form and FWIW, I'll add that I don't agree with much of what is purported there, being a very pro-PDF person myself. Daniel From luke@REDACTED Wed Mar 12 19:09:28 2003 From: luke@REDACTED (Luke Gorrie) Date: 12 Mar 2003 19:09:28 +0100 Subject: ANNOUNCE: erlguten In-Reply-To: <035601c2e8c1$c7a4e580$4cf36850@c1p4e3> References: <035601c2e8c1$c7a4e580$4cf36850@c1p4e3> Message-ID: "Pierpaolo BERNARDI" writes: > From: "Joe Armstrong" > > > TeX/LaTeX also are flawed - TeX can't line up rows in two parallel > > columns. > > Have you looked at Lout? > Lout is a text formatter TeX style, but better. I'm quite fond of "Latte" myself. It is basically a scheme dialect with a TeX syntax, designed for generating HTML. The syntax is a bit excessively ugly, but I do like using 'map', 'lambda', etc in my web pages. For example, my homepage is http://www.bluetail.com/~luke/ The source to that page is http://www.bluetail.com/~luke/index.latte And the "style sheet" (library functions) are at http://www.bluetail.com/~luke/style.latte I won't say it's beautiful, but it is quite fun :-) Cheers, Luke From Marc.Vanwoerkom@REDACTED Wed Mar 12 19:33:50 2003 From: Marc.Vanwoerkom@REDACTED (Marc Ernst Eddy van Woerkom) Date: Wed, 12 Mar 2003 19:33:50 +0100 (MET) Subject: ANNOUNCE: erlguten In-Reply-To: (message from Joe Armstrong on Wed, 12 Mar 2003 16:39:29 +0100 (CET)) Message-ID: <200303121833.h2CIXoA19074@bonsai.fernuni-hagen.de> > TeX/LaTeX also are flawed - TeX can't line up rows in two parallel > columns. It was an early system to typeset maths and a glorious example of literate programming (you can reconstruct the whole system from the publications even in 500 years). Of course it can't be the end of all things DTP BTW I recommend the book http://www-cs-faculty.stanford.edu/~knuth/dt.html > The use of LaTeX in producing scientific documents has resulted > in virtually all publications looking identical - > the typography is often awful as are the fonts - believe > me there are some really *beautiful* type 1 > postscript fonts which deserve to get used in scientific publications. I guess that is due to TeX being free with one (older) font, and professional fonts costing both money (priced in professional regions) and are available only from a few sources. E.g. the lucida fonts that were used for the LaTeX compagnion. I never encountered it in a book shop. So most folks took the old font. Even now, when it is possible to use a rather nice post script font in your LaTeX doc, e.g. http://www.utdallas.edu/~ryoung/txfonts/ one still encounters those horrible dvips2pdf-ized LaTeX docs, which don't scale. > Erlguten design will reflect this - the idea (not yet implemented) > is to have a small number of templates + a large database of articles. Thats the basic style file idea from LaTeX, or? > The other point is *quality* I want to achieved the highest possibly > quality - MS word etc. get character kerning *wrong* and miss out > ligatures - they make typographically crazy decisions - setting up > fixed columns (a la newspaper) is terribly difficult. I would need to train my typographic know-how. Anyone knows a standard book which is used to train typographers? > There seems to be no good free software to produce high quality PDF > from XML (I looked) the industry "standard" way of doing this is to > use XSLT to transform XML to the FOSSI XML DTD and then transform this > to a subset of TeX and then transform this to PDF. Somebody programmed a XSLT processor in TeX http://www.hobby.nl/~scaprea/context/ It so you can e.g. render Docbook into PDF. If it is good I can't judge. > This method is extremely complicated and > incredibly difficult to produce any good results (I've tried). Yes the setup is a PITA. The FreeBSD docbook team created an impressive metaport just for setting up the tools. http://www.freebsd.org/cgi/cvsweb.cgi/ports/textproc/docproj/ It has also pitfalls like overflows of the standard pool sizes for PDFTeX for a real world sized book. So you need to tweak the pool sizes. > *beautiful* typefaces - and get the layout right - try reading a few > books on typography first :-) ((seriously)) Please recommend some. Regards, Marc From Marc.Vanwoerkom@REDACTED Wed Mar 12 19:51:06 2003 From: Marc.Vanwoerkom@REDACTED (Marc Ernst Eddy van Woerkom) Date: Wed, 12 Mar 2003 19:51:06 +0100 (MET) Subject: ANNOUNCE: erlguten In-Reply-To: (message from Joe Armstrong on Wed, 12 Mar 2003 16:53:31 +0100 (CET)) Message-ID: <200303121851.h2CIp6U20756@bonsai.fernuni-hagen.de> > Yes - I'd like a PDF reader in Erlang - and I'd like to write GUIs > with the *same* layout language as used for creating PDF (like go 'ol > display postscript) Others do so http://www.apple.com/macosx/jaguar/quartzextreme.html http://a32.g.akamai.net/7/32/51/e3f09c3d615efe/www.apple.com/macosx/pdfs/Quartz_TB.pdf > I aim (of course) at better quality than TeX - whether I can do this > remains to be seen. I want to stress that TeX is not about ultimate quality. It was rather about reaching a sufficient quality at some point and then allowing TeX documents to stay reproducable in that quality over a lifetime longer than a few decades, e.g. in 500 years, by documenting the whole system TeX+Metafont+Fonts in a couple of books and feature freezing. TeX is kind of a software equivalent of the pyramids (seen as a temporal long distance message). Regards, Marc From joe@REDACTED Wed Mar 12 20:53:57 2003 From: joe@REDACTED (Joe Armstrong) Date: Wed, 12 Mar 2003 20:53:57 +0100 (CET) Subject: ANNOUNCE: erlguten In-Reply-To: <3E6F59E2.8010005@manderp.freeserve.co.uk> Message-ID: > > Following your example of inappropriate type faces, would a template > offer recommended type faces? Would other graphical elements be > incorporated, such as styles for graphics and tables? > yes ^ 10 I have some books on typography that just have page after page showing what different typefaces look like when set with different point size/leadings and set in different measures. The funny thing is that the "old style" books (pre DTP) were full of notes like "ITC Gothic Franklin" looks best in 24 pica columns when set 8.5/11 ... etc. - seeing these layed out next to each other in different combinations of Point size/Leading and in different measures is quite instructive. I imagine making different templates where I explicitly choose the basic Font/point size/leading/measure and what fonts to use for displays etc. - this is after all, what a newspaper does. I thought to start just by copying a normal newspaper design. That and a ruler and squared paper is all I need - oh and a pencil and rubber, we're talking high tech here - after all, saying that a frame should be 30 picas width is an infinitely precise measure - much better than vaguely indicating the position with a mouse. I'd also try to make templates with fonts that look nice when printed - one reason why people make crappy documents is, I think, because they spend ages fiddling with the document to make it look nice on the screen and then just assume that it will look nice on paper. Typefaces with very delicate serifs can look beautiful when printed on a decent printer, but will always look crap on a low resolution screen since the serifs just vanish - I assume this is why we are subjected to "Ariel" everywhere (because it looks nice on screen) - Garamond on the other hand looks worse on screen but much nicer on paper - which is when we rarely see it on paper. IMHO one should edit in EMACS and tell the system what font to use - if you actually *see* the font while editing it's either too big or too small so you have to fiddle with the "zoom" controls all the time to even see what you are editing - Thus I consider "content" to be something that is created in EMACS and stored in a data base of file system - and layout to be decided purely on the basis of what looks nice when it is printed *Not* on what looks nice when you are editing it. > Maybe going *slower* would improve things? Taking time to polish would > do wonders to the result. But we're all racing to produce stuff too > quickly I think. > Well in the good 'ol days at least 4 people were involved in book production. - the author (who hand wrote, or typed the manuscript) - the typesetter - the proof reader - the editor All these were highly skilled at their own jobs - it took about 6 years to become good at typesetting. Now the author (who knows precious little about layout and typography) has to do it all - no wonder quality is dropping. /Joe From erlang@REDACTED Wed Mar 12 21:41:11 2003 From: erlang@REDACTED (Peter Mander) Date: Wed, 12 Mar 2003 20:41:11 -0000 Subject: ANNOUNCE: erlguten References: Message-ID: <000501c2e8d7$fb136480$a9e7883e@qurious> ----- Original Message ----- From: "Sean Hinde" To: "'Peter-Henry Mander'" ; "Joe Armstrong" Cc: Sent: Wednesday, March 12, 2003 5:26 PM Subject: RE: ANNOUNCE: erlguten > > Hmm. Would display postscript be in the pipeline? The GNUstep project > > (gnustep.org) is working on something there. I'm interested in using > > GNUstep for developing GUIs. I was very interested when Next Inc. > > introduced their black cube. I hope to play with it at last > > after almost > > 15-20 years! > > AKAIK Apple originally wanted to use display postscript for OS X but they > couldn't agree licencing with Adobe. They fell back to display PDF as second > choice, but I remember reading that this caused them quite a performance > hit. > I had assumed that the use of GNU GhostScript or a derivative thereof would side-step the licensing issue in GNUstep. > > > Great - which bar?? > > > > > > > Hopefully one east of London? > > Or West of London?? Oh. So Scotland is northward, then? Oops! (-: Joe, please get correct directions from Sean, he's obviously more geographically clued up than I! I'm alright, embarassment isn't fatal, so I've heard. Pete. From chris_pressey@REDACTED Wed Mar 12 22:13:45 2003 From: chris_pressey@REDACTED (Chris Pressey) Date: Wed, 12 Mar 2003 16:13:45 -0500 (EST) Subject: ANNOUNCE: erlguten Message-ID: <20030312211345.36776.qmail@web20507.mail.yahoo.com> > ErlGuten is now available at > > http://www.sics.se/~joe/erlguten-2.0/erlguten.html > > ErlGuten aims to produce typographic quality PDF from XML or > a Erlang program. > > The release includes a library pdf.erl which can be used to create > PDF directly from an ERlang program. SWEET. Good timing too. A prospective client wants me to write some custom job costing software - I want to do this project in Erlang, but was worried that I'd have to resort to Visual Basic to fulfill his requirement for high-quality printed reports under Windows. I considered generating HTML, as I've used it in another project where I had to produce something printable and non-ugly, but there are two significant drawbacks: 1) HTML wasn't designed to be printed (no page breaks etc) 2) No automation (user must open HTML in browser and select 'Print') Erlguten (or just pdf.erl) definately solves #1. #2 can't be that hard - what would be most excellent would be able to say something like pdf:print(Document, PrinterName) and have this work in a platform-independent way. Under unix it should be easy (I think?) if the spool is properly set up to recognize PDF. Under Windows, it might be a bit hellish... Although, hmmm! I just discovered that I can shell "acroread.exe /p filename.pdf" and have it pop up a 'Print' dialog box - clicking 'OK' sends it to the default printer - definately good enough for now. Thank you, Joe. I feel I owe you more than a few beer :) -Chris ______________________________________________________________________ Post your free ad now! http://personals.yahoo.ca From mikael.karlsson@REDACTED Wed Mar 12 22:22:58 2003 From: mikael.karlsson@REDACTED (Mikael Karlsson) Date: Wed, 12 Mar 2003 22:22:58 +0100 Subject: ANNOUNCE: erlguten In-Reply-To: <035601c2e8c1$c7a4e580$4cf36850@c1p4e3> References: <035601c2e8c1$c7a4e580$4cf36850@c1p4e3> Message-ID: <200303122222.58488.mikael.karlsson@creado.com> Lout - http://snark.ptc.spbu.ru/~uwe/lout/ has some PDF processing now, limited though. I think you also have pretty good control were you can place things in Lout, but I am not sure if it fulfils Joes requirements. There is also an implementation in Haskell of the Lout "galleys" which I don't understand 100% of: http://ist.unibw-muenchen.de/kahl/Haskell/VGalleys.html Joe calls his xml layout files galley_001.gal, so I guess he had a look or two on the Basser Lout. onsdag 12 mars 2003 19:03 skrev Pierpaolo BERNARDI: /Mikael > From: "Joe Armstrong" > > > TeX/LaTeX also are flawed - TeX can't line up rows in two parallel > > columns. > > Have you looked at Lout? > Lout is a text formatter TeX style, but better. > > Its author, Jeff Kingston (jeff at cs.usyd.edu.au, being CC'ed), > has started working on a new functional language called > Nonpareil to be used for the implementation of Lout's successor. > > There's a thesis and other papers with a roadmap for > this new system. I don't have URL's handy, I hope Jeff > will supply them. > > Perhaps there's ground for a fertile exchange of ideas. > From matthias@REDACTED Wed Mar 12 22:22:09 2003 From: matthias@REDACTED (Matthias Lang) Date: Wed, 12 Mar 2003 22:22:09 +0100 Subject: Remote connect problems. In-Reply-To: <200303121115.47960.blitzfeuer@sc.rr.com> References: <15981.37713.413881.422852@antilipe.corelatus.se> <200303121115.47960.blitzfeuer@sc.rr.com> Message-ID: <15983.42241.974614.932205@antilipe.corelatus.se> Walter C. Reel III writes: > With the fully qualified name provided neither of the machines can talk to > each other now. [...] Everything you're doing looks correct. The next steps are to figure out whether epmd is doing the right things. If I start a node on each of my two machines and run 'epmd -names', I see: xterm1@REDACTED> erl -name 'whipper@REDACTED' -setcookie nocookie xterm2@REDACTED> /usr/local/lib/erlang/bin/epmd -names epmd: up and running on port 4369 with data: name whipper at port 1460 on the other machine xterm3@REDACTED> /opt/erlang/lib/erlang/erts-5.1.2/bin/epmd -names epmd: up and running on port 4369 with data: name snipper at port 4916 If you see something similar (i.e. each EPMD process has its local node registered), then it's starting to get hairy. You can get more information by sniffing the ethernet when you do the first ping from one node to the other. You should see a successful TCP 3-way on port 4369 followed by a second successful 3-way on another port. Anyone out there who uses Windows on a regular basis with some suggestions? Matthias From spearce@REDACTED Wed Mar 12 22:30:38 2003 From: spearce@REDACTED (Shawn Pearce) Date: Wed, 12 Mar 2003 16:30:38 -0500 Subject: Which is faster? Message-ID: <20030312213038.GB23238@spearce.org> So the "Efficiency Guide" leads me to believe that sticking a function in ets would be faster than using Module:Function(Arg) to invoke a function. ie: [#rec{function=Fun}] = ets:lookup(some_table, Key), Fun(X) is faster than: [#rec{module=Module, function=Function}] = ets:lookup(some_table, Key), Module:Function(X) Clearly either way we are doing an ets call, but I ask in the context of two things: - What is the cost of copying the fun from ets to the local process? - What happens when I reload the module that created Fun? Clearly in the second case hot-reloading works well. -- Shawn. Just to have it is enough. From etxuwig@REDACTED Wed Mar 12 22:44:22 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Wed, 12 Mar 2003 22:44:22 +0100 (MET) Subject: ANNOUNCE: erlguten In-Reply-To: Message-ID: On Wed, 12 Mar 2003, Joe Armstrong wrote: > IMHO one should edit in EMACS and tell the system what >font to use - if you actually *see* the font while editing >it's either too big or too small so you have to fiddle with >the "zoom" controls all the time to even see what you are >editing - Thus I consider "content" to be something that >is created in EMACS and stored in a data base of file >system - and layout to be decided purely on the basis of >what looks nice when it is printed *Not* on what looks nice >when you are editing it. Back when I spent my time teaching Word and Excel to bueraucrats, I used to urge people to just type and forget about formatting until later. The main reason was that most people had no idea how to use Word properly, and would insert lots of formatting the wrong way -- I always had to begin by "washing" the document from faulty formatting before I could begin tagging paragraphs properly. Most (?) people have difficulty leaving the text alone and want to fiddle the layout with it while they're writing. Perhaps this is a disease that started with WYSIWYG editors - I don't know. If I had to pick one aide to go with Emacs, it would be an outliner. The Word outliner was the main reason I didn't abandon it years ago. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From chris_pressey@REDACTED Wed Mar 12 23:14:38 2003 From: chris_pressey@REDACTED (Chris Pressey) Date: Wed, 12 Mar 2003 17:14:38 -0500 (EST) Subject: Statefulness = "Processness"...? Message-ID: <20030312221438.52114.qmail@web20503.mail.yahoo.com> Jay Nelson wrote: > When I mentioned Okasaki's term "persistence" it means > something very different than the same term applied to > OO instances. I understood that much, or at least I thought I did. I think I accidentally swapped the meaning of the terms, though. (I hate terminology. It's really unfortunate that I can idly say "single-assignment variable" and most programmers won't even blink.) > [...] > First note that paying attention to the internals without regard > to the display leads to an efficient and understandable data > structure that is completely unexpected when compared to the > imperative approach used by X-windows, et al. Absolutely. The condition is a lot worse in something like Visual Basic, which encourages a bizarre "front-in" design philosophy. > Second, the code uses the nature of functional data structure > versions that comes automatically to allow undo and redo. > [...] > To do this in an imperative language you would have to introduce > lists and explicitly copy the string every time (and I'll bet you > wouldn't have stored it backwards because you probably pre- > allocated the memory and used a pointer -- it wouldn't even occur > to you that backwards storage might be beneficial) Actually, this is mainly where my confusion was. In an imperative language, I don't think it's that much more complicated - I'd just use a stack for undo. A stack being a 'naturally backwards' list. My idea of the implicit 'undo' in a functional language results from the recursion itself, and doesn't require a list - the best example I can think of right now is backtracking (which is essentially a form of undo.) The old values are 'remembered' in the call stack (or whatever mechanism is used to do the recursion.) So you just return from the current scope, and the previous scope still has access to the data it was using before the call, since it can't have been changed by anything else. Undo, no lists required. The thing is, you can't do it this way with a textbox, essentially because the textbox is shared. Maybe you could do it this way with a single textbox in a modal dialog box with one owner which is patiently waiting for it to close and which isn't sharing it with anything else. But not in the general case. Definately not, if we're considering 'liveness' as an important property (some other node might want the textbox contents to change, etc.) > so I would > wager the imperative implementation would be less efficient. On > top of that you would have to make new instances with different > length pre-allocated buffers for each textbox you wanted, or else > make it really big and hope you never overrun it (probably the > most commonly occurring and most insecure bug in all of software) > or some complicated realloc refinement would have to be > introduced (which of course would triple the memory use > because you would realloc at double size, copy memory and > then free). Yeah, doing it without GC would suck. > In erlang, manipulating every version of the data structure that > ever existed is more natural and fairly straight-forward. The > textbox behaviour above could be in a separate process so no > other code could get at the internals other than using the message > interface (strong encapsulation). If a pointer to a particular > version of the textbox internals were obtained outside the > process, it couldn't be changed in a way that would affect the > textbox or undo / redo. Also you get concurrent execution with > all the other textboxes (think of scrolling stock tickers for > different stock market exchanges instead of text type-in boxes). > > In fact, other processes could arbitrarily ask for _any_ version > of the textbox internals if you provided an message interface to > do so. > > jay I pretty much agree with this when it comes to controls with state, like textboxes. But what about controls without state, or barely any state, I wonder? Like pushbuttons and frames and labels. Do they still get processes? If so, why, if it is wasteful enough to warrant not doing it? And if not, how do you deal with the unorthogonality that will almost certainly present? -Chris ______________________________________________________________________ Post your free ad now! http://personals.yahoo.ca From vances@REDACTED Wed Mar 12 23:22:43 2003 From: vances@REDACTED (Vance Shipley) Date: Wed, 12 Mar 2003 17:22:43 -0500 Subject: Remote connect problems. In-Reply-To: <15983.42241.974614.932205@antilipe.corelatus.se> References: <15981.37713.413881.422852@antilipe.corelatus.se> <200303121115.47960.blitzfeuer@sc.rr.com> <15983.42241.974614.932205@antilipe.corelatus.se> Message-ID: <20030312222243.GN30349@frogman.motivity.ca> You can turn on debugging by giving epmd the debug flasg(s): epmd -names -ddddd That'll give you more out put to look at. Compare sucessful to unsuccessful. -Vance From bernardp@REDACTED Wed Mar 12 23:06:57 2003 From: bernardp@REDACTED (Pierpaolo BERNARDI) Date: Wed, 12 Mar 2003 23:06:57 +0100 Subject: ANNOUNCE: erlguten References: <035601c2e8c1$c7a4e580$4cf36850@c1p4e3> <200303122222.58488.mikael.karlsson@creado.com> Message-ID: <000201c2e8eb$c5578100$90f06850@c1p4e3> From: "Mikael Karlsson" > Lout - http://snark.ptc.spbu.ru/~uwe/lout/ > has some PDF processing now, limited though. > I think you also have pretty good control were you can place > things in Lout, but I am not sure if it fulfils Joes requirements. Probably it doesn't, but I wanted to draw attention to Lout's successor, which is based on a functional language, which is being designed right now. Jeff Kingston recently requested comments on his design from experts in functional languages (specifically, on type systems, but anyway). So, I think there's some common ground between the two projects. > There is also an implementation in Haskell of the > Lout "galleys" which I don't understand 100% of: > http://ist.unibw-muenchen.de/kahl/Haskell/VGalleys.html I didn't knew this. > Joe calls his xml layout files galley_001.gal, so I > guess he had a look or two on the Basser Lout. Oh! I thought "galley" was a common enough typographical term that one could use it without knowing Lout. Cheers P. From etxuwig@REDACTED Thu Mar 13 00:13:40 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Thu, 13 Mar 2003 00:13:40 +0100 (MET) Subject: fun with referential integrity Message-ID: I decided to actually use my rdbms contrib today. (: I had a number of tables that I wanted to connect in a multi-level pattern of cascading delete. Due to some bad design decisions previously, I ended up having to define a cyclical pattern of dependencies, but pressed on with unwarranted confidence. (Just to clarify, what I was aiming for was this: if one deletes an object A, then all B and C should also be deleted if A.id == B.a_id, and B.id == C.b_id. The cyclical dependency was that one should also delete B (where B.id == C.b_id) anytime one deletes C (don't ask).) I discovered that rdbms did not, in fact cascade down more than one level. That is, when deleting A, all related B were deleted, but the Cs remained. I went into rdbms and made the obvious fix, which immediately threw me into an endless loop -- not good. After a few hours, I realised that the solution for cascading delete was obvious: delete A first, then do the cascade, and the same thing downwards. This worked, too. The real problem is of course with cascading update, which suffers from the same issues, but requires a different solution. I have to maintain a visited list, I guess, if I am to allow for the possibility of cyclical dependencies. Of course the visited list must support the notion of nested transactions, which means several levels of visited lists. ... or should I make it easier on myself and simply disallow cyclical dependencies? This seems like a fairly limiting restriction. How do the real pros do it? Does anyone know? /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From jay@REDACTED Thu Mar 13 05:27:21 2003 From: jay@REDACTED (Jay Nelson) Date: Wed, 12 Mar 2003 20:27:21 -0800 Subject: Statefulness = "Processness"...? Message-ID: <4.2.2.20030312200627.00d1e280@duomark.com> Chris Pressey wrote: > I'd just use a stack for undo. A stack being a 'naturally > backwards' list. A stack of strings? Or a stack of character stacks? The obvious would be a stack of strings, but every char you add means a copy of the string plus one char to be pushed on the stack. With a stack of character stacks you have to have a function that puts them together into a string that you return when any version is requested. Basically, anything you do needs a history of how this state was arrived at either by retaining a copy of all the states or by retaining a copy of all the edits performed. > My idea of the implicit 'undo' in a functional language > results from the recursion itself, and doesn't require a list This is non-obvious to the style of programming I do. It has a few drawbacks, the main one being that you can't manage the stack easily so you can't get back to a particular version (e.g., imagine a text box with a pulldown that shows every version of its state where you could select an older one). You still need a list, when the stack is unwound the chars have to be accumulated into a list (which may be partially built at each recursive call). The code and exceptions get a little hairy. It may require resorting to a catch / throw pair, a less than elegant solution. Cut of several characters in the middle of the string is particularly difficult. Typing in the data is not a recursive or inductive act, it is an unpredictable serialized sequence. It is much easier and clearer to use accumulator(s) in the recursion and the accumulator(s) look(s) like the record I used. > The thing is, you can't do it this way with a textbox, > essentially because the textbox is shared. Unless your definition of textbox is radically different than a standard one, it is by nature a single-state device. If two processes want to change it, there are either two instances, two closures with two views, or last changed view only. So I don't understand this statement. jay From jay@REDACTED Thu Mar 13 06:16:36 2003 From: jay@REDACTED (Jay Nelson) Date: Wed, 12 Mar 2003 21:16:36 -0800 Subject: What are processes good for? Message-ID: <4.2.2.20030312202751.00d34ea0@duomark.com> Chris Pressey wrote: > But what about controls without state, or barely any state, > I wonder? Like pushbuttons and frames and labels. Do > they still get processes? See discussion below. Frames and labels are generally static adornments. They could be changed by external function calls, or could be active themselves, but today they are generally just static state. Push buttons are input devices and need to be asynchronous stream signallers to other processes; they need to be always alive and able to send messages instantly. Their appearance on the screen is less relevant as in the case of frames and labels. > If so, why, if it is wasteful enough to warrant not doing it? Programmers should always waste resources in order of their availability. Amongst processes, memory, CPU cycles, communication bandwidth, etc. each situation may vary, but waste the cheapest and most abundant resource if it makes the code clearer, faster or more correct. In erlang processes are abundant, and if you need more CPU "wasting" them across nodes can increase performance if communication overhead is low. > And if not, how do you deal with > the unorthogonality that will almost certainly present? I don't understand this question. ================== Thoughts on Processes =================== Joe, et al, say that there should be one process for each real world concurrent activity (or something along those lines). Which is equivalent to the OO answer that there should be one Object for each real world object being modeled. While this is a good guideline, it assumes that the software is modeling real-world processes and activities. There are other reasons for using processes (once you are no longer a beginning programmer in erlang). Here are a few I thought of. I would be interested in any additions that others think of. Processes are useful for: 1) Modeling real world concurrent activities. - Self-explanatory for "liveness" purposes, but also in the realm of simulating multi-agent systems where each process is an independent agent. - OO programming would fall here. 2) Strong encapsulation - This is an engineering design decision to hide state, and provide a black-box communication interface to prevent unpredictability inside the model. - Finite state machine programming. - Or OO programming could fall here if you are not doing simulations or are working with abstract objects. 3) Code reuse / abstraction / adapting interfaces. - If strong encapsulation is used, two processes may only be able to talk to one another if they are aware of the interface design. An adaptor process can be added to allow reuse of the two without modification (within the limitations of semantic equivalence). - If a complicated feature is not yet implemented, a simple substitute can be dummied up in a process and replaced later (although functions work as well, build, execution and management may be simplified by a separate process). - Streams can be transformed by successive process filtering to interface two existing bodies of code, or to simplify the algorithms by eliminating exception handling. 4) Simulating environmental influences. - In test situations a stream of sample data is useful in exercising a system, or where access to the real environment is prohibitive (e.g., the device is not yet built, the sensors need to be in outer space, catastrophic physical world failures, etc.) - This could be viewed as #1 but I think it warrants separate consideration. 5) Creating unpredictable, complex behaviour / adaptive behaviour - Dynamic feedback of multiple very simple processes can be used to create complex behaviour. Think of a series of differential equations. - The ease of process creation and death allows for an approach to adaptive systems based on the collection of active processes changing in response to external influences. 6) Resource management / distribution - Relocation of connected resources may require the code to run on a different processor. Processes are more easily managed and dynamically distributed. - When a resource has initialization and finalization needs, a process that traps EXITs can simplify the implementation. - Code replacement may be easier if the functionality is subdivided to account for stateful and stateless pieces; processes allow for simpler replacement policies. - Non-stop operation requires replication, failover and redundancy as well as partial or whole retry semantics. - When a resource is in short supply on a single node, (e.g., power, CPU speed, memory, attached storage) distributing the processing to several nodes may be a necessary architectural consideration. - Providing several peripherals with a common interface or network accessibility requires separate processes on each. Any other ideas? jay From vlad_dumitrescu@REDACTED Thu Mar 13 06:27:22 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Thu, 13 Mar 2003 06:27:22 +0100 Subject: Statefulness = "Processness"...? References: <20030312221438.52114.qmail@web20503.mail.yahoo.com> Message-ID: Chris wrote: > The thing is, you can't do it this way with a textbox, essentially > because the textbox is shared. Maybe you could do it this way > with a single textbox in a modal dialog box with one owner which is > patiently waiting for it to close and which isn't sharing it with > anything else. > > But not in the general case. Definately not, if we're considering > 'liveness' as an important property (some other node might want the > textbox contents to change, etc.) Hi, Liveness is important, but I don't think it is good design to pop up a dialog for the user to enter data and let the content change "automagically" because of some background activity. It is unexpected and confusing, not to think about what happens if the user is mid-way through entering a name and it is suddenly replaced by something else. So liveness shouldn't affect fields where the user is expected to enter data. regards, Vlad From jay@REDACTED Thu Mar 13 06:39:26 2003 From: jay@REDACTED (Jay Nelson) Date: Wed, 12 Mar 2003 21:39:26 -0800 Subject: OO vs CO vs SO Message-ID: <4.2.2.20030312212113.00d33b50@duomark.com> Object Oriented programming (OO) defines a static inheritance hierarchy, and the lifecycle of object instances that interact. At first blush the inheritance aspect seemed the most important thing from a code reuse standpoint and a consistent model approach. It seems that current attitudes support the view that cooperating objects are more useful than inheritance hierarchies. The whole approach to design patterns is telling, with delegation and class factories and all that. Concurrent Oriented Programming (CO) seems to be a similar approach that defines the world in terms of concurrent activities and the encapsulation of state to make independent agents. However, neither objects nor processes exist in a vacuum or a fixed environment state. The world is constantly changing and the "agents" in the world react based on external sensors that impinge on the internal state, potentially cause a computation and a reaction that is broadcast to the external world. To me the most interesting thing is the interaction of all the agents, not the modeling of individual agents. When individual objects, or agent processes, are the focus, the difficult complexity of interaction is ignored in favor of the easier modeling problem. It becomes difficult to think of things on a larger scale. I find imperative programming restricts me to thinking in terms of the current case, or cases one at a time. The functional approach allows me to think inductively, or recursively, and to apply code to broader situations, so that I instinctively think of whole sets rather than single cases. (Once a "case ... of" function is written, I think of it as a magic handler of all the known cases and can now consider herds of data at once.) I think Stream Oriented Programming (SO) is an alternative that erlang allows, which is harder to consider in other languages. Rather than breaking a system down into real-world components, or logical pieces, consider mass data flows and their implications. This allows top down design, overall system architecture prior to worrying about algorithmic details and high-level discussion with others of the behaviour of the system, the problem space (rather than an instance of the problem space) and topologically equivalent solutions to consider as alternatives. Approaching a problem this way allows a much more reasonable answer to questions about failure, liveness, dynamics and appropriate system behaviour under the panoply of situations that it will encounter. jay From jay@REDACTED Thu Mar 13 06:44:56 2003 From: jay@REDACTED (Jay Nelson) Date: Wed, 12 Mar 2003 21:44:56 -0800 Subject: Statefulness = "Processness"...? Message-ID: <4.2.2.20030312214027.00d1db80@duomark.com> Vlad wrote: > So liveness shouldn't affect fields where the user is > expected to enter data. Active screens are useful for directing the user. 3D elements are just adornments, but a ticking sound that gets faster could spur the user to action, a changing of color could indicate a slider bar effect is being responded to, or other feedback may be extremely useful in a next generation display. Think of progress bars and remember when they were a big improvement that let people know the computer wasn't just locked up. Now think of the animated GIFs that were used for the same purpose, but didn't help at all (my browser is still running, but the server is locked). I agree that you don't want unexpected things to happen while the user is concentrating, but simple suggestions are very useful (think dialtone, busy signals, TV static on non-existent channels, etc.). jay From vlad_dumitrescu@REDACTED Thu Mar 13 07:01:42 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Thu, 13 Mar 2003 07:01:42 +0100 Subject: Statefulness = "Processness"...? References: <4.2.2.20030312214027.00d1db80@duomark.com> Message-ID: Jay wrote: > I agree that you don't want unexpected things to happen > while the user is concentrating, but simple suggestions > are very useful (think dialtone, busy signals, TV static on > non-existent channels, etc.). yes, of course, but these active fields are not the textboxes where the user is expected to type. They are only visual effects. If I am supposed to enter a file path and something interferes with it, changing it every half second, it will be very frustrating! :-) /Vlad From jay@REDACTED Thu Mar 13 07:46:03 2003 From: jay@REDACTED (Jay Nelson) Date: Wed, 12 Mar 2003 22:46:03 -0800 Subject: ANNOUNCE: erlguten Message-ID: <4.2.2.20030312220430.00d2fce0@duomark.com> Joe wrote: > In ErlGuten a document has three parts, a layout, content > and a map which maps content onto layout boxes ... > ErlGuten is the other way around - you start by defining > precisely where all the boxes on a page are to be, and all > the fonts etc. and then you say what text is to be put into > which box etc. Yes, yes way to go! This is the approach I am using with auto-generated website content: CSS2 stylesheets for layout, snippets for content. String snippets together to create the filler for a layout. > Erlguten design will reflect this - the idea (not yet implemented) > is to have a small number of templates + a large database of > articles. Making a document consists then of choosing a template > and dropping an article into it. I imagine generating these (content > -> template) map on the fly and producing personalized content. Exactly the right approach. Worry about typing content when that is what you are doing; worry about how it looks when that is what you are doing. I think modal tasking simplifies a complex problem. > IMHO one should edit in EMACS and tell the system what font to use I never thought of this. Seems interesting. I wonder if distel + Emacs would be a good collaborative P2P document environment. > Erlguten design will reflect this - the idea (not yet implemented) > is to have a small number of templates + a large database of articles. Hmmm, I can understand why you might have a large database of articles, but I tend to have a large collection of text snippets. I don't write an entire document at one sitting. I tend to collect interesting items, and I tend to write in bursts or throw down some ideas that I rework later. I string them together when I need to produce a document, and I reuse some of the ideas in later communications. I do keep my finished documents, but my unfinished docs and notes and snippets outnumber my finished documents. I don't consider received email a good candidate for a "document" but I would like to display them in different ways. When researching, I may quote from several of them, interspersed with explanation (sort of like this ramble). I want a database of snippets that I can easily reorganize and format for pretty output, sometimes creating "documents" from them. > I read that a typesetter setting newsprint on a Linotype machine > could enter properly formatted text 4 times faster than with a > modern desk top publishing system. This was *not* WYSIWYG > but all done single key type setting commands ... Oh gosh, that brings back memories. PageMaker v1.0 had just come outand we compared using PM to a low-level command line program that was like linotype with single keystroke formatting. Way faster for anything more than a newsletter, and kerning down to 1/1100 of an inch. I typeset a 40 page manual on the *new* Mac (in 1985, when the term WYSIWYG was first being used) using the typesetting software and sent the digital file to a Linotype shop for printing. The software let me use any PostScript commands and just generated a raw PostScript file, I don't think anything else like it was around it the time other than Linotype which was at least $35K for a workstation and you still needed to take it to a printer. Just a shell interface with an editor and lots of WordPerfect-style embedded formatting. > If anybody knows how to get a Linotype manual can they mail me :-) Unfortunately I never got my hands on the Linotype machine or the manual but remember seeing them and drooling. What a geek! Can't remember the name of the program we used. Hey, let me know when the beer thing is! I would like to be in on it if I can arrange it geographically. I think West London is closer to me. jay From svg@REDACTED Thu Mar 13 08:58:44 2003 From: svg@REDACTED (Vladimir Sekissov) Date: Thu, 13 Mar 2003 12:58:44 +0500 (YEKT) Subject: fun with referential integrity In-Reply-To: References: Message-ID: <20030313.125844.74756860.svg@surnet.ru> Good day, etxuwig> .... or should I make it easier on myself and simply disallow etxuwig> cyclical dependencies? This seems like a fairly limiting etxuwig> restriction. How do the real pros do it? Does anyone know? For my opinion cyclical references are a bad thing. I usually model bidirectional relationships using another table D with composite primary key and foreign keys to B and C. Best Regards, Vladimir Sekissov etxuwig> I decided to actually use my rdbms contrib today. (: etxuwig> etxuwig> I had a number of tables that I wanted to connect in a etxuwig> multi-level pattern of cascading delete. Due to some bad etxuwig> design decisions previously, I ended up having to define a etxuwig> cyclical pattern of dependencies, but pressed on with etxuwig> unwarranted confidence. etxuwig> etxuwig> (Just to clarify, what I was aiming for was this: if one etxuwig> deletes an object A, then all B and C should also be deleted etxuwig> if A.id == B.a_id, and B.id == C.b_id. The cyclical etxuwig> dependency was that one should also delete B (where B.id == etxuwig> C.b_id) anytime one deletes C (don't ask).) etxuwig> etxuwig> I discovered that rdbms did not, in fact cascade down more etxuwig> than one level. That is, when deleting A, all related B were etxuwig> deleted, but the Cs remained. I went into rdbms and made the etxuwig> obvious fix, which immediately threw me into an endless loop etxuwig> -- not good. etxuwig> etxuwig> After a few hours, I realised that the solution for etxuwig> cascading delete was obvious: delete A first, then do the etxuwig> cascade, and the same thing downwards. This worked, too. etxuwig> etxuwig> The real problem is of course with cascading update, which etxuwig> suffers from the same issues, but requires a different etxuwig> solution. I have to maintain a visited list, I guess, if I etxuwig> am to allow for the possibility of cyclical dependencies. Of etxuwig> course the visited list must support the notion of nested etxuwig> transactions, which means several levels of visited lists. etxuwig> etxuwig> .... or should I make it easier on myself and simply disallow etxuwig> cyclical dependencies? This seems like a fairly limiting etxuwig> restriction. How do the real pros do it? Does anyone know? etxuwig> etxuwig> /Uffe etxuwig> -- etxuwig> Ulf Wiger, Senior Specialist, etxuwig> / / / Architecture & Design of Carrier-Class Software etxuwig> / / / Strategic Product & System Management etxuwig> / / / Ericsson AB, Connectivity and Control Nodes From Vlad.Dumitrescu@REDACTED Thu Mar 13 09:13:55 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Thu, 13 Mar 2003 09:13:55 +0100 Subject: ANNOUNCE: erlguten Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D455@esemont203.gbg.edt.ericsson.se> > > -- how is flow between boxes handled? I tried to set a > "continue" parameter to another box, but it didn't work. Or > is it still on the ToDo list? > > To do > > > -- is automatic page flow implemented? > > To do - also I'm unsure about this. > > > -- when outputting XML, I see the demos have nice > precomputed galley boxes - how is it done when text doesn't > fit the box? > > > > The text that won't fit goes into the black hole Hi again, I was a little confused by the release number 2.0, that usually means there's a lot of mature functionality. Then I remembered the first Erlang version I came in contact with, and it was 47.4.1. :-) Oh, those days! /Vlad From bjorn@REDACTED Thu Mar 13 09:39:37 2003 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 13 Mar 2003 09:39:37 +0100 Subject: Unaccounted memory usage... In-Reply-To: Shawn Pearce's message of "Tue, 11 Mar 2003 15:56:11 -0500" References: <20030310101434.GB21274@spearce.org> <15980.49523.682650.103902@antilipe.corelatus.se> <20030311205611.GF26601@spearce.org> Message-ID: There is a correction for a memory problem (heap fragments being larger than needed) in R9B-1. /Bjorn Shawn Pearce writes: > Just an interesting note, R9B-0 on Windows XP with the same test > case uses 24 MB, peak memory. > > Odd how the Linux code uses so much, but the Windows code doesn't. > > Of course, Windows didn't have a large enough backlog on the socket > with {backlog, 5} to handle more than 64 simultaneous incoming > connections (Linux did). :( > > > Shawn Pearce writes: > > Can someone help me explain this a little? My beam process is > > currently at a little over 200 MB resident heap size. > > -- > Shawn. > > You'll feel much better once you've given up hope. > -- Bj?rn Gustavsson Ericsson Utvecklings AB bjorn@REDACTED ?T2/UAB/F/P BOX 1505 +46 8 727 56 87 125 25 ?lvsj? From joe@REDACTED Thu Mar 13 09:44:35 2003 From: joe@REDACTED (Joe Armstrong) Date: Thu, 13 Mar 2003 09:44:35 +0100 (CET) Subject: ANNOUNCE: erlguten In-Reply-To: <4.2.2.20030312220430.00d2fce0@duomark.com> Message-ID: > > Erlguten design will reflect this - the idea (not yet implemented) > > is to have a small number of templates + a large database of articles. > > Hmmm, I can understand why you might have a large database of > articles, but I tend to have a large collection of text snippets. I don't > write an entire document at one sitting. I tend to collect interesting > items, and I tend to write in bursts or throw down some ideas that > I rework later. I string them together when I need to produce a > document, and I reuse some of the ideas in later communications. > I do keep my finished documents, but my unfinished docs and notes > and snippets outnumber my finished documents. I don't consider > received email a good candidate for a "document" but I would like to > display them in different ways. When researching, I may quote > from several of them, interspersed with explanation (sort of like > this ramble). I want a database of snippets that I can easily > reorganize and format for pretty output, sometimes creating > "documents" from them. > yes - this is exactly what I do. My hard-disks (on about half a dozen different machines) have thousands of files with small fragments of information in them. My "grand plan" addresses the following problem: storing things finding things presenting things ErlGuten is a start at solving the third problem. In my plan *all* things with be tagged with GUIDs - to make a book you first *find* the things you want to publish (problem 2) retrieve them from storage (problem 1) and publish the result (problem 3) - In Erlguten (1) and (2) are ignored - the file system is used and I *know* where things are. > > > I read that a typesetter setting newsprint on a Linotype machine > > could enter properly formatted text 4 times faster than with a > > modern desk top publishing system. This was *not* WYSIWYG > > but all done single key type setting commands ... > > Oh gosh, that brings back memories. PageMaker v1.0 had just > come outand we compared using PM to a low-level command line program > that was like linotype with single keystroke formatting. Way faster > for anything more than a newsletter, and kerning down to 1/1100 > of an inch. I typeset a 40 page manual on the *new* Mac (in 1985, > when the term WYSIWYG was first being used) using the typesetting > software and sent the digital file to a Linotype shop for printing. The > software let me use any PostScript commands and just generated a > raw PostScript file, I don't think anything else like it was around it the > time other than Linotype which was at least $35K for a workstation > and you still needed to take it to a printer. Just a shell interface with > an editor and lots of WordPerfect-style embedded formatting. > > > If anybody knows how to get a Linotype manual can they mail me :-) > > Unfortunately I never got my hands on the Linotype machine or the > manual but remember seeing them and drooling. What a geek! > Can't remember the name of the program we used. What were the typesetting codes - help - these guys thought about this stuff for decades - this must be the intermediate langauge used by a typesetting language > Hey, let me know when the beer thing is! I would like to be in on it > if I can arrange it geographically. I think West London is closer to me. > I think Stockholm doesn't really count as "east London" - we'll have to introduce paypal beer tokens :-) /Joe > jay > > From eleberg@REDACTED Thu Mar 13 09:45:18 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Thu, 13 Mar 2003 09:45:18 +0100 (MET) Subject: ANNOUNCE: erlguten Message-ID: <200303130845.h2D8jIH22220@cbe.ericsson.se> > Date: Wed, 12 Mar 2003 18:42:39 +0100 > X-Sybari-Space: 00000000 00000000 00000000 00000000 > From: "G?sta Ask (EAB)" > User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.1) ...deteted > There is actually a good foundation for XML-based document handling > inside the Big Company, although it has fallen from grace lately; the > Powers that Rule seem to view MS Word as the end of the development > ladder. And I suppose it is (turned upside down). Quite a few Customer > Documents are still being written using Docware (the internal name for > SGML/XML-based documentation). The key is the XSEIF DTD. ...deleted > I used to write quite a few documents using SEIF; always preferred it to > Frame and the other alternatives. Version handling was good and the when working as a consultant ('95-'96) at the Big Company i was explicitly told _not_ to use Frame. it was beeing replaced by some sgml tool (probably SEIF, but the name eludes me). the only possible exception was if a project, as a whole, would be faster to do if using Frame. given the amount of Frame experience inside the Big Company, SEIF have (had?, since i do not see it around here) a very steep uphill battle to fight. fwiw, i liked SEIF. bengt From vances@REDACTED Thu Mar 13 09:48:05 2003 From: vances@REDACTED (Vance Shipley) Date: Thu, 13 Mar 2003 03:48:05 -0500 Subject: undocumented multicast Message-ID: <20030313084805.GY30349@frogman.motivity.ca> Can someone tell me the syntax of the undocumented multicast options? I thought I had figured it out but I still can't make it happy. I was trying this: 1> gen_udp:open(9875, [{add_membership, {{ip,{224,2,127,254}},{ip,{192,197,189,3}}}}]). ** exited: badarg ** ... but obviously that's not it. :( -Vance From Bruce@REDACTED Thu Mar 13 11:11:09 2003 From: Bruce@REDACTED (Bruce Fitzsimons) Date: Thu, 13 Mar 2003 23:11:09 +1300 Subject: TZ determination References: <200303111231.h2BCVmh18019@tordmule.bluetail.com> Message-ID: <004401c2e948$de955180$4021970a@norris> Hi Per, ----- Original Message ----- From: "Per Hedeland" To: Cc: Sent: Wednesday, March 12, 2003 1:31 AM Subject: Re: TZ determination > Hm, why the sudden interest in time zones (well, second question in two > weeks:-) I'm making the Yaws logging more Apache compliant so log analysers will work over it. It works well with Analog now. > needs to do such things... You want to watch out for non-integral-hours > offsets though: > > $ env TZ=Australia/Adelaide date +%z > +1030 > $ env TZ=Australia/Adelaide erl -noshell -s foo przone -s erlang halt > +1050 I eventually decided that inets must be doing something similar, looked, and it is. Almost exactly the same except without the bug you've noted. :-) > >Suggestions on how to better drive io_lib would be appreciated too - I ended > >up with 0-100 under some formatting/padding combinations, which seemed like > >a bug. > > Doesn't seem to happen with what you have now - though maybe > io*:format() is "overkill", you could do something like 4> io_lib:format("~6..0w", [-33]). [["000","-33"]] Which looks buggy, but it may be explainable. > > L = integer_to_list(trunc(abs(Val))), > "+" ++ lists:nthtail(length(L), "0000") ++ L. Better... > (at least you don't have to read the io man page to figure out what it > does:-). Even after reading it, I'm still confused. Every time I need to use for some special formatting it it takes me a few cycles to make it work. Is it just me? Thanks for the comments. /Bruce From joe@REDACTED Thu Mar 13 11:28:08 2003 From: joe@REDACTED (Joe Armstrong) Date: Thu, 13 Mar 2003 11:28:08 +0100 (CET) Subject: ANNOUNCE - erlguten 2.1 Message-ID: There were a number of small problems with erlguten 2.0 I have fixed a these in version 2.1 I should clarify something. The library pdf.erl presents a *stable* interface to the world All internals (called via erlguten_* calls) are violently unstable probably *everything* will change in the next release (except pdf.erl) The URL is now www.sics.se/~joe/erlguten.html This is a stable link and will re-direct to the latest version /Joe Don't hold you breath - the next version needs a lot of work - but at least I think I know how to do it :-) From enano@REDACTED Thu Mar 13 13:45:35 2003 From: enano@REDACTED (Miguel Barreiro Paz) Date: Thu, 13 Mar 2003 13:45:35 +0100 (CET) Subject: undocumented multicast In-Reply-To: <20030313084805.GY30349@frogman.motivity.ca> References: <20030313084805.GY30349@frogman.motivity.ca> Message-ID: > Can someone tell me the syntax of the undocumented multicast options? I > thought I had figured it out but I still can't make it happy. I was For some strange coincidence I was doing exactly the same today and having the same exact problem :-) From joe@REDACTED Thu Mar 13 15:01:47 2003 From: joe@REDACTED (Joe Armstrong) Date: Thu, 13 Mar 2003 15:01:47 +0100 (CET) Subject: typography books Message-ID: Several people mailed me for references to typography books The books I have read are listed below: If you only read one buy and read #1 /Joe PS feel free to mail me more titles 1) The Complete Manual of Typography - James Felici - ISBN: 0321127307 Published by Adobe Excellent - a lot of detail, several *chapters* devoted so line spacing and justification - lots of postscript specific details - interesting history of the reasons why Microsoft, Apple and Adobe stuff is incompatible. Why virtually identical fonts on Apple and Microsoft products have completely different names. Why truetype was developed ... 2) A typographic workbook - Kate Clair Paperback: 384 pages ; Dimensions (in inches): 0.75 x 11.01 x 8.59 Publisher: John Wiley & Sons; (January 4, 1999) ISBN: 0471292370 Also excellent - very good history of printing. The book is printed in hundreds of different typefaces - every two or three pages the main typefaces change - so you can see the effects of typesetting significant bodies of texts in different typefaces. Reading this book is *dangerous* - she warns that you'll never every look at a typeface again without trying to classify the serifs and trying to date it .. - do you know the difference between bracket and square serifs - how many serif families there are etc. 3) Making digital type look good - bob gordon Less good - rather quark specific - has nice potted histories of the major typeface designers - who was garamond etc. Many pages of comparison charts - i.e. prints of different typefaces varying leading, measure, .... etc. 4) About Face - Reviving the rules of typography. An arty book - nice prints of old 14-19 century books showing different typographies. 5) Bokstaven, ordet, texten - Christer Hellmark. (in swedish) - great book. This is a beautiful high quality book - the author not only discusses the typography but even details of the paper (like the weight of the paper, the color nuances, the type of cloth (and the color) used in the binding. This is modern printing at its best - there is attention to *all* levels of detail - the text is clear and well written - the typography is beautiful - the choice, color and weight of paper is exemplary, and it's well bound - it's even fairly cheap (c. 245 kr) From cpressey@REDACTED Thu Mar 13 15:12:46 2003 From: cpressey@REDACTED (Chris Pressey) Date: Thu, 13 Mar 2003 08:12:46 -0600 Subject: Statefulness = "Processness"...? In-Reply-To: References: <20030312221438.52114.qmail@web20503.mail.yahoo.com> Message-ID: <20030313081246.120f5382.cpressey@catseye.mb.ca> On Thu, 13 Mar 2003 06:27:22 +0100 "Vlad Dumitrescu" wrote: > Chris wrote: > > The thing is, you can't do it this way with a textbox, essentially > > because the textbox is shared. Maybe you could do it this way > > with a single textbox in a modal dialog box with one owner which is > > patiently waiting for it to close and which isn't sharing it with > > anything else. > > > > But not in the general case. Definately not, if we're considering > > 'liveness' as an important property (some other node might want the > > textbox contents to change, etc.) > > Hi, > > Liveness is important, but I don't think it is good design to pop up a > dialog for the user to enter data and let the content change > "automagically" because of some background activity. It is unexpected > and confusing, not to think about what happens if the user is mid-way > through entering a name and it is suddenly replaced by something else. That's quite germane of course - I hate it when I'm typing something into one window and another window pops up and half of my keystrokes go into it instead. On the other hand, if the data on the screen represents real live data then of course it should change on the screen right when it changes in the application - It's a bit strange that liveness is one of the things that started this GUI thread, but it's also the thing that has got the least treatment. :) > So liveness shouldn't affect fields where the user is expected to enter > data. I think there is a less restrictive way: when the user is entering data into a control, i.e. when that control has the focus, *lock* the control just as you would lock a record in a database or a file in a filesystem. (Barely related aside: I added ce_locker to Jungerl a couple of days ago because I wanted a nice generic design pattern for locking, like Mnesia does but for arbitrary resources. Like almost everything in ce it's nice and clean because it's academically (pathologically?) simple - but it could serve as a starting point.) > regards, > Vlad -Chris From richardc@REDACTED Thu Mar 13 15:23:50 2003 From: richardc@REDACTED (Richard Carlsson) Date: Thu, 13 Mar 2003 15:23:50 +0100 (MET) Subject: typography books In-Reply-To: References: Message-ID: On Thu, 13 Mar 2003, Joe Armstrong wrote: > Bokstaven, ordet, texten - Christer Hellmark. > (in swedish) - great book. > > This is modern printing at its best - there is attention to *all* > levels of detail - the text is clear and well written - the typography > is beautiful - the choice, color and weight of paper is exemplary, and > it's well bound - it's even fairly cheap (c. 245 kr) I can also warmly recommend "Typografisk handbok" by the same author. (Ordfront & Ytterlids, 1994). Small, to the point, and crammed with good advice on what to do, and what not to do, from the spacing around abbreviations to how to deal with "orphans" ("horungar" f?r att tala svenska). /Richard Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) E-mail: Richard.Carlsson@REDACTED WWW: http://user.it.uu.se/~richardc/ From Vlad.Dumitrescu@REDACTED Thu Mar 13 15:28:05 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Thu, 13 Mar 2003 15:28:05 +0100 Subject: Statefulness = "Processness"...? Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D463@esemont203.gbg.edt.ericsson.se> > That's quite germane of course - I hate it when I'm typing > something into > one window and another window pops up and half of my > keystrokes go into it > instead. > > On the other hand, if the data on the screen represents real live data > then of course it should change on the screen right when it changes in > the application - Mmmm, I didn't mean that... I referred to typing in a textbox and halfways, all I wrote dissapears and is replaced by something else. What I wanted to say is (in a different wording) that for example a textbox that the user can or must type in text should not be a direct view of the application's data. There should be only one possible source for changes in that box, either the user or the application (and in the latter case, the box should be read-only). I think it should be common-sense, I think my explanation was clumsy. regards, Vlad From cpressey@REDACTED Thu Mar 13 15:33:27 2003 From: cpressey@REDACTED (Chris Pressey) Date: Thu, 13 Mar 2003 08:33:27 -0600 Subject: Statefulness = "Processness"...? In-Reply-To: <4.2.2.20030312200627.00d1e280@duomark.com> References: <4.2.2.20030312200627.00d1e280@duomark.com> Message-ID: <20030313083327.328b9861.cpressey@catseye.mb.ca> On Wed, 12 Mar 2003 20:27:21 -0800 Jay Nelson wrote: > Chris Pressey wrote: > > > I'd just use a stack for undo. A stack being a 'naturally > > backwards' list. > > A stack of strings? Or a stack of character stacks? Depends on whether you want to undo character-by-character or entry-by-entry, I guess. > > My idea of the implicit 'undo' in a functional language > > results from the recursion itself, and doesn't require a list > > This is non-obvious to the style of programming I do. If you would like an obvious example, compare simple maze-solving programs (the kind you find in programming textbooks in the chapter on recursion) written in C and Erlang. > Typing in the data is not a recursive > or inductive act, it is an unpredictable serialized sequence. ....which is almost exactly why I don't think a functional language offers a significant advantange over an imperative one here - because this problem is different enough from the simple undoing used in solving a maze to require a list, no matter what language you use. If Erlang has an advantage here, it's because it has pattern matching, incremental GC, etc - not because it's single-assignment. > > The thing is, you can't do it this way with a textbox, > > essentially because the textbox is shared. > > Unless your definition of textbox is radically different than > a standard one, it is by nature a single-state device. If two > processes want to change it, there are either two instances, > two closures with two views, or last changed view only. So > I don't understand this statement. See my previous message re liveness and locking. > jay -Chris From mikael.karlsson@REDACTED Thu Mar 13 16:01:04 2003 From: mikael.karlsson@REDACTED (Mikael Karlsson) Date: Thu, 13 Mar 2003 16:01:04 +0100 Subject: typography books In-Reply-To: References: Message-ID: <200303131601.04749.mikael.karlsson@creado.com> Thu 13 mars 2003, Richard Carlsson wrote: > On Thu, 13 Mar 2003, Joe Armstrong wrote: > > Bokstaven, ordet, texten - Christer Hellmark. > > (in swedish) - great book. > > > > This is modern printing at its best - there is attention to *all* > > levels of detail - the text is clear and well written - the typography > > is beautiful - the choice, color and weight of paper is exemplary, and > > it's well bound - it's even fairly cheap (c. 245 kr) > > I can also warmly recommend "Typografisk handbok" by the same author. > (Ordfront & Ytterlids, 1994). Small, to the point, and crammed with good > advice on what to do, and what not to do, from the spacing around > abbreviations to how to deal with "orphans" ("horungar" f?r att tala > svenska). > > /Richard > I can recommend a third book of the same author and same publisher. "Provboken" - ISBN 91-7324-756-1 Presenting 24 typefaces with names like New Baskerville, Minion and Akzidenz Grotesk, and also 10 diffferent paper sorts. Really good if you want to explore alternatives to the default settings in the office programs. /Mikael From spearce@REDACTED Thu Mar 13 16:04:32 2003 From: spearce@REDACTED (Shawn Pearce) Date: Thu, 13 Mar 2003 10:04:32 -0500 Subject: Statefulness = "Processness"...? In-Reply-To: References: <4.2.2.20030312214027.00d1db80@duomark.com> Message-ID: <20030313150432.GC23238@spearce.org> Vlad Dumitrescu wrote: > > Jay wrote: > > I agree that you don't want unexpected things to happen > > while the user is concentrating, but simple suggestions > > are very useful (think dialtone, busy signals, TV static on > > non-existent channels, etc.). > > yes, of course, but these active fields are not the textboxes where the user > is expected to type. They are only visual effects. > > If I am supposed to enter a file path and something interferes with it, > changing it every half second, it will be very frustrating! :-) I think an example of a text box changing as you type is the popup list of websites you have recently visited in Mozilla or IE which match what you have typed thus far, or the programs you have run recently from the Windows 'Run' dialog. That list changes every time another key is entered and matched against the list of what is known. Perhaps doing that matching takes some time, as it causes the webserver to be scanned using WebDAV or some such event to help you complete the path. Thus it may be updating in the background as another thread, changing the contents of the combo box's list, but leaving the text field alone. -- Shawn. Living your life is a task so difficult, it has never been attempted before. From blitzfeuer@REDACTED Thu Mar 13 12:28:12 2003 From: blitzfeuer@REDACTED (Walter C. Reel III) Date: Thu, 13 Mar 2003 11:28:12 +0000 Subject: Remote connect problems. In-Reply-To: <15983.42241.974614.932205@antilipe.corelatus.se> References: <200303121115.47960.blitzfeuer@sc.rr.com> <15983.42241.974614.932205@antilipe.corelatus.se> Message-ID: <200303131128.12192.blitzfeuer@sc.rr.com> You know, I just realized last night that the shell treats single quotes differently in windows. As soon as I realized that I retested with the -name and IP addresses and everything worked exactly like you exampled. It's probably some config problem in linux box. Sorry for wasting your time, my bad. Walt On Wednesday 12 March 2003 09:22 pm, Matthias Lang wrote: > Walter C. Reel III writes: > > With the fully qualified name provided neither of the machines can talk > > to each other now. > > [...] > > Everything you're doing looks correct. > > The next steps are to figure out whether epmd is doing the right > things. If I start a node on each of my two machines and run 'epmd > -names', I see: > > xterm1@REDACTED> erl -name 'whipper@REDACTED' -setcookie nocookie > > xterm2@REDACTED> /usr/local/lib/erlang/bin/epmd -names > epmd: up and running on port 4369 with data: > name whipper at port 1460 > > on the other machine > > xterm3@REDACTED> /opt/erlang/lib/erlang/erts-5.1.2/bin/epmd -names > epmd: up and running on port 4369 with data: > name snipper at port 4916 > > If you see something similar (i.e. each EPMD process has its local > node registered), then it's starting to get hairy. You can get more > information by sniffing the ethernet when you do the first ping from > one node to the other. You should see a successful TCP 3-way on > port 4369 followed by a second successful 3-way on another port. > > Anyone out there who uses Windows on a regular basis with some > suggestions? > > Matthias From cpressey@REDACTED Thu Mar 13 16:57:21 2003 From: cpressey@REDACTED (Chris Pressey) Date: Thu, 13 Mar 2003 09:57:21 -0600 Subject: What are processes good for? In-Reply-To: <4.2.2.20030312202751.00d34ea0@duomark.com> References: <4.2.2.20030312202751.00d34ea0@duomark.com> Message-ID: <20030313095721.55502f6a.cpressey@catseye.mb.ca> On Wed, 12 Mar 2003 21:16:36 -0800 Jay Nelson wrote: > Chris Pressey wrote: > > > But what about controls without state, or barely any state, > > I wonder? Like pushbuttons and frames and labels. Do > > they still get processes? > > See discussion below. I have, but I don't see an answer to this question (which is admittedly a bit rhetorical.) > > If so, why, if it is wasteful enough to warrant not doing it? > > Programmers should always waste resources in order of > their availability. Amongst processes, memory, CPU > cycles, communication bandwidth, etc. each situation may > vary, but waste the cheapest and most abundant resource > if it makes the code clearer, faster or more correct. In erlang > processes are abundant, and if you need more CPU "wasting" > them across nodes can increase performance if communication > overhead is low. Of course it depends on your definition of waste, but I don't think programmers should ever truly waste resources, even cheap ones, when there are equally viable alternatives - which is what I would like to explore. > > And if not, how do you deal with > > the unorthogonality that will almost certainly present? > > I don't understand this question. Orthogonality = everything is treated the same way To digress: "everything is a process / object" is a nice mantra, but the folks at Sun didn't model integers as objects in Java, and I suspect even Joe would balk at the idea of each record in an ETS table (representing, say, the Shanghai phone book) getting it's own process. In other words, it seems that there *can* be too much of a good thing. Back to orthogonality. Say we want to hide a textbox. We know a textbox has a process, so we say (oversimplified though this is:) TextBoxPid ! hide. Now we want to hide a frame. Can we say FramePid ! hide. ? Only if each frame has it's own process. If not - to answer my own question - we can abstract it with a function call like hide(TextBoxId), hide(FrameId). Not the absolute best approach, but certainly good enough for, erm, government work. But still, one has to ask, how far does it go? How aware must the programmer be of whether the frame has dynamic behaviour or not? Will they be completely oblivious - will they write code to receive messages that will never be sent? If so - is it a good thing or a bad thing? There are probably arguments both ways. > [...] > Processes are useful for: > > 1) Modeling real world concurrent activities. > 2) Strong encapsulation > 3) Code reuse / abstraction / adapting interfaces. > 4) Simulating environmental influences. > 5) Creating unpredictable, complex behaviour / adaptive behaviour > 6) Resource management / distribution These are all useful & interesting points. However, I submit that #2 and #3 can be done in ways that don't require processes, and that using processes for them gives you little to no advantage over doing them without processes. At the risk of repeating myself - I realize Erlang processes have infinitesimal overhead, and good Erlang programs are generous with them. Unfortunately this can decay into the idea that you should use them even when you don't need them - when you could do it another way which has zero overhead. Interfaces - the key idea behind #2 and #3 - are static and mostly boring, and in Erlang, they can be expressed as part of the module structure. (-export()) Although I see how a process can provide an interface as well, I don't see why it is justifiable to use a process for this purpose *unless* the interface really has some discernable dynamic property. In summary - I'm currently leaning towards "most things are processes, but some aren't, but everything is accessed the same way despite that." One more point though - I think there is some confusion in the philosophy about modelling activities with processes. This may be due to my own misinterpretation. Sometimes it's stated as "one process per concurrent real-world activity", sometimes it's stated as "one process per truly concurrent activity." The former is easier to think about, but the real world is it's own can of ontological beans so to speak, so the latter interpretation is worth considering too (especially when you think about, say, Joe's statement about how tcp_server should create two processes per incoming socket connection - this is much easier to understand in the context of the latter statement plus an understanding of how gen_tcp:accept works - arguably not at all part of the "real world".) -Chris From etxuwig@REDACTED Thu Mar 13 18:26:47 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Thu, 13 Mar 2003 18:26:47 +0100 (MET) Subject: fun with referential integrity In-Reply-To: <20030313.125844.74756860.svg@surnet.ru> Message-ID: On Thu, 13 Mar 2003, Vladimir Sekissov wrote: >Good day, > >etxuwig> .... or should I make it easier on myself and simply disallow >etxuwig> cyclical dependencies? This seems like a fairly limiting >etxuwig> restriction. How do the real pros do it? Does anyone know? > >For my opinion cyclical references are a bad thing. I >usually model bidirectional relationships using another >table D with composite primary key and foreign keys to B >and C. Reading "A Guide to the SQL Standard", by C.J. Date, notes that "certain combinations of (1) referential structures (...), (2) referential action specifications, and (3) actual data values in the database can together lead to cetrain conflict situations and can potentially cause unpredictable behaviour." It then moves on to explain that these combinations are described elsewhere, and that it's up to the DBMS to detect and disallow any dependencies that would cause unpredictable behaviour. My interpretation is that this must be done at runtime. Unfortunately, the cited references are difficult to get for free... /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From cpressey@REDACTED Thu Mar 13 18:33:10 2003 From: cpressey@REDACTED (Chris Pressey) Date: Thu, 13 Mar 2003 11:33:10 -0600 Subject: back to basics: live(li)ness? In-Reply-To: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D463@esemont203.gbg.edt.ericsson.se> References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D463@esemont203.gbg.edt.ericsson.se> Message-ID: <20030313113310.039bd086.cpressey@catseye.mb.ca> On Thu, 13 Mar 2003 15:28:05 +0100 "Vlad Dumitrescu (EAW)" wrote: > > On the other hand, if the data on the screen represents real live data > > then of course it should change on the screen right when it changes in > > the application - > > Mmmm, I didn't mean that... I referred to typing in a textbox and > halfways, all I wrote dissapears and is replaced by something else. > > What I wanted to say is (in a different wording) that for example a > textbox that the user can or must type in text should not be a direct > view of the application's data. There should be only one possible source > for changes in that box, either the user or the application (and in the > latter case, the box should be read-only). > > I think it should be common-sense, I think my explanation was clumsy. Ah. I think what you are saying isn't live(li)ness by my definition :) I'm trying to follow what was put forth by Eric Merrit and Bob Smart almost exactly a month ago. Example: you want to print to "\\Printers\Laser017" so you select it in a listbox. As you are doing so the sysadmin takes that printer offline for repairs. If the GUI is live, the option disappears for you immediately. In an ideal world it offers some obvious feedback (beep) and an explanation as to why it happened, too. So - you don't just need locks, you probably need a prioritization / authority scheme, too (the sysadmin, who outranks you, can override your selection.) > regards, > Vlad -Chris From vances@REDACTED Thu Mar 13 18:47:36 2003 From: vances@REDACTED (Vance Shipley) Date: Thu, 13 Mar 2003 12:47:36 -0500 Subject: Statefulness = "Processness"...? In-Reply-To: <20030313150432.GC23238@spearce.org> References: <4.2.2.20030312214027.00d1db80@duomark.com> <20030313150432.GC23238@spearce.org> Message-ID: <20030313174736.GA30349@frogman.motivity.ca> On Thu, Mar 13, 2003 at 10:04:32AM -0500, Shawn Pearce wrote: } } I think an example of a text box changing as you type is the popup } list of websites you have recently visited in Mozilla or IE which } match what you have typed thus far, or the programs you have run } recently from the Windows 'Run' dialog. That list changes every time } another key is entered and matched against the list of what is known. Another example is something which I've always wanted but have never found and that is a dynamic command completion functionality. I want to waste computer cycles constantly trying to predict what I'm going to say next. This is similiar to the command completion in shells but with those you have to ask for the predictions by pressing TAB. The way I'd like to have it is that a prediction is made with every key I press, taking the context into account and having learned from working with me. The predictions show up as faint text balancing visibility with distraction. If I type "Va" I would see "nce Shipley\nMotivity Telecom Inc.\n+1 519 240 3684\nvances@REDACTED\n" show up after it and I could selct all of that with a single key. Now that's a dynamic text box. -Vance Vance Shipley Motivity Telecom Inc. +1 519 240 3684 vances@REDACTED From cpressey@REDACTED Thu Mar 13 18:51:18 2003 From: cpressey@REDACTED (Chris Pressey) Date: Thu, 13 Mar 2003 11:51:18 -0600 Subject: fun with referential integrity In-Reply-To: References: <20030313.125844.74756860.svg@surnet.ru> Message-ID: <20030313115118.33d00dab.cpressey@catseye.mb.ca> On Thu, 13 Mar 2003 18:26:47 +0100 (MET) Ulf Wiger wrote: > On Thu, 13 Mar 2003, Vladimir Sekissov wrote: > > >Good day, > > > >etxuwig> .... or should I make it easier on myself and simply disallow > >etxuwig> cyclical dependencies? This seems like a fairly limiting > >etxuwig> restriction. How do the real pros do it? Does anyone know? > > > >For my opinion cyclical references are a bad thing. I > >usually model bidirectional relationships using another > >table D with composite primary key and foreign keys to B > >and C. > > Reading "A Guide to the SQL Standard", by C.J. Date, notes > that "certain combinations of (1) referential structures > (...), (2) referential action specifications, and (3) > actual data values in the database can together lead to > cetrain conflict situations and can potentially cause > unpredictable behaviour." It then moves on to explain that > these combinations are described elsewhere, and that it's up > to the DBMS to detect and disallow any dependencies that > would cause unpredictable behaviour. My interpretation is > that this must be done at runtime. > > Unfortunately, the cited references are difficult to get for > free... My overall impression is that a really good data model avoids cyclical dependencies, but a really robust RDBM package would deal with the case when the data model turns out to be not so good (for whatever reason :) Anectodal: when I was toying with "records with active values", all was well for simple acyclical cases (change the width of a rectangle, the perimeter is automatically updated, OK) but for more sophisticated examples (one field imperial & the other metric & automatically updating each other - cyclic) I had to add a visited list. I don't know if there's a strong parallel between that and a typical database layout, but it seemed worth mentioning. > /Uffe -Chris From C.Reinke@REDACTED Thu Mar 13 18:57:07 2003 From: C.Reinke@REDACTED (C.Reinke) Date: Thu, 13 Mar 2003 17:57:07 +0000 Subject: ANNOUNCE: erlguten In-Reply-To: Message from Joe Armstrong of "Wed, 12 Mar 2003 16:39:29 +0100." Message-ID: > I read that a typesetter setting newsprint on a Linotype machine > could enter properly formatted text 4 times faster than with a modern > desk top publishing system. This was *not* WYSIWYG but all done single > key type setting commands ... If anybody knows how to get a Linotype > manual can they mail me :-) Don't know about manuals, but you know how companies go shopping;-) Linotype -> Linotype-Hell -> Heidelberger Druckmaschinen So http://www.heidelberg.com/hq/eng/ might be a good place to start searching? For fonts, there's also http://www.linotypelibrary.com/ as well as various linotype archeology & nostalgia sites, such as http://www.linotype.org/ But I guess you've already googled for linotype? Claus From etxuwig@REDACTED Thu Mar 13 19:02:49 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Thu, 13 Mar 2003 19:02:49 +0100 (MET) Subject: fun with referential integrity In-Reply-To: <20030313115118.33d00dab.cpressey@catseye.mb.ca> Message-ID: On Thu, 13 Mar 2003, Chris Pressey wrote: >My overall impression is that a really good data model >avoids cyclical dependencies, but a really robust RDBM >package would deal with the case when the data model turns >out to be not so good (for whatever reason :) Exactly. Also data models may well be good in the beginning, but then evolve into something not so good. >Anectodal: when I was toying with "records with active >values", all was well for simple acyclical cases (change >the width of a rectangle, the perimeter is automatically >updated, OK) but for more sophisticated examples (one field >imperial & the other metric & automatically updating each >other - cyclic) I had to add a visited list. I don't know >if there's a strong parallel between that and a typical >database layout, but it seemed worth mentioning. One complicating factor with mnesia is the support for nested transactions. Another is the fact that you have to rely on the process dictionary to keep track of state between operations within a transaction. Essentially, mnesia itself keeps a 'visited' list of objects that have been modified or deleted inside each transaction; they are invisible to the outside world or parent transaction until commited. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From Marc.Vanwoerkom@REDACTED Thu Mar 13 21:07:26 2003 From: Marc.Vanwoerkom@REDACTED (Marc Ernst Eddy van Woerkom) Date: Thu, 13 Mar 2003 21:07:26 +0100 (MET) Subject: PDF related sites In-Reply-To: (message from Joe Armstrong on Thu, 13 Mar 2003 15:01:47 +0100 (CET)) Message-ID: <200303132007.h2DK7QG26176@bonsai.fernuni-hagen.de> I just stumbled over a site focussed on PDF: http://www.planetpdf.com Regards, Marc From chris_pressey@REDACTED Thu Mar 13 21:12:51 2003 From: chris_pressey@REDACTED (Chris Pressey) Date: Thu, 13 Mar 2003 15:12:51 -0500 (EST) Subject: Extending Functionality: an expedient and questionable approach Message-ID: <20030313201251.39459.qmail@web20509.mail.yahoo.com> OK, so I finally got up the courage to ignore the warning in the error_handler documentation, and hacked error_handler.erl to handle the first iteration of Vlad D.'s proposal - basically, that delegation/inheritance can be handled at the module level. Partly this is because I agree that there ought to be something like this or I'll eventually end up creating too many processes with no good justification for their existence... and also because I couldn't figure out what the heck was going on in gen_server_2. :) What it does is this. If you call an undefined function in any module, it looks to see if that module exports a function called undefined_function/2. If it does, it calls that instead with (Func, Args) as the arguments. If not, it crashes like usual. I haven't tested it thoroughly yet, but it seems to work like a charm so far with the done-to-death example (which probably isn't even good OO modelling in many people's books) of square being a subclass of rectangle. I like this because it doesn't really have anything to do with OO. It's like Perl's approach - it gives you a nice general tool that happens to be useful for implementing a design pattern that happens to be associated with OO. So, it is submitted for your peer review. Am I worrying too much about changing error_handler.erl? (the warning in the man page is pretty dire, but I'm *pretty* sure this is mostly harmless - but not *totally* sure... you can probably shoot yourself in the foot something wicked if you call an undefined function from undefined_function/2) -Chris ------------ ---------- error_handler.diff 32d31 < crash(Module, Func, Args) 32a32,39 > %% If the module in question exports undefined_function/2, call > %% it instead of crashing. (this might be very stupid) > case erlang:function_exported(Module, undefined_function, 2) of > true -> > apply(Module, undefined_function, [Func, Args]); > false -> > crash(Module, Func, Args) > end ------------ ---------- error_handler.diff ------------ ------------ rectangle.erl -module(rectangle). -export([new/0]). % constructors -export([width/1, width/2, length/1, length/2]). % updatable props -export([perimeter/1, area/1]). % derived props -export([print/2]). % methods -record(rectangle, { width = 0, length = 0 }). new() -> #rectangle{}. width(#rectangle{ width = Width }) -> Width. width(Rectangle, Width) when number(Width) -> Rectangle#rectangle{ width = Width }. length(#rectangle{ length = Length }) -> Length. length(Rectangle, Length) when number(Length) -> Rectangle#rectangle{ length = Length }. perimeter(#rectangle{ width = Width, length = Length }) -> Width * 2 + Length * 2. area(#rectangle{ width = Width, length = Length }) -> Width * Length. print(#rectangle{ width = Width, length = Length }, IoDevice) -> io:fwrite(IoDevice, "rectangle: ~p x ~p~n", [Width, Length]). ------------ ------------ rectangle.erl ------------ -------------- square.erl -module(square). -define(SUPER, rectangle). -export([width/2, length/2]). % updatable props -export([undefined_function/2]). % inheritance driver width(Square, Side) -> ?SUPER:length(?SUPER:width(Square, Side), Side). length(Square, Side) -> ?SUPER:length(?SUPER:width(Square, Side), Side). undefined_function(Function, Args) -> apply(?SUPER, Function, Args). ------------ -------------- square.erl ______________________________________________________________________ Post your free ad now! http://personals.yahoo.ca From vances@REDACTED Thu Mar 13 21:34:26 2003 From: vances@REDACTED (Vance Shipley) Date: Thu, 13 Mar 2003 15:34:26 -0500 Subject: undocumented multicast In-Reply-To: References: <20030313084805.GY30349@frogman.motivity.ca> Message-ID: <20030313203426.GG30349@frogman.motivity.ca> On Thu, Mar 13, 2003 at 01:45:35PM +0100, Miguel Barreiro Paz wrote: } } > Can someone tell me the syntax of the undocumented multicast options? I } > thought I had figured it out but I still can't make it happy. I was } } For some strange coincidence I was doing exactly the same today } and having the same exact problem :-) } OK, problem solved. Actually it was solved in December of 2001: http://www.erlang.org/ml-archive/erlang-questions/200112/msg00068.html I was reaching the exact same conclusion when what I was looking at jogged my memory. In any event I am posting a patch against R9B-1 to teh patches list. Here is the (undocumented) syntax: gen_udp:open(9875, [{add_membership, {{224,2,127,254},{192,197,189,3}}}]). I tested this like this: 1> compile:file(inet, [{i, "/usr/local/lib/erlang/lib/kernel-2.8.0/src"}]). {ok,inet} 2> code:unstick_dir("/usr/local/lib/erlang/lib/kernel-2.8.0/ebin"). ok 3> code:load_file(inet). {module,inet} 4> code:which(inet). "/home/vances/inet.beam" 5> gen_udp:open(9875, [{add_membership, {{224,2,127,254},{192,197,189,3}}}]). {ok,#Port<0.87>} To verify that it works: $ netstat -ia Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Coll ... tx1 1500 192.197.189 frogman 703469 - 4233 - - SAP.MCAST.NET ALL-SYSTEMS.MCAST.NET The line SAP.MCAST.NET is mine. -Vance From lennart.ohman@REDACTED Thu Mar 13 22:02:11 2003 From: lennart.ohman@REDACTED (=?ISO-8859-1?Q?Lennart_=D6hman?=) Date: Thu, 13 Mar 2003 22:02:11 +0100 Subject: Extending Functionality: an expedient and questionable approach References: <20030313201251.39459.qmail@web20509.mail.yahoo.com> Message-ID: <3E70F1D3.3060504@st.se> With the risk in just throwing my self into a thread I have not followed closely... We have been down this road before, 10 years ago. In an attempt to introduce OO-mechanisms into Erlang. It did not turn out well... Consider that all the code you execute after the flow of control entered into the error_handler *must* be correct. /Lennart Chris Pressey wrote: > OK, so I finally got up the courage to ignore the warning in the error_handler documentation, and > hacked error_handler.erl to handle the first iteration of Vlad D.'s proposal - basically, that > delegation/inheritance can be handled at the module level. > > Partly this is because I agree that there ought to be something like this or I'll eventually end > up creating too many processes with no good justification for their existence... and also because > I couldn't figure out what the heck was going on in gen_server_2. :) > > What it does is this. If you call an undefined function in any module, it looks to see if that > module exports a function called undefined_function/2. If it does, it calls that instead with > (Func, Args) as the arguments. If not, it crashes like usual. > ... ------------------------------------------------------------- Lennart Ohman phone : +46-8-587 623 27 Sjoland & Thyselius Telecom AB cellular: +46-70-552 6735 Sehlstedtsgatan 6 fax : +46-8-667 8230 SE-115 28 STOCKHOLM, SWEDEN email : lennart.ohman@REDACTED From spearce@REDACTED Thu Mar 13 22:11:40 2003 From: spearce@REDACTED (Shawn Pearce) Date: Thu, 13 Mar 2003 16:11:40 -0500 Subject: Extending Functionality: an expedient and questionable approach In-Reply-To: <20030313201251.39459.qmail@web20509.mail.yahoo.com> References: <20030313201251.39459.qmail@web20509.mail.yahoo.com> Message-ID: <20030313211140.GB491@spearce.org> Chris Pressey wrote: > What it does is this. If you call an undefined function in any module, it looks to see if that > module exports a function called undefined_function/2. If it does, it calls that instead with > (Func, Args) as the arguments. If not, it crashes like usual. I had a use for something like this just the other day in Erlang, but it now escapes me what it was. I think having this in the base language would let us finally see Erlang be a 'real' language, as both Perl and Python have this feature and they are 'real' langauges while Erlang is still a toy. :-) What a slippery slope this presents. :) Its quite a nifty feature, and goes right along with -import. Being able to pull in common code to appear as 'local' calls (for shorthand typing) but keeping them remote goes right along with being able to inherit exported functions. I'd almost rather see this as a compiler option though, as we shouldn't really be allowing purely dynamic function names to be used. Perhaps use something like: -inherit(egui, [hide/1, show/1, display/1]). and the compiler generates: -export([hide/1,show/1,display/1). hide(A) -> egui:hide(A). show(A) -> egui:show(A). display(A) -> egui:display(A). AFAIK, this can be a parse transform or something. But I haven't looked that deep into it. Perhaps a -inherit(egui) would just import all exported functions declared in egui which are not defined already by -export statements. (Thus if we implement our own hide/1 to override what egui would have given us, we must export it or else the compiler would attempt to redefine it.) -- Shawn. You will have good luck and overcome many hardships. From chris_pressey@REDACTED Thu Mar 13 23:08:34 2003 From: chris_pressey@REDACTED (Chris Pressey) Date: Thu, 13 Mar 2003 17:08:34 -0500 (EST) Subject: Extending Functionality: an expedient and questionable approach Message-ID: <20030313220834.84019.qmail@web20502.mail.yahoo.com> Lennart ?hman wrote: > With the risk in just throwing my self into a thread I have > not followed closely... > > We have been down this road before, 10 years ago. In an attempt > to introduce OO-mechanisms into Erlang. It did not turn out > well... This tweak *is* a powerful feature which trades off organizational predictability for expressivity, and should be treated with respect. I can totally understand it being frowned upon. However... > Consider that all the code you execute after the flow of control > entered into the error_handler *must* be correct. ...otherwise what happens? I'm curious. i.e. an hour ago, I would have believed you... but I've been intentionally introducing errors into rectangle.erl and square.erl just to see what happens... And I'm suprised. I really, really, REALLY thought that calling an undefined function from square:undefined_function/2 (or something it calls) would throw the runtime into an infinite loop (or worse). But so far, I have yet to crash the emulator in a bad way - I just get the usual error reports (I can even catch them in the usual way - from the shell or with -run on the commandline) I just wish I understood why! > /Lennart -Chris ______________________________________________________________________ Post your free ad now! http://personals.yahoo.ca From chris_pressey@REDACTED Thu Mar 13 23:23:56 2003 From: chris_pressey@REDACTED (Chris Pressey) Date: Thu, 13 Mar 2003 17:23:56 -0500 (EST) Subject: Extending Functionality: an expedient and questionable approach Message-ID: <20030313222356.46900.qmail@web20505.mail.yahoo.com> OK, I finally found a way to lock up the emulator with this: use this in square.erl: undefined_function(Function, Args) -> apply(?MODULE, Function, Args). But is this really so unexpected? It's a lot like saying foo() -> foo(). Which we all know not to do :) As long as there's some termination to the chain of undefined_function/2 calls, it seems OK - i.e. there is no rectangle:undefined_function/2. Which makes some sense. Hmmm. -Chris ______________________________________________________________________ Post your free ad now! http://personals.yahoo.ca From spearce@REDACTED Thu Mar 13 23:56:45 2003 From: spearce@REDACTED (Shawn Pearce) Date: Thu, 13 Mar 2003 17:56:45 -0500 Subject: Extending Functionality: an expedient and questionable approach In-Reply-To: <20030313220834.84019.qmail@web20502.mail.yahoo.com> References: <20030313220834.84019.qmail@web20502.mail.yahoo.com> Message-ID: <20030313225645.GA708@spearce.org> Chris Pressey wrote: > i.e. an hour ago, I would have believed you... but I've been > intentionally introducing errors into rectangle.erl and square.erl just > to see what happens... > > And I'm suprised. I really, really, REALLY thought that calling an > undefined function from square:undefined_function/2 (or something it > calls) would throw the runtime into an infinite loop (or worse). But > so far, I have yet to crash the emulator in a bad way - I just get the > usual error reports (I can even catch them in the usual way - from the > shell or with -run on the commandline) Chris, I think this would do it: -module(square). -export([undefined_function/2]). % Delegate to parent undefined_function(F,A) -> apply(rectangle, F, A). -module(rectangle). % We forget to implement the shape:area call. -export([undefined_function/2]). % Delegate to parent undefined_function(F,A) -> apply(shape, F, A). -module(shape). -export([undefined_function/2]). % Delegate everything to child undefined_function(F, [A | Args]) -> Type = element(1, A), apply(A, F, [A | Args]). square:area({square, 4, 2}). Where the function called (area) gets kicked up to the parent, who calls back into shape, which calls back into the child as it is just a generic abstract call point for all 'shape' calls. Its really a problem when both modules implement undefined_function/2 and somehow enter into each referring to the other. Rare in OO cases, but possible if someone makes a mistake in one or the other module. My example above may be odd, but it makes some sense: its like declaring all methods abstract virtual in a base class 'shape' in C++ and defering all calls to the subclasses, but allowing the user to use shape to invoke the methods. I still prefer the compiler-based -inherit I suggested in my last email, as it is very explicit to both the compiler, runtime and developer(s) about what is happening, what is available, etc. The 'special' handling through undefined_function is cute, as you can now do: -module(os). undefined_function(F, [A]) -> os:cmd(atom_to_list(F) ++ " " ++ A). os:rm("the file.txt"). os:ls("mydir"). os:find("mydir -type f"). etc. But now you have no idea of what is available in the os module, what it doesn't provide, etc. What -inherit would prevent would be from doing a generic shape module that would push all calls down, but that could be done like so: -module(shape). -export([area/1, width/1, height/1]). -define(VIRTUAL(Name), Name(Shape) -> delegate(Shape, Name)). ?VIRTUAL(area). ?VIRTUAL(width). ?VIRTUAL(height). delegate(Object, Function) when is_tuple(Object) -> Type = element(1, Object), Type:Function(Object). And if square uses rectangle's area, we can still say: shape:area({square, 1, 1}). and have the system execute: shape:area/1 -> square:area/1 -> rectangle:area/1 -> 1. which is what we are looking for, but should we forget to implment rectangle:area/1: shape:area/1 -> square:area/1 -> exit({undef, {rectangle, area, [{square, 1, 1}]}}) Which is what we really want. Of course, this means the root level shape must define all calls and push them down. Of course, my idea of -inherit could possibly just be a macro locally defined, but compiler support through a parse transform would be nicer. -- Shawn. You like to form new friendships and make new acquaintances. From lennart.ohman@REDACTED Fri Mar 14 00:03:46 2003 From: lennart.ohman@REDACTED (=?ISO-8859-1?Q?Lennart_=D6hman?=) Date: Fri, 14 Mar 2003 00:03:46 +0100 Subject: Extending Functionality: an expedient and questionable approach References: <20030313220834.84019.qmail@web20502.mail.yahoo.com> Message-ID: <3E710E52.5020201@st.se> > ...otherwise what happens? I'm curious. Hi, one of the major ideas of Erlang/OTP is that it (and mainly the OTP part then) provides a recovery strategy which is capable of recovering from more or less any run-time error. (Through, possibly escalating, restarts). To make such a model work you must have some part of the code which *is* considered correct. That part is written by some wizards and reviewed, and then reveiwed by another bunch of wizards. If you are aiming to write software for environments requiering some kind of certificate, you can explain this in the application and get it approved. If you let the regular developer in to this sphere, you have violated the correctness assumption. Just my 2-cents of thoughts from someone who may have seen to much go wrong if have the slightest chance. /Lennart ------------------------------------------------------------- Lennart Ohman phone : +46-8-587 623 27 Sjoland & Thyselius Telecom AB cellular: +46-70-552 6735 Sehlstedtsgatan 6 fax : +46-8-667 8230 SE-115 28 STOCKHOLM, SWEDEN email : lennart.ohman@REDACTED From cpressey@REDACTED Fri Mar 14 00:40:49 2003 From: cpressey@REDACTED (Chris Pressey) Date: Thu, 13 Mar 2003 17:40:49 -0600 Subject: Extending Functionality: an expedient and questionable approach In-Reply-To: <20030313225645.GA708@spearce.org> References: <20030313220834.84019.qmail@web20502.mail.yahoo.com> <20030313225645.GA708@spearce.org> Message-ID: <20030313174049.0d0dcf06.cpressey@catseye.mb.ca> On Thu, 13 Mar 2003 17:56:45 -0500 Shawn Pearce wrote: > Its really a problem when both modules implement undefined_function/2 > and somehow enter into each referring to the other. Rare in OO cases, > but possible if someone makes a mistake in one or the other module. Yes. Hmmm... another problem involving cycles. Interesting. Now, if undefined_function/2 were to keep a visited-list... ;) Actually, just out of curiousity, does anyone know if there's a better way to investigate the call stack - better than the only method I've seen so far, that is, to catch an intentional error and examine the result? Also, calls like ?MODULE:function() (I noticed et has them, presumably for hot swapping code) could lead this right down the garden path when used in undefined_function/2. The compiler can't tell they don't exist (last I checked, it's very trusting about m:f type calls.) So in general, better to avoid this and turn to something nicer: > I still prefer the compiler-based -inherit I suggested in my last > email, Me too. A parse transform is definately a better way to go. > as it is very explicit to both the compiler, runtime and > developer(s) about what is happening, what is available, etc. The > 'special' handling through undefined_function is cute, as you can > now do: > > -module(os). > undefined_function(F, [A]) -> > os:cmd(atom_to_list(F) ++ " " ++ A). > > > os:rm("the file.txt"). > os:ls("mydir"). > os:find("mydir -type f"). > > etc. Cute, yes indeed (and some do this in Perl too IIRC)... but 'cute' doesn't build very good bridges. Hmmm... very educational experience though. I'll see if I can whip up a parse transform in my next batch of spare time, and see how that fares. Thanks, -Chris From spearce@REDACTED Fri Mar 14 03:12:00 2003 From: spearce@REDACTED (Shawn Pearce) Date: Thu, 13 Mar 2003 21:12:00 -0500 Subject: Executing boolean expressions on a list Message-ID: <20030314021200.GD23238@spearce.org> I find I'm writing a lot of: recursive(N, [H | T]) -> case somef(N, H) of true -> recursive(N, T); false -> false end; recursive(N, []) -> true. somef(N, E) -> .... % return true or false. Is there a faster way to write recursive/2 ? In some cases I have to hand around 2 or 3 args instead of just N, but usually they are just payload data to somef/2 (or whatever arity) to help it perform its test. I'm just wondering if perhaps there's a faster way to express the case .. end in recursive/2. I'm trying to keep it tail-recursive. I thought about: recursive(N, [H | T]) -> if somef(N, H) -> recursive(N, T); false -> false end; recursive(N, []) -> true. which I didn't like because of the formatting of the if statement, and: recursive(N, [H | T]) -> somef(N, H) and recursive(N, T); recursive(N, []) -> true. but was worried about order of evaluation on the and operator and not being able tail-recursive. Feedback from the Erlang pros is good. ;-) -- Shawn. Q: Minnesotans ask, "Why aren't there more pharmacists from Alabama?" A: Easy. It's because they can't figure out how to get the little bottles into the typewriter. From peter@REDACTED Fri Mar 14 03:29:49 2003 From: peter@REDACTED (Peter H|gfeldt) Date: Fri, 14 Mar 2003 03:29:49 +0100 (MET) Subject: Executing boolean expressions on a list In-Reply-To: <20030314021200.GD23238@spearce.org> Message-ID: How about lists:all/2, recursive(N, Es) -> lists:all(fun(E) -> somef(N, E) end, Es) ? /Peter On Thu, 13 Mar 2003, Shawn Pearce wrote: > I find I'm writing a lot of: > > recursive(N, [H | T]) -> > case somef(N, H) of > true -> recursive(N, T); > false -> false > end; > recursive(N, []) -> > true. > > somef(N, E) -> > .... % return true or false. > > Is there a faster way to write recursive/2 ? In some cases I have to hand > around 2 or 3 args instead of just N, but usually they are just payload > data to somef/2 (or whatever arity) to help it perform its test. I'm > just wondering if perhaps there's a faster way to express the case .. end > in recursive/2. > > I'm trying to keep it tail-recursive. I thought about: > > recursive(N, [H | T]) -> > if > somef(N, H) -> recursive(N, T); > false -> false > end; > recursive(N, []) -> true. > > which I didn't like because of the formatting of the if statement, and: > > recursive(N, [H | T]) -> somef(N, H) and recursive(N, T); > recursive(N, []) -> true. > > but was worried about order of evaluation on the and operator > and not being able tail-recursive. > > > Feedback from the Erlang pros is good. ;-) > > -- > Shawn. > > Q: Minnesotans ask, "Why aren't there more pharmacists from Alabama?" > A: Easy. It's because they can't figure out how to get the little > bottles into the typewriter. > From spearce@REDACTED Fri Mar 14 03:39:13 2003 From: spearce@REDACTED (Shawn Pearce) Date: Thu, 13 Mar 2003 21:39:13 -0500 Subject: Executing boolean expressions on a list In-Reply-To: References: <20030314021200.GD23238@spearce.org> Message-ID: <20030314023913.GE23238@spearce.org> >From lists.erl: 625 all(Pred, [Hd|Tail]) -> 626 case Pred(Hd) of 627 true -> all(Pred, Tail); 628 false -> false 629 end; 630 all(_, []) -> true. It would seem that the Erlang masters implemented it exactly as I have. At these few points in my code, I'd rather not do the remote function call + fun call, but lists:all/2 does what I want. :-) Maybe I'll change my code. Thanks Peter. Peter H|gfeldt wrote: > > How about lists:all/2, > > recursive(N, Es) -> > lists:all(fun(E) -> somef(N, E) end, Es) ? > > /Peter > > On Thu, 13 Mar 2003, Shawn Pearce wrote: > > > I find I'm writing a lot of: > > > > recursive(N, [H | T]) -> > > case somef(N, H) of > > true -> recursive(N, T); > > false -> false > > end; > > recursive(N, []) -> > > true. > > > > somef(N, E) -> > > .... % return true or false. -- Shawn. The human race is a race of cowards; and I am not only marching in that procession but carrying a banner. -- Mark Twain From urfaust@REDACTED Fri Mar 14 03:48:37 2003 From: urfaust@REDACTED (Faust) Date: Fri, 14 Mar 2003 13:48:37 +1100 Subject: ANNOUNCE - erlguten 2.1 In-Reply-To: (Joe Armstrong's message of "Thu, 13 Mar 2003 11:28:08 +0100 (CET)") References: Message-ID: <1y1a3bp6.fsf@optushome.com.au> Reading through the code of erlguten is a very enlightening and educational experience ! -- natsu-gusa ya / tsuwamono-domo-ga / yume no ato summer grasses / strong ones / dreams site Summer grasses, All that remains Of soldier's dreams (Basho trans. Stryk) From jay@REDACTED Fri Mar 14 03:58:47 2003 From: jay@REDACTED (Jay Nelson) Date: Thu, 13 Mar 2003 18:58:47 -0800 Subject: UI thoughts Message-ID: <4.2.2.20030313185619.00cdf600@duomark.com> You may have your OpenGL embedded graphics application sooner than you expected, Vlad! "We firmly believe that OpenGL ES will become an important graphics API in the embedded arena," said Bjorn Ekelund, Vice President Technology Development, Ericsson Mobile Platforms. http://www.linuxdevices.com/news/NS5751324086.html jay From Vlad.Dumitrescu@REDACTED Fri Mar 14 10:28:23 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Fri, 14 Mar 2003 10:28:23 +0100 Subject: Extending Functionality: an expedient and questionable approa ch Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D46D@esemont203.gbg.edt.ericsson.se> Hi guys, I happen to know this Vlad person :-D and he likes to be the fool that throws the stone into the lake and let 20 wise people try for a month to figure how to pick it back. My original idea, that Chris tested, has a major drawback (besides the problems Chris and the others observed): it allows only for an unknown function to be looked for in another module. This is fine, but is it enough? Is it what is really needed? Many (most?) times the functions that we'd like to extend have many clauses and it's probably so that we'd like to be able to select specific clauses from different modules. Since this functionality may not be very useful for library functions, but for processes, I think a better answer is to use my new gen_server_ext behaviour, featuring: - a list of "ancestors" that will be checked for loops and rejected if any are found - modules will look just like regular gen_server modules - use of gen_server_ext:next_call() [_cast, _info, etc] that make it possible to go up the "hierarchy" in a controlled way, i.e. 1) one can choose what functionality to reuse; 2) the reuse is explicit = no surprises from unexpected automatic handling 3) and the designer has to think about what he/she's doing - if the need should exist, the ancestor list may be made modifiable at run-time All in all, my impression is that this is very close in effect to the CommonLisp generic functions. It's powerful, flexible, easy to use. And what's maybe most important: doesn't need to get any "OO" label, it is a natural extension to gen_servers! :-) Okay, I'm not saying this is the ultimate answer (because we all know that's 42) but it may be the way to go and add improvements to. (I already have some buzzing around...) I will try to write some examples this weekend, hopefully some less than the most trivial, but don't hold your breath. Feedback is welcomed! Regards, Vlad From svg@REDACTED Fri Mar 14 11:01:28 2003 From: svg@REDACTED (Vladimir Sekissov) Date: Fri, 14 Mar 2003 15:01:28 +0500 (YEKT) Subject: Executing boolean expressions on a list In-Reply-To: <20030314021200.GD23238@spearce.org> References: <20030314021200.GD23238@spearce.org> Message-ID: <20030314.150128.41630571.svg@surnet.ru> Good day, spearce> recursive(N, [H | T]) -> somef(N, H) and recursive(N, T); ^^^ spearce> recursive(N, []) -> true. spearce> spearce> but was worried about order of evaluation on the and operator spearce> and not being able tail-recursive. recursive(N, [H | T]) -> somef(N, H) andalso recursive(N, T); ^^^^^^^ recursive(N, []) -> true. This variant would be the right answer. `andalso' calculates it's right part only if the left is true (as in C,Perl, etc). Best Regards, Vladimir Sekissov From myloginname@REDACTED Fri Mar 14 13:34:32 2003 From: myloginname@REDACTED (Manjeet Singh) Date: Fri, 14 Mar 2003 13:34:32 +0100 Subject: How to create a config file to read dynamically Message-ID: <3E71CC58.7251582E@eed.ericsson.se> Hi, I am working on a project, using erlang as the language, my requirement is that i want to create a config file which should be read at by the requesting task,at the run time with out stopping the system, how it is possible. Regards Manjeet From luke@REDACTED Fri Mar 14 13:22:49 2003 From: luke@REDACTED (Luke Gorrie) Date: 14 Mar 2003 13:22:49 +0100 Subject: ANNOUNCE: erlguten In-Reply-To: References: Message-ID: Ulf Wiger writes: > If I had to pick one aide to go with Emacs, it would be an > outliner. The Word outliner was the main reason I didn't > abandon it years ago. Emacs has an excellent outline-view for Texinfo documents. Texinfo is actually a very nice system for writing reference-manual type documents, IMO. I particularly like it's unobtrustive markup language. The printed manuals you buy from the FSF are all done with Texinfo (from the same sources as the 'info' files.) Cheers, Luke From matthias@REDACTED Fri Mar 14 13:57:51 2003 From: matthias@REDACTED (Matthias Lang) Date: Fri, 14 Mar 2003 13:57:51 +0100 Subject: UI thoughts In-Reply-To: <4.2.2.20030313185619.00cdf600@duomark.com> References: <4.2.2.20030313185619.00cdf600@duomark.com> Message-ID: <15985.53711.950977.194456@antilipe.corelatus.se> Jay Nelson writes: > You may have your OpenGL embedded graphics application > sooner than you expected, Vlad! > > "We firmly believe that OpenGL ES will become an important > graphics API in the embedded arena," said Bjorn Ekelund, > Vice President Technology Development, Ericsson Mobile > Platforms. I'm imagining today's Friday meeting: Kenneth will march out before the assembled OTP group, admire their freshly starched uniforms as they stand stiffly at attention and bark "OpenGL is now our #1 priority". All thunder in unison: "Yes SIR! OpenGL SIR!". Bulan shakes. It's almost like that in ?lvsj?, but not quite. ;-) It's likely that Bj?rn Ekelund has never heard of Erlang and that the OTP group haven't heard of Bj?rn Ekelund. I don't recognise the name. Then again, I never was much of an expert on Ericsson structure. Ericsson is (still) a big company. There's a lot of diversity. That's a good thing. Matthias From etxuwig@REDACTED Fri Mar 14 14:11:53 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Fri, 14 Mar 2003 14:11:53 +0100 (MET) Subject: How to create a config file to read dynamically In-Reply-To: <3E71CC58.7251582E@eed.ericsson.se> Message-ID: On Fri, 14 Mar 2003, Manjeet Singh wrote: >I am working on a project, using erlang as the language, my >requirement is that i want to create a config file which >should be read at by the requesting task,at the run time >with out stopping the system, how it is possible. There are a number of possibilities, for example: - Create a text file with one or more erlang terms, and read it with file:consult(File). You can generate such a file: store_config(Data, File) -> {ok,Fd} = file:open(File, [write]), io:fwrite(Fd, "p.~n", [Data]), file:close(Fd). - Store configuration data in an ets table, and then call ets:tab2file(EtsTable, File). The file can be read with ets:file2tab(File), which re-creates the ets table. - Store the configuration data using dets (disk-based hash tables.) - Use the mnesia database. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From enewhuis@REDACTED Fri Mar 14 14:20:15 2003 From: enewhuis@REDACTED (Eric Newhuis) Date: Fri, 14 Mar 2003 07:20:15 -0600 Subject: Redundant Streams in Erlang Message-ID: <00a601c2ea2c$739f1020$34c2cf0a@futuresource.com> Can anyone point me in the right direction on how to build a high availability solution in Erlang? I want to push a single stream of UDP packets from redundant Erlang nodes. If the master dies then the slave needs to take over until the master returns to life. So this is like a pair of redundant data transmitters. Is there a quick-and-dirty way? What is the *right* way? -------------- next part -------------- An HTML attachment was scrubbed... URL: From eleberg@REDACTED Fri Mar 14 14:27:49 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Fri, 14 Mar 2003 14:27:49 +0100 (MET) Subject: Redundant Streams in Erlang Message-ID: <200303141327.h2EDRnH28611@cbe.ericsson.se> > From: "Eric Newhuis" > To: > Subject: Redundant Streams in Erlang > Date: Fri, 14 Mar 2003 07:20:15 -0600 > MIME-Version: 1.0 > X-Priority: 3 > X-MSMail-Priority: Normal > X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2919.6600 > X-Scanned-By: MIMEDefang 2.30 (www . roaringpenguin . com / mimedefang) > > Can anyone point me in the right direction on how to build a high availability solution in Erlang? perhaps this is a start? ''Improving Robustness in Distributed Systems'' from Seventh International Erlang/OTP User Conference. http://www.erlang.se/euc/01/Bergqvist2001/sld001.htm bengt From enewhuis@REDACTED Fri Mar 14 14:32:44 2003 From: enewhuis@REDACTED (Eric Newhuis) Date: Fri, 14 Mar 2003 07:32:44 -0600 Subject: Redundant Streams in Erlang (Version 2) References: <00a601c2ea2c$739f1020$34c2cf0a@futuresource.com> Message-ID: <00af01c2ea2e$31948f50$34c2cf0a@futuresource.com> Can anyone point me in the right direction on how to build a high availability solution in Erlang? I want to push a single stream of UDP packets from redundant Erlang nodes. If the master dies then the slave needs to take over until the master returns to life. So this is like a pair of redundant data transmitters. Is there a quick-and-dirty way? What is the *right* way? Also, is there any popular technique for avoiding data loss? -------------- next part -------------- An HTML attachment was scrubbed... URL: From enano@REDACTED Fri Mar 14 14:44:26 2003 From: enano@REDACTED (Miguel Barreiro Paz) Date: Fri, 14 Mar 2003 14:44:26 +0100 (CET) Subject: Redundant Streams in Erlang (Version 2) In-Reply-To: <00af01c2ea2e$31948f50$34c2cf0a@futuresource.com> References: <00a601c2ea2c$739f1020$34c2cf0a@futuresource.com> <00af01c2ea2e$31948f50$34c2cf0a@futuresource.com> Message-ID: > Is there a quick-and-dirty way? What is the *right* way? Right way IMHO would be adding SCTP support to Erlang. From Chandrashekhar.Mullaparthi@REDACTED Fri Mar 14 15:45:49 2003 From: Chandrashekhar.Mullaparthi@REDACTED (Chandrashekhar Mullaparthi) Date: Fri, 14 Mar 2003 14:45:49 -0000 Subject: Extending Functionality: an expedient and questionable approa ch Message-ID: Another way to look at the stack...but it is not as pretty as what you'd see in a crash report. (camelns@REDACTED)212> erlang:process_display(whereis(cns_server), backtrace). program counter = 0x9895a0 (gen_server:loop/6 + 52) cp = 0x85ee6c (proc_lib:init_p/5 + 164) arity = 0 397b64 Return addr 0x85EE6C (proc_lib:init_p/5 + 164) y(0) [] y(1) infinity y(2) cns_server y(3) {state,[],0,0,17000} y(4) cns_server y(5) <0.25458.2> 397b80 Return addr 0x10F9F4 () y(0) Catch 0x85EE6C (proc_lib:init_p/5 + 164) y(1) gen y(2) init_it y(3) [gen_server,<0.25458.2>,<0.25458.2>,{local,cns_server},cns_server,normal,[]] true You can specify how much of the backtrace is saved using: erlang:system_flag(backtrace_depth, Value). -----Original Message----- From: Chris Pressey [mailto:cpressey@REDACTED] Sent: 13 March 2003 23:41 To: Shawn Pearce Cc: erlang-questions@REDACTED Subject: Re: Extending Functionality: an expedient and questionable approach On Thu, 13 Mar 2003 17:56:45 -0500 Shawn Pearce wrote: Actually, just out of curiousity, does anyone know if there's a better way to investigate the call stack - better than the only method I've seen so far, that is, to catch an intentional error and examine the result? NOTICE AND DISCLAIMER: This email (including attachments) is confidential. If you have received this email in error please notify the sender immediately and delete this email from your system without copying or disseminating it or placing any reliance upon its contents. We cannot accept liability for any breaches of confidence arising through use of email. Any opinions expressed in this email (including attachments) are those of the author and do not necessarily reflect our opinions. We will not accept responsibility for any commitments made by our employees outside the scope of our business. We do not warrant the accuracy or completeness of such information. From raimo.niskanen@REDACTED Fri Mar 14 17:12:48 2003 From: raimo.niskanen@REDACTED (Raimo Niskanen) Date: Fri, 14 Mar 2003 17:12:48 +0100 Subject: io interleaving Message-ID: <3E71FF80.8010302@uab.ericsson.se> Sorry for the late reply. I am digging in this code now for other reasons and have fixed the bug, in the next R9 release. The Erlang file I/O server did some read ahead, and writes did not reposition to compensate for buffered read data (if any). / Raimo Niskanen, Erlang/OTP ----------------------------------------------------------- Subject: io interleaving? From: Bengt Kleberg Date: Mon, 24 Feb 2003 14:39:33 +0100 (MET) To: erlang-questions@REDACTED greetings, where should io:fwrite() place things in a file? i have the following file line r1 line r2 line r3 if i open the file [read, write], write ''line w1'' and read ''line r2'' i have the contents: line w1 line r2 line r3 however, if i open the file [read, write], read ''line r1'' and write ''line w1'' i have the contents: line r1 line r2 line r3 line w1 i would have expected: line r1 line w1 line r3 is this a bug, or, why is it like this? bengt From D.WILLIAMS@REDACTED Fri Mar 14 17:15:38 2003 From: D.WILLIAMS@REDACTED (WILLIAMS Dominic) Date: Fri, 14 Mar 2003 17:15:38 +0100 Subject: Redundant Streams in Erlang Message-ID: > perhaps this is a start? ''Improving Robustness in Distributed > Systems'' from Seventh International Erlang/OTP User Conference. > http://www.erlang.se/euc/01/Bergqvist2001/sld001.htm Reading a slide presentation without having the commentary is tantalising and frustrating - especially when the slides seem so interesting! This stuff is exactly what I need (I am interested in the hardware/network aspects too, not just Erlang). Has it been written up in any more detail? Cheers, Dominic. From rasmus_jonsson@REDACTED Fri Mar 14 17:44:10 2003 From: rasmus_jonsson@REDACTED (=?iso-8859-1?q?Rasmus=20Jonsson?=) Date: Fri, 14 Mar 2003 17:44:10 +0100 (CET) Subject: jinterface problems In-Reply-To: <20030311201317.GC26601@spearce.org> Message-ID: <20030314164410.50963.qmail@web20511.mail.yahoo.com> Does really the higher java applet security (Sandbox) let you open TCP sockets the way you discribe here below? I mean, this sounds quite straight forward doing it in a java application, but doesn?t the "applet thing" add extra difficulties to this task? --- Shawn Pearce skrev: > Rasmus Jonsson wrote: > > What we actually are trying to accomplish is to let > > any client (anywhere) download an java applet over http > > from a inets server on the erlang node, and then we > > want the java applet and the e-node to start communica- > > ting. (here we cannot require any empd running on the > > client!) > The best idea would be to form a protocol between the applet > and the Erlang server, which responds to clients using gen_tcp. > Set {packet, 4} in gen_tcp and use the jinterface classes to > serialize messages in java and send them with 4 byte length > headers over a TCP socket. In Erlang you can use term_to_binary > and binary_to_term to convert back and forth. This is essentially > all the distribution system does, it just also automatically > relays the message to the destination pid, as well as provide > for linking and whatnot. > > -- > Shawn. > > Avoid reality at all costs. _____________________________________________________ G? f?re i k?n och f? din sajt v?rderad p? nolltid med Yahoo! Express Se mer p?: http://se.docs.yahoo.com/info/express/help/index.html From Sean.Hinde@REDACTED Fri Mar 14 19:24:24 2003 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Fri, 14 Mar 2003 18:24:24 -0000 Subject: jinterface problems Message-ID: You are allowed to open a conection back the the web server yes. I have used this technique to talk to applets before. Sean > -----Original Message----- > From: Rasmus Jonsson [mailto:rasmus_jonsson@REDACTED] > Sent: 14 March 2003 16:44 > To: Shawn Pearce; erlang-questions@REDACTED > Subject: Re: jinterface problems > > > Does really the higher java applet security (Sandbox) let you > open TCP sockets the way you discribe here below? I mean, this > sounds quite straight forward doing it in a java application, > but doesn?t the "applet thing" add extra difficulties to this > task? > > --- Shawn Pearce skrev: > > Rasmus Jonsson wrote: > > > What we actually are trying to accomplish is to let > > > any client (anywhere) download an java applet over http > > > from a inets server on the erlang node, and then we > > > want the java applet and the e-node to start communica- > > > ting. (here we cannot require any empd running on the > > > client!) > > > The best idea would be to form a protocol between the applet > > and the Erlang server, which responds to clients using gen_tcp. > > Set {packet, 4} in gen_tcp and use the jinterface classes to > > serialize messages in java and send them with 4 byte length > > headers over a TCP socket. In Erlang you can use term_to_binary > > and binary_to_term to convert back and forth. This is essentially > > all the distribution system does, it just also automatically > > relays the message to the destination pid, as well as provide > > for linking and whatnot. > > > > -- > > Shawn. > > > > Avoid reality at all costs. > > > _____________________________________________________ > G? f?re i k?n och f? din sajt v?rderad p? nolltid med Yahoo! Express > Se mer p?: http://se.docs.yahoo.com/info/express/help/index.html > NOTICE AND DISCLAIMER: This email (including attachments) is confidential. If you have received this email in error please notify the sender immediately and delete this email from your system without copying or disseminating it or placing any reliance upon its contents. We cannot accept liability for any breaches of confidence arising through use of email. Any opinions expressed in this email (including attachments) are those of the author and do not necessarily reflect our opinions. We will not accept responsibility for any commitments made by our employees outside the scope of our business. We do not warrant the accuracy or completeness of such information. From luke@REDACTED Fri Mar 14 21:31:34 2003 From: luke@REDACTED (Luke Gorrie) Date: 14 Mar 2003 21:31:34 +0100 Subject: Redundant Streams in Erlang (Version 2) In-Reply-To: <00af01c2ea2e$31948f50$34c2cf0a@futuresource.com> References: <00a601c2ea2c$739f1020$34c2cf0a@futuresource.com> <00af01c2ea2e$31948f50$34c2cf0a@futuresource.com> Message-ID: "Eric Newhuis" writes: > Can anyone point me in the right direction on how to build a high > availability solution in Erlang? I want to push a single stream of > UDP packets from redundant Erlang nodes. If the master dies then the > slave needs to take over until the master returns to life. So this is > like a pair of redundant data transmitters. > > Is there a quick-and-dirty way? What is the *right* way? Assuming all nodes know what data to send, I suppose the real problem is just making sure that only one node is sending at a time. I *think* the 'global' module is the Right Way to handle this, though I haven't used it myself. Though if you need very fast fail-over then perhaps the distributed erlang heartbeat won't be snappy enough and you'll need to roll your own.. > Also, is there any popular technique for avoiding data loss? I don't know one, but it seems like an interesting problem. Please let us know if you find a nice algorithm. Cheers, Luke From etxuwig@REDACTED Fri Mar 14 22:54:31 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Fri, 14 Mar 2003 22:54:31 +0100 (MET) Subject: jungerl addition: builder Message-ID: I added a utility, called 'builder', to jungerl. It's intended to simplify the building of OTP boot scripts. A slightly contrived and only partly example from building edoc in jungerl: 1) Check out and make the jungerl code 2) cd .../jungerl/lib/xmerl 3) erl -pa ../builder/ebin 4) 1> builder:go(). This will try to build the following files: ebin/xmerl.app priv/xmerl.rel priv/xmerl.script priv/xmerl.boot priv/xmerl_load.script priv/xmerl_load.boot (no start commands - only paths) priv/xmerl.start (shell script, works only on unix) priv/xmerl.load (another shell script) (The idea of the xmerl.load script is to start a VM with all the paths set, but only the basic applications running. This can be useful e.g. for initializing a mnesia database.) In the case of xmerl, it will probably fail. The src/xmerl.app.src contains a syntax error, as does the ebin/xmerl.app. Delete them and try again. (You may note that the version per default becomes "BLDR". Read builder/doc/builder.html for tips on how to change this.) You can now start an erlang node with the right paths for xmerl set by calling .../jungerl/lib/xmerl/priv/xmerl.start (in this case, xmerl doesn't start anything, but still...) 5) cd .../jungerl/syntax_tools 6) erl -pa ../builder/ebin 7) builder:go(). This won't work either. We are told why: The module proplists is specified in both stdlib and syntax_tools. We could delete proplists, but a slightly less dramatic option might be to tell builder to skip the module (while we're at it, let's also skip 'test') Delete the generated ebin/syntax_tools.app, and re-run: builder:go([{skip,[test,proplists]}]). 8) Let's now move to edoc. Now we have to do some special stuff. Edoc needs xmerl and syntax tools, which now have .app files. But we need to tell builder to look for them, and where to look. One more problem: there is a syntax_tools in Erlang R9B (and we should probably use that one, but let's pretend that we really want the one we just built.) 1> Path=["/home/etxuwig/jungerl/lib/*/ebin"|code:get_path()]. 2> builder:go([{apps,[xmerl,{syntax_tools,"BLDR"}]},{path,Path}]). 9) Let's now see how it works: cd ~/jungerl/lib/builder/src ../../edoc/priv/edoc.start Eshell ... 1> edoc:file("builder.erl"). ok OK, so the exercise did not go flawlessly, but then again the applications were not prepared. You can write an .app.src file for your application, and a .rel.src to specify your build. You can also write a src/BUILD_OPTIONS file containing erlang expressions, where the last expr returns a list of options for the build tool. The general idea is that you can write one application, run a build on that one, and start it using the proper OTP boot scripts. Then you can write another application, and build a script for that one, etc. It's supposed to be simple, but there are also lots of options to allow for custom builds and for dealing with reluctant applications. Read the builder/doc/builder.html for information on all the options, and please send comments and requests for improvements. Thanks to Chandru and Mickael for being beta testers and providing feedback. /Uffe -- Ulf Wiger, Senior Specialist / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From spearce@REDACTED Fri Mar 14 22:56:58 2003 From: spearce@REDACTED (Shawn Pearce) Date: Fri, 14 Mar 2003 16:56:58 -0500 Subject: R = catch foo() ? Message-ID: <20030314215657.GA6232@spearce.org> Why is this ok: case catch foo() of R -> .... end. and this is not? R = catch foo(), .... Reason I ask is, I know foo is failing, so I wanted to catch it instead of just saying: R = foo() for debug reasons to see why. In real production this is being caught by a standard supervisor behavior and is being restarted, but the supervisor won't restart if the app doesn't start at least once successfully. -- Shawn. Don't you feel more like you do now than you did when you came in? From etxuwig@REDACTED Fri Mar 14 23:00:57 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Fri, 14 Mar 2003 23:00:57 +0100 (MET) Subject: R = catch foo() ? In-Reply-To: <20030314215657.GA6232@spearce.org> Message-ID: On Fri, 14 Mar 2003, Shawn Pearce wrote: >Why is this ok: > > case catch foo() of > R -> .... > end. > >and this is not? > > R = catch foo(), > .... It has to do with the precedence rules in the parser. Try this: R = (catch foo()), ... /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From luke@REDACTED Fri Mar 14 22:58:52 2003 From: luke@REDACTED (Luke Gorrie) Date: 14 Mar 2003 22:58:52 +0100 Subject: R = catch foo() ? In-Reply-To: <20030314215657.GA6232@spearce.org> References: <20030314215657.GA6232@spearce.org> Message-ID: Shawn Pearce writes: > Why is this ok: > > case catch foo() of > R -> .... > end. > > and this is not? > > R = catch foo(), > .... Quirky parsing. You can write: R = (catch foo()), A ways back I hacked the grammar (erl_parse.yrl) to allow the other syntax, which looked reasonable I thought. I ran that copy for perhaps 6 months without noticing any troubles. Maybe there was something lurking though.. -Luke From spearce@REDACTED Fri Mar 14 23:10:26 2003 From: spearce@REDACTED (Shawn Pearce) Date: Fri, 14 Mar 2003 17:10:26 -0500 Subject: R = catch foo() ? In-Reply-To: References: <20030314215657.GA6232@spearce.org> Message-ID: <20030314221026.GA6336@spearce.org> Ok, something must be up with my mailing list subscription. Both Ulf and Luke responded to me before I received my original message back from the mailing list. :) Thanks for the clarification, that makes sense. Ulf Wiger wrote: > On Fri, 14 Mar 2003, Shawn Pearce wrote: > > >Why is this ok: > > > > case catch foo() of > > R -> .... > > end. > > > >and this is not? > > > > R = catch foo(), > > .... > > It has to do with the precedence rules in the parser. > Try this: > > R = (catch foo()), > ... > > /Uffe -- Shawn. It is a wise father that knows his own child. -- William Shakespeare, "The Merchant of Venice" From bernardp@REDACTED Fri Mar 14 23:57:47 2003 From: bernardp@REDACTED (Pierpaolo BERNARDI) Date: Fri, 14 Mar 2003 23:57:47 +0100 Subject: Executing boolean expressions on a list References: <20030314021200.GD23238@spearce.org> Message-ID: <023501c2ea7d$2478bfe0$51f36850@c1p4e3> From: "Shawn Pearce" > I'm trying to keep it tail-recursive. I thought about: ... > which I didn't like because of the formatting of the if statement, and: > > recursive(N, [H | T]) -> somef(N, H) and recursive(N, T); > recursive(N, []) -> true. > > but was worried about order of evaluation on the and operator > and not being able tail-recursive. andalso should be good here. P. From jay@REDACTED Sat Mar 15 06:41:21 2003 From: jay@REDACTED (Jay Nelson) Date: Fri, 14 Mar 2003 21:41:21 -0800 Subject: What are processes good for? Message-ID: <4.2.2.20030314211553.00d3ac60@duomark.com> Chris Pressey wrote: > Of course it depends on your definition of waste, but > I don't think programmers should ever truly waste resources, > even cheap ones, when thereare equally viable alternatives > - which is what I would like to explore. I sounded a bit overzealous here -- I actually am too worried about performance and waste most of the time. I recently saw at work how they ground their computers into dust and thought "mine are sitting idle right now, why aren't they working to make things easier for me later?" To me the goal of coding is to: 1) accomplish something useful, and 2) make clear the problem being solved so that it can be verified to work correctly. I generally ignore #1 and spend all my time working on problems that I find suitably interesting, but really concentrate on #2. I believe that computers have plenty enough power that you should always waste other things besides clarity and correctness. Whatever you have the most of should be traded off against the goal. If storing a value in two places in memory makes the code easier to understand and easier to write and maintain, the memory should be "wasted". > But what about controls without state, or barely any state, > I wonder? Like pushbuttons and frames and labels. Do > they still get processes? I've been thinking about this, and OO in general -- why it initially feels wrong to me in erlang. I may be way off, so correct me, but here is the thinking: The main characteristics of OO are statefulness and identity. The goal of OO is to encapsulate state, protect it from outside influence, publish a proscribed interface for interacting with it and maintain independence from other instances of state whilst trying to optimize and reuse the functionality that makes the data consistent and dynamic. It is an extension of structured programming in that it is concerned with improving verifiability and readability by limiting the scope of destructive side-effects. At its heart, it is fundamentally concerned with state and sharing state -- thus the need for identity. As an optimization, a small reference to a state can be shared among other entities, knowing that at all times they refer to the same state. The main characteristic of Functional Languages was to create a way to avoid state and side-effects so that code could be provably verified to perform to specification. State is maintained consistent by never modifying it, but rather creating a new version of the state to represent the new state. Pure functional languages cannot have a shared reference to dynamic state, only a shared reference to a particular version of state that is unchangeable. In erlang, processes are the only safe way to share dynamic state. That is why I listed "strong encapsulation" as a purpose for processes. The process id may be shared among many places in the code, and it will always refer to the currently accessible state that is available via the message interface. The server serialized access is what makes it possible, but also what makes it not a pure functional language. My answer to your question is: if the data is truly static, store it any way that is convenient for the clarity and correctness of the code. If the data is shared *and* may change but all references to it *must* refer to the same current state, then it *must* be a process. Being dynamic in and of itself may not qualify for a process if there is enough time to update it synchronously, and it is not shared by reference. If either of these conditions is not true, it most be a process. As you pointed out, the other case for using a process is to have a consistent interface, which was precisely my point about code reuse / adapting interfaces as another purpose of processes. Other methods work, but if you have a shared reference the other methods can't be trusted (and are unwieldy code-wise to implement correctly when there are several occurrences of the reference in complex data structures). jay From ulf.wiger@REDACTED Sat Mar 15 09:21:47 2003 From: ulf.wiger@REDACTED (Wiger Ulf) Date: Sat, 15 Mar 2003 09:21:47 +0100 Subject: jungerl addition: builder References: Message-ID: <004901c2eacb$ec04e680$fd7a40d5@telia.com> From: "Ulf Wiger" > A slightly contrived and only partly example from building > edoc in jungerl: Hmm, that should have been "...and only partly successful example" Sorry about that. /Uffe From richardc@REDACTED Sat Mar 15 13:03:13 2003 From: richardc@REDACTED (Richard Carlsson) Date: Sat, 15 Mar 2003 13:03:13 +0100 (MET) Subject: Executing boolean expressions on a list In-Reply-To: <023501c2ea7d$2478bfe0$51f36850@c1p4e3> References: <20030314021200.GD23238@spearce.org> <023501c2ea7d$2478bfe0$51f36850@c1p4e3> Message-ID: On Fri, 14 Mar 2003, Pierpaolo BERNARDI wrote: > > recursive(N, [H | T]) -> somef(N, H) and recursive(N, T); > > recursive(N, []) -> true. > > > > but was worried about order of evaluation on the and operator > > and not being able tail-recursive. > > andalso should be good here. Yes. However, it currently kills the tail recursion. The evaluation of 'andalso' checks that both arguments are booleans. With a bit of type analysis, the check for the recursive case could be removed, making the function tail recursive. The compiler will probably soon be able to do this, but right now the resulting code is not tail recursive. *However*: it is still an elegant way of writing the function, tail recursive or not, so unless you *really* feel that you must optimize for speed, I suggest that you use the 'andalso' version rather than rewriting it. /Richard Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) E-mail: Richard.Carlsson@REDACTED WWW: http://user.it.uu.se/~richardc/ From bernardp@REDACTED Sat Mar 15 17:49:02 2003 From: bernardp@REDACTED (Pierpaolo BERNARDI) Date: Sat, 15 Mar 2003 17:49:02 +0100 Subject: Executing boolean expressions on a list References: <20030314021200.GD23238@spearce.org> <023501c2ea7d$2478bfe0$51f36850@c1p4e3> Message-ID: <022901c2eb12$e5a798e0$28f06850@c1p4e3> From: "Richard Carlsson" > > andalso should be good here. > > Yes. However, it currently kills the tail recursion. The evaluation of > 'andalso' checks that both arguments are booleans. Drat. I hadn't realized this. I'll have to recheck my uses of andalso in this new light. Couldn't the spec of andalso and orelse be changed as to not guarantee that the result is boolean? in this case they could return their second argument with no checking. Correct code shouldn't be affected by this. > With a bit of type > analysis, the check for the recursive case could be removed, making the > function tail recursive. The compiler will probably soon be able to do > this, but right now the resulting code is not tail recursive. But even if, it will be able to do so only in the case of a self recursive function, I think? Certainly not across modules? > *However*: it is still an elegant way of writing the function, tail > recursive or not, so unless you *really* feel that you must optimize for > speed, I suggest that you use the 'andalso' version rather than > rewriting it. Space more than speed. Checking in my code, I found one case where this could matter: provalp(0,Dims) -> true; provalp(N,Dims) when N > 0 -> provalp1(Dims) andalso provalp(N-1,Dims). This function is checking that provalp1 always returns true. The algorithms being checked depend on the random number generator, so I used this function with big values of N. I must rewrite this function as: provalp(0,Dims) -> true; provalp(N,Dims) when N > 0 -> case provalp1(Dims) of false -> false; true -> provalp(N-1,Dims) end. Not nearly as pretty. 8-) P. From Chandrashekhar.Mullaparthi@REDACTED Sun Mar 16 00:08:20 2003 From: Chandrashekhar.Mullaparthi@REDACTED (Chandrashekhar Mullaparthi) Date: Sat, 15 Mar 2003 23:08:20 -0000 Subject: Compiler crash Message-ID: Got a compiler crash compiling this syntactically wrong code. Using R9B. -module(test). -author('cmullapa@REDACTED'). -compile(export_all). test() -> .io.format("abcd~n", []). % This should really be .io:format -------------------------- 18> c(test). ./test.erl:none: internal error in beam_clean; crash reason: {{case_clause,{'EXIT',{function_clause, [{dict,fetch_val,[4,[]]}, {beam_clean,find_all_used,3}, {beam_clean,module,2}, {compile, '-select_passes/2-anonymous-2-', 2}, {compile, '-internal_comp/4-anonymous-1-', 2}, {compile,fold_comp,3}, {compile,internal_comp,4}, {compile,internal,3}]}}}, [{compile,'-select_passes/2-anonymous-2-',2}, {compile,'-internal_comp/4-anonymous-1-',2}, {compile,fold_comp,3}, {compile,internal_comp,4}, {compile,internal,3}]} error cheers Chandru NOTICE AND DISCLAIMER: This email (including attachments) is confidential. If you have received this email in error please notify the sender immediately and delete this email from your system without copying or disseminating it or placing any reliance upon its contents. We cannot accept liability for any breaches of confidence arising through use of email. Any opinions expressed in this email (including attachments) are those of the author and do not necessarily reflect our opinions. We will not accept responsibility for any commitments made by our employees outside the scope of our business. We do not warrant the accuracy or completeness of such information. From spearce@REDACTED Sun Mar 16 03:14:23 2003 From: spearce@REDACTED (Shawn Pearce) Date: Sat, 15 Mar 2003 21:14:23 -0500 Subject: Executing boolean expressions on a list In-Reply-To: References: <20030314021200.GD23238@spearce.org> <023501c2ea7d$2478bfe0$51f36850@c1p4e3> Message-ID: <20030316021423.GA465@spearce.org> Richard Carlsson wrote: > > On Fri, 14 Mar 2003, Pierpaolo BERNARDI wrote: > > > > recursive(N, [H | T]) -> somef(N, H) and recursive(N, T); > > > recursive(N, []) -> true. > > > > > > but was worried about order of evaluation on the and operator > > > and not being able tail-recursive. > > > > andalso should be good here. > > Yes. However, it currently kills the tail recursion. The evaluation of > 'andalso' checks that both arguments are booleans. With a bit of type > analysis, the check for the recursive case could be removed, making the > function tail recursive. The compiler will probably soon be able to do > this, but right now the resulting code is not tail recursive. > > *However*: it is still an elegant way of writing the function, tail > recursive or not, so unless you *really* feel that you must optimize for > speed, I suggest that you use the 'andalso' version rather than > rewriting it. Double drat. :-) It was so pretty. But I don't want the cost in here. I don't think the case somef(...) of true .. false .. end is that much uglier than andalso, but it prevents me from chewing up stack space and saves me a little bit. I'm wrapping ets right now, and this code is sort of in the critical path between ets and my caller. ets performance was acceptable, so I don't want it to get much worse. Although the added functionality is good.... In retrospect, I shouldn't have written this code and just used mnesia. I think. ;-) -- Shawn. Look afar and see the end from the beginning. From urfaust@REDACTED Sun Mar 16 09:42:29 2003 From: urfaust@REDACTED (Faust) Date: Sun, 16 Mar 2003 19:42:29 +1100 Subject: ANNOUNCE: erlguten In-Reply-To: (Joe Armstrong's message of "Wed, 12 Mar 2003 20:53:57 +0100 (CET)") References: Message-ID: <4r63og7e.fsf@optushome.com.au> Joe Armstrong writes: > The funny thing is that the "old style" books (pre DTP) were full of > notes like "ITC Gothic Franklin" looks best in 24 pica columns when > set 8.5/11 ... etc. - seeing these layed out next to each other in > different combinations of Point size/Leading and in different measures > is quite instructive. Interesting. Is there somewhere online where some of this information is awailable ? -- ---- Breathing in, out, forward, back, living, dying. Two arrows meet in mid air, slice and sail on through into open space. I turn around. gesshu soko death poem january 1696 From jay@REDACTED Mon Mar 17 08:45:26 2003 From: jay@REDACTED (Jay Nelson) Date: Sun, 16 Mar 2003 23:45:26 -0800 Subject: TCP proxy using gen_server tutorial (Part 1) Message-ID: <4.2.2.20030316232716.00a23dc0@duomark.com> This will be a 3 part tutorial. Part 1 is complete, Part 2 will follow shortly and Part 3 will take a few weeks. It covers using gen_server to deliver a functionality similar to Joe's nano-webserver middleman. Please let me know of any problems you have with the code or the tutorial. The tutorial is at http://www.duomark.com/erlang/proxy.html The code is at http://www.duomark.com/erlang/tcp_proxy.erl and echo.erl (a braindead test driver accessible via telnet -- start via tcp_proxy(echo) and then 'telnet localhost 8000'). There are a few problems with the code as it sits: 1) If I kill the accept process, it is not caught in handle_info and it takes down the entire gen_server. I tried to trap_exit in tcp_proxy:start_link, but it just occurred to me I need to trap_exit where the accept process is spawned. [I thought it was automatically trapped by gen_server and reported in handle_info. As it stands the 'EXIT' clause of handle_info is never called. 'DOWN' works just peachy.] 2) If I start the server like: {ok, P2} = tcp_proxy:start_link(echo), and then erroneously call tcp_proxy:report_clients(P1) or any other function, the gen_server gets a badmatch, but takes down the tcp_proxy server with it. Why isn't P1 a different beast, especially if it is a non-existent process, and why should it affect the P2 process? Are all gen_server-based processes linked to the gen_server and will all come down if you make a typo in the shell? 3) When the server goes down, the existing clients remain connected. I thought when a Listen socket was closed, all Accept sockets derived from it would automatically be closed. As it is any previously connected clients will still get serviced after the server is down (I'm not sure if this is good or bad). jay From eleberg@REDACTED Mon Mar 17 10:01:29 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Mon, 17 Mar 2003 10:01:29 +0100 (MET) Subject: Compiler crash Message-ID: <200303170901.h2H91TH12675@cbe.ericsson.se> > From: Chandrashekhar Mullaparthi > To: "'erlang-questions@REDACTED'" > Subject: Compiler crash > Date: Sat, 15 Mar 2003 23:08:20 -0000 > MIME-Version: 1.0 > > Got a compiler crash compiling this syntactically wrong code. Using R9B. > > -module(test). > -author('cmullapa@REDACTED'). > > -compile(export_all). > > test() -> > .io.format("abcd~n", []). % This should really be .io:format this is a known bug. unfortunatly i can not remember what answer i got (about when it would be fixed) when i reported it. bengt From Vlad.Dumitrescu@REDACTED Mon Mar 17 10:48:56 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Mon, 17 Mar 2003 10:48:56 +0100 Subject: TCP proxy using gen_server tutorial (Part 1) Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D477@esemont203.gbg.edt.ericsson.se> Hi, Very good initiative, and good work! Some notes: * If you start the gen_server giving it a name to register, then there will only be at most one instance of it available at all times. I think you meant to register with the name of the service module, in this case echo? > 1) If I kill the accept process, it is not caught in handle_info > and it takes down the entire gen_server. I tried to trap_exit > in tcp_proxy:start_link, but it just occurred to me I need to > trap_exit where the accept process is spawned. * trap_exits has to be set on the gen_server process, and that means for example in tcp_proxy:init. * There is a small error in handle_info({'EXIT' : the result of spawn_link should be stored in a Pid2, and that one used in the answer. > 2) If I start the server like: {ok, P2} = tcp_proxy:start_link(echo), > and then erroneously call tcp_proxy:report_clients(P1) or any > other function, the gen_server gets a badmatch, * Use the pid only if the server has no registered name; see first note too. * The server goes down only because you don't catch the crashing gen_server:call. If you just add a 'catch', the tcp_proxy server will remain up. > 3) When the server goes down, the existing clients remain > connected. I thought when a Listen socket was closed, all > Accept sockets derived from it would automatically be closed. > As it is any previously connected clients will still get serviced > after the server is down (I'm not sure if this is good or bad). * Here I'm not sure either how to do it. best regards, Vlad From richardc@REDACTED Mon Mar 17 11:14:06 2003 From: richardc@REDACTED (Richard Carlsson) Date: Mon, 17 Mar 2003 11:14:06 +0100 (MET) Subject: Compiler crash In-Reply-To: <200303170901.h2H91TH12675@cbe.ericsson.se> References: <200303170901.h2H91TH12675@cbe.ericsson.se> Message-ID: On Mon, 17 Mar 2003, Bengt Kleberg wrote: > > From: Chandrashekhar Mullaparthi > > > > Got a compiler crash compiling this syntactically wrong code. Using R9B. > > > > test() -> > > .io.format("abcd~n", []). % This should really be .io:format > > this is a known bug. unfortunatly i can not remember what answer i got > (about when it would be fixed) when i reported it. Here's a patch. Apparently the fix did not make it into R9B-1 for some reason, but it definitely will be in R9C. file: lib/compiler/src/sys_pre_expand.erl ========================================= 403a404,405 > expr({call,Line,{record_field,_,_,_}=M,As0}, Vs, St0) -> > expr({call,Line,expand_package(M, St0),As0}, Vs, St0); /Richard Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) E-mail: Richard.Carlsson@REDACTED WWW: http://user.it.uu.se/~richardc/ "Having users is like optimization: the wise course is to delay it." -- Paul Graham From richardc@REDACTED Mon Mar 17 11:24:21 2003 From: richardc@REDACTED (Richard Carlsson) Date: Mon, 17 Mar 2003 11:24:21 +0100 (MET) Subject: Executing boolean expressions on a list In-Reply-To: <022901c2eb12$e5a798e0$28f06850@c1p4e3> References: <20030314021200.GD23238@spearce.org> <023501c2ea7d$2478bfe0$51f36850@c1p4e3> <022901c2eb12$e5a798e0$28f06850@c1p4e3> Message-ID: On Sat, 15 Mar 2003, Pierpaolo BERNARDI wrote: > > Yes. However, it currently kills the tail recursion. The evaluation of > > 'andalso' checks that both arguments are booleans. > > Drat. I hadn't realized this. I'll have to recheck my uses of andalso > in this new light. > > Couldn't the spec of andalso and orelse be changed as to not > guarantee that the result is boolean? in this case they could return > their second argument with no checking. Correct code shouldn't > be affected by this. Well, this is what I also said when we implemented it, but the OTP guys were not convinced, and preferred to have the check there. But perhaps your complaints will be more influential. Bj?rn, are you reading this? :-) > > With a bit of type > > analysis, the check for the recursive case could be removed, making the > > function tail recursive. The compiler will probably soon be able to do > > this, but right now the resulting code is not tail recursive. > > But even if, it will be able to do so only in the case of a self recursive > function, I think? Certainly not across modules? As long as it can be seen that the function always returns a boolean, self-recursive or indirectly does not matter. But generally not across modules. /Richard Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) E-mail: Richard.Carlsson@REDACTED WWW: http://user.it.uu.se/~richardc/ "Having users is like optimization: the wise course is to delay it." -- Paul Graham From bjarne@REDACTED Mon Mar 17 14:40:58 2003 From: bjarne@REDACTED (=?iso-8859-1?Q?Bjarne_D=E4cker?=) Date: Mon, 17 Mar 2003 14:40:58 +0100 Subject: 2nd ACM SIGPLAN Erlang Workshop - Call for papers Message-ID: <002401c2ec8a$d85fe380$261069d4@segeltorp> Dear Erlang friends, The 2nd ACM SIGPLAN Erlang Workshop takes place on Friday August 29, 2003, in Uppsala, Sweden. Please see the call for papers in http://www.erlang.se/workshop/2003/ We look forward to many high quality papers. Key dates: abstracts or preliminary papers due May 5, notification of acceptance June 2 and final papers due July 16. Welcome Thomas Arts, programme chairman thomas.arts@REDACTED Bjarne D?cker, organisation chairman bjarne@REDACTED -------------- next part -------------- An HTML attachment was scrubbed... URL: From bjorn@REDACTED Mon Mar 17 16:28:20 2003 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 17 Mar 2003 16:28:20 +0100 Subject: Executing boolean expressions on a list In-Reply-To: Richard Carlsson's message of "Mon, 17 Mar 2003 11:24:21 +0100 (MET)" References: <20030314021200.GD23238@spearce.org> <023501c2ea7d$2478bfe0$51f36850@c1p4e3> <022901c2eb12$e5a798e0$28f06850@c1p4e3> Message-ID: Richard Carlsson writes: > On Sat, 15 Mar 2003, Pierpaolo BERNARDI wrote: > > Well, this is what I also said when we implemented it, but the OTP > guys were not convinced, and preferred to have the check there. But > perhaps your complaints will be more influential. Bj?rn, are you > reading this? :-) > I not just me. When asking people in the OTP group, nobody liked the idea of not checking the right-hand side of 'andalso' and 'orelse'. The change would not be consistent with how 'and' and 'or' work. /Bjorn -- Bj?rn Gustavsson Ericsson Utvecklings AB bjorn@REDACTED ?T2/UAB/F/P BOX 1505 +46 8 727 56 87 125 25 ?lvsj? From jay@REDACTED Mon Mar 17 16:44:39 2003 From: jay@REDACTED (Jay Nelson) Date: Mon, 17 Mar 2003 07:44:39 -0800 Subject: TCP proxy using gen_server tutorial (Part 1) In-Reply-To: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D477@esemont203.gbg.ed t.ericsson.se> Message-ID: <4.2.2.20030317072500.00a2a9c0@duomark.com> Vlad Dumitrescu (EAW) wrote: > > I think you meant to register with the name of the service module, in > this case echo? Yes. > > * trap_exits has to be set on the gen_server process, and that means > for example in tcp_proxy:init. I had put it in start_link which was the calling process so that explains why it didn't work. > > * in handle_info({'EXIT' : the result of spawn_link should be stored in > a Pid2 Good catch! I missed this one completely. > > * Here I'm not sure either how to do it. I can run over the list of clients and kill them, but I'm not sure I want to. In my case, they are short-lived http requests so I will just let them run. Thanks, the changes have been made and updated in the tutorial and code. Hopefully this week I'll get a few hours to finish up Part 2. jay From cpressey@REDACTED Mon Mar 17 19:37:51 2003 From: cpressey@REDACTED (Chris Pressey) Date: Mon, 17 Mar 2003 12:37:51 -0600 Subject: Executing boolean expressions on a list In-Reply-To: References: <20030314021200.GD23238@spearce.org> <023501c2ea7d$2478bfe0$51f36850@c1p4e3> <022901c2eb12$e5a798e0$28f06850@c1p4e3> Message-ID: <20030317123751.6497f1e6.cpressey@catseye.mb.ca> On 17 Mar 2003 16:28:20 +0100 Bjorn Gustavsson wrote: > Richard Carlsson writes: > > > On Sat, 15 Mar 2003, Pierpaolo BERNARDI wrote: > > > > Well, this is what I also said when we implemented it, but the OTP > > guys were not convinced, and preferred to have the check there. But > > perhaps your complaints will be more influential. Bj?rn, are you > > reading this? :-) > > > > I not just me. When asking people in the OTP group, nobody liked the > idea of not checking the right-hand side of 'andalso' and 'orelse'. The > change would not be consistent with how 'and' and 'or' work. > > /Bjorn I can see why the thought of "true andalso 5" succeeding without an error would be disturbing to the OTP team. However, evaluating both sides for type correctness means that 'andalso' isn't really very short-circuiting... i.e. the only semantic difference between 'and' and 'andalso' is when the operands have side-effects, right? A quick grep through the OTP sources doesn't reveal any 'andalso's or 'orelse's with obviously side-effectful operands. (which is probably a *good* thing) So, it hadn't occurred to me before this thread, but this strikes me as a lot less useful than 'andalso' in a strongly-typed language. Personally I could live with "true andalso 5" succeeding; I could also live with plain 'and' and 'or' having short-circuiting semantics. Of course, whatever the OTP team decides, I'll manage :) -Chris From thomasl_erlang@REDACTED Mon Mar 17 23:30:50 2003 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Mon, 17 Mar 2003 14:30:50 -0800 (PST) Subject: Executing boolean expressions on a list In-Reply-To: Message-ID: <20030317223050.31743.qmail@web13307.mail.yahoo.com> --- Bjorn Gustavsson wrote: > Richard Carlsson writes: > > > On Sat, 15 Mar 2003, Pierpaolo BERNARDI wrote: > > > > Well, this is what I also said when we implemented > it, but the OTP > > guys were not convinced, and preferred to have the > check there. But > > perhaps your complaints will be more influential. > Bj?rn, are you > > reading this? :-) > > > > I not just me. When asking people in the OTP group, > nobody liked the idea > of not checking the right-hand side of 'andalso' and > 'orelse'. The change would > not be consistent with how 'and' and 'or' work. Here is the behaviour I would expect, with A and B being expressions. Is it anything like what is implemented? A andalso B => case A of true -> case B of true -> true; false -> false; Else -> exit(badarg) end; false -> false; Else -> exit(badarg) end And 'orelse' done in the same manner. I haven't checked what is done today, but erl_lint should also complain about pattern matching in A or B (at the very least B, since variables exported from B are unsafe). Best, Thomas __________________________________________________ Do you Yahoo!? Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop! http://platinum.yahoo.com From Erik.Stenman@REDACTED Mon Mar 17 20:04:13 2003 From: Erik.Stenman@REDACTED (Erik Stenman) Date: Mon, 17 Mar 2003 20:04:13 +0100 Subject: Executing boolean expressions on a list References: <20030314021200.GD23238@spearce.org> <023501c2ea7d$2478bfe0$51f36850@c1p4e3> <022901c2eb12$e5a798e0$28f06850@c1p4e3> <20030317123751.6497f1e6.cpressey@catseye.mb.ca> Message-ID: <040501c2ecb8$00222310$239ab280@lamppc27> Chris Pressey wrote: > Bjorn Gustavsson wrote: [...] > > I not just me. When asking people in the OTP group, nobody liked the > > idea of not checking the right-hand side of 'andalso' and 'orelse'. The > > change would not be consistent with how 'and' and 'or' work. > > I can see why the thought of "true andalso 5" succeeding without an error > would be disturbing to the OTP team. > > However, evaluating both sides for type correctness means that 'andalso' > isn't really very short-circuiting... i.e. the only semantic difference > between 'and' and 'andalso' is when the operands have side-effects, right? No, both sides are not evaluated for type correctness, but if the rhs needs to be evaluated then the result is checked for type correctness. i.e. true orelse 5 is ok, but false orelse 5 is not ok. This way orelse and andalso always returns a boolean, the "problem" is that any call on the rhs will not be tail-recursive, since the result needs to be checked. /Erik From bjorn@REDACTED Tue Mar 18 10:19:16 2003 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 18 Mar 2003 10:19:16 +0100 Subject: ECOMP (was:Re: OO vs. CO) In-Reply-To: References: Message-ID: Paulo Ferreira writes: > Mildly crazy: > > If the Beam specification matches well a virtual stack machine, why not > use a real stack machine like the PTSC IGNITE ( http://www.ptsc.com )? > Those guys sell the processor and the "IP" to put the processor on > your own FPGA. Beam is a register machine, not a stack machine. > > BTW is there something like "Beam specification for dummies"? > No. /Bjorn -- Bj?rn Gustavsson Ericsson Utvecklings AB bjorn@REDACTED ?T2/UAB/F/P BOX 1505 +46 8 727 56 87 125 25 ?lvsj? From richardc@REDACTED Tue Mar 18 11:35:07 2003 From: richardc@REDACTED (Richard Carlsson) Date: Tue, 18 Mar 2003 11:35:07 +0100 Subject: Executing boolean expressions on a list References: <20030317223050.31743.qmail@web13307.mail.yahoo.com> Message-ID: <006901c2ed3a$0c139050$50bfee82@gnit> ----- Original Message ----- From: "Thomas Lindgren" > Here is the behaviour I would expect, with A and B > being expressions. Is it anything like what is > implemented? > > A andalso B => > case A of > true -> > case B of > true -> true; > false -> false; > Else -> exit(badarg) > end; > false -> false; > Else -> exit(badarg) > end > > And 'orelse' done in the same manner. Precisely so. And as I mentioned, I too think it would be far more useful if the second expression was not checked. > I haven't checked what is done today, but erl_lint > should also complain about pattern matching in A or B > (at the very least B, since variables exported from B > are unsafe). I think this was overlooked. Thanks. /Richard From eleberg@REDACTED Tue Mar 18 12:37:16 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Tue, 18 Mar 2003 12:37:16 +0100 (MET) Subject: ECOMP (was:Re: OO vs. CO) Message-ID: <200303181137.h2IBbGH07424@cbe.ericsson.se> > X-Authentication-Warning: strider.du.uab.ericsson.se: bjorn set sender to bjorn@REDACTED using -f > To: erlang-questions@REDACTED > Subject: Re: ECOMP (was:Re: OO vs. CO) > From: Bjorn Gustavsson ...deleted > Beam is a register machine, not a stack machine. as to why a register machine is better than a stack machine, one can read ''The design of the Inferno virtual machine'' http://www.vitanuova.com/inferno/papers/hotchips.html . bengt From paf@REDACTED Tue Mar 18 17:10:59 2003 From: paf@REDACTED (Paulo Ferreira) Date: Tue, 18 Mar 2003 16:10:59 +0000 Subject: ECOMP (was:Re: OO vs. CO) In-Reply-To: <200303181137.h2IBbGH07424@cbe.ericsson.se> Message-ID: >> X-Authentication-Warning: strider.du.uab.ericsson.se: bjorn set sender to >bjorn@REDACTED using -f >> To: erlang-questions@REDACTED >> Subject: Re: ECOMP (was:Re: OO vs. CO) >> From: Bjorn Gustavsson >...deleted > >> Beam is a register machine, not a stack machine. > >as to why a register machine is better than a stack machine, one can >read ''The design of the Inferno virtual machine'' > >http://www.vitanuova.com/inferno/papers/hotchips.html . > > >bengt Well, I already am blushing with shame. :-( :-( So, thats why I did not understand Beam. :-( About register machines being better than stack machines thats a religious subject. :-) :-) :-) :-) If the virtual machine is typed, like the inferno VM, and the stack is in memory then some of things in the above paper are true. About compiling to stack machines see: Stack computers book: http://www.ece.cmu.edu/~koopman/stack_computers/contents.html and Anton Erl Papers at: http://www.complang.tuwien.ac.at/papers/ Greetings Paulo Ferreira ------------------------------------------------ Paulo Ferreira paf@REDACTED From cpressey@REDACTED Tue Mar 18 18:11:20 2003 From: cpressey@REDACTED (Chris Pressey) Date: Tue, 18 Mar 2003 11:11:20 -0600 Subject: Executing boolean expressions on a list In-Reply-To: <040501c2ecb8$00222310$239ab280@lamppc27> References: <20030314021200.GD23238@spearce.org> <023501c2ea7d$2478bfe0$51f36850@c1p4e3> <022901c2eb12$e5a798e0$28f06850@c1p4e3> <20030317123751.6497f1e6.cpressey@catseye.mb.ca> <040501c2ecb8$00222310$239ab280@lamppc27> Message-ID: <20030318111120.27798d3b.cpressey@catseye.mb.ca> On Mon, 17 Mar 2003 20:04:13 +0100 "Erik Stenman" wrote: > > Chris Pressey wrote: > > However, evaluating both sides for type correctness means that > > 'andalso' isn't really very short-circuiting... i.e. the only semantic > > difference between 'and' and 'andalso' is when the operands have > > side-effects, right? > > No, both sides are not evaluated for type correctness, > but if the rhs needs to be evaluated then the result is checked for type > correctness. Sorry, brain fart on my part - I swapped 'andalso' with 'orelse' in my example. Also, I committed the cardinal sin of not testing it in the shell: Eshell V5.2 (abort with ^G) 1> true orelse 5. true 2> false orelse 5. ** exited: {{badarg,5},[{erl_eval,expr,3}]} ** 3> true andalso 5. ** exited: {{badarg,5},[{erl_eval,expr,3}]} ** 4> false andalso 5. false This is the behaviour I expected. Thanks, -Chris From erlang@REDACTED Tue Mar 18 17:29:06 2003 From: erlang@REDACTED (Peter-Henry Mander) Date: Tue, 18 Mar 2003 16:29:06 +0000 Subject: unloaded module `hipe_converters' ?? Message-ID: <3E774952.5050407@manderp.freeserve.co.uk> Hi everyone, I have a HiPE related question on R8B-2 (Erlang (BEAM) emulator version 5.1.2 [source] [hipe], running on SuSE 8.1), when running any code I get the following report on the console, after which everything stops. The code server called the unloaded module `hipe_converters' This is my first foray into HiPE, purely out of curiousity I compiled Erlang/OTP with the ./configure --enable-hipe option. I have a cludge which forces hipe_converters module to load within the program start function after which everything is hunkydorey, but I'm sure there must be a better way, isn't there? Pete. From erlang@REDACTED Tue Mar 18 17:56:26 2003 From: erlang@REDACTED (Peter-Henry Mander) Date: Tue, 18 Mar 2003 16:56:26 +0000 Subject: unloaded module `hipe_converters' ?? References: <200303181748.h2IHmBlv014079@harpo.it.uu.se> Message-ID: <3E774FBA.8000608@manderp.freeserve.co.uk> Hi Kostis, I'm only using R8B because until now "it ain't broke, so I don't fix it!" But this may change since you say R9B is better anyway. I'll give R9B a go and let you know. Pete. Kostis Sagonas wrote: > Pete, > > > I have a HiPE related question on R8B-2 (Erlang (BEAM) emulator version > > 5.1.2 [source] [hipe], running on SuSE 8.1), when running any code I get > > the following report on the console, after which everything stops. > > > > The code server called the unloaded module `hipe_converters' > > > > This is my first foray into HiPE, purely out of curiousity I compiled > > Erlang/OTP with the ./configure --enable-hipe option. > > This does not solve your problem directly, but also just out of > curiosity is there any specific reason why you are still using R8 > rather than R9B where HiPE is an integrated and supported component > rather than an unsupported one? > > I am willing to bet that you will not experience any such problems > of you switch to R9 (and you will find that the HiPE compiler is more > robust there). > > If for some reason you insist on using R8, let us know and we will > try to look into this... > > Best, > Kostis. > > > From kostis@REDACTED Tue Mar 18 18:48:11 2003 From: kostis@REDACTED (Kostis Sagonas) Date: Tue, 18 Mar 2003 18:48:11 +0100 (MET) Subject: unloaded module `hipe_converters' ?? In-Reply-To: Mail from 'Peter-Henry Mander ' dated: Tue, 18 Mar 2003 16:29:06 +0000 Message-ID: <200303181748.h2IHmBlv014079@harpo.it.uu.se> Pete, > I have a HiPE related question on R8B-2 (Erlang (BEAM) emulator version > 5.1.2 [source] [hipe], running on SuSE 8.1), when running any code I get > the following report on the console, after which everything stops. > > The code server called the unloaded module `hipe_converters' > > This is my first foray into HiPE, purely out of curiousity I compiled > Erlang/OTP with the ./configure --enable-hipe option. This does not solve your problem directly, but also just out of curiosity is there any specific reason why you are still using R8 rather than R9B where HiPE is an integrated and supported component rather than an unsupported one? I am willing to bet that you will not experience any such problems of you switch to R9 (and you will find that the HiPE compiler is more robust there). If for some reason you insist on using R8, let us know and we will try to look into this... Best, Kostis. From DANIESC.SCHUTTE@REDACTED Wed Mar 19 05:31:09 2003 From: DANIESC.SCHUTTE@REDACTED (DANIESC SCHUTTE) Date: Wed, 19 Mar 2003 06:31:09 +0200 Subject: Erlang Nested Records Message-ID: Morning to everyone, I have got a question about adressing nested records - is there a standard rule of thumb :) that can be used. given the following record formats: %% ========================================================== record formats begin -record( additional_amount_data, { account_type, amount_type, currency_code, amount_sign, amount }). -record( additional_amounts, { data_length, additional_amount_data_1 = #additional_amount_data{}, additional_amount_data_2 = #additional_amount_data{}, additional_amount_data_3 = #additional_amount_data{}, additional_amount_data_4 = #additional_amount_data{}, additional_amount_data_5 = #additional_amount_data{}, additional_amount_data_6 = #additional_amount_data{} }). %% ========================================================== record formats end how would one assign values to additional amounts internal records? the following syntax yielded a syntax error - the assignment can be done by first assigning the data_length attribute and then in another Record assign the additional amount data. But is there a more elegant "single" assignment statement that works - I tried a few without success - so I now know which DOES NOT work :) %% ========================================================== record assignment code (syntax error) begin case RecordNumber of 1 -> NewAdditionalAmountRecord = AdditionalAmountRecord#additional_amounts{ data_length = 1, additional_amount_data_1#additional_amount_data{ account_type = lists:sublist(AdditionalAmountData, 1, 2), amount_type = lists:sublist(AdditionalAmountData, 3, 2), currency_code = lists:sublist(AdditionalAmountData, 5, 3), amount_sign = lists:sublist(AdditionalAmountData, 8, 1), amount = lists:sublist(AdditionalAmountData, 9, 12)}}, unpack_additional_amounts(DataLength-20, lists:nthtail(20,AdditionalAmountData), 2, NewAdditionalAmountRecord); %% ========================================================== record assignment code (syntax error) end. Thanks to everyone helping and responding Danie Schutte Phone: +27 - 11 - 203 - 1615 Mobile: 084-468-3138 e-Mail: Daniesc@REDACTED ##################################################################################### The information contained in this message and or attachments is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any system and destroy and copies. ##################################################################################### From eleberg@REDACTED Wed Mar 19 06:51:20 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Wed, 19 Mar 2003 06:51:20 +0100 (MET) Subject: Erlang Nested Records Message-ID: <200303190551.h2J5pKH05170@cbe.ericsson.se> > Date: Wed, 19 Mar 2003 06:31:09 +0200 > From: "DANIESC SCHUTTE" > To: "<" > Subject: Erlang Nested Records > Mime-Version: 1.0 > Content-Disposition: inline > Content-Transfer-Encoding: 8bit > X-MIME-Autoconverted: from quoted-printable to 8bit by hades.cslab.ericsson.net id h2J4biJ84408 > > Morning to everyone, > > I have got a question about adressing nested records - is there a standard rule of thumb :) that can be used. > ...deleted > how would one assign values to additional amounts internal records? simplified records (shorter names) and example included below. please let me know if i have unanswered your question, by changing record names. bengt -module(record). -export([main/1]). -record( account, { owner, amount=0 }). -record( bank, { account0 = #account{}, account1 = #account{} }). main(_) -> io:format( "~n" ), Account0 = #account{owner=gustav}, Account1 = #account{owner=kalle}, Bank = #bank{account0 = Account0, account1 = Account1}, io:format( "~w~n", [Bank] ), New_Bank = update(Bank, 0, 100), io:format( "~w~n", [New_Bank] ), init:stop( ). update(Bank, Account, Amount) -> case Account of 0 -> Bank#bank{account0 = (Bank#bank.account0)#account{amount = Amount}}; 1 -> Bank#bank{account1 = (Bank#bank.account1)#account{amount = Amount}} end. From peter@REDACTED Wed Mar 19 06:56:02 2003 From: peter@REDACTED (Peter Lund) Date: Wed, 19 Mar 2003 06:56:02 +0100 Subject: SV: Erlang Nested Records In-Reply-To: Message-ID: You seem to have forgot a "=". Look below: NewAdditionalAmountRecord = AdditionalAmountRecord#additional_amounts{ data_length = 1, additional_amount_data_1 = %% HERE you forgot the "=" #additional_amount_data{ account_type = lists:sublist(AdditionalAmountData, 1, 2), amount_type = lists:sublist(AdditionalAmountData, 3, 2), currency_code = lists:sublist(AdditionalAmountData, 5, 3), amount_sign = lists:sublist(AdditionalAmountData, 8, 1), amount = lists:sublist(AdditionalAmountData, 9, 12) } }, /Peter > -----Ursprungligt meddelande----- > Fran: owner-erlang-questions@REDACTED > [mailto:owner-erlang-questions@REDACTED]For DANIESC SCHUTTE > Skickat: den 19 mars 2003 05:31 > Till: < > Amne: Erlang Nested Records > > > Morning to everyone, > > I have got a question about adressing nested records - is there a > standard rule of thumb :) that can be used. > > given the following record formats: > > > %% ========================================================== > record formats begin > > -record( additional_amount_data, { > account_type, > amount_type, > currency_code, > amount_sign, > amount }). > > -record( additional_amounts, { > data_length, > additional_amount_data_1 = #additional_amount_data{}, > additional_amount_data_2 = #additional_amount_data{}, > additional_amount_data_3 = #additional_amount_data{}, > additional_amount_data_4 = #additional_amount_data{}, > additional_amount_data_5 = #additional_amount_data{}, > additional_amount_data_6 = #additional_amount_data{} > }). > > %% ========================================================== > record formats end > > > how would one assign values to additional amounts internal > records? the following syntax yielded a syntax error - > the assignment can be done by first assigning the data_length > attribute and then in another Record assign the additional amount > data. But is there a more elegant "single" assignment statement > that works - I tried a few without success - so I now know which > DOES NOT work :) > > %% ========================================================== > record assignment code (syntax error) begin > > > case RecordNumber of > 1 -> NewAdditionalAmountRecord = > AdditionalAmountRecord#additional_amounts{ data_length = 1, > > additional_amount_data_1#additional_amount_data{ > > account_type = lists:sublist(AdditionalAmountData, 1, 2), > > amount_type = lists:sublist(AdditionalAmountData, 3, 2), > > currency_code = lists:sublist(AdditionalAmountData, 5, 3), > > amount_sign = lists:sublist(AdditionalAmountData, 8, 1), > > amount = lists:sublist(AdditionalAmountData, 9, 12)}}, > unpack_additional_amounts(DataLength-20, > lists:nthtail(20,AdditionalAmountData), 2, NewAdditionalAmountRecord); > > %% ========================================================== > record assignment code (syntax error) end. > > Thanks to everyone helping and responding > > > > Danie Schutte > Phone: +27 - 11 - 203 - 1615 > Mobile: 084-468-3138 > e-Mail: Daniesc@REDACTED > > ################################################################## > ################### > The information contained in this message and or attachments is intended > only for the person or entity to which it is addressed and may contain > confidential and/or privileged material. Any review, retransmission, > dissemination or other use of, or taking of any action in reliance upon, > this information by persons or entities other than the intended recipient > is prohibited. If you received this in error, please contact the > sender and > delete the material from any system and destroy and copies. > ################################################################## > ################### > From DANIESC.SCHUTTE@REDACTED Wed Mar 19 06:56:04 2003 From: DANIESC.SCHUTTE@REDACTED (DANIESC SCHUTTE) Date: Wed, 19 Mar 2003 07:56:04 +0200 Subject: SV: Erlang Nested Records Message-ID: You are completely right :) thanks - - >>> "Peter Lund" 03/19/03 07:56AM >>> You seem to have forgot a "=". Look below: NewAdditionalAmountRecord = AdditionalAmountRecord#additional_amounts{ data_length = 1, additional_amount_data_1 = %% HERE you forgot the "=" #additional_amount_data{ account_type = lists:sublist(AdditionalAmountData, 1, 2), amount_type = lists:sublist(AdditionalAmountData, 3, 2), currency_code = lists:sublist(AdditionalAmountData, 5, 3), amount_sign = lists:sublist(AdditionalAmountData, 8, 1), amount = lists:sublist(AdditionalAmountData, 9, 12) } }, /Peter > -----Ursprungligt meddelande----- > Fran: owner-erlang-questions@REDACTED > [mailto:owner-erlang-questions@REDACTED]For DANIESC SCHUTTE > Skickat: den 19 mars 2003 05:31 > Till: < > Amne: Erlang Nested Records > > > Morning to everyone, > > I have got a question about adressing nested records - is there a > standard rule of thumb :) that can be used. > > given the following record formats: > > > %% ========================================================== > record formats begin > > -record( additional_amount_data, { > account_type, > amount_type, > currency_code, > amount_sign, > amount }). > > -record( additional_amounts, { > data_length, > additional_amount_data_1 = #additional_amount_data{}, > additional_amount_data_2 = #additional_amount_data{}, > additional_amount_data_3 = #additional_amount_data{}, > additional_amount_data_4 = #additional_amount_data{}, > additional_amount_data_5 = #additional_amount_data{}, > additional_amount_data_6 = #additional_amount_data{} > }). > > %% ========================================================== > record formats end > > > how would one assign values to additional amounts internal > records? the following syntax yielded a syntax error - > the assignment can be done by first assigning the data_length > attribute and then in another Record assign the additional amount > data. But is there a more elegant "single" assignment statement > that works - I tried a few without success - so I now know which > DOES NOT work :) > > %% ========================================================== > record assignment code (syntax error) begin > > > case RecordNumber of > 1 -> NewAdditionalAmountRecord = > AdditionalAmountRecord#additional_amounts{ data_length = 1, > > additional_amount_data_1#additional_amount_data{ > > account_type = lists:sublist(AdditionalAmountData, 1, 2), > > amount_type = lists:sublist(AdditionalAmountData, 3, 2), > > currency_code = lists:sublist(AdditionalAmountData, 5, 3), > > amount_sign = lists:sublist(AdditionalAmountData, 8, 1), > > amount = lists:sublist(AdditionalAmountData, 9, 12)}}, > unpack_additional_amounts(DataLength-20, > lists:nthtail(20,AdditionalAmountData), 2, NewAdditionalAmountRecord); > > %% ========================================================== > record assignment code (syntax error) end. > > Thanks to everyone helping and responding > > > > Danie Schutte > Phone: +27 - 11 - 203 - 1615 > Mobile: 084-468-3138 > e-Mail: Daniesc@REDACTED > > ################################################################## > ################### > The information contained in this message and or attachments is intended > only for the person or entity to which it is addressed and may contain > confidential and/or privileged material. Any review, retransmission, > dissemination or other use of, or taking of any action in reliance upon, > this information by persons or entities other than the intended recipient > is prohibited. If you received this in error, please contact the > sender and > delete the material from any system and destroy and copies. > ################################################################## > ################### > ##################################################################################### The information contained in this message and or attachments is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any system and destroy and copies. ##################################################################################### From erlang@REDACTED Wed Mar 19 09:21:22 2003 From: erlang@REDACTED (Peter-Henry Mander) Date: Wed, 19 Mar 2003 08:21:22 +0000 Subject: unwanted borders in GS (was Re: unloaded module `hipe_converters' ??) References: <200303181748.h2IHmBlv014079@harpo.it.uu.se> Message-ID: <3E782882.1030105@manderp.freeserve.co.uk> Hi Kostis, Migration to R9B-1 on SuSE 8.1 was painless, and seems to solve the problem, thanks. It's nice to see the Megaco bug fixes in there too, thanks to the maintainers thereof :-) Although I do have a query about GS, which has obviously changed since R8B-2 with the consequence illustrated in the attached PNG file. How do I remove the borders? The {bw,0} option doesn't fix it, they're not related to that option which has effects elsewhere. Any suggestions from the GS users? Pete. Kostis Sagonas wrote: > Pete, > > > I have a HiPE related question on R8B-2 (Erlang (BEAM) emulator version > > 5.1.2 [source] [hipe], running on SuSE 8.1), when running any code I get > > the following report on the console, after which everything stops. > > > > The code server called the unloaded module `hipe_converters' > > > > This is my first foray into HiPE, purely out of curiousity I compiled > > Erlang/OTP with the ./configure --enable-hipe option. > > This does not solve your problem directly, but also just out of > curiosity is there any specific reason why you are still using R8 > rather than R9B where HiPE is an integrated and supported component > rather than an unsupported one? > > I am willing to bet that you will not experience any such problems > of you switch to R9 (and you will find that the HiPE compiler is more > robust there). > > If for some reason you insist on using R8, let us know and we will > try to look into this... > > Best, > Kostis. > > > -------------- next part -------------- A non-text attachment was scrubbed... Name: sample.png Type: image/png Size: 684 bytes Desc: not available URL: From Vlad.Dumitrescu@REDACTED Wed Mar 19 12:35:00 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Wed, 19 Mar 2003 12:35:00 +0100 Subject: Throttling a process Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D489@esemont203.gbg.edt.ericsson.se> Hi, I need to be able to throttle down a process, if the node is very busy with more important things. What I thought I could do is check erlang:statistics() and also follow a few well-chosen processes with erlang:process_info(). This information will then be used to set longer sleep intervals for my process, or to simply make it wait until load goes down. Is this the way to do it? I noticed that process_info has a warning "to noly be used when debugging" - is that a soft warning, or a hard one? :-) Thanks in advance. Regards, Vlad From erlang@REDACTED Wed Mar 19 11:57:16 2003 From: erlang@REDACTED (Peter-Henry Mander) Date: Wed, 19 Mar 2003 10:57:16 +0000 Subject: unwanted borders in GS (was Re: unloaded module `hipe_converters' ??) References: <200303181748.h2IHmBlv014079@harpo.it.uu.se> <3E782882.1030105@manderp.freeserve.co.uk> Message-ID: <3E784D0C.3020909@manderp.freeserve.co.uk> I found the solution, the required option is {highlightbw,0}. Another case of UTSL. TFM doesn't appear to list this option, unless I haven't RTFM properly. There's a lot of untold cool GS features listed in the comments :-) Pete. Peter-Henry Mander wrote: > Hi Kostis, > > Migration to R9B-1 on SuSE 8.1 was painless, and seems to solve the > problem, thanks. It's nice to see the Megaco bug fixes in there too, > thanks to the maintainers thereof :-) > > Although I do have a query about GS, which has obviously changed since > R8B-2 with the consequence illustrated in the attached PNG file. How do > I remove the borders? The {bw,0} option doesn't fix it, they're not > related to that option which has effects elsewhere. > > Any suggestions from the GS users? > > Pete. > > Kostis Sagonas wrote: > >> Pete, >> >> > I have a HiPE related question on R8B-2 (Erlang (BEAM) emulator >> version > 5.1.2 [source] [hipe], running on SuSE 8.1), when running >> any code I get > the following report on the console, after which >> everything stops. >> > > The code server called the unloaded module `hipe_converters' >> > > This is my first foray into HiPE, purely out of curiousity I >> compiled > Erlang/OTP with the ./configure --enable-hipe option. >> >> This does not solve your problem directly, but also just out of >> curiosity is there any specific reason why you are still using R8 >> rather than R9B where HiPE is an integrated and supported component >> rather than an unsupported one? >> >> I am willing to bet that you will not experience any such problems >> of you switch to R9 (and you will find that the HiPE compiler is more >> robust there). >> >> If for some reason you insist on using R8, let us know and we will >> try to look into this... >> >> Best, >> Kostis. >> >> >> > > > ------------------------------------------------------------------------ > From francesco@REDACTED Wed Mar 19 13:02:10 2003 From: francesco@REDACTED (Francesco Cesarini) Date: Wed, 19 Mar 2003 12:02:10 +0000 Subject: Throttling a process In-Reply-To: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D489@esemont203.gbg.edt.ericsson.se> References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D489@esemont203.gbg.edt.ericsson.se> Message-ID: <3E785C42.5080007@erlang-consulting.com> Hi Vlad, you could use instrument.erl I have never used it myself, so I am unaware over pitfalls/performance, but it appears to do the monitoring job. And if you want to get nasty, you have the bifs suspend and resume to start and stop your processes. If you use them, just make sure I do not get sent to Gothenburg to review your code ;-) Francesco -- http://www.erlang-consulting.com Vlad Dumitrescu (EAW) wrote: >Hi, > >I need to be able to throttle down a process, if the node is very busy with more important things. What I thought I could do is check erlang:statistics() and also follow a few well-chosen processes with erlang:process_info(). This information will then be used to set longer sleep intervals for my process, or to simply make it wait until load goes down. > >Is this the way to do it? I noticed that process_info has a warning "to noly be used when debugging" - is that a soft warning, or a hard one? :-) > >Thanks in advance. Regards, >Vlad > > > > From Vlad.Dumitrescu@REDACTED Wed Mar 19 13:06:41 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Wed, 19 Mar 2003 13:06:41 +0100 Subject: Throttling a process Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D48A@esemont203.gbg.edt.ericsson.se> No, this is for a private project, and I can't afford to send for you from England. :-) But now that you mention it, it might be possible to use the answer at work too! Anyway, what I want is to let my process run in the background, when the load isn't too high. The VM doesn't offer this functionality (maybe it should?) but I am especially after a few processes that I don't want to disturb. Thanks! regards, Vlad > -----Original Message----- > From: Francesco Cesarini [mailto:francesco@REDACTED] > Sent: Wednesday, March 19, 2003 1:02 PM > To: Vlad Dumitrescu (EAW) > Cc: Erlang-questions (E-mail) > Subject: Re: Throttling a process > > > Hi Vlad, > > you could use instrument.erl I have never used it myself, so I am > unaware over pitfalls/performance, but it appears to do the > monitoring > job. And if you want to get nasty, you have the bifs suspend > and resume > to start and stop your processes. If you use them, just make > sure I do > not get sent to Gothenburg to review your code ;-) > > Francesco > -- > http://www.erlang-consulting.com > > Vlad Dumitrescu (EAW) wrote: > > >Hi, > > > >I need to be able to throttle down a process, if the node is > very busy with more important things. What I thought I could > do is check erlang:statistics() and also follow a few > well-chosen processes with erlang:process_info(). This > information will then be used to set longer sleep intervals > for my process, or to simply make it wait until load goes down. > > > >Is this the way to do it? I noticed that process_info has a > warning "to noly be used when debugging" - is that a soft > warning, or a hard one? :-) > > > >Thanks in advance. Regards, > >Vlad > > > > > > > > > > From francesco@REDACTED Wed Mar 19 13:17:06 2003 From: francesco@REDACTED (Francesco Cesarini) Date: Wed, 19 Mar 2003 12:17:06 +0000 Subject: Throttling a process In-Reply-To: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D48A@esemont203.gbg.edt.ericsson.se> References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D48A@esemont203.gbg.edt.ericsson.se> Message-ID: <3E785FC2.1060300@erlang-consulting.com> > > >Anyway, what I want is to let my process run in the background, when the load isn't too high. The VM doesn't offer this functionality (maybe it should?) but I am especially after a few processes that I don't want to disturb. > Have you looked at process priorities? You could toggle between low and medium for a number of processes based on the load. Not as bad as suspend.. Actually, priorities might be all you need... Francesco -- http://www.erlang-consulting.com From etxuwig@REDACTED Wed Mar 19 13:34:27 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Wed, 19 Mar 2003 13:34:27 +0100 (MET) Subject: Throttling a process In-Reply-To: <3E785FC2.1060300@erlang-consulting.com> Message-ID: On Wed, 19 Mar 2003, Francesco Cesarini wrote: >>Anyway, what I want is to let my process run in the >>background, when the load isn't too high. The VM doesn't >>offer this functionality (maybe it should?) but I am >>especially after a few processes that I don't want to >>disturb. >Have you looked at process priorities? You could toggle >between low and medium for a number of processes based on >the load. Not as bad as suspend.. Actually, priorities >might be all you need... Beware of the possibility of priority inversion, though. The way priorities are currently implemented in Erlang, you may be surprised during high load if you have a large number of normal priority processes and one or a few low priority processes. BEAM will schedule 8 normal priority processes, and then schedule one low priority process. In situations where lots of normal priority processes contend for time slices, a lone low priority process may well get the most CPU time. This will happen if it takes a normal priority process more than (8 time slices * number of queued low prio processes) to be scheduled again. Probably a are case, I admit. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From Vlad.Dumitrescu@REDACTED Wed Mar 19 14:11:51 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Wed, 19 Mar 2003 14:11:51 +0100 Subject: Throttling a process Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D48B@esemont203.gbg.edt.ericsson.se> > Beware of the possibility of priority inversion, though. Good point! I think I will try the "hand-made" solution I was thinking about, because what I need to watch most are things like the file system load, or the Internet bandwidth used, or the CPU usage. I don't mind if I will have to wait 2 or 5 minutes for (relative) quiescence. Thanks all for the hints! regards, Vlad From matthias@REDACTED Wed Mar 19 13:26:20 2003 From: matthias@REDACTED (Matthias Lang) Date: Wed, 19 Mar 2003 13:26:20 +0100 Subject: Throttling a process In-Reply-To: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D489@esemont203.gbg.edt.ericsson.se> References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D489@esemont203.gbg.edt.ericsson.se> Message-ID: <15992.25068.7470.438858@antilipe.corelatus.se> Vlad Dumitrescu (EAW) writes: > I need to be able to throttle down a process, if the node is very > busy with more important things. I've never actually used it, but take a look at erlang:process_flag(priority, low) Matthias From cpressey@REDACTED Wed Mar 19 17:13:27 2003 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 19 Mar 2003 10:13:27 -0600 Subject: Extending Functionality: gen_server_ext In-Reply-To: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D46D@esemont203.gbg.edt.ericsson.se> References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D46D@esemont203.gbg.edt.ericsson.se> Message-ID: <20030319101327.1f89f389.cpressey@catseye.mb.ca> On Fri, 14 Mar 2003 10:28:23 +0100 "Vlad Dumitrescu (EAW)" wrote: > Hi guys, > > I happen to know this Vlad person :-D and he likes to be the fool that > throws the stone into the lake and let 20 wise people try for a month > to figure how to pick it back. > [... gen_server_ext ...] Hi Vlad, I think you're really onto something here (for dynamic behaviour at least, i.e. when you already know for sure you're going to have a process), I just wanted to clarify how it works. First, it occurs to me that I don't know any good term for "module which implements a behaviour", so I'm going to use "behaver" for better or worse (sounds a lot like "behaviour" when spoken so I'm open to better suggestions.) So - my impression is that, when you write a behaver for gen_server_ext, you typically code it so that when it receives a message it doesn't understand, it passes it on to the next behaver with gen_server_ext:next_*() The other option open seems to be that any unrecognized message would be passed along to the next behaver in the chain. (a bit like gen_event?) I can see why you would want to go with the first method - it's more flexible and more explicit/predictable - but I think there are some minor oddities with it being explicit, too - could you accidentally call next_cast within a call handler? (then what happens? Is this "legal"?) -Chris From Vlad.Dumitrescu@REDACTED Wed Mar 19 18:18:48 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Wed, 19 Mar 2003 18:18:48 +0100 Subject: Extending Functionality: gen_server_ext Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D490@esemont203.gbg.edt.ericsson.se> Hi, > So - my impression is that, when you write a behaver for > gen_server_ext, > you typically code it so that when it receives a message it doesn't > understand, it passes it on to the next behaver with > gen_server_ext:next_*() > > The other option open seems to be that any unrecognized > message would be > passed along to the next behaver in the chain. (a bit like > gen_event?) > I can see why you would want to go with the first method - it's more > flexible and more explicit/predictable - but I think there > are some minor > oddities with it being explicit, too - could you accidentally call > next_cast within a call handler? (then what happens? Is this > "legal"?) Yes, it should be legal. I think it's a lot like virtual methods: you can ignore the previous implementation, or you can reuse it and select from it what is relevant. The second option can only handle messages that "fall through" and are not handled at all in the current handler. This is way too rigid, for example if root handler handles {get, Data, Index} and in the new handler I want to only handle differently {get, Data, 0}, I can't. One could also use regular gen_server and hardcode the next_call to a specific module. This would work in an inheritance hierarchy, but what I would like to do (inspired by Jay) is free composition of independent behaviours. I hope that what I wrote makes sense. Test is starting to dance before my eyes, so I'm on my way home now. :-) Best regards, Vlad From cpressey@REDACTED Wed Mar 19 18:42:01 2003 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 19 Mar 2003 11:42:01 -0600 Subject: Extending Functionality: gen_server_ext In-Reply-To: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D490@esemont203.gbg.edt.ericsson.se> References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D490@esemont203.gbg.edt.ericsson.se> Message-ID: <20030319114201.23c1543b.cpressey@catseye.mb.ca> On Wed, 19 Mar 2003 18:18:48 +0100 "Vlad Dumitrescu (EAW)" wrote: > Hi, > > > So - my impression is that, when you write a behaver for > > gen_server_ext, > > you typically code it so that when it receives a message it doesn't > > understand, it passes it on to the next behaver with > > gen_server_ext:next_*() > > > > The other option open seems to be that any unrecognized > > message would be > > passed along to the next behaver in the chain. (a bit like > > gen_event?) > > > I can see why you would want to go with the first method - it's more > > flexible and more explicit/predictable - but I think there > > are some minor > > oddities with it being explicit, too - could you accidentally call > > next_cast within a call handler? (then what happens? Is this > > "legal"?) > > Yes, it should be legal. I think it's a lot like virtual methods: you > can ignore the previous implementation, or you can reuse it and select > from it what is relevant. But surely the client isn't expecting the call to be transformed into a cast... ?? My vague feeling is that ideally there should be one function, gen_server_ext:next(), that goes to the same type of handler (cast, call, info etc) in the next behaver. > The second option can only handle messages that "fall through" and are > not handled at all in the current handler. This is way too rigid, for > example if root handler handles {get, Data, Index} and in the new > handler I want to only handle differently {get, Data, 0}, I can't. Very true. > One could also use regular gen_server and hardcode the next_call to a > specific module. This would work in an inheritance hierarchy, but what I > would like to do (inspired by Jay) is free composition of independent > behaviours. Also agreed. Another question: what are the pros and cons of having to call next_call() et al, as opposed to returning a value like {next_call, ...} from the handler, and having gen_server_ext pay attention to that? > I hope that what I wrote makes sense. Test is starting to dance before > my eyes, so I'm on my way home now. :-) > > Best regards, > Vlad Still before noon here :) Thanks for the clarification, -Chris From cpressey@REDACTED Wed Mar 19 19:27:52 2003 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 19 Mar 2003 12:27:52 -0600 Subject: inspecting the call stack from a program (was: Re: Extending Functionality: an expedient and questionable approa ch) In-Reply-To: References: Message-ID: <20030319122752.680c0a88.cpressey@catseye.mb.ca> On Fri, 14 Mar 2003 14:45:49 -0000 Chandrashekhar Mullaparthi wrote: > Another way to look at the stack...but it is not as pretty as what you'd > see in a crash report. > > (camelns@REDACTED)212> erlang:process_display(whereis(cns_server), > backtrace). > [...] Sorry... I should have been more specific. I meant - a way for a program to inspect the call stack. I'm currently using this function: call_stack() -> {'EXIT', {Error, CallStack}} = (catch 1 = 2), tl(CallStack). I find this useful in conjunction with e.g. logging (e.g. in /jungerl/lib/ce/src/ce_log.erl) It's just that the "(catch 1 = 2)" strikes me as, uhm, ungraceful :) -Chris From spearce@REDACTED Wed Mar 19 20:17:17 2003 From: spearce@REDACTED (Shawn Pearce) Date: Wed, 19 Mar 2003 14:17:17 -0500 Subject: inspecting the call stack from a program (was: Re: Extending Functionality: an expedient and questionable approa ch) In-Reply-To: <20030319122752.680c0a88.cpressey@catseye.mb.ca> References: <20030319122752.680c0a88.cpressey@catseye.mb.ca> Message-ID: <20030319191717.GA28739@spearce.org> Chris Pressey wrote: > Sorry... I should have been more specific. I meant - a way for a program > to inspect the call stack. > > I'm currently using this function: > > call_stack() -> > {'EXIT', {Error, CallStack}} = (catch 1 = 2), > tl(CallStack). > > I find this useful in conjunction with e.g. logging (e.g. in > /jungerl/lib/ce/src/ce_log.erl) > > It's just that the "(catch 1 = 2)" strikes me as, uhm, ungraceful :) So then use {'EXIT', {Error, CallStack}} = (catch 1 = undefined), :-) This is like the old Java trick of throwing an exception, catching it, printing it to a stream, parsing the stream to locate the text of the method you want, and pulling that back into a variable. Oh wait, its still cleaner in Erlang. -- Shawn. * woot is now known as woot-dinner * Knghtbrd sprinkles a little salt on woot I've never had a woot before... Hope they taste good noooo! don't eat me! * Knghtbrd decides he does not want a dinner that talks to him... hehe From mbj@REDACTED Wed Mar 19 20:28:19 2003 From: mbj@REDACTED (Martin Bjorklund) Date: Wed, 19 Mar 2003 20:28:19 +0100 (CET) Subject: inspecting the call stack from a program In-Reply-To: <20030319122752.680c0a88.cpressey@catseye.mb.ca> References: <20030319122752.680c0a88.cpressey@catseye.mb.ca> Message-ID: <20030319.202819.104054721.mbj@bluetail.com> Chris Pressey wrote: > On Fri, 14 Mar 2003 14:45:49 -0000 > Chandrashekhar Mullaparthi > wrote: > > > Another way to look at the stack...but it is not as pretty as what you'd > > see in a crash report. > > > > (camelns@REDACTED)212> erlang:process_display(whereis(cns_server), > > backtrace). > > [...] > > Sorry... I should have been more specific. I meant - a way for a program > to inspect the call stack. > > I'm currently using this function: > > call_stack() -> > {'EXIT', {Error, CallStack}} = (catch 1 = 2), > tl(CallStack). Here's a snippet from our user_default.erl, which I posted to the list a couple of years (?) ago. (our user_default also contains pi() for port inspection, i/1 with a pid or registered name as argument etc). Can be used like this from the shell: Eshell V5.2.b1 (abort with ^G) 1> bt(self()). program counter = 0x8168454 (unknown function) cp = 0x8490954 (user_default:pinfo/2 + 172) 0x4009bc64 Return addr 0x849131C (user_default:bt/1 + 40) y(0) <0.23.0> y(1) backtrace [... deleted] ---------------------------------------------------------- %% Doesn't do process_display, which means it can be used when %% remotely connecting to a node. bt(Pid) when pid(Pid) -> case pinfo(Pid, backtrace) of {backtrace, Bin} -> io:format("~s\n", [binary_to_list(Bin)]); _ -> undefined end; bt(Name) when atom(Name) -> case whereis(Name) of undefined -> undefined; Pid -> bt(Pid) end. bt(X,Y,Z) -> bt(c:pid(X,Y,Z)). pinfo(Pid, Item) -> case is_alive() of true -> rpc:call(node(Pid), erlang, process_info, [Pid, Item]); false -> process_info(Pid, Item) end. /martin From vlad_dumitrescu@REDACTED Wed Mar 19 20:36:38 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Wed, 19 Mar 2003 20:36:38 +0100 Subject: Extending Functionality: gen_server_ext References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D490@esemont203.gbg.edt.ericsson.se> <20030319114201.23c1543b.cpressey@catseye.mb.ca> Message-ID: > But surely the client isn't expecting the call to be transformed into a > cast... ?? My vague feeling is that ideally there should be one function, > gen_server_ext:next(), that goes to the same type of handler (cast, call, > info etc) in the next behaver. Oh, sorry -- I didn't read your question properly. Long day, lots of work :-) Of course my answer only applies to calling next_call from a handle call. > Another question: what are the pros and cons of having to call next_call() > et al, as opposed to returning a value like {next_call, ...} from the > handler, and having gen_server_ext pay attention to that? If you return with {next_call, ...} then you can't get the answer back and refine it. It's something in between the two options you mentioned before, I think. I have this feeling that there's a lot more to dig out here. regards, Vlad From etxuwig@REDACTED Wed Mar 19 23:51:26 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Wed, 19 Mar 2003 23:51:26 +0100 (MET) Subject: inspecting the call stack from a program (was: Re: Extending Functionality: an expedient and questionable approa ch) In-Reply-To: <20030319122752.680c0a88.cpressey@catseye.mb.ca> Message-ID: On Wed, 19 Mar 2003, Chris Pressey wrote: >I'm currently using this function: > > call_stack() -> > {'EXIT', {Error, CallStack}} = (catch 1 = 2), > tl(CallStack). Not that it's necessarily better, but out of curiosity, I tried to write a program that presented a call stack based on process_info(Pid,backtrace) (actually, it does have the nice property that it can be used on any process.) Interestingly, the (badly written) regexp:first_match() in the commented version seems to loop endlessly. Bug or feature? The same pattern passed to egrep works fine. I cannot guarantee that this version always gives a correct answer. My "parsing" of the backtrace is sloppy, to say the least. /Uffe all_stack() -> {_, Stack} = process_info(self(),backtrace), case format(binary_to_list(Stack)) of [{?MODULE,call_stack,0}|Tail] -> Tail; Other -> Other end. % format(Str) -> % case regexp:first_match( % Str,"\\([a-z]+[a-z0-9_]*:[a-z]+[a-z0-9_]*+/[0-9]+") of % {match,Start,Length} -> % Fun = string:substr(Str,Start+1,Length-1), % [M,F,A] = string:tokens(Fun,":/"), % [{list_to_atom(M),list_to_atom(F),list_to_integer(A)}| % format(string:substr(Str,Start+Length))]; % nomatch -> % [] % end. format(Str) -> Tokens = string:tokens(Str,"\n "), funs(Tokens). funs(["(" ++ Rest|Toks]) -> case string:tokens(Rest,":/") of [M,F,A] -> [{list_to_atom(M),list_to_atom(F),list_to_integer(A)}| funs(Toks)]; _ -> funs(Toks) end; funs([_|Toks]) -> funs(Toks); funs([]) -> []. -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From DANIESC.SCHUTTE@REDACTED Thu Mar 20 09:02:56 2003 From: DANIESC.SCHUTTE@REDACTED (DANIESC SCHUTTE) Date: Thu, 20 Mar 2003 10:02:56 +0200 Subject: Compile time Message-ID: Morning everyone, I have got a question about the time it takes to copile a script, I have got a script that that takes about 40 - 60 seconds to compile - ( I included the source here - any idea why it would take so long? Am I making a gross mistake somewhere? ##################################################################################### The information contained in this message and or attachments is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any system and destroy and copies. ##################################################################################### -------------- next part -------------- A non-text attachment was scrubbed... Name: costing_manager.erl Type: application/octet-stream Size: 16147 bytes Desc: not available URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: int_trx.hrl URL: From dufflebunk@REDACTED Wed Mar 19 23:26:12 2003 From: dufflebunk@REDACTED (Dufflebunk) Date: Wed, 19 Mar 2003 18:26:12 -0400 Subject: R8B make fails with RH's perl 5.8.0 Message-ID: <200303192326.h2JNQCKk012046@achilles.go-nix.ca> Hi, I'm compiling the latest (R9B-1) on a red hat 8.0 box. This same error is present. I found this post with google, I don't subscribe to this list, so I hope it does through. You want to use bytes, not byte. This may be obvious, but I don't know perl so it took some searching ;) Also, after failure, if you run make again it will continue the build process, but error out later complaining about: /space/dl/otp_src_R9B-1/erts/obj.beam/i686-pc-linux-gnu/sys.o: In function `sys_preloaded': /space/dl/otp_src_R9B-1/erts/emulator/sys/unix/sys.c:3236: undefined reference to `pre_loaded' /space/dl/otp_src_R9B-1/erts/obj.beam/i686-pc-linux-gnu/ttsl_drv.o: In function `start_termcap': /space/dl/otp_src_R9B-1/erts/emulator/drivers/unix/ttsl_drv.c:599: undefined reference to `tgetent' It seems to be compilnig happily now that I made that change. ----- Manualy Quoted message ----- Thu, 3 Oct 2002 13:55:44 -0700 Just installed RetHat 8.0 on a new box. On the first attempt(s), the perl script erts/emulator/utils/make_preload kept on failing on the first file: form size 1208 greater than size 1056 of module at utils/make_preload line 145, chuck 1. The problems stems from RH's perl 5.8.0 and its length() function, which now returns a character-based length. With use byte; The length function returns the correct 1216 for the length of $_ for the beam length of lib/kernel/ebin/otp_ring0.beam. --erikp-- From jay@REDACTED Thu Mar 20 15:05:11 2003 From: jay@REDACTED (Jay Nelson) Date: Thu, 20 Mar 2003 06:05:11 -0800 Subject: Extending Functionality: gen_server_ext Message-ID: <4.2.2.20030320052138.00ce9dd0@duomark.com> Chris and Vlad discussed: > Extensions to gen_server to support "behavers" and pseudo > inheritance call chains ... This seems an interesting approach to reusability or extension of functionality. I haven't thought about a specific problem that it would apply to but I have some general thoughts about a structural architecture. I guess these features could be useful in a situation where you have two machines, one having more functionality than another (but the lesser functionality reused) or when users can login with differing levels of privileged access. I'm sure there are many other applications, the main issue being whether you want dynamic modification of behaviour or a static application structure. Chained processes - deep inheritance This seems to be the thrust of the initial thinking. It mirrors the deeper inheritance structures used in OO. The bottom of a chain is the base behaviour in a gen_server, and refinements are placed in front of the base like popcorn strung on a thread. Issues: 1) Explicit interface vs. implicit interface: use explicit delegation and fail if message unhandled, or pass unhandled requests down the chain until they are handled and then back up the chain 2) Allow installation of handlers the way gen_event does to get situationally adaptive behaviour? 3) Multiple inheritance: what if two base chains are joined by a single gen_server? Not allowed or deterministic searching for unhandled messages to be passed to base chain. 4) If the chain is deep, there could be a lot of wasted message passing searching for the right handler. You may want to use memoization to cache the found handler in an ets table the first time it is used. Even in a dynamic scenario, you could de-momoize if a new handler is installed. 5) Death of a single process can interrupt much computation. 6) Single process can only participate in one chain. A separate instance is needed to participate in a different chain. Interface amalgam - shallow inheritance Create a single Amalgam process (similar to supervisor) that combines the desired interfaces from several gen_servers. gen_servers are all on equal footing, supervisor created using an ordering of the gen_servers which may or may not be modified after creation (Amalgam interface specification). 1) Explicit interface vs. implicit interface: Explicit works the same way as before -- unhandled messages fail. Implicit relies on the ordering Amalgam interface specification when searching for message handler. 2) Installation of handlers should not occur on gen_servers, but by modification of Amalgam interface specification. 3) Inheritance is explicitly defined -- no ambiguity or restrictions. 4) Message passing only one level deep: Amalgam <--> gen_server 5) Death of a single process only eliminates some features; it may be anticipated and a less capable process answers, dynamic relaunching (ala supervisor behaviour) reinstalls. 6) A single process can participate in any number of Amalgams. The first approach cannot model arbitrary computations as easily. The second affords more control over inheritance, and allows simultaneous reuse. Here is an example of an Amalgam: amalgam:start_link( Server, Workers ) Server -> name, pid Workers -> Ordered list of tuples amalgam:start_link( Window, [ gen_window, {File_menu, Gen_menu}, {Edit_menu, Gen_menu}, {My_address_form, Gen_address_form, Gen_form}, {Ok_cancel_buttons}] The amalgam:init() function would start all the processes and then build a call table using left to right ordering of list elements. If a process in a tuple goes down, the others in that tuple may be used as backup handlers. If all processes representing one element of the list go down, that bundle of functions is not available until at least one process is restarted. You may still want an explicit chain, or may be forced to use an explicit chain if the network topology does not allow the Amalgam to directly access a process. A generalized approach would combine the two techniques, but my programming style would favor single level Amalgams because it is a clearer expression of the computation desired. The same processes could participate in two Amalgams, but with a different ordering to get a different behaviour. A person logging in could be handled by collecting a set of privileges from the database, then dynamically constructing an Amalgam that presents only the interfaces that they are allowed to access. Refusing to propagate a missing handler can be a feature. The Amalgam could be combined with a gen_fsm to dynamically add or subtract processes from the call table based on the current state of the FSM. This is a reasonably easy model to understand that gives rise to a complex network of process behaviour that is manageable and fault- tolerant. jay From hakan.stenholm@REDACTED Thu Mar 20 15:35:36 2003 From: hakan.stenholm@REDACTED (=?ISO-8859-1?Q?H=E5kan_Stenholm?=) Date: Thu, 20 Mar 2003 15:35:36 +0100 Subject: Compile time In-Reply-To: Message-ID: <36C32359-5AE1-11D7-822D-000393B8AB26@mbox304.swipnet.se> On torsdag, mar 20, 2003, at 09:02 Europe/Stockholm, DANIESC SCHUTTE wrote: > Morning everyone, > > I have got a question about the time it takes to copile a script, I > have got a script that that takes about 40 - 60 seconds to compile - ( > I included the source here - any idea why it would take so long? It does indeed run slow on my machine as well (R9B0 on a PowerMac G4 2x867 MHz), I'm not sure why it should be this slow but I noticed that you have a very large function with lots of nested case statements as well as that your case statements look like: case .... of .... -> Var = .... .... -> Var = .... .... -> Var = .... end rather than the more common (and slightly more compact) Var = case ... of .... -> .... .... -> .... .... -> .... end You might try rewriting it this way to see if compiles more efficiently > > Am I making a gross mistake somewhere? > > > ####################################################################### > ############## > The information contained in this message and or attachments is > intended > only for the person or entity to which it is addressed and may contain > confidential and/or privileged material. Any review, retransmission, > dissemination or other use of, or taking of any action in reliance > upon, > this information by persons or entities other than the intended > recipient > is prohibited. If you received this in error, please contact the > sender and > delete the material from any system and destroy and copies. > ####################################################################### > ############## > From martin@REDACTED Thu Mar 20 17:55:37 2003 From: martin@REDACTED (martin j logan) Date: 20 Mar 2003 10:55:37 -0600 Subject: Extending Functionality: gen_server_ext In-Reply-To: <4.2.2.20030320052138.00ce9dd0@duomark.com> References: <4.2.2.20030320052138.00ce9dd0@duomark.com> Message-ID: <1048179338.14147.54.camel@berimbau> Hello, I have been following this thread since it started with some interest. I fear that I am not quite smart enough for all of this. This whole notion feels distinctly un-erlang. Erlang is simple, straight forward and fairly consistent, that is what makes it great. Processes are painfully easy to conceptualize, and I can make them talk, its all so easy. I don't think about mutex. My logic variables once assigned are not going to change value unexpectedly. Code is mostly referentially transparent except when it is "simpler" to cheat and have a global, again, real easy. Erlang is simple and expressive. It allows for rapid development and ease of refactoring. While the ideas that are expressed in this thread are quite interesting and have much merit I think that they would serve to undermine erlangs greatest strength - simplicity. Cheers, Martin On Thu, 2003-03-20 at 08:05, Jay Nelson wrote: > Chris and Vlad discussed: > > > Extensions to gen_server to support "behavers" and pseudo > > inheritance call chains ... > > This seems an interesting approach to reusability or extension > of functionality. I haven't thought about a specific problem that > it would apply to but I have some general thoughts about a > structural architecture. I guess these features could be useful > in a situation where you have two machines, one having more > functionality than another (but the lesser functionality reused) > or when users can login with differing levels of privileged access. > I'm sure there are many other applications, the main issue being > whether you want dynamic modification of behaviour or a static > application structure. > > Chained processes - deep inheritance > > This seems to be the thrust of the initial thinking. It mirrors the > deeper inheritance structures used in OO. The bottom of a > chain is the base behaviour in a gen_server, and refinements > are placed in front of the base like popcorn strung on a thread. > > Issues: > > 1) Explicit interface vs. implicit interface: use explicit delegation > and fail if message unhandled, or pass unhandled requests down > the chain until they are handled and then back up the chain > > 2) Allow installation of handlers the way gen_event does to get > situationally adaptive behaviour? > > 3) Multiple inheritance: what if two base chains are joined by > a single gen_server? Not allowed or deterministic searching for > unhandled messages to be passed to base chain. > > 4) If the chain is deep, there could be a lot of wasted message > passing searching for the right handler. You may want to use > memoization to cache the found handler in an ets table the first > time it is used. Even in a dynamic scenario, you could de-momoize > if a new handler is installed. > > 5) Death of a single process can interrupt much computation. > > 6) Single process can only participate in one chain. A separate > instance is needed to participate in a different chain. > > > Interface amalgam - shallow inheritance > > Create a single Amalgam process (similar to supervisor) that combines > the desired interfaces from several gen_servers. gen_servers > are all on equal footing, supervisor created using an ordering > of the gen_servers which may or may not be modified after > creation (Amalgam interface specification). > > 1) Explicit interface vs. implicit interface: Explicit works the same > way as before -- unhandled messages fail. Implicit relies on the > ordering Amalgam interface specification when searching > for message handler. > > 2) Installation of handlers should not occur on gen_servers, but by > modification of Amalgam interface specification. > > 3) Inheritance is explicitly defined -- no ambiguity or restrictions. > > 4) Message passing only one level deep: Amalgam <--> gen_server > > 5) Death of a single process only eliminates some features; it may > be anticipated and a less capable process answers, dynamic relaunching > (ala supervisor behaviour) reinstalls. > > 6) A single process can participate in any number of Amalgams. > > > The first approach cannot model arbitrary computations as easily. > The second affords more control over inheritance, and allows > simultaneous reuse. Here is an example of an Amalgam: > > amalgam:start_link( Server, Workers ) > > Server -> name, pid > Workers -> Ordered list of tuples > > amalgam:start_link( Window, > [ gen_window, {File_menu, Gen_menu}, {Edit_menu, Gen_menu}, > {My_address_form, Gen_address_form, Gen_form}, > {Ok_cancel_buttons}] > > The amalgam:init() function would start all the processes and then build > a call table using left to right ordering of list elements. If a process in a > tuple goes down, the others in that tuple may be used as backup handlers. > If all processes representing one element of the list go down, that bundle > of functions is not available until at least one process is restarted. > > You may still want an explicit chain, or may be forced to use an explicit > chain if the network topology does not allow the Amalgam to directly access > a process. A generalized approach would combine the two techniques, > but my programming style would favor single level Amalgams because it > is a clearer expression of the computation desired. The same processes > could participate in two Amalgams, but with a different ordering to get a > different behaviour. A person logging in could be handled by collecting > a set of privileges from the database, then dynamically constructing an > Amalgam that presents only the interfaces that they are allowed to access. > Refusing to propagate a missing handler can be a feature. > > The Amalgam could be combined with a gen_fsm to dynamically add or > subtract processes from the call table based on the current state of the > FSM. This is a reasonably easy model to understand that gives rise to > a complex network of process behaviour that is manageable and fault- > tolerant. > > jay > > > From wwsprague@REDACTED Thu Mar 20 19:01:50 2003 From: wwsprague@REDACTED (Webb Sprague) Date: Thu, 20 Mar 2003 10:01:50 -0800 Subject: Newbie question on arrays and indexing References: <4.2.2.20030320052138.00ce9dd0@duomark.com> <1048179338.14147.54.camel@berimbau> Message-ID: <3E7A020E.8020602@ucdavis.edu> Hi Everybody, I am afraid this is just a stupid question, so if it is, please be nice and point me to some documentation... :) I am wondering what is the best way to handle indexing into a list or tuple. The issue at hand is that I want to play around with virtual clocks, as per Garg 2001, but all the algorithms are in terms of indexing using integers, like Matrix[3,4]. Thanks Webb From martin@REDACTED Thu Mar 20 19:27:16 2003 From: martin@REDACTED (martin j logan) Date: 20 Mar 2003 12:27:16 -0600 Subject: Newbie question on arrays and indexing In-Reply-To: <3E7A020E.8020602@ucdavis.edu> References: <4.2.2.20030320052138.00ce9dd0@duomark.com> <1048179338.14147.54.camel@berimbau> <3E7A020E.8020602@ucdavis.edu> Message-ID: <1048184837.14147.75.camel@berimbau> On Thu, 2003-03-20 at 12:01, Webb Sprague wrote: > Hi Everybody, > > I am afraid this is just a stupid question, so if it is, please be nice > and point me to some documentation... :) You don't have to worry about juvenile flames on this list. > > I am wondering what is the best way to handle indexing into a list or > tuple. The issue at hand is that I want to play around with virtual > clocks, as per Garg 2001, but all the algorithms are in terms of > indexing using integers, like Matrix[3,4]. > The best way, the only way as far as I know, to deal with indexing into a list is to iterate though it. something like itterate(2, List) to get the second element. itterate(Count, [H|T]) -> itterate(Count -1, T); itterate(1, [H|T]) -> H; itterate(Count, []) -> exit({error, outofbounds}). or you could use stdlib: lists:nth(N, List) -> Element There are a few other ways to do this. Lists are quite fast but if you are really concerned about speed you might want to try using some other structure. Tuples might be better if you know how many elements you are going to need before hand. To index a tuple use element(N, Tuple) this can be found in the kernel module "erlang". Good Luck Cheers, Martin > Thanks > Webb > From vances@REDACTED Thu Mar 20 19:29:43 2003 From: vances@REDACTED (Vance Shipley) Date: Thu, 20 Mar 2003 13:29:43 -0500 Subject: Extending Functionality: gen_server_ext In-Reply-To: <1048179338.14147.54.camel@berimbau> References: <4.2.2.20030320052138.00ce9dd0@duomark.com> <1048179338.14147.54.camel@berimbau> Message-ID: <20030320182943.GU25555@frogman.motivity.ca> On Thu, Mar 20, 2003 at 10:55:37AM -0600, martin j logan wrote: } } Code is mostly referentially transparent except when it is } "simpler" to cheat and have a global, I was thinking recently about how I struggled with how to write code without global variables when learning Erlang. "How the hell can you live without globals?" I asked. It reminded me of learning the C language. "How the hell can you live without GOTOs?"(*) I asked having only ever programmed in BASIC. I've never used either and no longer see any reason to do so. -Vance (*) C does have a goto but you're told not to use it just as you're told not to use the process dictionary. From spearce@REDACTED Thu Mar 20 19:30:12 2003 From: spearce@REDACTED (Shawn Pearce) Date: Thu, 20 Mar 2003 13:30:12 -0500 Subject: Newbie question on arrays and indexing In-Reply-To: <3E7A020E.8020602@ucdavis.edu> References: <4.2.2.20030320052138.00ce9dd0@duomark.com> <1048179338.14147.54.camel@berimbau> <3E7A020E.8020602@ucdavis.edu> Message-ID: <20030320183012.GB31062@spearce.org> Try element/2: > T = {1, 2, 3, 4}. {1, 2, 3, 4} > element(1, T). 1 > element(3, T). 3 The first item in a tuple is index 1. I'm sure there's a function in lists to get the nth item of a list, I just haven't had the need to use that one. Webb Sprague wrote: > Hi Everybody, > > I am afraid this is just a stupid question, so if it is, please be nice > and point me to some documentation... :) > > I am wondering what is the best way to handle indexing into a list or > tuple. The issue at hand is that I want to play around with virtual > clocks, as per Garg 2001, but all the algorithms are in terms of > indexing using integers, like Matrix[3,4]. > > Thanks > Webb > -- Shawn. ... the flaw that makes perfection perfect. From enewhuis@REDACTED Thu Mar 20 19:42:57 2003 From: enewhuis@REDACTED (Eric Newhuis) Date: Thu, 20 Mar 2003 12:42:57 -0600 Subject: Extending Functionality: gen_server_ext References: <4.2.2.20030320052138.00ce9dd0@duomark.com> <1048179338.14147.54.camel@berimbau> Message-ID: <002a01c2ef10$86af8440$34c2cf0a@futuresource.com> I agree. ----- Original Message ----- From: "martin j logan" To: "Jay Nelson" Cc: Sent: Thursday, March 20, 2003 10:55 AM Subject: RE: Extending Functionality: gen_server_ext > Hello, > I have been following this thread since it started with some > interest. I fear that I am not quite smart enough for all of this. This > whole notion feels distinctly un-erlang. Erlang is simple, straight > forward and fairly consistent, that is what makes it great. Processes > are painfully easy to conceptualize, and I can make them talk, its all > so easy. I don't think about mutex. My logic variables once assigned are > not going to change value unexpectedly. Code is mostly referentially > transparent except when it is "simpler" to cheat and have a global, > again, real easy. Erlang is simple and expressive. It allows for rapid > development and ease of refactoring. While the ideas that are expressed > in this thread are quite interesting and have much merit I think that > they would serve to undermine erlangs greatest strength - simplicity. > > Cheers, > Martin > > > > On Thu, 2003-03-20 at 08:05, Jay Nelson wrote: > > Chris and Vlad discussed: > > > > > Extensions to gen_server to support "behavers" and pseudo > > > inheritance call chains ... > > > > This seems an interesting approach to reusability or extension > > of functionality. I haven't thought about a specific problem that > > it would apply to but I have some general thoughts about a > > structural architecture. I guess these features could be useful > > in a situation where you have two machines, one having more > > functionality than another (but the lesser functionality reused) > > or when users can login with differing levels of privileged access. > > I'm sure there are many other applications, the main issue being > > whether you want dynamic modification of behaviour or a static > > application structure. > > > > Chained processes - deep inheritance > > > > This seems to be the thrust of the initial thinking. It mirrors the > > deeper inheritance structures used in OO. The bottom of a > > chain is the base behaviour in a gen_server, and refinements > > are placed in front of the base like popcorn strung on a thread. > > > > Issues: > > > > 1) Explicit interface vs. implicit interface: use explicit delegation > > and fail if message unhandled, or pass unhandled requests down > > the chain until they are handled and then back up the chain > > > > 2) Allow installation of handlers the way gen_event does to get > > situationally adaptive behaviour? > > > > 3) Multiple inheritance: what if two base chains are joined by > > a single gen_server? Not allowed or deterministic searching for > > unhandled messages to be passed to base chain. > > > > 4) If the chain is deep, there could be a lot of wasted message > > passing searching for the right handler. You may want to use > > memoization to cache the found handler in an ets table the first > > time it is used. Even in a dynamic scenario, you could de-momoize > > if a new handler is installed. > > > > 5) Death of a single process can interrupt much computation. > > > > 6) Single process can only participate in one chain. A separate > > instance is needed to participate in a different chain. > > > > > > Interface amalgam - shallow inheritance > > > > Create a single Amalgam process (similar to supervisor) that combines > > the desired interfaces from several gen_servers. gen_servers > > are all on equal footing, supervisor created using an ordering > > of the gen_servers which may or may not be modified after > > creation (Amalgam interface specification). > > > > 1) Explicit interface vs. implicit interface: Explicit works the same > > way as before -- unhandled messages fail. Implicit relies on the > > ordering Amalgam interface specification when searching > > for message handler. > > > > 2) Installation of handlers should not occur on gen_servers, but by > > modification of Amalgam interface specification. > > > > 3) Inheritance is explicitly defined -- no ambiguity or restrictions. > > > > 4) Message passing only one level deep: Amalgam <--> gen_server > > > > 5) Death of a single process only eliminates some features; it may > > be anticipated and a less capable process answers, dynamic relaunching > > (ala supervisor behaviour) reinstalls. > > > > 6) A single process can participate in any number of Amalgams. > > > > > > The first approach cannot model arbitrary computations as easily. > > The second affords more control over inheritance, and allows > > simultaneous reuse. Here is an example of an Amalgam: > > > > amalgam:start_link( Server, Workers ) > > > > Server -> name, pid > > Workers -> Ordered list of tuples > > > > amalgam:start_link( Window, > > [ gen_window, {File_menu, Gen_menu}, {Edit_menu, Gen_menu}, > > {My_address_form, Gen_address_form, Gen_form}, > > {Ok_cancel_buttons}] > > > > The amalgam:init() function would start all the processes and then build > > a call table using left to right ordering of list elements. If a process in a > > tuple goes down, the others in that tuple may be used as backup handlers. > > If all processes representing one element of the list go down, that bundle > > of functions is not available until at least one process is restarted. > > > > You may still want an explicit chain, or may be forced to use an explicit > > chain if the network topology does not allow the Amalgam to directly access > > a process. A generalized approach would combine the two techniques, > > but my programming style would favor single level Amalgams because it > > is a clearer expression of the computation desired. The same processes > > could participate in two Amalgams, but with a different ordering to get a > > different behaviour. A person logging in could be handled by collecting > > a set of privileges from the database, then dynamically constructing an > > Amalgam that presents only the interfaces that they are allowed to access. > > Refusing to propagate a missing handler can be a feature. > > > > The Amalgam could be combined with a gen_fsm to dynamically add or > > subtract processes from the call table based on the current state of the > > FSM. This is a reasonably easy model to understand that gives rise to > > a complex network of process behaviour that is manageable and fault- > > tolerant. > > > > jay > > > > > > > From wwsprague@REDACTED Thu Mar 20 20:00:54 2003 From: wwsprague@REDACTED (Webb Sprague) Date: Thu, 20 Mar 2003 11:00:54 -0800 Subject: Newbie question on arrays and indexing References: <4.2.2.20030320052138.00ce9dd0@duomark.com> <1048179338.14147.54.camel@berimbau> <3E7A020E.8020602@ucdavis.edu> <20030320183012.GB31062@spearce.org> Message-ID: <3E7A0FE6.3000709@ucdavis.edu> Shawn Pearce wrote: >Try element/2: > > > >>T = {1, 2, 3, 4}. >> >> >{1, 2, 3, 4} > > >>element(1, T). >> >> >1 > > >>element(3, T). >> >> >3 > >The first item in a tuple is index 1. >I'm sure there's a function in lists to get the nth item of a list, >I just haven't had the need to use that one. > This works, as does the following: 1>T = {{1, 2},{10, 20}}. 2>element(1, element(2,T)). 10 I was just wondering if there were a more graceful way to do it. I will look into more variations on element. Thanks W From martin@REDACTED Thu Mar 20 20:10:31 2003 From: martin@REDACTED (martin j logan) Date: 20 Mar 2003 13:10:31 -0600 Subject: Extending Functionality: gen_server_ext In-Reply-To: <20030320182943.GU25555@frogman.motivity.ca> References: <4.2.2.20030320052138.00ce9dd0@duomark.com> <1048179338.14147.54.camel@berimbau> <20030320182943.GU25555@frogman.motivity.ca> Message-ID: <1048187431.14093.98.camel@berimbau> I really should have said side-effect not used global as an example of one. I was actually referring to something like ETS. It seems to me that it can serve much the same purpose as put/2 get/1 i.e a side effect of sorts or "global" storage at one scope or another. We all try to stay away from such things but sometimes we break referential transparency, alter a value that has nothing to do with the expression being evaluated, when it is convenient. Cheers, Martin On Thu, 2003-03-20 at 12:29, Vance Shipley wrote: > On Thu, Mar 20, 2003 at 10:55:37AM -0600, martin j logan wrote: > } > } Code is mostly referentially transparent except when it is > } "simpler" to cheat and have a global, > > > I was thinking recently about how I struggled with how to write > code without global variables when learning Erlang. "How the hell > can you live without globals?" I asked. It reminded me of learning > the C language. "How the hell can you live without GOTOs?"(*) I > asked having only ever programmed in BASIC. I've never used either > and no longer see any reason to do so. > > -Vance > > (*) C does have a goto but you're told not to use it just as you're > told not to use the process dictionary. From spearce@REDACTED Thu Mar 20 20:14:24 2003 From: spearce@REDACTED (Shawn Pearce) Date: Thu, 20 Mar 2003 14:14:24 -0500 Subject: Extending Functionality: gen_server_ext In-Reply-To: <20030320182943.GU25555@frogman.motivity.ca> References: <4.2.2.20030320052138.00ce9dd0@duomark.com> <1048179338.14147.54.camel@berimbau> <20030320182943.GU25555@frogman.motivity.ca> Message-ID: <20030320191424.GD31062@spearce.org> Erlang has a two kinds of globals: registered processes named ets tables Without either you'd be up a creek without a paddle, or at least being forced to hand an argument to every function to lookup a process - what a mess. You simply cannot write complex programs easily (meaning with few keystrokes) without SOME form of globals. It just happens that Erlang's concept of globals are actually not dangerous, quite unlike globals in most object and imperative programming languages. Vance Shipley wrote: > On Thu, Mar 20, 2003 at 10:55:37AM -0600, martin j logan wrote: > } > } Code is mostly referentially transparent except when it is > } "simpler" to cheat and have a global, > > > I was thinking recently about how I struggled with how to write > code without global variables when learning Erlang. "How the hell > can you live without globals?" I asked. It reminded me of learning > the C language. "How the hell can you live without GOTOs?"(*) I > asked having only ever programmed in BASIC. I've never used either > and no longer see any reason to do so. > > -Vance > > (*) C does have a goto but you're told not to use it just as you're > told not to use the process dictionary. -- Shawn. Last night the power went out. Good thing my camera had a flash.... The neighbors thought it was lightning in my house, so they called the cops. -- Steven Wright From vances@REDACTED Thu Mar 20 20:37:00 2003 From: vances@REDACTED (Vance Shipley) Date: Thu, 20 Mar 2003 14:37:00 -0500 Subject: Extending Functionality: gen_server_ext In-Reply-To: <20030320191424.GD31062@spearce.org> References: <4.2.2.20030320052138.00ce9dd0@duomark.com> <1048179338.14147.54.camel@berimbau> <20030320182943.GU25555@frogman.motivity.ca> <20030320191424.GD31062@spearce.org> Message-ID: <20030320193700.GW25555@frogman.motivity.ca> Ah well that is another story isn't it? You can do two main things to share knowledge between processes in Erlang: 1) store it in ETS 2) store it in the State data of a server process The latter is probably a more pure solution. You can call ETS cheating in the same way that the process dictionary is cheating if you wish. I call it optimizing. :) I use ETS quite often for this purpose. I'm especially prone to: ets:update_counter(Tid, callReference, 1). -Vance On Thu, Mar 20, 2003 at 02:14:24PM -0500, Shawn Pearce wrote: } } Erlang has a two kinds of globals: } } registered processes } named ets tables From hp@REDACTED Thu Mar 20 20:49:07 2003 From: hp@REDACTED (HP Wei) Date: Thu, 20 Mar 2003 14:49:07 -0500 (EST) Subject: monitor and update an object collaboratively Message-ID: <200303201949.h2KJn7v5019734@ram.rentec.com> Hi, Is there an example of codes for doing the following ? An object (a file contents, a drawing board etc) is monitored by many users on different nodes. Each user can modify the object. At that time of modification by one user, all others can only 'see' but not be able to modify the object. thanks, HP From vances@REDACTED Thu Mar 20 21:21:09 2003 From: vances@REDACTED (Vance Shipley) Date: Thu, 20 Mar 2003 15:21:09 -0500 Subject: monitor and update an object collaboratively In-Reply-To: <200303201949.h2KJn7v5019734@ram.rentec.com> References: <200303201949.h2KJn7v5019734@ram.rentec.com> Message-ID: <20030320202109.GY25555@frogman.motivity.ca> You can do the global locking with global: http://www.erlang.org/doc/r9b/lib/kernel-2.8.0/doc/html/index.html It'll be up to your application(s) to respect the locks so if you want to allow read access you just do. Preventing write access is a matter of respecting the locks (i.e. requesting a lock first). -Vance On Thu, Mar 20, 2003 at 02:49:07PM -0500, HP Wei wrote: } Is there an example of codes for doing the following ? } } An object (a file contents, a drawing board etc) } is monitored by many users on different nodes. } Each user can modify the object. } At that time of modification by one user, } all others can only 'see' but not be able to modify the object. } } thanks, } HP } From svg@REDACTED Thu Mar 20 20:08:43 2003 From: svg@REDACTED (Vladimir Sekissov) Date: Fri, 21 Mar 2003 00:08:43 +0500 (YEKT) Subject: monitor and update an object collaboratively In-Reply-To: <200303201949.h2KJn7v5019734@ram.rentec.com> References: <200303201949.h2KJn7v5019734@ram.rentec.com> Message-ID: <20030321.000843.74756895.svg@surnet.ru> Good day, I think global locks would be the simplest way: update_board(BoardName, RowNum, Data) -> LockId = {{BoardName, RowNum}, {node(), self()}}, case global:trans(LockId, fun () -> set_board_row(BoardName, RowNum, Data) end) of aborted -> {error, locked}; Ret -> Ret end. Best Regards, Vladimir Sekissov hp> Hi, hp> Is there an example of codes for doing the following ? hp> hp> An object (a file contents, a drawing board etc) hp> is monitored by many users on different nodes. hp> Each user can modify the object. hp> At that time of modification by one user, hp> all others can only 'see' but not be able to modify the object. hp> hp> thanks, hp> HP From bernardp@REDACTED Thu Mar 20 22:19:49 2003 From: bernardp@REDACTED (Pierpaolo BERNARDI) Date: Thu, 20 Mar 2003 22:19:49 +0100 Subject: Newbie question on arrays and indexing References: <4.2.2.20030320052138.00ce9dd0@duomark.com> <1048179338.14147.54.camel@berimbau> <3E7A020E.8020602@ucdavis.edu> Message-ID: <004a01c2ef26$881a0ec0$6ef06850@c1p4e3> From: "Webb Sprague" > I am wondering what is the best way to handle indexing into a list or > tuple. The issue at hand is that I want to play around with virtual > clocks, as per Garg 2001, but all the algorithms are in terms of > indexing using integers, like Matrix[3,4]. In addition to the other suggestions be sure to consider also gb_trees, gb_sets and ets tables. Find attached an example of an array interface built on gb_trees 11> A = array:make([5,7,9]). {[5,7,9],not_initialized,{0,nil}} 12> A1 = array:set(A,[3,4,5],42). {[5,7,9],not_initialized,{1,{[3,4,5],42,nil,nil}}} 13> array:ref(A1,[3,4,5]). 42 14> array:ref(A1,[1,1,1]). not_initialized Cheers P. -------------- next part -------------- A non-text attachment was scrubbed... Name: array.erl Type: application/octet-stream Size: 911 bytes Desc: not available URL: From ulf.wiger@REDACTED Thu Mar 20 22:19:58 2003 From: ulf.wiger@REDACTED (Wiger Ulf) Date: Thu, 20 Mar 2003 22:19:58 +0100 Subject: Newbie question on arrays and indexing References: <4.2.2.20030320052138.00ce9dd0@duomark.com> <1048179338.14147.54.camel@berimbau> <3E7A020E.8020602@ucdavis.edu> <20030320183012.GB31062@spearce.org> <3E7A0FE6.3000709@ucdavis.edu> Message-ID: <004c01c2ef26$7639f260$fd7a40d5@telia.com> From: "Webb Sprague" > Shawn Pearce wrote: > > >Try element/2: > >>T = {1, 2, 3, 4}. > >{1, 2, 3, 4} > >>element(1, T). > >1 > >>element(3, T). > >3 > I was just wondering if there were a more graceful way to do it. I will > look into more variations on element. Tuples are pretty good for this. There is a function called erlang:make_tuple(Size,DefaultValue) that allows you to cheaply create even a rather large tuple. For _very_large arrays, tuples are not so great, and neither are lists. You can use ets, or perhaps a utility called dynarray, that you will find under user contributions at erlang.org. Dynarray basically behaves as an infinite array. It's implemented using a dynamically expanding tuple tree. Its main drawback is in debugging, as the printouts can get unwieldy. In this respect, ets tables are very nice. /Uffe From ulf.wiger@REDACTED Thu Mar 20 22:24:30 2003 From: ulf.wiger@REDACTED (Wiger Ulf) Date: Thu, 20 Mar 2003 22:24:30 +0100 Subject: Extending Functionality: gen_server_ext References: <4.2.2.20030320052138.00ce9dd0@duomark.com> <1048179338.14147.54.camel@berimbau> <20030320182943.GU25555@frogman.motivity.ca> <20030320191424.GD31062@spearce.org> <20030320193700.GW25555@frogman.motivity.ca> Message-ID: <006801c2ef27$183e6320$fd7a40d5@telia.com> Well, you can actually implement a program that perfectly mimics ETS, using only processes and message passing (and some nifty data structure, like dict). The only tangible difference is that performance will be roughly 30x slower. ;-) Semantically, I don't think ETS tables are dirtier than processes, for this very reason. /Uffe ----- Original Message ----- From: "Vance Shipley" To: Sent: den 20 mars 2003 20:37 Subject: Re: Extending Functionality: gen_server_ext > > Ah well that is another story isn't it? > > You can do two main things to share knowledge between processes in > Erlang: > > 1) store it in ETS > > 2) store it in the State data of a server process > > The latter is probably a more pure solution. You can call ETS > cheating in the same way that the process dictionary is cheating > if you wish. I call it optimizing. :) > > I use ETS quite often for this purpose. I'm especially prone to: > > ets:update_counter(Tid, callReference, 1). > > > -Vance > > > On Thu, Mar 20, 2003 at 02:14:24PM -0500, Shawn Pearce wrote: > } > } Erlang has a two kinds of globals: > } > } registered processes > } named ets tables From vances@REDACTED Thu Mar 20 22:36:04 2003 From: vances@REDACTED (Vance Shipley) Date: Thu, 20 Mar 2003 16:36:04 -0500 Subject: gen_server:format_status/2 only works with registered processes Message-ID: <20030320213604.GZ25555@frogman.motivity.ca> Background Both gen_server.erl and gen_fsm.erl have a (undocumented) function which is used to pretty print the persistent data they keep. The way it works is that you first call sys:get_status/1 (documented) to retrieve the process's status and then format the state data in a contextually relevant way with gen_[server|fsm]:format_status/2. The nice thing is that gen_[server|fsm]:format_status/2 will check to see if the user's callback module has exported a format_status/2 and if so it will call that function to get an even more contextually relevant way to present the data. I find this all very handy. Problem Now the problem is that, at least in R9B-[0|1], this only works if the process is registered! In the following example I am peeking at a couple gen_server processes the system runs. I am referring to each by PID but the process which is not registerd fails. -Vance $ erl Erlang (BEAM) emulator version 5.2.3.3 [source] [hipe] [threads:0] Eshell V5.2.3.3 (abort with ^G) 1> i(). Pid Initial Call Heap Reds Msgs Registered Current Function Stack ... <0.17.0> code_server:init/1 377 46225 0 code_server gen_server:loop/6 12 ... <0.23.0> kernel_config:init/1 233 45 0 gen_server:loop/6 12 ... 2> {_,_,_,StatusData} = sys:get_status(list_to_pid("<0.17.0>")), 2> gen_server:format_status([], StatusData). [{header,"Status for generic server code_server"}, {data,[{"Status",running},{"Parent",<0.9.0>},{"Logged events",[]}]}, {data,[{"State", {state,"/usr/local/lib/erlang", [".", "/usr/local/lib/erlang/lib/kernel-2.8.1.1/ebin", "/usr/local/lib/erlang/lib/stdlib-1.11.4.1/ebin", "/usr/local/lib/erlang/lib/webtool-0.7.1/ebin", "/usr/local/lib/erlang/lib/tv-2.0.4/ebin", "/usr/local/lib/erlang/lib/tools-2.2/ebin", "/usr/local/lib/erlang/lib/toolbar-1.1.0/ebin", "/usr/local/lib/erlang/lib/ssl-2.3.5/ebin", "/usr/local/lib/erlang/lib/snmp-3.3.8/ebin", "/usr/local/lib/erlang/lib/sasl-1.9.4/ebin", "/usr/local/lib/erlang/lib/runtime_tools-1.3/ebin", "/usr/local/lib/erlang/lib/pman-2.4.1/ebin", "/usr/local/lib/erlang/lib/parsetools-1.2/ebin", "/usr/local/lib/erlang/lib/os_mon-1.6.0.2/ebin", "/usr/local/lib/erlang/lib/orber-3.4/ebin", "/usr/local/lib/erlang/lib/observer-0.9.3/ebin", "/usr/local/lib/erlang/lib/mnesia_session-1.1.5/ebin"|...], 9, 10, interactive}}]}] 3> f(StatusData). ok 4> {_,_,_,StatusData} = sys:get_status(list_to_pid("<0.23.0>")), 4> gen_server:format_status([], StatusData). ** exited: {function_clause,[{lists,thing_to_list,[<0.23.0>]}, {lists,flatmap,2}, {gen_server,format_status,2}, {erl_eval,expr,3}, {erl_eval,exprs,4}, {shell,eval_loop,2}]} ** =ERROR REPORT==== 20-Mar-2003::16:31:37 === Error in process <0.25.0> with exit value: {function_clause,[{lists,thing_to_list,[<0.23.0>]},{lists,flatmap,2},{gen_server,format_status,2},{erl_eval,expr,3},{erl_eval,exprs,4},{shell,eval_loop,2}]} From jamesh@REDACTED Thu Mar 20 16:37:46 2003 From: jamesh@REDACTED (James Hague) Date: Thu, 20 Mar 2003 09:37:46 -0600 Subject: List comprehension bug? Message-ID: I posted this last month, but it was buried inside of another thread, so here's another shot :) You get a bizarre runtime error and no compile time warnings if you don't bind a variable on the right side of a list comprehension. For example, take the standard definition of map: map(F, [H|T]) -> [F(H)|map(F, T)]; map(_, []) -> []. and change it to: map(F, [H|T]) -> [F(H)||map(F, T)]; map(_, []) -> []. I did this by accident once, and it took me half an hour to see the typo. You get an runtime error report indicating that a case expression couldn't be matched, but I would think this code shouldn't get through the compiler in the first place. Or is there a reason to allow list comprehensions with a single predicate on the right side? James From vances@REDACTED Fri Mar 21 00:04:37 2003 From: vances@REDACTED (Vance Shipley) Date: Thu, 20 Mar 2003 18:04:37 -0500 Subject: gen_server:format_status/2 only works with registered processes In-Reply-To: <20030320213604.GZ25555@frogman.motivity.ca> References: <20030320213604.GZ25555@frogman.motivity.ca> Message-ID: <20030320230437.GA30323@frogman.motivity.ca> OK, I found the problem. The following patch to lists.erl does it: *** lists.erl.dist Thu Mar 20 17:56:16 2003 --- lists.erl Thu Mar 20 17:58:26 2003 *************** *** 280,285 **** --- 280,286 ---- thing_to_list(X) when integer(X) -> integer_to_list(X); thing_to_list(X) when float(X) -> float_to_list(X); thing_to_list(X) when atom(X) -> atom_to_list(X); + thing_to_list(X) when pid(X) -> pid_to_list(X); thing_to_list(X) when list(X) -> X. %Assumed to be a string %% flatten(List) -Vance Vance Shipley Motivity Telecom Inc. +1 519 240 3684 vances@REDACTED On Thu, Mar 20, 2003 at 04:36:04PM -0500, Vance Shipley wrote: } } Now the problem is that, at least in R9B-[0|1], this only works if the } process is registered! In the following example I am peeking at a } couple gen_server processes the system runs. I am referring to each } by PID but the process which is not registerd fails. ... } Error in process <0.25.0> with exit value: {function_clause,[{lists,thing_to_list,[<0.23.0>]},{lists,flatmap,2},{gen_server,format_status,2},{erl_eval,expr,3},{erl_eval,exprs,4},{shell,eval_loop,2}]} } From cpressey@REDACTED Fri Mar 21 00:55:22 2003 From: cpressey@REDACTED (Chris Pressey) Date: Thu, 20 Mar 2003 17:55:22 -0600 Subject: Extending Functionality: gen_server_ext In-Reply-To: References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D490@esemont203.gbg.edt.ericsson.se> <20030319114201.23c1543b.cpressey@catseye.mb.ca> Message-ID: <20030320175522.67366879.cpressey@catseye.mb.ca> On Wed, 19 Mar 2003 20:36:38 +0100 "Vlad Dumitrescu" wrote: > > But surely the client isn't expecting the call to be transformed into > > a cast... ?? My vague feeling is that ideally there should be one > > function, gen_server_ext:next(), that goes to the same type of handler > > (cast, call, info etc) in the next behaver. > > Oh, sorry -- I didn't read your question properly. Long day, lots of > work:-) Of course my answer only applies to calling next_call from a > handle call. No problem. It probably wouldn't be a common typo, and I'm sure there'd be a way to catch it before anything weird happens... by examining the call stack, perhaps :) > > Another question: what are the pros and cons of having to call > > next_call() et al, as opposed to returning a value like {next_call, > > ...} from the handler, and having gen_server_ext pay attention to > > that? > > If you return with {next_call, ...} then you can't get the answer back > and refine it. It's something in between the two options you mentioned > before, I think. Yeah, makes sense. > I have this feeling that there's a lot more to dig out here. > > regards, > Vlad I dunno, it sounds better and better the more I think about it. Consider an example, say you have a server and you want to add logging of some kind. All you need to do is add another behaver inside gen_server_ext, "in front of" your server, that logs whatever, then calls next_call. Seems more elegant to me than having a seperate gen_server for logging which delegates to the original gen_server. But that's kind of a contrived example, I'll try to think of a better one. On the subject of what I've been exploring - that is, having a seamless transition between processless and processful objects - I had a bit of an epiphany this afternoon - I think it would turn out to be something like Ulf's mdisp package (which I unfortunately haven't looked at closely enough yet), except more dynamic. I have something half-coded that I'll try to finish - basically, I have a bunch of things in an ETS table, and a function notify/2 which sends a thing a message. If the thing is inactive (no process,) it gets activated first (a process is spawned for it.) The process generally runs a receive statement (which can deactivate itself after a timeout, if need be.) This should let me track tens (or maybe hundreds) of thousands of things, but only have as many processes as are actually needful at any given time. I'll keep y'all updated... :) -Chris From cpressey@REDACTED Fri Mar 21 04:49:15 2003 From: cpressey@REDACTED (Chris Pressey) Date: Thu, 20 Mar 2003 21:49:15 -0600 Subject: Extending Functionality: mdisp In-Reply-To: <20030320175522.67366879.cpressey@catseye.mb.ca> References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D490@esemont203.gbg.edt.ericsson.se> <20030319114201.23c1543b.cpressey@catseye.mb.ca> <20030320175522.67366879.cpressey@catseye.mb.ca> Message-ID: <20030320214915.4a190e3c.cpressey@catseye.mb.ca> On Thu, 20 Mar 2003 17:55:22 -0600 Chris Pressey wrote: > On the subject of what I've been exploring - that is, having a seamless > transition between processless and processful objects - I had a bit of > an epiphany this afternoon - I think it would turn out to be something > like Ulf's mdisp package (which I unfortunately haven't looked at > closely enough yet), except more dynamic. Er - now that I've looked at it - it is almost *exactly* what I was thinking of... *except*... This will probably sound quite weird in the context of mdisp, but what if threads could do stuff while they were asleep? That is - if you were to execute a *synchronous* call to a thread, would it even have to wake up? It could execute entirely in the context of the caller. It would only have to wake up for casts. (Unless of course I've completely gone off the deep end on this one - a distinct possibility :) If my hunch *is* on target, then mdisp might serve as a good basis for a compromise between processes and objects, such as what might be desirable for a GUI, or a simulated world. Any thoughts on this? -Chris From spearce@REDACTED Fri Mar 21 05:34:17 2003 From: spearce@REDACTED (Shawn Pearce) Date: Thu, 20 Mar 2003 23:34:17 -0500 Subject: Extending Functionality: mdisp In-Reply-To: <20030320214915.4a190e3c.cpressey@catseye.mb.ca> References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D490@esemont203.gbg.edt.ericsson.se> <20030319114201.23c1543b.cpressey@catseye.mb.ca> <20030320175522.67366879.cpressey@catseye.mb.ca> <20030320214915.4a190e3c.cpressey@catseye.mb.ca> Message-ID: <20030321043417.GA31836@spearce.org> Chris Pressey wrote: > If my hunch *is* on target, then mdisp might serve as a good basis for a > compromise between processes and objects, such as what might be desirable > for a GUI, or a simulated world. Any thoughts on this? One - why do we have to put processes asleep? What's fundamentally wrong with erts that is causing us to consider paging state/context on and off of processes? This is smelling a whole lot like what we would have to do in Java to accomplish the same task, only we can currently create more processes (threads) before the emulator faults, and there is the fancy thing called ETS. :) What I'm getting at is, why can't these be normal processes and let erts handle the very concept of them not being alive, or executing on the sender's call stack, etc. And then can we fix erts? I've been watching this thread with interest, wondering what will come of it. I'm praying its not another bastard semi-threaded / semi-not-threaded system. :) -- Shawn. Test-tube babies shouldn't throw stones. From Vlad.Dumitrescu@REDACTED Fri Mar 21 09:44:14 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Fri, 21 Mar 2003 09:44:14 +0100 Subject: Extending Functionality: gen_server_ext Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D496@esemont203.gbg.edt.ericsson.se> Hi, > From: martin j logan [mailto:martin@REDACTED] > I have been following this thread since it started with some > interest. I fear that I am not quite smart enough for all of this. I can assure you the discussion not have anything to do with being smart or not. If anything, maybe with my own inability to grasp key concepts. :-) > Erlang is simple, straight forward and fairly consistent, that is > what makes it great. Processes are painfully easy to conceptualize, > and I can make them talk, its all so easy. I don't think about > mutex. My logic variables once assigned are not going to change > value unexpectedly. Code is mostly referentially transparent except > when it is "simpler" to cheat and have a global, again, real > easy. Erlang is simple and expressive. It allows for rapid > development and ease of refactoring. Yes, you are absolutely right! > While the ideas that are expressed in this thread are quite > interesting and have much merit I think that they would serve to > undermine erlangs greatest strength - simplicity. Here I don't really agree. Erlang is just as you say, but not anything about Erlang is simple. Take for example OTP (there was a thread recently about this) and please anybody who can really say he/she masters it, raise your hand! I think there won't be more than ten hands raised... the reason: OTP is complex, even if it's built on Erlang. Now is there anyone doubting the need for OTP in a complex system setting? Not many hands here either, I'd guess... the reason: OTP is useful. We accept the price of added complexity because it saves effort somewhere else. What we are talking about here about extendig Erlang, is not really about the language, but about OTP. The language is a base to build on, with higher-level abstractions. If it weren't like that, we would all still write assembler. What we are exploring is another approach to building functionality. Maybe in the end it will not look at all like we are discussing it today, maybe it will be much simpler. But for now I can only think of it in these terms. best regards, Vlad From Vlad.Dumitrescu@REDACTED Fri Mar 21 11:22:01 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Fri, 21 Mar 2003 11:22:01 +0100 Subject: Extending Functionality: gen_server_ext Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D497@esemont203.gbg.edt.ericsson.se> Hello, > From: Jay Nelson [mailto:jay@REDACTED] >Chris and Vlad discussed: >> Extensions to gen_server to support "behavers" and pseudo >> inheritance call chains ... > Chained processes - deep inheritance <...snipped...> > Interface amalgam - shallow inheritance <...snipped...> You make some interesting observations, and I will have to sit down and think about it properly before replying. Right now, I'd like to make some observations of my own. What I think it would be best (inspired from both your and Chris' ideas) is some kind of behavioural composition. It might involve a separate process per simple behaviour, or maybe thay can be combined in a single process. It was the latter I was thinking about when writing gen_server_ext: one process implementing several behaviours. But this latest idea of the Amalgam, is really interesting. What I'd like to be able to do is create a process by specifying several interfaces/behaviours it will support, a GUI related example might be for a button: I need let's say 'drawable', 'clickable', 'mouse_over'. Just by naming them, I get the functionality, and I can (if I want) to override some of the functionality to better suit the button's needs. There will be some callbacks that the behaviours need: for example 'mouse_over' can call button:on_mouse_over(), where the pointer can be set to a hand instead of an arrow. If the button shall become inactive, it will be enough to just disable it's 'clickable' behaviour. Potential problem: how to ensure that these behaviours do not have overlapping interfaces? (i.e. message tags or callback names that are the same) Maybe a better analogy than "objects" is "components". Use behaviours (as processes or as modules) as components, building stones for more advanced components and finally whole systems. This didn't work so well for OO components, but this doesn't mean the basic idea is flawed. Of course, all this can be done by hand, but it seems like a general enough functionality to implement once, test properly and reuse. Just like gen_server, for example :-) best regards, Vlad From matthias@REDACTED Fri Mar 21 12:31:32 2003 From: matthias@REDACTED (Matthias Lang) Date: Fri, 21 Mar 2003 12:31:32 +0100 Subject: Extending Functionality: gen_server_ext In-Reply-To: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D496@esemont203.gbg.edt.ericsson.se> References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D496@esemont203.gbg.edt.ericsson.se> Message-ID: <15994.63508.125246.558481@antilipe.corelatus.se> martin> While the ideas that are expressed in this thread are martin> quite interesting and have much merit I think that they martin> would serve to undermine erlangs greatest strength - martin> simplicity. vlad> What we are talking about here about extendig Erlang, is vlad> not really about the language, but about OTP. Changing the meaning of a function call is not about changing OTP. It is changing the language. You can no longer be sure that the code executed by a call to foo:bar() can be found in the module foo. That is a big new uncertainty. Matthias From Vlad.Dumitrescu@REDACTED Fri Mar 21 13:14:53 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Fri, 21 Mar 2003 13:14:53 +0100 Subject: Extending Functionality: gen_server_ext Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D498@esemont203.gbg.edt.ericsson.se> Hi, > vlad> What we are talking about here about extendig Erlang, is > vlad> not really about the language, but about OTP. > > Changing the meaning of a function call is not about changing OTP. It > is changing the language. You can no longer be sure that the code > executed by a call to foo:bar() can be found in the module foo. > > That is a big new uncertainty. Of course not all ideas are necessary right, it's more like a brainstorming. The idea of automatically dispatching to some other module any call to an undefined function is a little older (in the context) and for what I am concerned I am already past it. I thought Martin's remark was about the latest topics, where I talked about extending behaviours. regards, Vlad From jay@REDACTED Fri Mar 21 14:45:19 2003 From: jay@REDACTED (Jay Nelson) Date: Fri, 21 Mar 2003 05:45:19 -0800 Subject: Extending Functionality: gen_server_ext In-Reply-To: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D497@esemont203.gbg.ed t.ericsson.se> Message-ID: <4.2.2.20030321054201.00cf8b70@duomark.com> At 11:22 AM 3/21/03 +0100, Vlad Dumitrescu (EAW) wrote: >Maybe a better analogy than "objects" is "components". Use behaviours >(as processes or as modules) as components, building stones for more >advanced components and finally whole systems. This didn't work so >well for OO components, but this doesn't mean the basic idea is >flawed. I like the term "composites". It doesn't give any notion of concreteness like objects or components, but it does convey the same sense of "amalgam" that I was trying to describe. I am trying hard to avoid being tainted by OO thinking because I am struggling and think out loud about new ways of coding because I have a new tool that has different features than my old tools. I am thinking in terms of combining processes. You could override in the process that binds behaviours, but it is more reusable if you override by creating a new process (which might delegate functions either via module delegation or via process delegation) so that both versions are always available as you move forward. jay From luke@REDACTED Fri Mar 21 14:47:21 2003 From: luke@REDACTED (Luke Gorrie) Date: 21 Mar 2003 14:47:21 +0100 Subject: inspecting the call stack from a program (was: Re: Extending Functionality: an expedient and questionable approa ch) In-Reply-To: References: Message-ID: Ulf Wiger writes: > Interestingly, the (badly written) regexp:first_match() in > the commented version seems to loop endlessly. Bug or > feature? The same pattern passed to egrep works fine. I think it's a bug in the regexp module - matching on certain regexps fails to terminate. > Str,"\\([a-z]+[a-z0-9_]*:[a-z]+[a-z0-9_]*+/[0-9]+") of ^^ That marked part is the most likely suspect: * can match nothing, so *+ can match infinitely many nothings, and the current module will consider all nothings (i.e. loop forever.) I've reimplemented the same regexp-matching algorithm learned from regexp.erl a couple of times and been caught out with this bug. I'm quite curious to know of a nice fix, since it's a lovely and simple algorithm. Sofar I haven't found a fix that's pretty enough to adopt :-) I think I heard rumour of a simple algorithm for transforming regexps so that they will never hit this case, but I'm not sure. NB: if you are passing user-supplied regexps to the regexp module, e.g. from web-forms, this may be a serious problem. Cheers, Luke From kent@REDACTED Fri Mar 21 15:28:32 2003 From: kent@REDACTED (Kent Boortz) Date: 21 Mar 2003 15:28:32 +0100 Subject: ensure_started In-Reply-To: References: Message-ID: Ulf Wiger writes: > I posted the following suggestion a few weeks ago, now > slightly modified: > > ensure_started() -> > Id = {{?MODULE,ensure_started}, self()}, > global:trans( > Id, fun() -> > case whereis(?MODULE) of > undefined -> > Pid = proc_lib:spawn(?MODULE,init,[]), > register(?MODULE, Pid), > {ok, Pid}; > Pid when pid(Pid) -> > {ok, Pid} > end > end, [node()]). > > > Since you know that the ensure_started() call is always > local you can use global:trans(Id, Fun, [node()]) which will > cut it down to two gen_server calls to the nearest global > name server. As an experiment I wrote a new bif that could simplify coding of things like this. The bif will as an "atomic operation" start and register a process if a process with that name doesn't exist. If it does exist the pid of the existing process will be returned. If 'link' is in SpawnOpts a link is created to the started/existing process. Haven't implemented the user API but it should look something like erlang:ensure_started(RegisteredName, FunToRun, SpawnOpts) and maybe a version for remote start erlang:ensure_started(RegisteredName, Node, FunToRun, SpawnOpts) With these functions it should be easy to implement a new function proc_lib:ensure_started(...) that should cover what the code above try to do. Any thoughts? kent From peter@REDACTED Fri Mar 21 16:22:12 2003 From: peter@REDACTED (Peter H|gfeldt) Date: Fri, 21 Mar 2003 16:22:12 +0100 (MET) Subject: ensure_started In-Reply-To: Message-ID: On Feb 1, 1997 I wrote the following, addressed to the OTP developing team. I think it is still valid. /Peter "Sometimes I see code like the following (in real applications or in examples in documents): start(Name, Module, Args) -> case whereis(Name) of undefined -> Pid = spawn(Module, init, Args), register(Name, Pid), Pid; Other -> Other end. That is bad programming: 1. Concurrency: You do not know what happens between whereis/1 and spawn/3. Some other process might be scheduled in between, and call start/2. 2. If register/2 fails, we already have a process registered as Name, and an additional process (it was spawned before we tried to register) doing the same things as the registered one, but not known by a registered name. If the purpose of the newly spawned process is to control system unique resources, we might have two processes competing for the same resources (think e.g. of two Erlang shells competing for user input). What to do: Put the register/2 part in the Module:init function, so that the newly created process fails (and terminates if properly programmed) if the name is already registered. Then there will be at most one process doing 'the thing'. In fact, in the good ol'BOS, we imposed the rule that registration should be done by the process itself in its "init-phase", i.e. before it enters its service loop (the last thing to do in the init-phase was to acknowlegde the start to the supervisor by a start-ack message). (The above code *might* be acceptable if the process started is controlled by (an OTP) supervisor (the spawn should then be replace by a spawn_link) and if it is obvious that only the supervisor calls Module:start/1. But then the whereis/1 is superfluous provided the supervisor knows what it is doing, etc). The difficulty is doing a thing precisely once: not doing it at all, or doing it several times is easy. By having the register/2 in the process itself, we assure that there is at most one process of the kind running, and by having it controlled by a supervisor we will have precisely one running most of the time (the supervisor will restart a process that terminates). Concurrency is more difficult than you believe." On 21 Mar 2003, Kent Boortz wrote: > > Ulf Wiger writes: > > I posted the following suggestion a few weeks ago, now > > slightly modified: > > > > ensure_started() -> > > Id = {{?MODULE,ensure_started}, self()}, > > global:trans( > > Id, fun() -> > > case whereis(?MODULE) of > > undefined -> > > Pid = proc_lib:spawn(?MODULE,init,[]), > > register(?MODULE, Pid), > > {ok, Pid}; > > Pid when pid(Pid) -> > > {ok, Pid} > > end > > end, [node()]). > > > > > > Since you know that the ensure_started() call is always > > local you can use global:trans(Id, Fun, [node()]) which will > > cut it down to two gen_server calls to the nearest global > > name server. > > As an experiment I wrote a new bif that could simplify coding of > things like this. The bif will as an "atomic operation" start and > register a process if a process with that name doesn't exist. > If it does exist the pid of the existing process will be returned. > If 'link' is in SpawnOpts a link is created to the started/existing > process. > > Haven't implemented the user API but it should look something like > > erlang:ensure_started(RegisteredName, FunToRun, SpawnOpts) > > and maybe a version for remote start > > erlang:ensure_started(RegisteredName, Node, FunToRun, SpawnOpts) > > With these functions it should be easy to implement a new function > proc_lib:ensure_started(...) that should cover what the code above > try to do. > > Any thoughts? > > kent > From mbj@REDACTED Fri Mar 21 16:28:29 2003 From: mbj@REDACTED (Martin Bjorklund) Date: Fri, 21 Mar 2003 16:28:29 +0100 (CET) Subject: ensure_started In-Reply-To: References: Message-ID: <20030321.162829.11638205.mbj@bluetail.com> Peter H|gfeldt wrote: > > On Feb 1, 1997 I wrote the following, addressed to the OTP developing > team. I think it is still valid. I was just writing something along these lines. I fully agree! Don't introduce another bif for something you can do anyway. (which I hope was your point ;) /martin From cpressey@REDACTED Fri Mar 21 19:12:44 2003 From: cpressey@REDACTED (Chris Pressey) Date: Fri, 21 Mar 2003 12:12:44 -0600 Subject: Extending Functionality: mdisp In-Reply-To: <20030321043417.GA31836@spearce.org> References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D490@esemont203.gbg.edt.ericsson.se> <20030319114201.23c1543b.cpressey@catseye.mb.ca> <20030320175522.67366879.cpressey@catseye.mb.ca> <20030320214915.4a190e3c.cpressey@catseye.mb.ca> <20030321043417.GA31836@spearce.org> Message-ID: <20030321121244.19656137.cpressey@catseye.mb.ca> On Thu, 20 Mar 2003 23:34:17 -0500 Shawn Pearce wrote: > Chris Pressey wrote: > > If my hunch *is* on target, then mdisp might serve as a good basis for > > a compromise between processes and objects, such as what might be > > desirable for a GUI, or a simulated world. Any thoughts on this? > > > One - why do we have to put processes asleep? We don't. (that's why mdisp is a user contrib and not a part of OTP) > [...] > I've been watching this thread with interest, wondering what will come > of it. I'm praying its not another bastard semi-threaded / > semi-not-threaded system. :) I'm praying it is. (if you've been watching the thread you've probably noticed I'm interested in "Everything is a process, except what isn't, except everything is treated the same regardless of that" - or "bastard semi-threaded semi-not-threaded", if you like) If you don't like it, don't use it, simple as that. -Chris From cpressey@REDACTED Fri Mar 21 19:27:57 2003 From: cpressey@REDACTED (Chris Pressey) Date: Fri, 21 Mar 2003 12:27:57 -0600 Subject: Extending Functionality: gen_server_ext In-Reply-To: <15994.63508.125246.558481@antilipe.corelatus.se> References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D496@esemont203.gbg.edt.ericsson.se> <15994.63508.125246.558481@antilipe.corelatus.se> Message-ID: <20030321122757.2d896aae.cpressey@catseye.mb.ca> On Fri, 21 Mar 2003 12:31:32 +0100 Matthias Lang wrote: > > martin> While the ideas that are expressed in this thread are > martin> quite interesting and have much merit I think that they > martin> would serve to undermine erlangs greatest strength - > martin> simplicity. > > vlad> What we are talking about here about extendig Erlang, is > vlad> not really about the language, but about OTP. > > Changing the meaning of a function call is not about changing OTP. It > is changing the language. You can no longer be sure that the code > executed by a call to foo:bar() can be found in the module foo. > > That is a big new uncertainty. > > Matthias Is it really so new? -module(foo). bar() -> baz:quuz(). i.e.: 1. you can't design a language which disallows spaghetti. 2. the more powerful a language feature, the easier it makes spaghetti. 3. when you introduce a new feature that makes spaghetti easier, you should probably make a note of that lest it looks like you're encouraging it. Other than that... I do agree that Erlang is, if not simple, then straightforward, and any proposed extension that doesn't meet a sort of common straightforwardness criterion will likely not be adopted. -Chris From cpressey@REDACTED Fri Mar 21 20:04:18 2003 From: cpressey@REDACTED (Chris Pressey) Date: Fri, 21 Mar 2003 13:04:18 -0600 Subject: Extending Functionality: gen_server_ext In-Reply-To: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D497@esemont203.gbg.edt.ericsson.se> References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D497@esemont203.gbg.edt.ericsson.se> Message-ID: <20030321130418.2c4ce19c.cpressey@catseye.mb.ca> On Fri, 21 Mar 2003 11:22:01 +0100 "Vlad Dumitrescu (EAW)" wrote: > Hello, > > > From: Jay Nelson [mailto:jay@REDACTED] > >Chris and Vlad discussed: > >> Extensions to gen_server to support "behavers" and pseudo > >> inheritance call chains ... (aside: just to clarify: "behaver" is not a new thing, it's a coined term for "a module which implements a behaviour"... which Erlangers write every day, but don't seem to have a non-specific word for - they tend to use the name of the specific behaviour that they're implementing as in "I've written a gen_server" rather than "I've written a behaver for gen_server") > [...] > What I'd like to be able to do is create a process by specifying > several interfaces/behaviours it will support, a GUI related example > might be for a button: I need let's say 'drawable', 'clickable', > 'mouse_over'. Just by naming them, I get the functionality, -module(my_button). -behaviour(drawable). -behaviour(clickable). -behaviour(mouse_over). ? > and I can > (if I want) to override some of the functionality to better suit the > button's needs. before_draw(Button) -> % arbitrarily don't draw the button if it's on the right side case x(Button) of X when X > screen_width() / 2 -> cancel; _ -> ok end. ? > Potential problem: how to ensure that these behaviours do not have > overlapping interfaces? (i.e. message tags or callback names that are > the same) Prepend a tag? -Chris From spearce@REDACTED Fri Mar 21 20:24:15 2003 From: spearce@REDACTED (Shawn Pearce) Date: Fri, 21 Mar 2003 14:24:15 -0500 Subject: Extending Functionality: gen_server_ext In-Reply-To: <20030321122757.2d896aae.cpressey@catseye.mb.ca> References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D496@esemont203.gbg.edt.ericsson.se> <15994.63508.125246.558481@antilipe.corelatus.se> <20030321122757.2d896aae.cpressey@catseye.mb.ca> Message-ID: <20030321192415.GA1296@spearce.org> Chris, I think Matthias' concern was more related to overloading the undefined_function behavior in error_handler, or some similiarly abstract way of making a function call. Even my -inherit() and dispatch function I proposed would fall here, as it makes the code signifcantly harder to follow. At least now you can lookup module foo, locate the definition of bar and see it calls baz:quuz(), and recurse. :) One of the things I like about Erlang is just how simple it is. It only takes me 5 minutes to locate the definition of almost any system function, even if it is down deep in the emulator's native C code. That's hard to do in most other current 'high-level' programming languages. (I use the term 'high-level' loosely too.) Lately I've been reading about just how flawed SQL databases are from Codd's relational model introduced in '69. I'm starting to feel the same way about object oriented programming in general, and I'm just hoping that the same tendenacies that caused programmers to build, adopt and eventually believe that SQL databases are perfect, true relational systems doesn't cause Erlang to grow into a simliar type of system. On the other hand, I just wrote a server for which I use two gen_server processes to implement a TCP server. (Like what was kicking around here a week or two ago.) Only I wanted support of both gen_tcp and ssl, and in both passive and active modes (I use {active, once}). Can we say macros, include files, and just some weird magic to make it work? Its not as bad as I'd feared (5 macros, 1 major source file, 2 module files to set the 5 macros and include the major source file), but its still not ideal. Chris Pressey wrote: > On Fri, 21 Mar 2003 12:31:32 +0100 > Matthias Lang wrote: > > Changing the meaning of a function call is not about changing OTP. It > > is changing the language. You can no longer be sure that the code > > executed by a call to foo:bar() can be found in the module foo. > > > > That is a big new uncertainty. > > > > Matthias > > Is it really so new? > > -module(foo). > bar() -> baz:quuz(). -- Shawn. "I think trash is the most important manifestation of culture we have in my lifetime." - Johnny Legend From chris_pressey@REDACTED Fri Mar 21 22:57:27 2003 From: chris_pressey@REDACTED (Chris Pressey) Date: Fri, 21 Mar 2003 16:57:27 -0500 (EST) Subject: Extending Functionality Message-ID: <20030321215727.71524.qmail@web20504.mail.yahoo.com> Shawn Pearce wrote: > Chris, I think Matthias' concern was more related to overloading > the undefined_function behavior in error_handler, or some similiarly > abstract way of making a function call. Even my -inherit() and > dispatch function I proposed would fall here, as it makes the code > signifcantly harder to follow. At least now you can lookup module > foo, locate the definition of bar and see it calls baz:quuz(), > and recurse. :) Yes... I took it as a general comment, since gen_server_ext falls here too (next_call makes the redirection from one module to another less explicit). The rule of thumb I'm using here is: the easier it is to write code in layers, the harder it will be to follow the code. On one extreme you have OO-maniacs valuing the ease of writing code in layers (inheritance) above all else, under the mistaken impression this will lead to infinite code reuse that will save everyone lots of time and money in the future. On the other extreme you have OO-phobics reinventing the wheel because it's quicker and/or more efficient to rewrite it (in Erlang, anyway) than to locate existing code that does exactly what they want. The only important question (to me) is where the maintainability of one of these approaches eclipses the maintainability of the other. Based on history I don't doubt the optimal point is closer to the OO-phobic end of the scale, but at the same time it would feel wrong to settle on the status quo - we have to keep experimenting and looking for a more optimal point, if only to fatten the accumulated body of knowledge about *why* alternate approaches to reuse don't provide any benefits over what we already use... -Chris ______________________________________________________________________ Post your free ad now! http://personals.yahoo.ca From vlad_dumitrescu@REDACTED Sat Mar 22 22:51:46 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Sat, 22 Mar 2003 22:51:46 +0100 Subject: Extending Functionality: gen_server_ext References: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D497@esemont203.gbg.edt.ericsson.se> <20030321130418.2c4ce19c.cpressey@catseye.mb.ca> Message-ID: Hi all, First, I got a link from Vladimir Sekissov (thanks a lot!) for something very close to what I in mind (but not as well-thought as in the paper, of course). I wouldn't stop at just GUIs, however. http://citeseer.nj.nec.com/gansner93multithreaded.html From: "Chris Pressey" > > What I'd like to be able to do is create a process by specifying > > several interfaces/behaviours it will support, a GUI related example > > might be for a button: I need let's say 'drawable', 'clickable', > > 'mouse_over'. Just by naming them, I get the functionality, > > -module(my_button). > -behaviour(drawable). > -behaviour(clickable). > -behaviour(mouse_over). Not really, this means we have a module where we will have to implement callbacks for all these behaviours. If 80% of those are just delegating the work away, then I think it's a waste of effort. Also you can't dynamically add/remove behaviours. Also to Shawn: I agree that being able to see from the code what a call will result in is good, but it is possible (and done) today too to have a server holding a list of callbacks that clients have registered - you can't know in the code which ones will be present at runtime. I don't think it's a fundamental difference... Or one could send a Fun to be called in another process - if that fun was received from somewhere else, then it can't be traced without scanning the whole system. I couldn't see any warning in the Programming Rules about this... Otherwise, Chris' and other's comments are pertinent and I mostly agree (where I don't, it really is a matter of taste). I will repeat that I don't think this suggestion I made is The True Solution (tm), just like I don't think Erlang is perfect and will never need any improvements. One way that will probably please most, is the one Jay proposed first, to use many simple cooperating processes (and this is also done in the paper mentioned before). A remaining question is how to easily connect together these processes so that they work as they should. I am thinking about it. BTW, a not directly related question: let's consider a process that receives input (messages) and just dispatches them to a number of registered clients. Is this okay to do? It's not possible to trace where the messages go from just inspecting the code, but I think it is a very useful functionality. best regards, Vlad From cpressey@REDACTED Sun Mar 23 19:03:17 2003 From: cpressey@REDACTED (Chris Pressey) Date: Sun, 23 Mar 2003 12:03:17 -0600 Subject: problem building R9B-1 crypto under FreeBSD 4.8-RC2 Message-ID: <20030323120317.7d67f7af.cpressey@catseye.mb.ca> This is on a fresh FreeBSD 4.8-RC2 install (well, virtually fresh - I did one 'make update / make world' on it, last night, and there were only a handful of diffs.) I think (am guessing) this might have something to do with the recent import of openssl 0.97 into 4.8-RC2. gmake[4]: Entering directory `/tmp/otp_src_R9B-1/lib/crypto/c_src' /usr/bin/install -c -d ../priv/obj/i386-unknown-freebsd4.8 gcc -c -o ../priv/obj/i386-unknown-freebsd4.8/crypto_drv.o -g -O2 -I/tmp/otp_src_R9B-1/erts/i386-unknown-freebsd4.8 -DHAVE_CONFIG_H -O2 -I/usr/include/openssl -I/usr/include -I /tmp/otp_src_R9B-1/erts/emulator/beam crypto_drv.c crypto_drv.c: In function `control': crypto_drv.c:370: cannot convert to a pointer type crypto_drv.c:372: incompatible type for argument 4 of indirect function call crypto_drv.c:384: cannot convert to a pointer type crypto_drv.c:385: cannot convert to a pointer type crypto_drv.c:386: cannot convert to a pointer type crypto_drv.c:389: incompatible type for argument 4 of indirect function call crypto_drv.c:389: incompatible type for argument 5 of indirect function call crypto_drv.c:389: incompatible type for argument 6 of indirect function call gmake[4]: *** [../priv/obj/i386-unknown-freebsd4.8/crypto_drv.o] Error 1 -Chris From cpressey@REDACTED Sun Mar 23 19:38:22 2003 From: cpressey@REDACTED (Chris Pressey) Date: Sun, 23 Mar 2003 12:38:22 -0600 Subject: goats Message-ID: <20030323123822.6b015967.cpressey@catseye.mb.ca> Regarding my musing on mdisp; Shawn's response is very reasonable in the context of mdisp. That context, however, is just what I want to avoid. For mdisp, Ulf says "the threads themselves believe they stay up permanently"[1]. I want to go one step further: the entities in question themselves aren't even aware if they're threads or not (!) I've decided to call the entities in question 'goats'. This is because goats are cute, and they have square pupils. (In other words - there is no good reason - at this point 'goat' is no less accurate than 'object' or 'thread' or 'dispatcher' would be.) Clearly one of the main reasons Ulf wrote mdisp was for performance (packing more processes into the runtime than would otherwise fit, leveraging ETS when it scales better than processes, etc;) for me, that's just a bonus. The main reason I'm writing a framework for 'goats' is because I want to see what it is like coding in a style which abstracts away as much of the difference between (dynamic) servers and (static) structures as possible. I'm not even sure it's fair to say that goats are concurrent at this point; probably better to say that goats are 'temporally independent') Hope this clarifies some. If you want to see my code so far, I added lib/ce/src/ce_goat.erl to Jungerl. -Chris [1] the threads do react to an 'awaken' callback, so one could infer that they are at least superficially aware that they were asleep. From kent@REDACTED Sun Mar 23 19:46:05 2003 From: kent@REDACTED (Kent Boortz) Date: 23 Mar 2003 19:46:05 +0100 Subject: problem building R9B-1 crypto under FreeBSD 4.8-RC2 In-Reply-To: <20030323120317.7d67f7af.cpressey@catseye.mb.ca> References: <20030323120317.7d67f7af.cpressey@catseye.mb.ca> Message-ID: Chris Pressey writes: > This is on a fresh FreeBSD 4.8-RC2 install (well, virtually fresh - I did > one 'make update / make world' on it, last night, and there were only a > handful of diffs.) I think (am guessing) this might have something to do > with the recent import of openssl 0.97 into 4.8-RC2. Hopefully the patch from Jimmy Olgeni included below will correct this problem, kent Building with OpenSSL 0.9.7 requires this patch: --- lib/crypto/c_src/crypto_drv.c.orig Thu Oct 21 15:37:08 1999 +++ lib/crypto/c_src/crypto_drv.c Mon Mar 3 15:12:27 2003 @@ -29,6 +29,7 @@ #include #include "erl_driver.h" +#define OPENSSL_DES_LIBDES_COMPATIBILITY #include "des.h" #include "md5.h" #include "sha.h" From jay@REDACTED Sun Mar 23 19:50:42 2003 From: jay@REDACTED (Jay Nelson) Date: Sun, 23 Mar 2003 10:50:42 -0800 Subject: Extending Functionality: gen_server_ext Message-ID: <4.2.2.20030323101442.00cdb4e0@duomark.com> martin j logan wrote: >This whole notion feels distinctly un-erlang. Erlang is simple, >straight forward and fairly consistent, that is what makes it great. ... >While the ideas that are expressed in this thread are quite >interesting and have much merit I think that they would serve >to undermine erlangs greatest strength - simplicity. Eric Newhuis wrote: >I agree. I am interested in hearing what makes you say that. I am wrestling with ideas and thinking out loud, so any reactions are extremely helpful in reformulating my opinions. I have proposed no change to the language and no change to the way an erlang process operates. Where my goals differ from Chris' goals is that I am new to having cheap, easy processes and would like to exploit them to their fullest (he may already be beyond that by a couple orders of magnitude in the number of processes and is thinking of other things). I believe that writing a very simple process, with almost no error checking, has great advantage. I would rather waste processes than waste programming time and effort struggling with the mundane aspects of a program. I want to spend my time thinking of the system level integration, throughput, distribution and limits rather than which functional decomposition is correct. My discussion centered on the communication mechanisms among processes, considering these alternatives: 1) a <--> b <--> c <--> d <--> user 2) a <---->| b <---->| <--> d <--> user c <---->| where each of a, b, c and d are processes. I was proposing that #2 is a richer model, #1 can be used on the back end of a, b, and c, that a, b, and c can be dynamically added and removed from d (consider that d is a UI textbox process and that c is the 'editable' set of behaviours -- if it is not present the textbox is not editable). Vlad wrote: >Potential problem: how to ensure that these behaviours do not >have overlapping interfaces? (i.e. message tags or callback >names that are the same) This is a good and fundamental question that is right on the mark. What I am trying to propose is a method for code reuse that does not bind up discrete, rigid, pre-architected objects into a monolithic application. Each process is closer to an abstract datatype than an object (but I still refrain from making that assumption). In my earlier post on uses of processes I mentioned: >3) Code reuse / abstraction / adapting interfaces. Process d in #2 above abstracts the gen_server interface to the user. It *also* abstracts the gen_server interface to the backend processes. a,b,c and have no higher level knowledge, d contains higher level knowledge and that is why I correlated it to a supervisor rather than a gen_server; it acts like a gen_server but it is init'ed and controlled like a supervisor with dynamic children. If any of the backend process have overlapping interfaces, the task of building an instance of d includes interjecting 'shim' processes to eliminate ambiguity in message passing. The author of a,b,c cannot anticipate the places where they may be used; the author of d does not have access to modify the internals of a,b,c because that will break other code that relies on them. Instead he might introduce a new process 'e' which transforms messages coming from b and c so that they are not ambiguous to d. This approach encourages having a,b,c do exactly what they are intended to do and nothing more or nothing less, without requiring d to introduce message disambiguation code which detracts from algorithms d is really concerned with implementing. e becomes one of your extremely simple erlang processes that are easy to test and easy to see when they are not implemented correctly (the process fails and communications break down). The integrator rummages through the process toolbox and at runtime declares which tools are bound together in which way to get the desired results. jay From jay@REDACTED Sun Mar 23 19:59:56 2003 From: jay@REDACTED (Jay Nelson) Date: Sun, 23 Mar 2003 10:59:56 -0800 Subject: What are processes good for? Message-ID: <4.2.2.20030323105223.00cdadc0@duomark.com> In a previous post (http://www.erlang.org/ml-archive/erlang-questions/200303/msg00282.html) I listed some ideas: > 1) Modeling real world concurrent activities. > 2) Strong encapsulation > 3) Code reuse / abstraction / adapting interfaces. > 4) Simulating environmental influences. > 5) Creating unpredictable, complex behaviour / adaptive behaviour > 6) Resource management / distribution I have a new one to add: 7) Partitioning for fault isolation purposes / instrumenting data flow Inter-process communication is a fundamental concept in erlang. The language provides bifs for sending / receiving messages and for trapping a process that fails unexpectedly. One source of unexpected failure is unexpected input. Isolating a failing function in a separate process means that the datastream in and out of the function can be monitored in realtime without interference with the rest of the system (potentially even on a different node) or modification to the failing function itself. Likewise, whenever a dataflow measurement is desired, a process boundary can be introduced with the data being fed to both the instrumenting process and the follow on process. This can be implemented in a way analogous to error_logger so that multiple processes can contribute data that are compiled and organized using a single mechanism. jay From jay@REDACTED Sun Mar 23 20:14:27 2003 From: jay@REDACTED (Jay Nelson) Date: Sun, 23 Mar 2003 11:14:27 -0800 Subject: eXene Message-ID: <4.2.2.20030323110413.00cff6b0@duomark.com> eXene is the user interface writting in Concurrent ML that Vlad & Vlad referred to. I am about half way through the article and see a lot of similarity in what I have been thinking about, but one big dissimilarity. They are using the X server model and still view an 'application' as a desirable thing. I am thinking a little more radically in trying to eliminate objects, and thus am trying to eliminate applications. I really don't want anything that is statically pre-architected. I detest static type checking, I found erlang because Java objects forced me to structure my code in ways that did not mirror the medium it was running on and web services are less applications than collections of tasks. I don't want to reimplement the same UI in a different language, I would rather think about a wholly new approach to UI. I have been thinking mainly about processes, streams and how they fit together. User input arrives from the Universal Serial Bus nowadays, so it is expected to be a stream of actions. Monitors are also a serial device, but they use 2 dimensions to allow random access of data more easily. Why not view the UI as a pool of data that is streamed out? My biggest problem with OO and applications is that they rigidly impose _one_ interpretation and force the user to deal with that model. As a user I would rather restructure my display based on the tasks I need to accomplish, not based on the applications that I have installed. If the computer is a general-purpose machine why are the programs not general-purpose? jay From cpressey@REDACTED Sun Mar 23 20:32:36 2003 From: cpressey@REDACTED (Chris Pressey) Date: Sun, 23 Mar 2003 13:32:36 -0600 Subject: problem building R9B-1 crypto under FreeBSD 4.8-RC2 In-Reply-To: References: <20030323120317.7d67f7af.cpressey@catseye.mb.ca> Message-ID: <20030323133236.7cae7d3f.cpressey@catseye.mb.ca> On 23 Mar 2003 19:46:05 +0100 Kent Boortz wrote: > Hopefully the patch from Jimmy Olgeni included below > will correct this problem, > > kent It did. Much obliged. For some reason I never got into the habit of installing Erlang from ports, it probably wouldn't have been an issue then. -Chris From jay@REDACTED Sun Mar 23 20:45:34 2003 From: jay@REDACTED (Jay Nelson) Date: Sun, 23 Mar 2003 11:45:34 -0800 Subject: Pools, pipes and filters or Stream Algebra Message-ID: <4.2.2.20030323111437.00cdb760@duomark.com> How can I accomplish a task? This is what I really want to do rather than use an application. Around 1990 people were asking me if they should buy a PC. I usually said no because they had no reason for one and no task that they wanted to accomplish. They just thought they should have one. I started thinking about why the average user couldn't do anything with a computer, and why it was hopeless for most to try to write a program. I concluded that it was because everything was abstract and there were no constraints on how things could be constructed. The most powerful and flexible tool is useless to all but the trained professional, but a screwdriver can be used by nearly everyone. I embarked on a mental exercise designing a Rube-Goldbergian programming language that consisted of physical devices and an analog language replete with flashlights, spinning slotted disks, paper punches and light sensors. A hopeless exercise, but it was driven by the belief that observable behavior and feedback is easier for the average person to understand than abstract concepts. My goal at the time was a simple quest: how would an average person use their computer to check if they had won the Lotto each week, by writing their own program. It is a much more difficult task than expected and I came away convinced that if such a simple task was as impossible as it seemed, computers were useless to the populace (and actually programmers can do great harm to the populace by misleading them with programs they don't understand -- look at all the spyware and viruses that now circulate and the potential for propaganda unlike anything seen on TV since the impressionable computer user believes that he is in control). Lately I've been worried about load balancing, distributed computing, process management, code reuse and dynamic UIs. I want to look at the problems holistically rather than individually. Iterative and OO languages subliminally make you reason about individual objects or single situations and prevent you from seeing how the system works as a dynamic, adaptive organism. I want to think about the life of the system, the range of data it will ever see, the ebb and tide of data flows, the whirlpools of local data feedback and the dispersal of results all at once and try to perceive where the real issues will occur. I also want to do this analysis and modelling without having to implement the underlying detailed functionality. Earlier discussions talked about piping processes together and building dynamic, cooperative sets of processes. My current view of what was traditionally called an 'application' is a pool of data that resides in the computer and streams that affect that pool. The user is a pump that supplies new data to the pool. Filters are imposed between the user and the trusted pool that represents the current internal state to keep it from being contaminated. The user's requests may cause the display to reconfigure so that the view he sees is appropriate for the task he is currently concerned about. The screen is a pool that can siphon from the data model pool or can receive pumped data from the data model. Filters are what eliminate errors, remove redundant or unwanted data, reduce the volume based on system constraints or user constraints or otherwise transform the data before arriving at a pool. Splitters, repeaters and replicators can be used to handle multiple pools from a single stream or to replenish pools that leak. Multiple streams can likewise be coalesced with a composite filter to generate a single pool. Ultimately I would be interested in a Stream Algebra that encompasses streams and the operations that may occur on them, axioms and theories of computation equivalence using the algebra and an implementation of the operators inherent in such an algebra. Given such an algebra it seems that graphical tools for developing a system would be much easier to use than that which OO promised to deliver. I envision something that a plumber would feel very comfortable working with on screen. jay From cpressey@REDACTED Sun Mar 23 20:55:22 2003 From: cpressey@REDACTED (Chris Pressey) Date: Sun, 23 Mar 2003 13:55:22 -0600 Subject: ensure_started In-Reply-To: References: Message-ID: <20030323135522.409db3de.cpressey@catseye.mb.ca> On Fri, 21 Mar 2003 16:22:12 +0100 (MET) Peter H|gfeldt wrote: > On Feb 1, 1997 I wrote the following, addressed to the OTP developing > team. I think it is still valid. > [...] > Put the register/2 part in the Module:init function, so that > the newly created process fails (and terminates if properly > programmed) if the name is already registered. Then there > will be at most one process doing 'the thing'. Wow, six years... This got me thinking. Although this may sound a bit harsh - isn't register/2 perhaps a design flaw? If it were register/1, and always applied to self(), it would force you code process registration this way, by the newly created process. Is there ever a truly convincing reason to register a process that isn't self()? > [...] > Concurrency is more difficult than you believe." I believe it :) I was wondering if there's a similar case when a process dies. Is there a way to absolutely ensure that a process'es mailbox is empty before it dies? Especially if more than one process is sending messages to the process. Example: server() -> receive {Pid, Data} -> Reply = do_stuff(Data), Pid ! Reply, server(); shut_yourself_down -> % --> mightn't we get another message right here? % --> if we do, the sender will never get a reply exit(was_shut_down) end. -Chris From svg@REDACTED Sun Mar 23 19:07:23 2003 From: svg@REDACTED (Vladimir Sekissov) Date: Sun, 23 Mar 2003 23:07:23 +0500 (YEKT) Subject: ensure_started In-Reply-To: <20030323135522.409db3de.cpressey@catseye.mb.ca> References: <20030323135522.409db3de.cpressey@catseye.mb.ca> Message-ID: <20030323.230723.130241433.svg@surnet.ru> Good day, loop() -> receive Msg -> do_something, loop(); please_die -> receive Msg -> % there are some messages, continue loop() after 0 -> % nobody wants to talk to me exit(shutdown) end end. Best Regards, Vladimir Sekissov cpressey> I was wondering if there's a similar case when a process dies. Is there a cpressey> way to absolutely ensure that a process'es mailbox is empty before it cpressey> dies? Especially if more than one process is sending messages to the cpressey> process. Example: cpressey> cpressey> server() -> cpressey> receive cpressey> {Pid, Data} -> cpressey> Reply = do_stuff(Data), cpressey> Pid ! Reply, cpressey> server(); cpressey> shut_yourself_down -> cpressey> % --> mightn't we get another message right here? cpressey> % --> if we do, the sender will never get a reply cpressey> exit(was_shut_down) cpressey> end. cpressey> cpressey> -Chris From etxuwig@REDACTED Sun Mar 23 21:42:47 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Sun, 23 Mar 2003 21:42:47 +0100 (MET) Subject: ensure_started In-Reply-To: <20030323135522.409db3de.cpressey@catseye.mb.ca> Message-ID: On Sun, 23 Mar 2003, Chris Pressey wrote: >I was wondering if there's a similar case when a process >dies. Is there a way to absolutely ensure that a >process'es mailbox is empty before it dies? Especially if >more than one process is sending messages to the process. The mdisp contrib has a pattern for this. The simplest way to check from the outside if a process has any messages pending is process_info(P, message_queue_len), which returns the length of P's message queue. The mdisp 'sleep' protocol was designed to handle the killing of temporary threads without losing any messages, and without consuming any messages detected during the 'sleep' negotiation. That last one may be of minor importance, but I think that the administrative code should leave it to the programmer to receive his own messages. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From etxuwig@REDACTED Sun Mar 23 22:01:50 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Sun, 23 Mar 2003 22:01:50 +0100 (MET) Subject: goats In-Reply-To: <20030323123822.6b015967.cpressey@catseye.mb.ca> Message-ID: On Sun, 23 Mar 2003, Chris Pressey wrote: >Clearly one of the main reasons Ulf wrote mdisp was for >performance (packing more processes into the runtime than >would otherwise fit, leveraging ETS when it scales better >than processes, etc;) True. Although I don't quite recall who wrote the first incarnation of mdisp. It would be Peter Lundell or Mats Cronqvist. It could well have been Kurt Jonsson, but I recall him being on holiday at the time. (: Ola Samuelsson originally (1996) wrote a multi_fsm(*) -- a version of gen_fsm that handled lots of gen_fsm instances in the same process. Mdisp was the successor of that model. We did actually discuss the mdisp model already back then, but for various odd reasons, we didn't get around to actually trying it out until years later. The mdisp model has proven better in at least one respect: With multiple FSMs sharing the same process, all operations must be non-blocking (or at least never block for long). This led to asynchronous programming, which is very difficult to handle. Inventing ways to "raise the ceiling" was a higher priority before OTP R9, since Erlang "only" supported 32,000 simultaneous processes. Now, with support for 262,000 processes, mdisp has lost some of its original justification. It may still be useful for other reasons (or in cases where roughly 200,000 simultaneous processes is still not enough. ;) /Uffe (*) If memory serves me, Ola also wrote the gen_fsm behaviour, as well as the original 'gs'. -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From cpressey@REDACTED Sun Mar 23 22:58:50 2003 From: cpressey@REDACTED (Chris Pressey) Date: Sun, 23 Mar 2003 15:58:50 -0600 Subject: ensure_started In-Reply-To: <20030323.230723.130241433.svg@surnet.ru> References: <20030323135522.409db3de.cpressey@catseye.mb.ca> <20030323.230723.130241433.svg@surnet.ru> Message-ID: <20030323155850.452c4eff.cpressey@catseye.mb.ca> On Sun, 23 Mar 2003 23:07:23 +0500 (YEKT) Vladimir Sekissov wrote: > Good day, > > loop() -> > receive > Msg -> > do_something, > loop(); > please_die -> > receive > Msg -> % there are some messages, continue > loop() > after 0 -> % nobody wants to talk to me Is there a guarantee that you won't get a message right here? > exit(shutdown) > end > end. > > Best Regards, > Vladimir Sekissov -Chris From svg@REDACTED Sun Mar 23 21:29:51 2003 From: svg@REDACTED (Vladimir Sekissov) Date: Mon, 24 Mar 2003 01:29:51 +0500 (YEKT) Subject: ensure_started In-Reply-To: <20030323155850.452c4eff.cpressey@catseye.mb.ca> References: <20030323135522.409db3de.cpressey@catseye.mb.ca> <20030323.230723.130241433.svg@surnet.ru> <20030323155850.452c4eff.cpressey@catseye.mb.ca> Message-ID: <20030324.012951.104031136.svg@surnet.ru> Good day, cpressey> > after 0 -> % nobody wants to talk to me cpressey> cpressey> Is there a guarantee that you won't get a message right here? >From "Concurent Programming in Erlang" p.76: A timeout of 0 means that the timeout will occur immediately, but the system tries all messages currently in the mailbox first If your mailbox is empty you haven't time to receive any other message if you exit immediately. I believe that mailbox scanning is atomic operation. There were some explanations in this list how system changes management policy for processes with huge mailboxes. Best Regards, Vladimir Sekissov cpressey> > loop() -> cpressey> > receive cpressey> > Msg -> cpressey> > do_something, cpressey> > loop(); cpressey> > please_die -> cpressey> > receive cpressey> > Msg -> % there are some messages, continue cpressey> > loop() cpressey> > after 0 -> % nobody wants to talk to me cpressey> cpressey> Is there a guarantee that you won't get a message right here? cpressey> cpressey> > exit(shutdown) cpressey> > end cpressey> > end. cpressey> > cpressey> > Best Regards, cpressey> > Vladimir Sekissov cpressey> cpressey> -Chris From cpressey@REDACTED Mon Mar 24 04:15:28 2003 From: cpressey@REDACTED (Chris Pressey) Date: Sun, 23 Mar 2003 21:15:28 -0600 Subject: Extending Functionality: gen_server_ext In-Reply-To: <4.2.2.20030323101442.00cdb4e0@duomark.com> References: <4.2.2.20030323101442.00cdb4e0@duomark.com> Message-ID: <20030323211528.4c5c2187.cpressey@catseye.mb.ca> On Sun, 23 Mar 2003 10:50:42 -0800 Jay Nelson wrote: > I have proposed no change to the language and no change > to the way an erlang process operates. Where my goals differ from > Chris' goals is that I am new to having cheap, easy processes > and would like to exploit them to their fullest (he may already > be beyond that by a couple orders of magnitude in the number > of processes and is thinking of other things). Nah, I've just got a wicked conservative streak (literally, not politically) verging on Luddism - and a bad case of NIH ;) No matter how cheap processes are, I'd just never feel quite right modelling things that strike me as "really static" with them. At the same time, I'm a big proponent of orthogonality - parts should interchangeable, with general rules which have only as many exceptions as truly necessary. Same goes for simplicity - things should be as simple as possible, but *no simpler* (or you'll lose something valuable.) I have been having some problems following most of this thread lately because it does seem to be getting rather involved and in danger of being bogged down in minutiae. But, I probably just need to think about it more; gimme a couple more days... -Chris From cpressey@REDACTED Mon Mar 24 07:39:01 2003 From: cpressey@REDACTED (Chris Pressey) Date: Mon, 24 Mar 2003 00:39:01 -0600 Subject: Pools, pipes and filters or Stream Algebra In-Reply-To: <4.2.2.20030323111437.00cdb760@duomark.com> References: <4.2.2.20030323111437.00cdb760@duomark.com> Message-ID: <20030324003901.30ab013e.cpressey@catseye.mb.ca> On Sun, 23 Mar 2003 11:45:34 -0800 Jay Nelson wrote: > How can I accomplish a task? This is what I really want to > do rather than use an application. False dilemma, isn't it? An application is what you use to accomplish a task, pretty much by definition. > [...] The most powerful and flexible tool is useless to > all but the trained professional, but a screwdriver can be used > by nearly everyone. In this case, the screwdriver is the "application" - the task is removing or installing a screw. In other words, I'm not sure if you want constraints on how things are constructed, or not, as you've now given arguments for both sides. I'm assuming that you do, but you want looser constraints than are commonly found at present. I agree with the spirit of your approach, I think, but I find I'm having more and more trouble grasping the letter of it. > [...] > Ultimately I would be interested in a Stream Algebra that encompasses > streams and the operations that may occur on them, axioms and theories > of computation equivalence using the algebra and an implementation of > the operators inherent in such an algebra. Given such an algebra it > seems that graphical tools for developing a system would be much easier > to use than that which OO promised to deliver. I envision something > that a plumber would feel very comfortable working with on screen. > > jay As someone who *has* developed Rube-Goldbergesque programming languages (cited in the Hacker's Dictionary, no less :) I think you are making an error here. You're merely substituting one skilled trade (computer programming) for another skilled trade (plumbing.) I don't think computers will empower the *average* individual until AI & SR advance to a point where a human can simply ask their computer, a la Star Trek, "Computer, how did my lotto numbers do?" To put it another way: say you develop a stream algebra. Would it really help you see problems in a holistic manner, or would it merely colour your perceptions in a *different* subliminal way (not that that would necessarily be a bad thing)? I'm afraid there is no rule for how to break rules, nor any formal system for analyzing things unsystematically... if you try to put chaos in a box, it becomes order. To put it yet another way, you said it yourself: the most powerful and flexible tool is useless to all but the trained professional. Packaging functionalities into applications trades off power and flexibility for usability in the hands of the average person. How do you have your cake and eat it too? I could go on about this (probably for several pages) but you're a bright person and you surely get the thrust of what I'm saying. Specifically as it relates to a GUI: I agree that applications are not the best abstraction for what to present in a UI. Applications are behind the scenes and the user shouldn't have to think about them - they will be more productive if they can focus on *what* they are doing, not what *with*. However that's not just the task itself - it is the current state of the task - i.e. their work-in-progress. A text document, rather than a text editor or the activity of editing text; a web page, rather than a web browser or the notion of surfing the 'net; a spreadsheet rather than Excel or number-crunching, and so forth. For that reason - because people deal with objects so easily (even if it is often to their detriment), I wouldn't dismiss object-orientation out of hand. -Chris From Vlad.Dumitrescu@REDACTED Mon Mar 24 09:01:51 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Mon, 24 Mar 2003 09:01:51 +0100 Subject: eXene Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D4A1@esemont203.gbg.edt.ericsson.se> Hi, > I am thinking a little more radically in trying to eliminate > objects, and thus am trying to eliminate applications. I > really don't want anything that is statically pre-architected. This might be another case of "name confusion", but I don't see how one can do without applications. The starting point has to be a need for a certain functionality. Then one has to implement it in some way and when one wants to use it, one has to be able to tell the system "I need the XYZ functionality". The system then has to figure out what it needs to be able to provide that functionality. The place taht holds all the links to relevant code/data/information is just the application (or at least that's how I call it). > I don't want to reimplement the same UI in a different language, > I would rather think about a wholly new approach to UI. Yes, me too, but since there are no good enough low-level graphics packages implemented for Erlang yet, we have to use what is already here: X, or OpenGL, or something else. > Why not view the UI as a pool of data that is streamed out? Very reasonable :-) > As a user I would rather restructure > my display based on the tasks I need to accomplish, not > based on the applications that I have installed. If the computer > is a general-purpose machine why are the programs not > general-purpose? Oh, just wait until DotNet comes!! :-D regards, Vlad From rprice@REDACTED Mon Mar 24 01:00:57 2003 From: rprice@REDACTED (Roger Price) Date: Mon, 24 Mar 2003 01:00:57 +0100 (CET) Subject: Arranging arguments for speed Message-ID: Given a function such as f(X,alpha) -> ...; f(X,bravo) -> ...; ..... f(X,zebra) -> ... ., would it run faster if re-written as g(alpha,X) -> ...; g(bravo,X) -> ...; ..... g(zebra,X) -> ... . ? It was certainly the case for a Prolog system I once used, and I wondered if Erlang also used a hash of the function name and the first argument to find the clause. Roger From etxuwig@REDACTED Mon Mar 24 09:37:36 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Mon, 24 Mar 2003 09:37:36 +0100 (MET) Subject: ensure_started In-Reply-To: <20030324.012951.104031136.svg@surnet.ru> Message-ID: On Mon, 24 Mar 2003, Vladimir Sekissov wrote: >Good day, > >cpressey> > after 0 -> % nobody wants to talk to me >cpressey> >cpressey> Is there a guarantee that you won't get a message right here? > >From "Concurent Programming in Erlang" p.76: > > A timeout of 0 means that the timeout will occur immediately, > but the system tries all messages currently in the mailbox first > >If your mailbox is empty you haven't time to receive any >other message if you exit immediately. > >I believe that mailbox scanning is atomic operation. There >were some explanations in this list how system changes >management policy for processes with huge mailboxes. Mailbox scanning is an atomic operation, yes, but there is of course still a chance that you will be scheduled out before the exit(shutdown). In the case of mdisp, this is not considered a problem, since the process should only go to sleep in places where the next message always comes through mdisp (the rule being: it's OK for temporary processes to talk directly to each other in transition states, but in stable state, messages need to go through the mdisp process; alternatively, all messages always go through the mdisp process.) /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From thomasl_erlang@REDACTED Mon Mar 24 11:21:57 2003 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Mon, 24 Mar 2003 02:21:57 -0800 (PST) Subject: Arranging arguments for speed In-Reply-To: Message-ID: <20030324102157.38713.qmail@web13305.mail.yahoo.com> --- Roger Price wrote: > Given a function such as > > f(X,alpha) -> ...; > f(X,bravo) -> ...; > ..... > f(X,zebra) -> ... ., > > would it run faster if re-written as > > g(alpha,X) -> ...; > g(bravo,X) -> ...; > ..... > g(zebra,X) -> ... . ? > > It was certainly the case for a Prolog system I once > used, and I wondered > if Erlang also used a hash of the function name and > the first argument to > find the clause. There is luckily no need for that. The BEAM compiler uses a more flexible algorithm than most Prologs. (The reason is roughly that unification is hairier than pattern matching, so one normally has to be more conservative in a Prolog compiler.) Try 'erl -S foo.erl' to get the BEAM code for foo and see if it looks right. Best, Thomas __________________________________________________ Do you Yahoo!? Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop! http://platinum.yahoo.com From Vlad.Dumitrescu@REDACTED Mon Mar 24 11:57:37 2003 From: Vlad.Dumitrescu@REDACTED (Vlad Dumitrescu (EAW)) Date: Mon, 24 Mar 2003 11:57:37 +0100 Subject: Pools, pipes and filters or Stream Algebra Message-ID: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D4A4@esemont203.gbg.edt.ericsson.se> Hi, Just a short comment this time :-) > Ultimately I would be interested in a Stream Algebra that encompasses > streams and the operations that may occur on them, axioms and theories > of computation equivalence using the algebra and an implementation of > the operators inherent in such an algebra. Given such an > algebra it seems > that graphical tools for developing a system would be much > easier to use > than that which OO promised to deliver. For example, http://www.dcs.shef.ac.uk/~ajc/dfa/ or a much heavier one at http://www4.informatik.tu-muenchen.de/reports/TUM-I9620.html Search with Google for "flow algebra" I have to confess it seemed like heavy for me, possibly because I don't have studied the basics of the domain. But it might be what's needed... regards, Vlad From joe@REDACTED Mon Mar 24 12:49:06 2003 From: joe@REDACTED (Joe Armstrong) Date: Mon, 24 Mar 2003 12:49:06 +0100 (CET) Subject: ensure_started In-Reply-To: Message-ID: On Fri, 21 Mar 2003, Peter H|gfeldt wrote: > > On Feb 1, 1997 I wrote the following, addressed to the OTP developing > team. I think it is still valid. > > /Peter > > "Sometimes I see code like the following (in real applications or in > examples in documents): > > start(Name, Module, Args) -> > case whereis(Name) of > undefined -> > Pid = spawn(Module, init, Args), > register(Name, Pid), > Pid; > Other -> > Other > end. > > That is bad programming: > ... etc. Indeed it is :-) - I often wonder why we made spawn/3 a primitive and not just spawn a "universal" empty process and then send it a message telling it what to do. Pid = spawn() Pid ! Fun() where spawn() -> spawn(fun() -> receive Fun -> Fun() end end). This is particularly useful when you need to setup sets of mutually recursive processes, then you can say: Pid1 = spawn() Pid2 = spawn(), Pid1 ! fun() -> ... Pid2 ... end, Pid2 ! fun() -> ... Pid1 ... end, /Joe From etxuwig@REDACTED Mon Mar 24 13:03:39 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Mon, 24 Mar 2003 13:03:39 +0100 (MET) Subject: ensure_started In-Reply-To: Message-ID: On Mon, 24 Mar 2003, Joe Armstrong wrote: >I often wonder why we made spawn/3 a primitive and not just >spawn a "universal" empty process and then send it a >message telling it what to do. > > > Pid = spawn() > Pid ! Fun() > >where > > spawn() -> > spawn(fun() -> > receive > Fun -> > Fun() > end > end). > > This is particularly useful when you need to setup sets >of mutually recursive processes, then you can say: > > Pid1 = spawn() > Pid2 = spawn(), > Pid1 ! fun() -> ... Pid2 ... end, > Pid2 ! fun() -> ... Pid1 ... end, > > /Joe Interesting... but how long should a universal process live before it gives up waiting for a fun thing to do? Or should empty unreferenced processes be garbage-collected? This would require a unified heap, or reference-counted pids. Oh well, nothing that couldn't have been solved. (: BTW, the reason you didn't do this from the beginning was that Erlang didn't have funs back then. ;-) /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From joe@REDACTED Mon Mar 24 13:03:42 2003 From: joe@REDACTED (Joe Armstrong) Date: Mon, 24 Mar 2003 13:03:42 +0100 (CET) Subject: Arranging arguments for speed In-Reply-To: <20030324102157.38713.qmail@web13305.mail.yahoo.com> Message-ID: erlc -S ... works even better :-) I tried this with f(X,alpha) -> a; f(X,bravo) -> b; f(X,zebra) -> c. g(alpha,X) -> a; g(bravo,X) -> b; g(zebra,X) -> c. Looking in the object code file You'll see it generated {function, f, 2, 2}. {label,1}. {func_info,{atom,test},{atom,f},2}. {label,2}. {test,is_atom,{f,1},[{x,1}]}. {select_val,{x,1}, {f,1}, {list,[{atom,zebra}, {f,3}, {atom,bravo}, {f,4}, {atom,alpha}, {f,5}]}}. ... and {function, g, 2, 7}. {label,6}. {func_info,{atom,test},{atom,g},2}. {label,7}. {test,is_atom,{f,6},[{x,0}]}. {select_val,{x,0}, {f,6}, {list,[{atom,zebra}, {f,8}, {atom,bravo}, {f,9}, {atom,alpha}, {f,10}]}}. ... In other words - logically *identical* code - which is as it should be. /Joe On Mon, 24 Mar 2003, Thomas Lindgren wrote: > > --- Roger Price wrote: > > Given a function such as > > > > f(X,alpha) -> ...; > > f(X,bravo) -> ...; > > ..... > > f(X,zebra) -> ... ., > > > > would it run faster if re-written as > > > > g(alpha,X) -> ...; > > g(bravo,X) -> ...; > > ..... > > g(zebra,X) -> ... . ? > > > > It was certainly the case for a Prolog system I once > > used, and I wondered > > if Erlang also used a hash of the function name and > > the first argument to > > find the clause. > > There is luckily no need for that. The BEAM compiler > uses a more flexible algorithm than most Prologs. (The > reason is roughly that unification is hairier than > pattern matching, so one normally has to be more > conservative in a Prolog compiler.) > > Try 'erl -S foo.erl' to get the BEAM code for foo and > see if it looks right. > > Best, > Thomas > > > __________________________________________________ > Do you Yahoo!? > Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop! > http://platinum.yahoo.com > From richardc@REDACTED Mon Mar 24 13:10:00 2003 From: richardc@REDACTED (Richard Carlsson) Date: Mon, 24 Mar 2003 13:10:00 +0100 (MET) Subject: ensure_started In-Reply-To: References: Message-ID: On Mon, 24 Mar 2003, Joe Armstrong wrote: > Indeed it is :-) - I often wonder why we made spawn/3 a primitive and > not just spawn a "universal" empty process and then send it a message > telling it what to do. > [...] > This is particularly useful when you need to setup sets of > mutually recursive processes, then you can say: > > Pid1 = spawn() > Pid2 = spawn(), > Pid1 ! fun() -> ... Pid2 ... end, > Pid2 ! fun() -> ... Pid1 ... end, However, when you set up processes like that, things can easily go wrong. If a process (Pid2 above) first of all enters a state where it expects to be told what to do next, and another process (Pid1) thinks that it's OK to talk to Pid2, then if the scheduler plays a little trick on you, the message from Pid1 to Pid2 can arrive before the "startup" message, and the program crashes. If you still want to do it this way for some reason, you will have to establish two distinct phases. As an example, I once had a simple program that set up a ring of processes. It all worked well, until I upped the number of processes in the ring over some limit (a couple of hundred) - at which time the scheduler started running some of the first spawned processes before the ring was completed. This would not have been a problem if the processes had not been expecting an initialization message before they heard from their neighbours. /Richard Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) E-mail: Richard.Carlsson@REDACTED WWW: http://user.it.uu.se/~richardc/ "Having users is like optimization: the wise course is to delay it." -- Paul Graham From C.Reinke@REDACTED Mon Mar 24 13:45:31 2003 From: C.Reinke@REDACTED (C.Reinke) Date: Mon, 24 Mar 2003 12:45:31 +0000 Subject: eXene In-Reply-To: Message from Jay Nelson of "Sun, 23 Mar 2003 11:14:27 PST." <4.2.2.20030323110413.00cff6b0@duomark.com> Message-ID: [some random thoughts, triggered by your message:-] > I have been thinking mainly about processes, streams and > how they fit together. User input arrives from the Universal > Serial Bus nowadays, so it is expected to be a stream of > actions. Monitors are also a serial device, but they use > 2 dimensions to allow random access of data more easily. > Why not view the UI as a pool of data that is streamed out? Functional languages, especially non-strict ones, have had a long history of using networks of mutually recursive stream processors to model operating systems, IO and GUIs. It kind of worked, but never seemed to be a satisfactory solution, and functional IO approaches have moved on to focus on more modular compositions of single message/activation/response-structures instead of whole streams. But that's probably what you mean anyway. Fudgets http://www.cs.chalmers.se/ComputingScience/Research/Functional/Fudgets/ were a fairly recent functional GUI approach based on stream-processors, so their publications should have references to most earlier approaches. (for the general process/stream-model, dataflow languages and Petri nets may be useful search keywords). Btw: I've often thought that high-level Petri nets (with functional inscription languages) would make a good modeling language for functional programs, especially when concurrency is so central as it is in Erlang. Is there anyone out here who's using both Erlang and Petri nets? Or at least knows about Petri nets and thinks this combination would have some merit?-) [for those who haven't come accross Petri nets, see: http://www.daimi.au.dk/PetriNets/ ] > My biggest problem with OO and applications is that they > rigidly impose _one_ interpretation and force the user to > deal with that model. As a user I would rather restructure > my display based on the tasks I need to accomplish, not > based on the applications that I have installed. If the computer > is a general-purpose machine why are the programs not > general-purpose? OO is perhaps not as bad as some of its fans make it seem: "The early history of Smalltalk", Alan C Kay (in: History of Programming Languages II, 1996) http://portal.acm.org/citation.cfm?id=155364&dl=ACM&coll=portal "..[dynabook vs mainframe].. ; millions of potential users meant that the user interface would have to become a learning environment along the lines of Montessori and Bruner; and needs for large scope, reduction in complexity, and end-user literacy would require that data and control structures be done away with in favor of a more biological scheme of protected universal cells interacting only through messages that could mimic any desired behavior. Early Smalltalk was the first complete realization of these new points of view as parented by its many predecessors in hardware, language and user interface design." "Smalltalk's design -and existence- is due to the insight that everything we can describe can be represented by the recursive composition of a single kind of behavioural building block that hides its combination of state and process inside itself and can be dealt with only through the exchange of messages." "In computer terms, Smalltalk is a recursion on the notion of computer itself. Instead of dividing 'computer stuff' into things each less than the whole -such as data structures, procedures, and functions that are the usual paraphernalia of programming languages- each Smalltalk object is a recursion of the entire posssibilities of the computer. Thus its semantics are a bit like having thousands and thousands of computers all hooked together by a very fast network." Sounds pretty general-purpose (and concurrent) to me. "I made up the term 'object-oriented', and I can tell you I didn't have C++ in mind" - Alan Kay, OOPSLA '97 Was he thinking of Erlang instead?-) Well, almost. But Smalltalk also addressed what I call the "applications considered harmful" aspect, which your messages also seem to refer to: in Smalltalk, you didn't take a programming language and implemented lots of stand-alone applications, to be shipped to customers in isolation; instead, you evolved and extended your favourite general-purpose programming environment to be able to express the things you wanted to say in your favourite problem domains. Another way I like to phrase it: users are not dummies, they are domain experts (though their domain is usually not computers or software); they don't want computer experts to give them lots of words (applications), they need a tailor-made language in which they can express their domain knowledge to tackle their daily problems. Hope that wasn't too far off topic, Claus From raimo.niskanen@REDACTED Mon Mar 24 13:52:24 2003 From: raimo.niskanen@REDACTED (Raimo Niskanen) Date: Mon, 24 Mar 2003 13:52:24 +0100 Subject: gen_server:format_status/2 only works with registered processes References: <20030320213604.GZ25555@frogman.motivity.ca> Message-ID: Vance Shipley wrote: > OK, I found the problem. The following patch to lists.erl does it: > > *** lists.erl.dist Thu Mar 20 17:56:16 2003 > --- lists.erl Thu Mar 20 17:58:26 2003 > *************** > *** 280,285 **** > --- 280,286 ---- > thing_to_list(X) when integer(X) -> integer_to_list(X); > thing_to_list(X) when float(X) -> float_to_list(X); > thing_to_list(X) when atom(X) -> atom_to_list(X); > + thing_to_list(X) when pid(X) -> pid_to_list(X); > thing_to_list(X) when list(X) -> X. %Assumed to be a string > > %% flatten(List) > I am sorry, I do not think that is the correct(tm) solution. It seems that lists:thing_to_list/1 handles items that look the same in a parseable Erlang source file as when printed. Some types that are missing are: pid(), port(), reference(), all not parseable from their string representation. So I think it is gen_server:format_status/2 that is faulty, trying to call lists:concat/1 with a pid(). See the diff following. / Raimo Niskanen, Erlang/OTP Note that the following diff might not patch as it is since it is not from the R9B-1 version of the file. *************** *** 670,676 **** %%----------------------------------------------------------------- format_status(Opt, StatusData) -> [PDict, SysState, Parent, Debug, [Name, State, Mod, _Time]] = StatusData, ! Header = lists:concat(["Status for generic server ", Name]), Log = sys:get_debug(log, Debug, []), Specfic = case erlang:function_exported(Mod, format_status, 2) of --- 670,681 ---- %%----------------------------------------------------------------- format_status(Opt, StatusData) -> [PDict, SysState, Parent, Debug, [Name, State, Mod, _Time]] = StatusData, ! NameTag = if pid(Name) -> ! pid_to_list(Name); ! atom(Name) -> ! Name ! end, ! Header = lists:concat(["Status for generic server ", NameTag]), Log = sys:get_debug(log, Debug, []), Specfic = case erlang:function_exported(Mod, format_status, 2) of > > > -Vance > > Vance Shipley > Motivity Telecom Inc. > +1 519 240 3684 > vances@REDACTED > > On Thu, Mar 20, 2003 at 04:36:04PM -0500, Vance Shipley wrote: > } > } Now the problem is that, at least in R9B-[0|1], this only works if the > } process is registered! In the following example I am peeking at a > } couple gen_server processes the system runs. I am referring to each > } by PID but the process which is not registerd fails. > ... > } Error in process <0.25.0> with exit value: {function_clause,[{lists,thing_to_list,[<0.23.0>]},{lists,flatmap,2},{gen_server,format_status,2},{erl_eval,expr,3},{erl_eval,exprs,4},{shell,eval_loop,2}]} > } Vance Shipley wrote: > Background > > Both gen_server.erl and gen_fsm.erl have a (undocumented) function > which is used to pretty print the persistent data they keep. The > way it works is that you first call sys:get_status/1 (documented) > to retrieve the process's status and then format the state data > in a contextually relevant way with gen_[server|fsm]:format_status/2. > The nice thing is that gen_[server|fsm]:format_status/2 will check > to see if the user's callback module has exported a format_status/2 > and if so it will call that function to get an even more contextually > relevant way to present the data. I find this all very handy. > > Problem > > Now the problem is that, at least in R9B-[0|1], this only works if the > process is registered! In the following example I am peeking at a > couple gen_server processes the system runs. I am referring to each > by PID but the process which is not registerd fails. > > -Vance > > > $ erl > Erlang (BEAM) emulator version 5.2.3.3 [source] [hipe] [threads:0] > > Eshell V5.2.3.3 (abort with ^G) > 1> i(). > Pid Initial Call Heap Reds Msgs > Registered Current Function Stack > ... > <0.17.0> code_server:init/1 377 46225 0 > code_server gen_server:loop/6 12 > ... > <0.23.0> kernel_config:init/1 233 45 0 > gen_server:loop/6 12 > ... > > 2> {_,_,_,StatusData} = sys:get_status(list_to_pid("<0.17.0>")), > 2> gen_server:format_status([], StatusData). > [{header,"Status for generic server code_server"}, > {data,[{"Status",running},{"Parent",<0.9.0>},{"Logged events",[]}]}, > {data,[{"State", > {state,"/usr/local/lib/erlang", > [".", > "/usr/local/lib/erlang/lib/kernel-2.8.1.1/ebin", > "/usr/local/lib/erlang/lib/stdlib-1.11.4.1/ebin", > "/usr/local/lib/erlang/lib/webtool-0.7.1/ebin", > "/usr/local/lib/erlang/lib/tv-2.0.4/ebin", > "/usr/local/lib/erlang/lib/tools-2.2/ebin", > "/usr/local/lib/erlang/lib/toolbar-1.1.0/ebin", > "/usr/local/lib/erlang/lib/ssl-2.3.5/ebin", > "/usr/local/lib/erlang/lib/snmp-3.3.8/ebin", > "/usr/local/lib/erlang/lib/sasl-1.9.4/ebin", > "/usr/local/lib/erlang/lib/runtime_tools-1.3/ebin", > "/usr/local/lib/erlang/lib/pman-2.4.1/ebin", > "/usr/local/lib/erlang/lib/parsetools-1.2/ebin", > "/usr/local/lib/erlang/lib/os_mon-1.6.0.2/ebin", > "/usr/local/lib/erlang/lib/orber-3.4/ebin", > "/usr/local/lib/erlang/lib/observer-0.9.3/ebin", > "/usr/local/lib/erlang/lib/mnesia_session-1.1.5/ebin"|...], > 9, > 10, > interactive}}]}] > 3> f(StatusData). > ok > 4> {_,_,_,StatusData} = sys:get_status(list_to_pid("<0.23.0>")), > 4> gen_server:format_status([], StatusData). > ** exited: {function_clause,[{lists,thing_to_list,[<0.23.0>]}, > {lists,flatmap,2}, > {gen_server,format_status,2}, > {erl_eval,expr,3}, > {erl_eval,exprs,4}, > {shell,eval_loop,2}]} ** > > =ERROR REPORT==== 20-Mar-2003::16:31:37 === > Error in process <0.25.0> with exit value: {function_clause,[{lists,thing_to_list,[<0.23.0>]},{lists,flatmap,2},{gen_server,format_status,2},{erl_eval,expr,3},{erl_eval,exprs,4},{shell,eval_loop,2}]} > From jay@REDACTED Mon Mar 24 15:35:23 2003 From: jay@REDACTED (Jay Nelson) Date: Mon, 24 Mar 2003 06:35:23 -0800 Subject: Pools, pipes and filters or Stream Algebra In-Reply-To: <5F03ACA2F76DD411B8BC00508BE3B4D713D8D4A4@esemont203.gbg.ed t.ericsson.se> Message-ID: <4.2.2.20030324063418.00d20b60@duomark.com> At 11:57 AM 3/24/03 +0100, you wrote: >For example, >http://www.dcs.shef.ac.uk/~ajc/dfa/ Excellent! Just what I was looking for! >or a much heavier one at >http://www4.informatik.tu-muenchen.de/reports/TUM-I9620.html I had this one. It was too heavy for me. jay From jay@REDACTED Mon Mar 24 15:47:00 2003 From: jay@REDACTED (Jay Nelson) Date: Mon, 24 Mar 2003 06:47:00 -0800 Subject: eXene In-Reply-To: References: <4.2.2.20030323110413.00cff6b0@duomark.com> Message-ID: <4.2.2.20030324063946.00d207e0@duomark.com> C. Reinke wrote: > [for those who haven't come accross Petri nets, see: > http://www.daimi.au.dk/PetriNets/ ] I had forgotten about these. Will read up to jog my memory. >Sounds pretty general-purpose (and concurrent) to me. I like the sounds of the concurrent processes interpretation. OO seems so different than what he described. I never did any SmallTalk, but read the SmallTalk 80 book to learn about design. I liked it at the time, but the class hierarchy was so big it seemed difficult to become proficient. I really wanted to code it after reading the book, though. > "I made up the term 'object-oriented', and I can tell you I didn't > have C++ in mind" - Alan Kay, OOPSLA '97 Bingo. That is very funny! >Another way I like to phrase it: users are not dummies, they are >domain experts (though their domain is usually not computers or >software); they don't want computer experts to give them lots of >words (applications), they need a tailor-made language in which they >can express their domain knowledge to tackle their daily problems. I like this. I had overlooked the fact that the users are domain experts. That is a good concept to keep in mind. jay From matthias@REDACTED Mon Mar 24 16:31:20 2003 From: matthias@REDACTED (Matthias Lang) Date: Mon, 24 Mar 2003 16:31:20 +0100 Subject: unsolicited Erlang job request Message-ID: <15999.9416.355041.517889@antilipe.corelatus.se> Hi, I don't know anything about the job, Brian or OCC-computing. I'm posting it to the list in case someone else is interested. I'm not. Be careful. It may be a scam---I have no idea where they got my address from, which makes it sus. Matt ---------------------------------------------------------------------- From: Brian Harris To: matthias@REDACTED Subject: SS7/ERLANG Date: Mon, 24 Mar 2003 14:44:24 +0000 For a swedish mobile comms company near Kista we are looking for a senior sw engineer with development experience of Erlang and experience of ss7 networks.Are you still interested in such roles? Brian Harris OCC Computer Personnel 108 Welsh Row Nantwich Cheshire CW5 5EY Tel. +44 (0) 1270 627206 Fax. +44 (0) 1270 629168 For a list of current vacancies then please visit: http://www.occ-computing.co.uk/vacancies.htm From jay@REDACTED Mon Mar 24 16:11:01 2003 From: jay@REDACTED (Jay Nelson) Date: Mon, 24 Mar 2003 07:11:01 -0800 Subject: Pools, pipes and filters or Stream Algebra In-Reply-To: <20030324003901.30ab013e.cpressey@catseye.mb.ca> References: <4.2.2.20030323111437.00cdb760@duomark.com> <4.2.2.20030323111437.00cdb760@duomark.com> Message-ID: <4.2.2.20030324065006.00d0b100@duomark.com> Chris Pressey wrote: >In other words, I'm not sure if you want constraints on how things are >constructed, or not, as you've now given arguments for both sides. I'm >assuming that you do, but you want looser constraints than are commonly >found at present. I agree with the spirit of your approach, I think, but >I find I'm having more and more trouble grasping the letter of it. As a user I don't want the layout and tools all predetermined. In an email client I have a composer, folders and a browser. Sometimes I want that and sometimes I want a different layout and different ways of finding and organizing things. Why only folders? Often I want the email data in my word processor or database or address book. Why does the data have to be divided by application? Why can't the data just be data and let me operate on it or view it in whatever fashion I choose from among the set of tools that are available to me? The real issue is that "applications" are goal oriented. They are designed to achieve a specific goal that is presumably optimized to the most commonly desired goals of general users of the application. Now that we have more processing power, it should be possible to store data in a general fashion and optimize it on the fly as the computer adapts to the user's desire rather than the other way around. There are constraints on the simple tools that I might use to manipulate the data, but there shouldn't be constraints on when they are available and what I can do to the data. Hints and suggestions for error situations maybe, but not complete out-and-out prevention. >To put it another way: say you develop a stream algebra. Would it really >help you see problems in a holistic manner, or would it merely colour your >perceptions in a *different* subliminal way (not that that would >necessarily be a bad thing)? Yes you are right. Applications were designed during the era of time-shared computing and carried over to the single user disconnected PC. As such they partitioned and restricted the user to best utilize the limited resources. Today we have networked processors, stateless transactions and dynamically assembled groups of computers performing peer-to-peer tasks. A new paradigm is necessary to take advantage of today's reality. The stream algebra is for me to develop a tool for the building of systems. The purpose of the algebra is to be able to reason about and prove the interchangeability of computational elements. The "plumber's tool" I referred to is the system designer's tool -- a trained professional. What is constructed with this tool is an ecosystem of processes and data that the user can hook together in many different ways dynamically as they interact with the system. I want to receive email that I can excerpt and sort in a database that can be reassembled into a document or HTML page, without having to deal with three "applications" but by just manipulating the data on my computer. Cut and paste shouldn't have to exist; when someone posts code on this email list I would like to try it out while I am reading the email message. Unfortunately, I blurred the distinction between designer tools and end user tools since in this case I am performing both roles. jay From vlad_dumitrescu@REDACTED Mon Mar 24 16:59:09 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Mon, 24 Mar 2003 16:59:09 +0100 Subject: Pools, pipes and filters or Stream Algebra References: <4.2.2.20030323111437.00cdb760@duomark.com> <4.2.2.20030323111437.00cdb760@duomark.com> <4.2.2.20030324065006.00d0b100@duomark.com> Message-ID: Jay wrote: > As a user I don't want the layout and tools all predetermined. In an > email client I have a composer, folders and a browser. Sometimes > I want that and sometimes I want a different layout and different ways > of finding and organizing things. Why only folders? Often I want the > email data in my word processor or database or address book. Why > does the data have to be divided by application? Why can't the data > just be data and let me operate on it or view it in whatever fashion I > choose from among the set of tools that are available to me? You mean, for example have a window open on a file, mark out some text and the right-button menu will say: View As -> Word processing Database Email CAD something else? Most conversions can be done automatically, and some of this is already present in today's file managers, so it's not really a technical problem, I suppose, but the implied paradigm shift for users as well as developers? regards, Vlad From per@REDACTED Mon Mar 24 17:07:01 2003 From: per@REDACTED (Per Bergqvist) Date: Mon, 24 Mar 2003 17:07:01 +0100 Subject: unsolicited Erlang job request In-Reply-To: <15999.9416.355041.517889@antilipe.corelatus.se> Message-ID: <200303241605.h2OG5YY32672@lejon.levonline.com> > > Be careful. It may be a scam---I have no idea where they got my > address from, which makes it sus. > Sounds like CellPoint #3 or #4 or whatever ... /Per :-) > Matt > > ---------------------------------------------------------------------- > From: Brian Harris > To: matthias@REDACTED > Subject: SS7/ERLANG > Date: Mon, 24 Mar 2003 14:44:24 +0000 > > For a swedish mobile comms company near Kista we are looking for a senior > sw engineer with development experience of Erlang and experience of ss7 > networks.Are you still interested in such roles? > > > Brian Harris > > > > OCC Computer Personnel > 108 Welsh Row > Nantwich > Cheshire > CW5 5EY > > Tel. +44 (0) 1270 627206 > Fax. +44 (0) 1270 629168 > > For a list of current vacancies then please visit: > http://www.occ-computing.co.uk/vacancies.htm > ========================================================= Per Bergqvist Synapse Systems AB Phone: +46 709 686 685 Email: per@REDACTED From garry@REDACTED Mon Mar 24 17:39:27 2003 From: garry@REDACTED (Garry Hodgson) Date: Mon, 24 Mar 2003 11:39:27 -0500 (EST) Subject: joe's beers Message-ID: <200303241639.LAA04032@sprache.sage.att.com> Chris Pressey wrote: > Thank you, Joe. I feel I owe you more than a few beer :) i think if everyone gave joe all the beers we owe him, he might never get any more code written. ---- "You've been telling lies so long Some believe they're true So they close their eyes to things You have no right to do" --- Steppenwolf From jhouchin@REDACTED Mon Mar 24 17:44:19 2003 From: jhouchin@REDACTED (Jimmie Houchin) Date: Mon, 24 Mar 2003 10:44:19 -0600 Subject: eXene In-Reply-To: <4.2.2.20030324063946.00d207e0@duomark.com> References: <4.2.2.20030323110413.00cff6b0@duomark.com> <4.2.2.20030324063946.00d207e0@duomark.com> Message-ID: <3E7F35E3.6040402@texoma.net> Anybody who is interested in looking at what Alan Kay and Smalltalk are doing try out Squeak. http://www.squeak.org There are several parallels between Squeak and Erlang. Each have their pros and cons. Squeak is a much better understanding of true OO than you will have found other places. That said, Squeak is looking for better ways to implement solutions. OO is one way, however the Squeak community is very open minded to other ways of expressing solutions. They are open to learning what other language communities have learned. While Squeak may not ever become a 'Functional' language you may find it interesting. There was a recent discussion on modeling things in a more 'declarative' manner. So with Squeak (not necessarily other Smalltalks) there is an openness for better solutions. Interestingly enough in regarding this thread, Squeak already does it's own GUI. It does not use native widgets. Squeak is very cross-platform to about 30-40 (I think) platforms currently. It is open source and ready to play. An OS is being written in Squeak called OpenCroquet. http://www.opencroquet.org Squeak currently isn't as proficient for massive parallel/concurrent applications as Erlang. But there is a desire to get there. Squeak is very much a living environment. It is very malleable and able to be changed while being used. Like the 'Hot Code Replacement' thread in comp.lang.functional. It's meant to staying running indefinitely. Not trying to hijack the Erlang list here. Just wanted to inform those who may be interested. Thanks, Jimmie Houchin Jay Nelson wrote: > C. Reinke wrote: > >> [for those who haven't come accross Petri nets, see: >> http://www.daimi.au.dk/PetriNets/ ] > > > > I had forgotten about these. Will read up to jog my memory. > > >> Sounds pretty general-purpose (and concurrent) to me. > > > > I like the sounds of the concurrent processes interpretation. > OO seems so different than what he described. I never did > any SmallTalk, but read the SmallTalk 80 book to learn about > design. I liked it at the time, but the class hierarchy was so > big it seemed difficult to become proficient. I really wanted to > code it after reading the book, though. > > >> "I made up the term 'object-oriented', and I can tell you I didn't >> have C++ in mind" - Alan Kay, OOPSLA '97 > > > > Bingo. That is very funny! > >> Another way I like to phrase it: users are not dummies, they are >> domain experts (though their domain is usually not computers or >> software); they don't want computer experts to give them lots of >> words (applications), they need a tailor-made language in which they >> can express their domain knowledge to tackle their daily problems. > > > > I like this. I had overlooked the fact that the users are domain > experts. That is a good concept to keep in mind. > > jay From cpressey@REDACTED Mon Mar 24 17:45:50 2003 From: cpressey@REDACTED (Chris Pressey) Date: Mon, 24 Mar 2003 10:45:50 -0600 Subject: ensure_started In-Reply-To: References: <20030324.012951.104031136.svg@surnet.ru> Message-ID: <20030324104550.4d26f088.cpressey@catseye.mb.ca> On Mon, 24 Mar 2003 09:37:36 +0100 (MET) Ulf Wiger wrote: > Mailbox scanning is an atomic operation, yes, but there is > of course still a chance that you will be scheduled out > before the exit(shutdown). > > In the case of mdisp, this is not considered a problem, > since the process should only go to sleep in places where > the next message always comes through mdisp (the rule being: > it's OK for temporary processes to talk directly to each > other in transition states, but in stable state, messages > need to go through the mdisp process; alternatively, all > messages always go through the mdisp process.) > > /Uffe My concern, when I pointed that out, was more about the thousands of plain servers and gen_servers that have been written, although mdisp might indeed provide some salvation for short-lived processes. I was also operating under the assumption that the following would, generally speaking, fail: list_to_pid("<0.400.0>") ! foo. Trying it from the shell, it doesn't, foo just goes into a black hole presumably. (now I better understand why some people use the phrase "send and pray") I guess the lesson to take from this is that it's good coding style to always use a finite timeout when waiting for a reply from something you're not linked to, because that reply simply may never show up no matter how carefully you code the server... ? -Chris From etxuwig@REDACTED Mon Mar 24 17:59:03 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Mon, 24 Mar 2003 17:59:03 +0100 (MET) Subject: ensure_started In-Reply-To: <20030324104550.4d26f088.cpressey@catseye.mb.ca> Message-ID: On Mon, 24 Mar 2003, Chris Pressey wrote: >I was also operating under the assumption that the >following would, generally speaking, fail: > > list_to_pid("<0.400.0>") ! foo. > >Trying it from the shell, it doesn't, foo just goes into a >black hole presumably. (now I better understand why some >people use the phrase "send and pray") However, reg_name ! foo _will_ fail if there is no process registered as 'reg_name'. >I guess the lesson to take from this is that it's good >coding style to always use a finite timeout when waiting >for a reply from something you're not linked to, because >that reply simply may never show up no matter how carefully >you code the server... ? Oh yes. (: Actually, monitors take care of the cases where the server dies before responding, but there are other cases where a timeout is really needed. Deadlocks due to rare combinations of events is one such occasion. Finite timeouts give a rather clear indication that something is not quite right. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From etxuwig@REDACTED Mon Mar 24 18:12:05 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Mon, 24 Mar 2003 18:12:05 +0100 (MET) Subject: ensure_started In-Reply-To: <20030324104550.4d26f088.cpressey@catseye.mb.ca> Message-ID: On Mon, 24 Mar 2003, Chris Pressey wrote: >My concern, when I pointed that out, was more about the >thousands of plain servers and gen_servers that have been >written, although mdisp might indeed provide some salvation >for short-lived processes. I'm not sure if it's possible, or even relevant to solve the general case of a server trying to make sure that there are no more messages before it finally dies. After all, this is fundamentally a race condition. The dispatcher contrib had an example adaptation where gen_server-like processes were dispatched, and went to sleep automatically after a pre-configured idle period. It was not the most efficient, but the idea was to allow for a way to quickly turn gen_server processes into dispatched servers. There was once discussion about being able to give a process several registered names, allowing it to act as a proxy for temporary processes (I'm not sure if I do the idea justice - but I'm sure someone will correct me otherwise.) That might allow for a much cleaner adaptation to an mdisp model. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From luke@REDACTED Mon Mar 24 18:19:46 2003 From: luke@REDACTED (Luke Gorrie) Date: 24 Mar 2003 18:19:46 +0100 Subject: ensure_started In-Reply-To: References: Message-ID: Ulf Wiger writes: > >I guess the lesson to take from this is that it's good > >coding style to always use a finite timeout when waiting > >for a reply from something you're not linked to, because > >that reply simply may never show up no matter how carefully > >you code the server... ? > > Oh yes. (: > > Actually, monitors take care of the cases where the server > dies before responding, but there are other cases where a > timeout is really needed. Deadlocks due to rare combinations > of events is one such occasion. Finite timeouts give a > rather clear indication that something is not quite right. Perhaps one should really use gen:call for synchronous calls in home-made processes? I wonder if the occasionally-proposed "!!" synchronous message send could be neatly implemented as syntactic sugar for gen:call. Or perhaps !? for (gen:)call and !! for (gen:)reply. Too bad you can't tweak the language grammar with parse transforms alone to try this stuff :-) -Luke From svg@REDACTED Mon Mar 24 16:12:18 2003 From: svg@REDACTED (Vladimir Sekissov) Date: Mon, 24 Mar 2003 20:12:18 +0500 (YEKT) Subject: ensure_started In-Reply-To: <20030324104550.4d26f088.cpressey@catseye.mb.ca> References: <20030324.012951.104031136.svg@surnet.ru> <20030324104550.4d26f088.cpressey@catseye.mb.ca> Message-ID: <20030324.201218.78706332.svg@surnet.ru> Good day, cpressey> I guess the lesson to take from this is that it's good coding style to cpressey> always use a finite timeout when waiting for a reply from something you're cpressey> not linked to, because that reply simply may never show up no matter how cpressey> carefully you code the server... ? I usually use erlang:monitor/2 in such cases. You don't need to use timeout with it if you shure that process can only answer or die (no hungs). Small example from code I use with mdisp: %% We are implementing synchronous call to mdisp process, %% it answers with its Pid and after with actual Result disp_call(Name, Key, Args) -> mdisp_tt:send(Name, Key, {self(), continue, Args}), rec_answer(Key). rec_answer(Key) -> receive {Key, iam, Pid} -> Ref = erlang:monitor(process, Pid), receive {'DOWN', Ref, _, _, Reson} -> exit(Reson); {Key, Answer} -> erlang:demonitor(Ref), Answer end after 500 -> {error, {nothread, Key}} end. Best Regards, Vladimir Sekissov From cpressey@REDACTED Mon Mar 24 19:15:07 2003 From: cpressey@REDACTED (Chris Pressey) Date: Mon, 24 Mar 2003 12:15:07 -0600 Subject: Pools, pipes and filters or Stream Algebra In-Reply-To: <4.2.2.20030324065006.00d0b100@duomark.com> References: <4.2.2.20030323111437.00cdb760@duomark.com> <4.2.2.20030323111437.00cdb760@duomark.com> <4.2.2.20030324065006.00d0b100@duomark.com> Message-ID: <20030324121507.3e328c97.cpressey@catseye.mb.ca> On Mon, 24 Mar 2003 07:11:01 -0800 Jay Nelson wrote: > Chris Pressey wrote: > > >In other words, I'm not sure if you want constraints on how things are > >constructed, or not, as you've now given arguments for both sides. I'm > >assuming that you do, but you want looser constraints than are commonly > >found at present. I agree with the spirit of your approach, I think, > >but I find I'm having more and more trouble grasping the letter of it. > > As a user I don't want the layout and tools all predetermined. In an > email client I have a composer, folders and a browser. Sometimes > I want that and sometimes I want a different layout and different ways > of finding and organizing things. Why only folders? Often I want the > email data in my word processor or database or address book. Why > does the data have to be divided by application? Why can't the data > just be data and let me operate on it or view it in whatever fashion I > choose from among the set of tools that are available to me? Short answer is: because different tools make different assumptions about data. If you're working at the level of a hex editor, the data *is* just data and you can do whatever you like with it. But obviously humans want to work with data at a more human level. The problem is that there are infinitely many ways to arrange that. In order for different tools to interoperate, they need a common interchange system. Current interchange systems have achieved ubquity through two main ways: bottom-up expedience (hierarchical file systems, ASCII, etc) and top-down standards (XML, OLE, etc.) The first category tends to be too simple to be really flexible; the latter, too complex to be tractable. The first category tends to win out (witness virtually any MUA: ASCII messages in hierarchical folders.) If you want something more sophisticated, you have to select or create a standard. In order for the standard to actually provide an interchange benefit, *everything* on the computer (/network) has to work by the same (or compatible) standards. This is remarkably difficult (witness IPv6!), which is why progress towards it is remarkably slow. > The real issue is that "applications" are goal oriented. [...] I think that's unavoidable. I think the issue is that applications currently serve goals that are too elaborate for your tastes - you seem to want smaller, more single-purpose micro-applications (traditionally called 'utilities') which can be combined into composites as the user desires. This is not new, nor does it have anything to do with processor power as far as I can see. In fact, this is the old way, the way from a time before computers were ever thought of as personal possessions; from a time when all computer users had some skill at building things out of smaller things (and from when looking at all data through a hex editor was not out of the ordinary.) Once computers became a mass-market consumer product, the demand for more 'turnkeying' led to more packaging... just as it has in the food industry, for whatever that analogy is worth (TV dinners, anyone?) For better or worse, most people will prefer convenience to flexibility. Now this is just an explanation - it doesn't mean I like it any better than you. But the shortest route for those of us in the minority who prefer flexibility to prepackaging, for at least the next few years (possibly a lot longer,) will be to become programmers ourselves so we can change what we desire to change the most, to suit our own needs. > The stream algebra is for me to develop a tool for the building of > systems. The purpose of the algebra is to be able to reason about and > prove the interchangeability of computational elements. That's admirable, but the important question that occurs to me is what happens when you prove that two streams aren't interchangeable. If you're talking about a top-down approach, then you can define a standard which all streams follow, and you don't need to prove anything so long as you can reasonably guarantee that all streams do follow it. If you're talking about a bottom-up, ad-hoc approach, you'll never be able to guarantee that two arbitrary streams are interchangeable - so if someone sends you an stream you can't recognize, what do you do with it? Ideally, sure, a computer should just adapt to recognize it - but to do that it needs a description of it - or a hell of a lot of AI. Ignoring it is the only practical way to deal with it right now. And we already have that well established, streams or no, stream calculus or no. If I download a file in an unrecognized format, well, it's back to the ol' hex editor for me innit? This situation is mirrored in Erlang quite well, I think. If you want to send a message to a server, you have to know what kinds of messages that server will accept - you have to know its top-down structure. Or, you can ad-hoc send a message to a server that you hope it will understand. But even then, if you don't know for sure which messages the server will recognize, and what the server will do with unrecoginzed messages, you're taking a wild gamble... not the best way to ensure good results. The nice thing about Erlang is that it allows the ad-hoc approach, while a language with strict interfaces and strong typing generally forces you into the top-down structure (on the assumption that anything else has a likelihood of messing things up, which is often true.) Probably a middleground could be found in having a top-down structure which defines, as part of itself, an ad-hoc substructure... but even then there are still no guarantees, and it's hard to see how it could adapt to novel, unpredicted input, without being a programming language in its own right, which brings along its own dangers (even sandboxes can't overcome the Halting Problem :) -Chris From svg@REDACTED Mon Mar 24 17:38:32 2003 From: svg@REDACTED (Vladimir Sekissov) Date: Mon, 24 Mar 2003 21:38:32 +0500 (YEKT) Subject: Web related programming with mdisp In-Reply-To: References: Message-ID: <20030324.213832.112629109.svg@surnet.ru> Good day, Experimenting a lot with web related programming using mdisp and yaws I've found that I could write my programs in two major styles: 1. Application consists from mdisp managed processes communicating with mdisp. Advantages: It looks mostly like ordinary Erlang application Disadvantages: Big waste of resources especially in nondeterministic web interaction. All processes must communicate only with mdisp to be manageable in uniform way. Process management must be implemented explicitly by application (no links). 2. Writing application in Distel-like trampoline style, where application consists from custom threads and thread combinators. Every thread accepts only one argument(Yaws #arg{}) and return: {continue, Result, Continuation} | {die, Result} Result is displayed to the user and application dies or continue with Continuation waiting user response. Combinators are threads themselves and manage other threads constructing output stream. For example simple combinator which sequentially runs threads and calls next with result of previous as argument. Every thread can interact with user returning {continue, Result, Cont} arbitrary times, start subthreads etc... applyn([F]) -> fun (Arg) -> F(Arg) end; applyn([F|Fs]) -> Fun = fun (Arg) -> case F(Arg) of {continue, Res, Cont} -> continue(Res, applyn([Cont|Fs])); {die, Res} -> case Fs of [] -> die(Res); _ -> (applyn(Fs))(Res) end end end. Advantage: Lower waste of resources and ability to save whole application state on the user side if you want to switch from server-side store. The major disadvantage: not so natural programming style. I'm slightly in troubles which approach to use as major and would be glad to here your thoughts and suggestions. Best Regards, Vladimir Sekissov From vlad_dumitrescu@REDACTED Mon Mar 24 21:04:25 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Mon, 24 Mar 2003 21:04:25 +0100 Subject: Pools, pipes and filters or Stream Algebra References: <4.2.2.20030323111437.00cdb760@duomark.com> <20030324003901.30ab013e.cpressey@catseye.mb.ca> Message-ID: Hi, It occured to me that in order to provide a multi-process implementation for some functionality, so that this feature is transparent to the clients, we would need somehing like process groups. Using it, one could for example easily and dynamically extend Joe's mini-web server so that it can handle FTP requests, or anything asking for a file. However, the pg module is still experimental. Are there plans to develop it further? regards, Vlad From spearce@REDACTED Mon Mar 24 21:47:21 2003 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 24 Mar 2003 15:47:21 -0500 Subject: Pools, pipes and filters or Stream Algebra In-Reply-To: References: <4.2.2.20030323111437.00cdb760@duomark.com> <20030324003901.30ab013e.cpressey@catseye.mb.ca> Message-ID: <20030324204721.GB10608@spearce.org> I've thought that there are two things sort-of missing from the gen_* modules which would be nice to have: 1) Local version of pg, dispatching requests onto worker threads for long running operations, etc. Sort of a mini-mdisp or something. These are pretty easy to write in Erlang, but still somewhat hard. Would need to be able to limit the maximum number of worker processes, etc. I have a simple version of this type of service where there is a maximum number of workers to run and requests are queued up when this number is exceeded. Essentially an 'async' background process. 2) gen_tcp_server, a gen_server based generic TCP server to handle any protocol by handing the protocol to the callback module. Ideally this would also support the ssl application and support either plaintext or ssl sockets, but only require the callback module to implement one set of calls: init(Sock,Args) -> init the callback protocol handler with the newly accepted socket and the handler's arguments. handle_call(Req, From, State) -> standard gen_server handle_call/3. handle_cast(Req, State) -> standard gen_server handle_cast/2. handle_info(Req, State) -> standard gen_server handle_info/2. handle_socket({data, Sock, Data}, State) ->; handle_socket({closed, Sock} State) ->; handle_socket({error, Sock, Data}, State) ->; converting tcp, tcp_closed, tcp_error into data, closed, error, and ssl, ssl_closed, ssl_error into data, closed error. Thus one service module can handle either SSL or plaintext. or some such thing. Again, it should implement process controls, registration, proper socket handling, perhaps an ets table of all current connections, lookup of service process by connection info, admin tools to kill connections individually, etc. Even if either of both of these became commonly used user contribs that would be good. :) I can provide my current modules that I use for the above two cases, but I'm sure the Erlang masters have better ones to start from. Vlad Dumitrescu wrote: > Hi, > > It occured to me that in order to provide a multi-process implementation for > some functionality, so that this feature is transparent to the clients, we > would need somehing like process groups. Using it, one could for example > easily and dynamically extend Joe's mini-web server so that it can handle > FTP requests, or anything asking for a file. > > However, the pg module is still experimental. Are there plans to develop it > further? > > regards, > Vlad -- Shawn. tax office, n.: Den of inequity. From luke@REDACTED Tue Mar 25 00:38:03 2003 From: luke@REDACTED (Luke Gorrie) Date: 25 Mar 2003 00:38:03 +0100 Subject: Lovely UI toolkits (Was: Re: eXene) In-Reply-To: <3E7F35E3.6040402@texoma.net> References: <4.2.2.20030323110413.00cff6b0@duomark.com> <4.2.2.20030324063946.00d207e0@duomark.com> <3E7F35E3.6040402@texoma.net> Message-ID: Jimmie Houchin writes: > Anybody who is interested in looking at what Alan Kay and Smalltalk > are doing try out Squeak. > > http://www.squeak.org Yeah, Squeak is pretty amazing. BTW, I just tried out web browser written in Common Lisp under the free CLIM implementation. It isn't yet up to the standard of mozilla/opera/etc, but it's bloody impressive. Screenshot: http://www.bluetail.com/~luke/misc/closure.png Homepage: http://www.stud.uni-karlsruhe.de/~unk6/closure/ Took quite a bit of fiddling to get it up and running. Unfortunately it can't handle forms yet, so I can't google with it. However, CLIM does seem to be emerging as a candidate to replace/complement the only UI toolkit that I currently really like - Emacs. It's high time for a description of how lovely Emacs is. I haven't seen its virtues as a UI toolkit written up anywhere, and it's by far the most convenient one I've ever used - both as a programmer and as a suitably-brainwashed user. (Of course, I've never tried a Lisp machine..) To illustrate how convenient it is, here is a simple file-browsing program in the spirit of Windows Explorer. You tell it to browse a directory, and it presents a buffer listing the files and subdirectories. If you press return on one of them, it either opens it for editing (if it's a file) or "recursively" browses it (if it's a directory.) The program is less than 30 lines of code. It's implemented in two functions: one that generates a buffer showing the files in a directory and tagging each entry with useful semantic information; and one function that selects an entry in that buffer. Here's the main function for generating a directory list and recording semantic information: 01 (defun dirlist (dir) 02 "Display a buffer showing the contents of DIR. 03 Each filename is tagged with two text properties: 04 type - a symbol, either 'dir or 'file 05 path - the fully qualified path" 06 (interactive "DDirectory: ") 07 (unless (file-directory-p dir) 08 (error "Not a directory!")) 09 (pop-to-buffer (get-buffer-create "*Dirlist*")) 10 (erase-buffer) 11 (setq header-line-format (format "Directory listing of: %s" dir)) 12 (use-local-map dirlist-keymap) 13 (dolist (path (directory-files dir t)) 14 (let ((line (format "%s\n" (file-name-nondirectory path)))) 15 (insert (propertize line 16 'type (if (file-directory-p path) 'dir 'file) 17 'path path)))) 18 (goto-char (point-min))) Lines 1-5 are the function header. The function takes one argument: the directory to examine, called DIR. Note that the documentation string can be queried online with commands like describe-function, apropos, etc. Line 6 declares that it's an interactively callable command, i.e. that you can bind it to a key or invoke it with M-x. The first character "D" says that its argument is a directory, so Emacs will give you appropriate prompting and completion. The rest of the string is the prompt to display. Lines 7-8 make sure that the specified path is really a directory, and raise an error otherwise. Line 9 gets a buffer called *Dirlist* (creating it if necessary), then displays and selects it in "somewhere" on the screen - Emacs has heuristics to make it display in a good place. Line 10 nukes any contents of that buffer, which we may have from previous uses of this command. Line 11 sets up a banner across the top of the of the buffer's window, saying which directory it is listing. This banner is always displayed at the top line, even if you scroll in the buffer. Line 12 makes the buffer use a special local keymap, in addition to the default mappings. The keymap is defined below. Line 13 starts a loop over all the files in DIR - for each file it evaluates the enclosed expressions with "path" bound to the filename. The second argument to directory-files, 't', tells it to return absolute filenames. Line 14 creates the line of text that we will insert into this buffer: the filename (sans directory) followed by a newline. Lines 15-17 insert the line after added two "text properties": one called `type' containing `dir' or `file' as appropriate; one called `path' containing the fully qualified path. These properties are for our other command, which will extract them from the text to find out which file to act on. Line 18 jumps back to the beginning of the buffer, so that it will be displayed from the start. When you call that command with "M-x dirlist", you get a buffer on the screen showing all the files in the directory you specify, and each line is tagged with information for this next command which "visits" a directory entry: 19 (defun dirlist-visit () 20 "Visit the file or directory on the current line of a dirlist buffer." 21 (interactive) 22 (let ((path (get-text-property (point) 'path))) 23 (case (get-text-property (point) 'type) 24 (file (find-file path)) 25 (dir (dirlist (file-truename path)))))) Lines 19-20 are the header, and line 21 declares the command as interactive but taking no formal arguments. Line 22 retrieves the `path' text property at the current buffer position and puts it in a local variable. Lines 23-25 check the type of the entry: if it's a file, it calls the builtin `find-file' function (aka C-x C-f), if it's a directory it calls our `dirlist' command to display its contents - `file-truename' is used to canonicalise "." and "..". Pretty easy. Finally, here is the keymap that `dirlist' uses so that pressing return will visit an entry: 26 (defvar dirlist-keymap (make-sparse-keymap)) 27 (define-key dirlist-keymap [return] 'dirlist-visit) That's a pretty short and simple program. I personally wouldn't be able to write a similarly concise one with any other language/toolkit. (If people on this list are familiar with some toolkits that let you write such a program so easily, I'd really love to check out some code!) So, that is my case for Emacs being nice for the programmer. For the user, this `dirlist' program also has some desirable properties: all motion commands work perfectly with it - arrow keys, isearch, {start,end}-of-buffer, and even homemade ones. If you like you can show different parts of the buffer in different windows using standard window-manipulation commands, and do any of the other billion-or-two things that Emacs knows how to do with buffers. The universality [1] of Emacs commands is very nice for users. For example, I have some home-made motion commands for doing a manual binary-search to a particular line on the screen. These commands work with every Emacs program - mail readers, web browsers, text editing, etc. It doesn't matter that the authors of those programs might think the commands are arcane or silly - I wrote them, I like them, and I can use them in every single Emacs program. Truly, this is the Tao of programming. [1]: "universality" is a real word, according to the universally available Emacs spellchecker. NB 1: See also http://ww.telent.net/diary/2003/1/#14.28515 NB 2: Emacs already comes with a directory-listing program called "dired". It's about 5,000 lines of code, and I don't know many of its features. One day, when I learn all about it, I probably won't believe I ever lived without it. NB 3: I didn't get a chance to mention many of Emacs's other wonderful UI features, like builtin undo and "abort" (none of this "bugger, I can't click Cancel because I have an hourglass-pointer!") NB 4: To number the lines in the dired program, I wrote a small Emacs command. Now I can conveniently number source lines in emails, HTML or TeX documents, etc. So can you if you want, here is the command: (defun number-lines (start end) "Number lines in the region. Hardcoded for 2-digit numbering." (interactive "r") (goto-char start) (let ((end-marker (set-marker (make-marker) end)) (line 0)) (unwind-protect (while (< (point) end-marker) (incf line) (when (< line 10) (insert "0")) (insert (format "%S " line)) (next-line 1) (beginning-of-line)) (delete-marker end-marker)))) If you want to run the dired program, you can easily strip off the line numbers using the Emacs `kill-rectangle' (C-x r k) command. Cheers, Luke From ehz4@REDACTED Tue Mar 25 07:39:00 2003 From: ehz4@REDACTED (Edwin Zacharias) Date: Mon, 24 Mar 2003 22:39:00 -0800 (PST) Subject: Bit Syntax Problem Message-ID: <20030325063900.81671.qmail@web13202.mail.yahoo.com> I'm having a problem with the bit syntax in the following function: g() -> case <<0>> of <<0:1, _/binary>> -> true; _ -> false end. This should return true, but it returns false when I run it. However when I run just the body of the function in erl, it returns true. Is there something wrong with my function declaration? -Edwin __________________________________________________ Do you Yahoo!? Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop! http://platinum.yahoo.com From matthias@REDACTED Tue Mar 25 08:37:39 2003 From: matthias@REDACTED (Matthias Lang) Date: Tue, 25 Mar 2003 08:37:39 +0100 Subject: Bit Syntax Problem In-Reply-To: <20030325063900.81671.qmail@web13202.mail.yahoo.com> References: <20030325063900.81671.qmail@web13202.mail.yahoo.com> Message-ID: <16000.1859.603881.149016@antilipe.corelatus.se> Edwin Zacharias writes: > I'm having a problem with the bit syntax in the > following function: > > g() -> > case <<0>> of > <<0:1, _/binary>> -> true; > _ -> false > end. > > This should return true, but it returns false when I > run it. However when I run just the body of the > function in erl, it returns true. Is there something > wrong with my function declaration? The pattern <<0:1, _/binary>> is not allowed; the "unit" for binaries is 8 bits, which means that the whole expression will be a multiple of N*8 + 1 bits. That's not allowed. What you probably want to do is h() -> case <<0>> of <<0:1, _:7>> -> true; -> false end. the compiler could be a little more helpful by giving you a warning, but it doesn't. References: http://www.erlang.org/doc/r9b/doc/extensions/bit_syntax.html (in particular 6.6, which mentions a case similar to yours) Matthias From eleberg@REDACTED Tue Mar 25 10:36:48 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Tue, 25 Mar 2003 10:36:48 +0100 (MET) Subject: Lovely UI toolkits (Was: Re: eXene) Message-ID: <200303250936.h2P9ami26619@cbe.ericsson.se> > To: Jimmie Houchin > Cc: Jay Nelson , erlang-questions@REDACTED > Subject: Lovely UI toolkits (Was: Re: eXene) > From: Luke Gorrie ...deleted > It's high time for a description of how lovely Emacs is. when the time had come for me to move to a wimp environment (1990) emacs was not mouse aware. i choose sam, and later wily, instead. the ui toolkit is very restricted in wily. there are only the 3 mouse buttons, and the automagically created window panes. plus _any_ program i can run under unix. it works for me. http://www.cs.yorku.ca/~oz/wily bengt From luke@REDACTED Wed Mar 26 01:18:06 2003 From: luke@REDACTED (Luke Gorrie) Date: 26 Mar 2003 01:18:06 +0100 Subject: Distel 3.3, with User Manual and Win32 setup instructions Message-ID: Howdyhoy, I've made a new release of Distel, and written a proper user manual. You can download the release and manual from the homepage, http://www.bluetail.com/~luke/distel/ There is also an INSTALL.WIN32 file in the distribution, describing the ugly-but-straightforward process of installing it on Windows with cygwin and GNU Emacs 21 (and probably other Emacsen too.) >From the NEWS file: Version 3.3: A User Manual is now available from the homepage, http://www.bluetail.com/~luke/distel/ 'fdoc' online docmentation is now included, with "C-c C-d d" and "C-c C-d a" to do "describe" and "apropos", respectively. 'fdoc' is a program for automatically extracting documentation from the comments in source files - it primarily exists in the Jungerl. Refactoring support now exists, with a command to take an expression from a function and "refactor" it into a separate sub-function. Distel automatically passes the appropriate variables to the new function by using the 'syntax_tools' package to analyse the expression. This feature requires 'syntax_tools' version 1.2 to be installed separately. Breakpoint handling in the debugger has been improved in many small ways. There is also an extra keybinding for toggling breakpoints, "C-x SPC", for consistency with other Emacs packages. Giving a numeric prefix argument to M-. will force it to prompt for the function to lookup. This is useful if you want to find the source for a function that isn't being called in any code that you have handy. You can give it a numeric prefix with e.g. "M-1 M-." Cheerio, Luke From samuel@REDACTED Wed Mar 26 10:50:59 2003 From: samuel@REDACTED (Samuel Rivas) Date: Wed, 26 Mar 2003 10:50:59 +0100 Subject: TV don't show user table Message-ID: <20030326095059.GA9572@crusher.lfcia.pri> Hi: The TV application does something strange if I define a mnesia table called user. mnesia can create the table and insert data on it without troubles, however, this table does not appear on the tv tables list for the node. Any other tables that I've crated are properly listed. I've done the next experiment to ilustrate this unexpected behaviour ---------------------------------------------------------------------- (mnesia_test@REDACTED)1> mnesia:create_schema([node()]). ok (mnesia_test@REDACTED)2 mnesia:create_table(user, [{disc_copies, [node()]}, {attributes, [id, name]}]). {atomic,ok} (mnesia_test@REDACTED)3> mnesia:create_table(oser, [{disc_copies, [node()]}, {attributes, [id, name]}]). {atomic,ok} (mnesia_test@REDACTED)4> mnesia:info(). ---> Processes holding locks <--- ---> Processes waiting for locks <--- ---> Participant transactions <--- ---> Coordinator transactions <--- ---> Uncertain transactions <--- ---> Active tables <--- oser : with 0 records occupying 276 words of mem user : with 0 records occupying 276 words of mem schema : with 3 records occupying 606 words of mem ===> System info in version "4.0", debug level = none <=== opt_disc. Directory "/home/lfcia/samuel/Mnesia.mnesia_test@REDACTED" is used. use fallback at restart = false running db nodes = [mnesia_test@REDACTED] stopped db nodes = [] master node tables = [] remote = [] ram_copies = [] disc_copies = [oser,schema,user] disc_only_copies = [] [{mnesia_test@REDACTED,disc_copies}] = [schema,user,oser] 4 transactions committed, 1 aborted, 0 restarted, 2 logged to disc 0 held locks, 0 in queue; 0 local transactions, 0 remote 0 transactions waits for other nodes: [] ok ---------------------------------------------------------------------- The table oser is listed by TV, but not the table user. Thanks -- --------------------- Samuel --------------------- From samuel@REDACTED Wed Mar 26 11:08:49 2003 From: samuel@REDACTED (Samuel Rivas) Date: Wed, 26 Mar 2003 11:08:49 +0100 Subject: Answering my own questions :) In-Reply-To: <20030326095059.GA9572@crusher.lfcia.pri> References: <20030326095059.GA9572@crusher.lfcia.pri> Message-ID: <20030326100848.GA9737@crusher.lfcia.pri> On Wed, Mar 26, 2003 at 10:50:59AM +0100, Samuel Rivas wrote: > Hi: > > The TV application does something strange if I define a mnesia table > called user. mnesia can create the table and insert data on it > without troubles, however, this table does not appear on the tv tables > list for the node. Any other tables that I've crated are properly > listed. That is!, TV recognize my table as a system table, and proprely list it if I set the system tables option. Now the question is: Why my table user is recognized as a system table?, is a TV asumption or is not recommended to use such a name for a non system table? Thanks -- --------------------- | Samuel | --------------------- From gunilla@REDACTED Wed Mar 26 11:39:45 2003 From: gunilla@REDACTED (Gunilla Arendt) Date: Wed, 26 Mar 2003 11:39:45 +0100 Subject: Answering my own questions :) References: <20030326095059.GA9572@crusher.lfcia.pri> <20030326100848.GA9737@crusher.lfcia.pri> Message-ID: <3E818371.3B744C4B@erix.ericsson.se> The tables that TV regards as 'system tables' are hardcoded in tv_main.hrl. If you use the named_table option when creating new ets tables, I would recommend that you avoid these names or a name collision may occur. / Gunilla Samuel Rivas wrote: > > On Wed, Mar 26, 2003 at 10:50:59AM +0100, Samuel Rivas wrote: > > Hi: > > > > The TV application does something strange if I define a mnesia table > > called user. mnesia can create the table and insert data on it > > without troubles, however, this table does not appear on the tv tables > > list for the node. Any other tables that I've crated are properly > > listed. > > That is!, TV recognize my table as a system table, and proprely list > it if I set the system tables option. > > Now the question is: Why my table user is recognized as a system table?, > is a TV asumption or is not recommended to use such a name for a non > system table? > > Thanks > > -- > --------------------- > | Samuel | > --------------------- From samuel@REDACTED Wed Mar 26 12:08:42 2003 From: samuel@REDACTED (Samuel Rivas) Date: Wed, 26 Mar 2003 12:08:42 +0100 Subject: Answering my own questions :) In-Reply-To: <3E818371.3B744C4B@erix.ericsson.se> References: <20030326095059.GA9572@crusher.lfcia.pri> <20030326100848.GA9737@crusher.lfcia.pri> <3E818371.3B744C4B@erix.ericsson.se> Message-ID: <20030326110842.GA10068@crusher.lfcia.pri> On Wed, Mar 26, 2003 at 11:39:45AM +0100, Gunilla Arendt wrote: > The tables that TV regards as 'system tables' are hardcoded in > tv_main.hrl. If you use the named_table option when creating new ets > tables, I would recommend that you avoid these names or a name collision > may occur. > > / Gunilla What is the reason of user name to be a recognized as 'reserved' by TV? It appears on both MNESIA_TABLES and SYSTEM_OWNERS lists, but when I start a node and inspet the ets tables and the mnesia tables I don't find any user table. I guess that some erlang application that I'm not using needs an ets or mnesia tablewith this name. Thanks -- --------------------- | Samuel | --------------------- From Erik.Reitsma@REDACTED Wed Mar 26 14:19:58 2003 From: Erik.Reitsma@REDACTED (Erik Reitsma (ETM)) Date: Wed, 26 Mar 2003 14:19:58 +0100 Subject: HTTP client problems Message-ID: <440A2703A54A8F4FB2AC2AE34F27129D215A2A@ESEALNT889.al.sw.ericsson.se> Hi all, I am using the HTTP client of inets-3.0.3. When I do a synchronous HTTP request, and the process from which I do the request receives some message X while waiting for the result, I get this other message X as the result. This is to be expected when I read the code of http.erl, but before I had read the code, I had not expected this. The http:request_sync/4 accepts all messages, but in my case this is a message that is not related to the HTTP request: it is a message that I send from some other process. Could I remove lines 183 and 184 from http.erl without harm, or can indeed other HTTP-related messages arrive, that are not matched by the existing clauses? I have removed them for now, but now I may miss some error messages, of which I do not know. I do not know which these are, otherwise I could match them explicitly. Another solution may be, to spawn a process for the HTTP request, but it seems to me that the HTTP client code of inets should already take care of this. *Erik. Erik Reitsma System Engineer, Technology Strategies Service Network and Applications Ericsson Telecommunicatie B.V. Research and Development Tel.: +31 161 242582 Fax: +31 161 242206 erik.reitsma@REDACTED http://www.ericsson.nl From garry@REDACTED Wed Mar 26 19:28:36 2003 From: garry@REDACTED (Garry Hodgson) Date: Wed, 26 Mar 2003 13:28:36 -0500 Subject: odd problem with distributed erlang system Message-ID: <200303261828.h2QISaK01757@kestrel.sage.att.com> i'm trying to debug a strange problem we're seeing in one of our systems. we've got a number of linux clusters, all running vanilla redhat 7.x, and we only see this on one of them. the application is a pretty basic one, where we have a master node that starts up processes on other compute nodes. each of these others is runs an erlang port process which invokes an external program to handle queries. the whole thing is accessed through a web site which does queries of the master server. the master forwards the query to the appropriate child. each type of information server is started on a different node, in on-demand order. the problem is this: the first query comes in, causing a server, say, foo, to run on node1. all is good. a different query comes in which needs a baz server, which gets started on node2. this query will run *realllllly* slow, eventually likely timing out before it returns a result (which it will do eventually). when i say slow, i'm talking minutes. the really odd thing is that the child process is writing to a log file (nfs mounted from master), using the erlang dblog stuff, and debug messages that occur in the same function, only a few lines apart, come in several minutes apart. the problem is independent of the order in which the nodes start, or the servers start, or which subserver runs on whoich node, etc. we've eliminated (i think) all the obvious cases. it really feels like a machine configuration problem. this cluster is in a secure lab, and has gone through a few rounds of network rearrangements. the problem doesn't occur on any of the other similar systems we've deployed, and we can't recreate it in our development systems. so, does anybody have any ideas about what to look for, or what kinds of things could make erlang run so slow on machine? it feels like a timeout of some sort, but we've looked at the obvious name lookup things and such (does erlang require dns? we're using local /etc/host for name resolution). is there something else internal that we might be waiting on? any ideas, suggestions, or pointers to useful test cases would be greatly appreciated. it's awkward to debug since we have only restricted access to the broken system. thanks for your help. From jeinhorn@REDACTED Wed Mar 26 20:58:28 2003 From: jeinhorn@REDACTED (Jeff Einhorn) Date: Wed, 26 Mar 2003 13:58:28 -0600 Subject: MD5 in erlang. Message-ID: I was wondering if erlang had any built-in tools to generate an MD5 Hash that looks similiar what is generated by md5sum on linux. Example if I do an md5sum on the string "hello" I get: b1946ac92492d2347c6235b4d2611184 erlang:md5("hello"). <<93,65,64,42,188,75,42,118,185,113,157,145,16,23,197,146>> Does erlang have any built in functions for converting binary to hex? -jeff Jeffrey M. Einhorn Software Engineer Web Development Group FutureSource, LLC jeinhorn@REDACTED http://www.futuresource.com From matthias@REDACTED Wed Mar 26 21:34:39 2003 From: matthias@REDACTED (Matthias Lang) Date: Wed, 26 Mar 2003 21:34:39 +0100 Subject: MD5 in erlang. In-Reply-To: References: Message-ID: <16002.3807.130791.845508@antilipe.corelatus.se> Jeff Einhorn writes: > Does erlang have any built in functions for converting binary to hex? No BIF, but there's httpd_util:integer_to_hexlist/1. See http://www.erlang.org/doc/r9b/lib/inets-3.0/doc/html/httpd_util.html Various people have posted patches to allow io:fwrite to do it, e.g. http://www.erlang.org/ml-archive/erlang-questions/200211/msg00208.html http://www.erlang.org/ml-archive/erlang-questions/200110/msg00148.html Matthias From garry@REDACTED Wed Mar 26 21:59:44 2003 From: garry@REDACTED (Garry Hodgson) Date: Wed, 26 Mar 2003 15:59:44 -0500 Subject: odd problem with distributed erlang system Message-ID: <200303262059.h2QKxiY02823@kestrel.sage.att.com> one additional data point: we commented out the call to disk_log:blog() in our common print routines, effectively turning off all logging. the problem then goes away. so something down in there relies on some kind of configuration that we've apparently got wrong. i hope that helps narrow it down a bit. From mbj@REDACTED Wed Mar 26 22:13:26 2003 From: mbj@REDACTED (Martin Bjorklund) Date: Wed, 26 Mar 2003 22:13:26 +0100 (CET) Subject: odd problem with distributed erlang system In-Reply-To: <200303262059.h2QKxiY02823@kestrel.sage.att.com> References: <200303262059.h2QKxiY02823@kestrel.sage.att.com> Message-ID: <20030326.221326.112625433.mbj@bluetail.com> Garry Hodgson wrote: > a log file (nfs mounted from master), using the erlang dblog stuff, [...] > we commented out the call to disk_log:blog() in our common > print routines, effectively turning off all logging. the > problem then goes away. So when you don't do NFS writes, the problem goes away. That should give you a hint... Try to log to local disk instead. /martin From svg@REDACTED Wed Mar 26 19:32:19 2003 From: svg@REDACTED (Vladimir Sekissov) Date: Wed, 26 Mar 2003 23:32:19 +0500 (YEKT) Subject: MD5 in erlang. In-Reply-To: References: Message-ID: <20030326.233219.39149718.svg@surnet.ru> Good day, jeinhorn> I was wondering if erlang had any built-in tools to generate an MD5 Hash jeinhorn> that looks similiar what is generated by md5sum on linux. jeinhorn> erlang:md5("hello"). jeinhorn> <<93,65,64,42,188,75,42,118,185,113,157,145,16,23,197,146>> At first your must call: erlang:md5("hello\n"). if you want your md5 sum be equal to output of `md5sum' Add hoc solution: hex(L) when list (L) -> lists:flatten([hex(I) || I <- L]); hex(I) when I > 16#f -> [hex0((I band 16#f0) bsr 4), hex0((I band 16#0f))]; hex(I) -> [$0, hex0(I)]. hex0(10) -> $a; hex0(11) -> $b; hex0(12) -> $c; hex0(13) -> $d; hex0(14) -> $e; hex0(15) -> $f; hex0(I) -> $0 +I. 5> test:hex(erlang:md5("hello\n")). "b1946ac92492d2347c6235b4d2611184" Best Regards, Vladimir Sekissov From spearce@REDACTED Wed Mar 26 22:42:01 2003 From: spearce@REDACTED (Shawn Pearce) Date: Wed, 26 Mar 2003 16:42:01 -0500 Subject: odd problem with distributed erlang system In-Reply-To: <20030326.221326.112625433.mbj@bluetail.com> References: <200303262059.h2QKxiY02823@kestrel.sage.att.com> <20030326.221326.112625433.mbj@bluetail.com> Message-ID: <20030326214201.GA14975@spearce.org> Or try logging through erlang distributed messaging to the master server, rather than using NFS to do the log writes. Martin Bjorklund wrote: > Garry Hodgson wrote: > > > a log file (nfs mounted from master), using the erlang dblog stuff, > > [...] > > > we commented out the call to disk_log:blog() in our common > > print routines, effectively turning off all logging. the > > problem then goes away. > > So when you don't do NFS writes, the problem goes away. That should > give you a hint... Try to log to local disk instead. > > > /martin -- Shawn. The heart has its reasons which reason knows nothing of. -- Blaise Pascal From cpressey@REDACTED Thu Mar 27 01:51:38 2003 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 26 Mar 2003 18:51:38 -0600 Subject: ensure_started Message-ID: <20030326185138.03a31ff4.cpressey@catseye.mb.ca> Ulf Wiger wrote: >I'm not sure if it's possible, or even relevant to solve the >general case of a server trying to make sure that there are >no more messages before it finally dies. After all, this is >fundamentally a race condition. It's evidently not a huge problem in practice. I've refined my guideline: in waiting for a reply, a) if you monitor the process, always accept a DOWN message as a valid reply (as Vlad S. pointed out); b) if you link to the process, always accept an EXIT message as a valid reply (unless you want your process to die too); c) if you don't monitor or link, always use a finite timeout. To avoid the timeout in the case of c) (just thinking out loud here, not suggesting anything) you'd need an atomic recieve_or_exit. Ulf also wrote: >However, reg_name ! foo _will_ fail if there is no process >registered as 'reg_name'. However, if we wanted to take this approach for avoiding timeouts (again, just thinking out loud), not only would we need an atomic recieve_or_unregister_self, we would have a need to register processes dynamically, so we'd need to either garbage-collect the atom table, or allow processes to be named with arbitrary (or at least garbage-collectable) terms. A bit messy, any way you slice it. I have yet to use monitor; I learned Erlang from "the book" and I've been slower to adopt things that aren't mentioned in it. I should definately look into it soon. -Chris From garry@REDACTED Thu Mar 27 02:39:22 2003 From: garry@REDACTED (Garry Hodgson) Date: Wed, 26 Mar 2003 20:39:22 -0500 (EST) Subject: odd problem with distributed erlang system Message-ID: <200303270139.UAA35300@sprache.sage.att.com> Shawn Pearce wrote: > Or try logging through erlang distributed messaging to the master > server, rather than using NFS to do the log writes. > > Martin Bjorklund wrote: > > So when you don't do NFS writes, the problem goes away. That should > > give you a hint... Try to log to local disk instead. thank you both for your suggestions. i can work around the problem. but i'd still like to understand just what's going on. specifically, - why only the second and subsequent subservers have this problem? after all, by that time, both the master node and one sub node have been logging successfully, with the master owning the file system that is nfs-mounted on the subnodes, and the first subnode accessing it via nfs. - why we have no other apparent nfs issues? the subnodes mount /usr/local, which is where all the code, libs, scripts, and even erlang itself lives. - why we don't see this on any other installation. it smells of a configuration problem, yet this is the only symptom we see. no errors show up in any of the system logs. for what it's worth, i'm opening the logs using the following. it gets called by the master and the subservers when they start. am i doing something exceptionally stupid here? disk_log:open( [ {name, LogName }, { file, LogFile }, { format, external }, { distributed, [node()] }, { repair, true }, { size, { 1024*1024, 16 } }, { type, wrap } ] ) thanks again for all your help. ---- "You've been telling lies so long Some believe they're true So they close their eyes to things You have no right to do" --- Steppenwolf From cpressey@REDACTED Thu Mar 27 08:13:16 2003 From: cpressey@REDACTED (Chris Pressey) Date: Thu, 27 Mar 2003 01:13:16 -0600 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang.) In-Reply-To: <16002.3807.130791.845508@antilipe.corelatus.se> References: <16002.3807.130791.845508@antilipe.corelatus.se> Message-ID: <20030327011316.12f6a496.cpressey@catseye.mb.ca> On Wed, 26 Mar 2003 21:34:39 +0100 Matthias Lang wrote: > Jeff Einhorn writes: > > > Does erlang have any built in functions for converting binary to > > hex? > > No BIF, but there's httpd_util:integer_to_hexlist/1. See > > http://www.erlang.org/doc/r9b/lib/inets-3.0/doc/html/httpd_util.html Every few months this comes up and every time it does I get more irritated. Before you choose to call httpd_util:integer_to_hexlist/1 from your program, PLEASE consider the following excerpt. >From http://www.erlang.se/doc/programming_rules.shtml : 3.3 Put commonly used code into libraries - "Great effort should be made in ensuring that libraries contain functions of the same type. Thus a library such as lists containing only functions for manipulating lists is a good choice, whereas a library, lists_and_maths containing a combination of functions for manipulating lists and for mathematics is a very bad choice." I count 16 functions in httpd_util that have *ABSOLUTELY*NOTHING* to do with HTTP. Makes me want to scream, it does. -Chris From Erik.Stenman@REDACTED Thu Mar 27 12:32:20 2003 From: Erik.Stenman@REDACTED (Erik Stenman) Date: Thu, 27 Mar 2003 12:32:20 +0100 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang.) References: <16002.3807.130791.845508@antilipe.corelatus.se> <20030327011316.12f6a496.cpressey@catseye.mb.ca> Message-ID: <010901c2f454$87a67ae0$239ab280@lamppc27> Chris Pressey wrote: [...] > Every few months this comes up and every time it does I get more > irritated. [...] Here we go agian, my pet peeve ;) We have had the posibility to format integers in different bases in our local HiPE system for several years now, but for some reason the OTP team does not want to add it to the distribution. Robert Virding has also promised to implement it but that implementation has not made it into the distribution either. Please, please add this functionallity to stdlib! (I can write the documentation if that is a problem ;) /Erik -------------------------------------- I'm Happi, you should be happy. Praeterea censeo "0xCA" scribere Erlang posse. Index: lib/stdlib/src/io_lib_format.erl =================================================================== RCS file: /it/project/fo/hipe/repository/otp/lib/stdlib/src/io_lib_format.erl,v retrieving revision 1.1.1.1 retrieving revision 1.4 diff -u -r1.1.1.1 -r1.4 --- lib/stdlib/src/io_lib_format.erl 26 Mar 2001 18:36:34 -0000 1.1.1.1 +++ lib/stdlib/src/io_lib_format.erl 27 Mar 2002 16:47:22 -0000 1.4 @@ -101,11 +101,16 @@ collect_cc([$p|Fmt], [A|Args]) -> {$p,[A],Fmt,Args}; collect_cc([$W|Fmt], [A,Depth|Args]) -> {$W,[A,Depth],Fmt,Args}; collect_cc([$P|Fmt], [A,Depth|Args]) -> {$P,[A,Depth],Fmt,Args}; +collect_cc([$#|Fmt], [A,Base|Args]) -> {$#,[A,Base],Fmt,Args}; +collect_cc([$B|Fmt], [A|Args]) -> {$B,[A],Fmt,Args}; +collect_cc([$b|Fmt], [A|Args]) -> {$b,[A],Fmt,Args}; collect_cc([$s|Fmt], [A|Args]) -> {$s,[A],Fmt,Args}; collect_cc([$e|Fmt], [A|Args]) -> {$e,[A],Fmt,Args}; collect_cc([$f|Fmt], [A|Args]) -> {$f,[A],Fmt,Args}; collect_cc([$g|Fmt], [A|Args]) -> {$g,[A],Fmt,Args}; collect_cc([$c|Fmt], [A|Args]) -> {$c,[A],Fmt,Args}; +collect_cc([$x|Fmt], [A|Args]) -> {$x,[A],Fmt,Args}; +collect_cc([$X|Fmt], [A|Args]) -> {$X,[A],Fmt,Args}; collect_cc([$~|Fmt], Args) -> {$~,[],Fmt,Args}; collect_cc([$n|Fmt], Args) -> {$n,[],Fmt,Args}; collect_cc([$i|Fmt], [A|Args]) -> {$i,[A],Fmt,Args}. @@ -155,6 +160,20 @@ term(io_lib:write(A, Depth), F, Adj, P, Pad); control($P, [A,Depth], F, Adj, P, Pad, I) when integer(Depth) -> print(A, Depth, F, Adj, P, Pad, I); +control($#, [A,Base], F, Adj, P, Pad, I) when integer(Base), + 2 =< Base, + Base =< 16-> + string(int_to_base(A, Base), F, Adj, P, Pad); +control($B, [A], F, Adj, P, Pad, I) -> + string( + if A < 0 -> [$- | int_to_base(-A, [], 2)]; + true -> int_to_base(A, [], 2) + end, + F, Adj, P, Pad); +control($b, [A], F, Adj, none, Pad, I) -> + string(int_to_binary(A, 32), F, Adj, none, Pad); +control($b, [A], F, Adj, P, Pad, I) -> + string(int_to_binary(A, P), F, Adj, P, Pad); control($s, [A], F, Adj, P, Pad, I) when atom(A) -> string(atom_to_list(A), F, Adj, P, Pad); control($s, [L], F, Adj, P, Pad, I) -> @@ -168,6 +187,10 @@ fwrite_g(A, F, Adj, P, Pad); control($c, [A], F, Adj, P, Pad, I) when integer(A) -> char(A band 255, F, Adj, P, Pad); +control($x, [A], F, Adj, P, Pad, I) when integer(A) -> + string(int_to_hex(A), F, Adj, P, Pad); +control($X, [A], F, Adj, P, Pad, I) when integer(A) -> + string(int_to_Hex(A), F, Adj, P, Pad); control($~, [], F, Adj, P, Pad, I) -> char($~, F, Adj, P, Pad); control($n, [], F, Adj, P, Pad, I) -> newline(F, Adj, P, Pad); control($i, [A], F, Adj, P, Pad, I) -> []. @@ -388,3 +411,58 @@ flat_length([H|T], L) -> flat_length(T, L + 1); flat_length([], L) -> L. + +int_to_hex(N) -> int_to_hex(N, $a-10). +int_to_Hex(N) -> int_to_hex(N, $A-10). + +int_to_hex(N, LetterBase) -> + if N < 0 -> [$-, $0, $x | int_to_hex(-N, [], LetterBase)]; + true -> [$0, $x | int_to_hex(N, [], LetterBase)] + end. + +int_to_hex(N, Tail, LetterBase) -> + NewN = N bsr 4, + Digit = N band 15, + Char = + if Digit < 10 -> Digit+$0; + true -> Digit+LetterBase + end, + NewTail = [Char | Tail], + if NewN =:= 0 -> NewTail; + true -> int_to_hex(NewN, NewTail, LetterBase) + end. + +int_to_binary(N, Wordsize) -> + if N < 0 -> + Bits = int_to_base(-N, [],2), + pad(length(Bits),Bits,Wordsize,$1); + true -> + Bits = int_to_base(N, [], 2), + pad(length(Bits),Bits,Wordsize,$0) + end. + +pad(N,Bits,Wordsize, Pad) -> + if N < Wordsize -> + pad(N+1,[Pad|Bits],Wordsize,Pad); + true -> + Bits + end. + + +int_to_base(N, Base) -> + if N < 0 -> [$- | integer_to_list(Base)] + ++ [$# | int_to_base(-N, [], Base)]; + true -> integer_to_list(Base) ++ [$# | int_to_base(N, [], Base)] + end. + +int_to_base(N, Tail, Base) -> + NewN = N div Base, + Digit = N - (NewN*Base), + Char = + if Digit < 10 -> Digit+$0; + true -> Digit+$a-10 + end, + NewTail = [Char | Tail], + if NewN =:= 0 -> NewTail; + true -> int_to_base(NewN, NewTail, Base) + end. From etxuwig@REDACTED Thu Mar 27 13:19:11 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Thu, 27 Mar 2003 13:19:11 +0100 (MET) Subject: ensure_started In-Reply-To: <20030326185138.03a31ff4.cpressey@catseye.mb.ca> Message-ID: On Wed, 26 Mar 2003, Chris Pressey wrote: >I've refined my guideline: in waiting for a reply, >a) if you monitor the process, always accept a DOWN message as a valid >reply (as Vlad S. pointed out); >b) if you link to the process, always accept an EXIT message as a valid >reply (unless you want your process to die too); >c) if you don't monitor or link, always use a finite timeout. > >To avoid the timeout in the case of c) (just thinking out >loud here, not suggesting anything) you'd need an atomic >recieve_or_exit. I don't think that's enough. The server may receive your message and then die while processing it, or it may die while the message is still in the queue. >Ulf also wrote: >>However, reg_name ! foo _will_ fail if there is no process >>registered as 'reg_name'. > >However, if we wanted to take this approach for avoiding >timeouts (again, just thinking out loud), not only would we >need an atomic recieve_or_unregister_self, we would have a >need to register processes dynamically, so we'd need to >either garbage-collect the atom table, or allow processes >to be named with arbitrary (or at least >garbage-collectable) terms. A bit messy, any way you slice >it. You still have to have a timeout and (preferably) a monitor. >I have yet to use monitor; I learned Erlang from "the book" >and I've been slower to adopt things that aren't mentioned >in it. I should definately look into it soon. Monitors were added because you cannot use links easily in e.g. a function like gen:call(). The main differences between link and monitor are: - monitors are one way. Thus, the other side cannot mess up your supervision by unlinking. - they are stackable, meaning that you will get a distinct DOWN message for each call to monitor. Links are not stackable; subsequent calls to link/1 are simply ignored, but you only need one call to unlink/1 to remove the link. This forces you to implement a reference counting framework for links if you want to use them for temporary supervision. - Links can be used for automatic cascading exits. Monitors can't (you have to explicitly react to the DOWN message and exit if you want to do the same with monitors.) Another way of putting it: 'EXIT' is a special message that will kill a process that's not trapping exits(*) while 'DOWN' is a plain message. My recommendation is: always use monitor to monitor another process; use links for cascading exit. /Uffe (*) {'EXIT',Pid,normal} is not lethal. -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From cpressey@REDACTED Thu Mar 27 17:00:55 2003 From: cpressey@REDACTED (Chris Pressey) Date: Thu, 27 Mar 2003 10:00:55 -0600 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang.) In-Reply-To: <010901c2f454$87a67ae0$239ab280@lamppc27> References: <16002.3807.130791.845508@antilipe.corelatus.se> <20030327011316.12f6a496.cpressey@catseye.mb.ca> <010901c2f454$87a67ae0$239ab280@lamppc27> Message-ID: <20030327100055.65e23403.cpressey@catseye.mb.ca> On Thu, 27 Mar 2003 12:32:20 +0100 "Erik Stenman" wrote: > Chris Pressey wrote: > [...] > > Every few months this comes up and every time it does I get more > > irritated. > [...] > > Here we go agian, my pet peeve ;) Ah, so I'm not alone :) Moving it from inets to stdlib solves the bigger headache. I'm still not sure how I feel about it being in io_lib; string, or math, or a new module called base might be better, but that's minor compared to it not being in stdlib. -Chris From jch@REDACTED Thu Mar 27 18:02:00 2003 From: jch@REDACTED (Jenny Dybedahl) Date: 27 Mar 2003 18:02:00 +0100 Subject: odd problem with distributed erlang system In-Reply-To: <200303270139.UAA35300@sprache.sage.att.com> References: <200303270139.UAA35300@sprache.sage.att.com> Message-ID: Garry Hodgson writes: > - why only the second and subsequent subservers have this > problem? after all, by that time, both the master node and one > sub node have been logging successfully, with the master owning > the file system that is nfs-mounted on the subnodes, and the > first subnode accessing it via nfs. > > - why we have no other apparent nfs issues? the subnodes mount > /usr/local, which is where all the code, libs, scripts, and even > erlang itself lives. > > - why we don't see this on any other installation. it smells of a > configuration problem, yet this is the only symptom we see. no > errors show up in any of the system logs. > > for what it's worth, i'm opening the logs using the following. it > gets called by the master and the subservers when they start. am i > doing something exceptionally stupid here? Are all nodes using the same logfile, or are they using separate logfiles stored on the same disk? If they're trying to use the same log file, I'd say you have a classic case of NFS locking problem. File locking over NFS is notoriously problematic. If there's any way you can avoid having to write to the same file from two different servers, do so. -- "I live in the heart of the machine. We are one." From jamesh@REDACTED Thu Mar 27 20:12:36 2003 From: jamesh@REDACTED (James Hague) Date: Thu, 27 Mar 2003 13:12:36 -0600 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang .) Message-ID: I've often thought Erlang should have the BIFs: integer_to_list(Base, Integer) list_to_integer(Base, List) In addition to the arity-1 versions that currently exist. From jim@REDACTED Thu Mar 27 18:57:52 2003 From: jim@REDACTED (Jim Larson) Date: Thu, 27 Mar 2003 09:57:52 -0800 Subject: odd problem with distributed erlang system In-Reply-To: Your message of "27 Mar 2003 18:02:00 +0100." Message-ID: <200303271757.h2RHvqFK065105@krumkake.jetcafe.org> In message Jenny Dybedahl writes: >File locking over NFS is notoriously problematic. If there's any way >you can avoid having to write to the same file from two different >servers, do so. With a *good* NFSv3 server, exclusive file creation can serve as a locking mechanism. If you have a server that exploits NVRAM, such as NetApp filers, the performance isn't even all that bad. You do need to have a policy for cleaning up orphaned locks. Jim From cpressey@REDACTED Fri Mar 28 01:54:53 2003 From: cpressey@REDACTED (Chris Pressey) Date: Thu, 27 Mar 2003 18:54:53 -0600 Subject: regexp: how to match a null string? Message-ID: <20030327185453.5170cfc8.cpressey@catseye.mb.ca> Hello again. The regexp behaviour seems very weird to me. In my mind, "^(.*)$" should match a null string. It doesn't match any characters, but it's still a valid match. But because regexp deals only in terms of characters matched - there's no way to tell! Erlang (BEAM) emulator version 5.2.3.3 [source] [hipe] Eshell V5.2.3.3 (abort with ^G) 1> S = "". [] 2> P = "^(.*)$". "^(.*)$" 3> regexp:match(S, P). nomatch 4> regexp:first_match(S, P). nomatch 5> regexp:matches(S, P). {match,[]} 6> regexp:matches("foo", "bar"). {match,[]} Would anyone else be interested in a function like regexp:is_match(String, RegExp) -> true | false ? Or is there a better way to solve this problem? -Chris From cpressey@REDACTED Fri Mar 28 05:09:45 2003 From: cpressey@REDACTED (Chris Pressey) Date: Thu, 27 Mar 2003 22:09:45 -0600 Subject: An explanation re Erlang GUI project Message-ID: <20030327220945.4447d063.cpressey@catseye.mb.ca> OK... The reason I've become increasingly critical of Jay's approach is because I like it, and I don't want to see it go down the garden path. Why is development on TUNES[1] so slow? Because TUNES is a Useful, Not Expedient, System. 'Nuff said. It will quite possibly never materialize. I don't want to see the same thing happen to an Erlang GUI. Two things can kill a project: developing too quickly and developing too slowly. The former way, you run yourself into a dead end by having code that works - sort of - but is unmaintainable, and breaks mysteriously on every new change. The latter way, you run yourself down the garden path, where you never write any worthwhile code because you can never settle on a design that's good enough. Plenty are the languages with which you can crank out code, and plenty are the languages with which you can write beautiful code. Rare is the language with which you can crank out beautiful code... I guess what I'm saying is that if tomorrow someone were to go and prototype their impression of a simplified version of Jay's level 1 (z-ordering, clipping, with stubs for alpha) using OpenGL as level 0, I wouldn't shed any tears. A prototype would provide feedback, which is looking more and more needful, as it would lead to more informed choices as to the project's direction, which could in turn provide momentum towards actually producing a finished product. In the absence of feedback, it's too easy to get stuck daydreaming. Plus there are certain estimations I'd like to make, such as, what kind of performance would be desirable for running the thing decently? All the nice features aside, that's probably the most important factor - no one wants to run a GUI that's a dog, no matter how usable it is. Unfortunately I know next to nothing about OpenGL and, not being a graphics programmer, I get the impression that I'd have a lot to learn if I wanted to give it a shot. -Chris [1] http://www.eleves.ens.fr:8080/home/madore/computers/tunes.html From pdejuan@REDACTED Fri Mar 28 03:08:09 2003 From: pdejuan@REDACTED (Pablo Dejuan) Date: Fri, 28 Mar 2003 03:08:09 +0100 Subject: Problems with Strings Message-ID: <3E83AE89.9090708@ucu.edu.uy> Hi. I'm new in this and I have dificulties using strings. I tried to do an "inverese" function that should turn "bac" into "cab" but instead of this I get [98,[97,[99,[]]]] which I noticed that are tha Ascii codes for c, a, and b. Here is the code: inversa("") -> ""; inversa([Ini|Cont]) -> Inv= inversa(Cont), [Ini,Inv]. Thanks In Advance. From cpressey@REDACTED Fri Mar 28 07:16:07 2003 From: cpressey@REDACTED (Chris Pressey) Date: Fri, 28 Mar 2003 00:16:07 -0600 Subject: regexp: how to match a null string? In-Reply-To: <20030327185453.5170cfc8.cpressey@catseye.mb.ca> References: <20030327185453.5170cfc8.cpressey@catseye.mb.ca> Message-ID: <20030328001607.61f72a7e.cpressey@catseye.mb.ca> On Thu, 27 Mar 2003 18:54:53 -0600 Chris Pressey wrote: > In my mind, "^(.*)$" should match a null string. > It doesn't match any characters, but it's still a valid match. > But because regexp deals only in terms of characters matched - > there's no way to tell! In lieu of a better solution... attached is a patch to regexp.erl which adds the function is_match(String, RegExp) -> true | false | {error, Reason} -Chris -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: regexp.patch URL: From raimo.niskanen@REDACTED Fri Mar 28 07:49:34 2003 From: raimo.niskanen@REDACTED (Raimo Niskanen) Date: Fri, 28 Mar 2003 07:49:34 +0100 Subject: Problems with Strings References: <3E83AE89.9090708@ucu.edu.uy> Message-ID: inversa("") -> ""; inversa([Ini|Cont]) -> Inv= inversa(Cont), [Ini|Inv]. -----------------------------------------------^-here You have accidentally built a deep list, which does not print as a string (beginner mistake no ~3). If you would have written your deep list to a file, or printed it with io:format("~s~n", [[$c,[$a,[$b]]]]), you would have got what you wanted. And why not use lists:reverse/1,2 instead of writing your own? They use a built in emulator function that is much faster than any Erlang code. Background: There are no strings in Erlang. They are represented as lists of character ascii values. "abc" is syntactical sugar for [$a,$b,$c]. If you print a list using format character ~p it will use the "abc" syntactical sugar style if the list is a flat list of printable characters. / Raimo Niskanen, Erlang/OTP Pablo Dejuan wrote: > Hi. I'm new in this and I have dificulties using strings. I tried to do > an "inverese" function that should turn "bac" into "cab" but instead of > this I get [98,[97,[99,[]]]] which I noticed that are tha Ascii codes > for c, a, and b. > > Here is the code: > inversa("") -> ""; > inversa([Ini|Cont]) -> Inv= inversa(Cont), [Ini,Inv]. > > Thanks In Advance. > From ehz4@REDACTED Fri Mar 28 09:15:00 2003 From: ehz4@REDACTED (Edwin Zacharias) Date: Fri, 28 Mar 2003 00:15:00 -0800 (PST) Subject: Compiling Linked-in Drivers on Mac OS X Message-ID: <20030328081500.7830.qmail@web13202.mail.yahoo.com> I'm trying to get the linked-in driver example in the Erlang documentation to compile for Mac OS X. I'm using the following command for gcc-2.95.2: gcc -o exampledrv -I/usr/local/lib/erlang/erts-5.2.3.3/src -flat_namespace -shared complex.c port_driver.c and I get: /usr/bin/ld: Undefined symbols: _main _driver_alloc _driver_free _driver_output I know dynamic libraries work a little differently in OS X, but I'm not very experienced with them. Any help would be appreciated. - Edwin __________________________________________________ Do you Yahoo!? Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop! http://platinum.yahoo.com From Sean.Hinde@REDACTED Fri Mar 28 09:24:45 2003 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Fri, 28 Mar 2003 08:24:45 -0000 Subject: Compiling Linked-in Drivers on Mac OS X Message-ID: > I'm trying to get the linked-in driver example in the > Erlang documentation to compile for Mac OS X. I'm > using the following command for gcc-2.95.2: > > gcc -o exampledrv > -I/usr/local/lib/erlang/erts-5.2.3.3/src > -flat_namespace -shared complex.c port_driver.c > > and I get: > > /usr/bin/ld: Undefined symbols: > _main > _driver_alloc > _driver_free > _driver_output > > I know dynamic libraries work a little differently in > OS X, but I'm not very experienced with them. Any > help would be appreciated. There are some nice hints down at the bottom of the OS X section of the top level README of the R9B-1 release. Sean NOTICE AND DISCLAIMER: This email (including attachments) is confidential. If you have received this email in error please notify the sender immediately and delete this email from your system without copying or disseminating it or placing any reliance upon its contents. We cannot accept liability for any breaches of confidence arising through use of email. Any opinions expressed in this email (including attachments) are those of the author and do not necessarily reflect our opinions. We will not accept responsibility for any commitments made by our employees outside the scope of our business. We do not warrant the accuracy or completeness of such information. From etxuwig@REDACTED Fri Mar 28 10:15:02 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Fri, 28 Mar 2003 10:15:02 +0100 (MET) Subject: Problems with Strings In-Reply-To: <3E83AE89.9090708@ucu.edu.uy> Message-ID: Raimo has given one answer. Here's a suggestion on how to write your inversa/1 function in order to get the desired effect. The common trick is to use an accumulator: -module(demo). -export([inversa/1]). inversa(Str) -> inversa(Str, []). inversa([], Acc) -> Acc; inversa([H|T], Acc) -> inversa(T, [H|Acc]). Eshell V5.2.3.1 (abort with ^G) 1> demo:inversa("abc"). "cba" 2> The accumulator is often useful when writing list iterator functions (if you don't want to use the map, fold et al in lists.erl). The thing to bear in mind is that the accumulator will be reversed at the end of the iteration. In your case, it's what you want. The most common situation is: iter(List, F) -> iter(List, F, Acc = []). iter([H|T], F, Acc) -> iter(T, F, [F(H)|Acc]); iter([], F, Acc) -> %% return the accumulator, after reversing it. lists:reverse(Acc). Semantically, this is the same as iter([H|T], F) -> [F(H)|iter(T,F)]; iter([], _) -> []. But the former tends to be more efficient, despite the extra reverse() at the end, because you make more efficient use of the call stack. As Raimo pointed out, lists:reverse("abc") is certainly the most straightforward (and efficient!) way of reversing a string. Using lists:foldl/3 is a more contrived way: 2> lists:foldl(fun(Char,Acc) -> [Char|Acc] end, [], "abc"). "cba" (That is, lists:foldl/3 with a function that only "saves" each item works exactly like lists:reverse/1) 3> lists:foldr(fun(Char,Acc) -> [Char|Acc] end, [], "abc"). "abc" (That is, lists:foldr/3 with the same function does not produce a reversed list.) The only point of showing this is to point out that there are many ways to iterate over a list. Some approaches naturally produce reversed output, while others don't. The natural way to simply reverse a list is lists:reverse/1. Hopefully, this didn't just increase your confusion. (: /Uffe On Fri, 28 Mar 2003, Pablo Dejuan wrote: >Hi. I'm new in this and I have dificulties using strings. I >tried to do an "inverese" function that should turn "bac" >into "cab" but instead of this I get [98,[97,[99,[]]]] >which I noticed that are tha Ascii codes for c, a, and b. > >Here is the code: >inversa("") -> ""; >inversa([Ini|Cont]) -> Inv= inversa(Cont), [Ini,Inv]. > >Thanks In Advance. > > -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From pdejuan@REDACTED Fri Mar 28 11:12:08 2003 From: pdejuan@REDACTED (Pablo Dejuan) Date: Fri, 28 Mar 2003 11:12:08 +0100 Subject: Problems with Strings In-Reply-To: References: Message-ID: <3E841FF8.70103@ucu.edu.uy> Dear folks, Thank you very much for the answers. I was trying to rewrite that function because it was part of my current studies. I just get the idea! After looking at the API more carefully, I realized that to concat two strings you should use ++ (I know it's sounds silly but I was confused with other languages). So I'll rewrite it as: inversa("") -> ""; inversa([A1|A]) -> inversa(A) ++ [A1]. See you From etxuwig@REDACTED Fri Mar 28 15:34:42 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Fri, 28 Mar 2003 15:34:42 +0100 (MET) Subject: Problems with Strings In-Reply-To: <3E841FF8.70103@ucu.edu.uy> Message-ID: On Fri, 28 Mar 2003, Pablo Dejuan wrote: >After looking at the API more carefully, I realized that to concat two >strings you should use ++ (I know it's sounds silly but I was confused >with other languages). >So I'll rewrite it as: >inversa("") -> ""; >inversa([A1|A]) -> inversa(A) ++ [A1]. You could do that, but be aware of the fact that append has O(N) complexity. I some cases, this may not matter, but it's always good to know. Lists are represented as "cons" cells. Look upon them as linked lists (without a "last" pointer). Using ++ to append is about as expensive as traversing a normal linked list from start to end each iteration in order to add one element. I assume that what you're after is something other than simply reversing a string (since you can't beat lists:reverse/1 for that). If you really want to implement reverse in plain erlang, then this is the most efficient version: reverse(List) -> reverse(List, []). reverse([H|T],Acc) -> reverse(T,[H|Acc]); reverse([], Acc) -> Acc. A few words then on ++ If you use ++ in hard-coded constructs like URL = "http://" ++ Location this is no more expensive than URL = [$h,$t,$t,$p,$:,$/,$/|Location] but some may find it easier to read. You may also use ++ in pattern matching: location("http://" ++ L) -> L. which is equivalent to location([$h,$t,$t,$p,$:,$/,$/|L]) -> L. These constructs yield identical compiled code. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From rpettit@REDACTED Sun Mar 30 01:54:14 2003 From: rpettit@REDACTED (Rick Pettit) Date: Sat, 29 Mar 2003 18:54:14 -0600 Subject: R9B-1 Compilation errors on OpenBSD 3.3-Current (as of Mar 23, 2003) Message-ID: <20030330005414.GA24953@vailsys.com> Just got the following when attempting to install OTP R9B-1. This is after running a vanilla ./configure (i.e. w/no args): gmake[2]: Leaving directory `/home/rpettit/downloads/otp_src_R9B-1/lib/crypto/src' gmake[2]: Entering directory `/home/rpettit/downloads/otp_src_R9B-1/lib/crypto/c_src' gmake -f i386-unknown-openbsd3.3/Makefile TYPE=opt gmake[3]: Entering directory `/home/rpettit/downloads/otp_src_R9B-1/lib/crypto/c_src' /usr/bin/install -c -d ../priv/obj/i386-unknown-openbsd3.3 gcc -c -o ../priv/obj/i386-unknown-openbsd3.3/crypto_drv.o -g -O2 -I/home/rpettit/downloads/otp_src_R9B-1/erts/i386-unknown-openbsd3.3 -DHAVE_CONFIG_H -O2 -I/usr/include/openssl -I/usr/include -I /home/rpettit/downloads/otp_src_R9B-1/erts/emulator/beam crypto_drv.c crypto_drv.c: In function `control': crypto_drv.c:370: cannot convert to a pointer type crypto_drv.c:372: incompatible type for argument 4 of indirect function call crypto_drv.c:384: cannot convert to a pointer type crypto_drv.c:385: cannot convert to a pointer type crypto_drv.c:386: cannot convert to a pointer type crypto_drv.c:389: incompatible type for argument 4 of indirect function call crypto_drv.c:389: incompatible type for argument 5 of indirect function call crypto_drv.c:389: incompatible type for argument 6 of indirect function call gmake[3]: *** [../priv/obj/i386-unknown-openbsd3.3/crypto_drv.o] Error 1 gmake[3]: Leaving directory `/home/rpettit/downloads/otp_src_R9B-1/lib/crypto/c_src' gmake[2]: *** [opt] Error 2 gmake[2]: Leaving directory `/home/rpettit/downloads/otp_src_R9B-1/lib/crypto/c_src' gmake[1]: *** [opt] Error 2 gmake[1]: Leaving directory `/home/rpettit/downloads/otp_src_R9B-1/lib/crypto' gmake: *** [opt] Error 2 *** Error code 2 Stop in /home/rpettit/downloads/otp_src_R9B-1 (line 157 of Makefile). Any suggestions? -Rick From raimo.niskanen@REDACTED Sun Mar 30 03:09:27 2003 From: raimo.niskanen@REDACTED (Raimo Niskanen) Date: Sun, 30 Mar 2003 03:09:27 +0200 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang.) References: <16002.3807.130791.845508@antilipe.corelatus.se>, <20030327011316.12f6a496.cpressey@catseye.mb.ca>, <010901c2f454$87a67ae0$239ab280@lamppc27> Message-ID: Hi Happi. I am digging into the I/O system for performance reasons, so this time I will add the any-base printing to io_lib for R9C. Not exactly as your suggestion, though. As I read your code, you suggested: io_lib:format("~#", [-31,16]) -> "-16#1f" io_lib:format("~B", [-30]) -> "-1111110" io_lib:format("~b", [18]) -> "00000000000000000000000000010010" io_lib:format("~.8b", [-18]) -> "11101110" io_lib:format("~x", [-31]) -> "-0x1f" io_lib:format("~X", [-31]) -> "-0x1F" And, first I do not want 0x-prefix for hex notation. That is C, not Erlang. A user definable prefix would be better. Second, I would like to be able to choose either upper or lowercase for "~#". Third, I don't see why binary notation would deserve a letter of its own, base 2 without prefix would do the job. So I want a possibility to loose the prefix. So I will most probably implement (if no-one convinces me that I must change something): io_lib:format("~.16b", [-31]) -> "-16#1f" io_lib:format("~.16B", [-31]) -> "-16#1F" io_lib:format("~.16x", [-31,"0x"]) -> "-0x1f" io_lib:format("~.16X", [-31,"0x"]) -> "-0x1F" io_lib:format("~.2.0u", [18,32]) -> "00000000000000000000000000010010" io_lib:format("~.2u", [-18,8]) -> "11101110" io_lib:format("~.16u", [31,16]) -> "1f" io_lib:format("~.16U", [-31,16]) -> "FFEE" I.e b/B for Erlang signed any-Base notation. x/X for eXplicitly prefiXed signed any-base notation. u/U for unprefixed unsigned words of any width. The precision field chooses number base. Second mandatory argument for x/X chooses prefix, for u/U word width. Default base is 10. I am not too happy with my choice of letters, but the best were taken. / Raimo Niskanen, Erlang/OTP Erik Stenman wrote: > Chris Pressey wrote: > [...] > >>Every few months this comes up and every time it does I get more >>irritated. > > [...] > > Here we go agian, my pet peeve ;) > > We have had the posibility to format integers in different bases in our > local HiPE system for several years now, > but for some reason the OTP team does not want to add it to the > distribution. > Robert Virding has also promised to implement it but that implementation has > not made it into the distribution either. > > Please, please add this functionallity to stdlib! > (I can write the documentation if that is a problem ;) > > /Erik > -------------------------------------- > I'm Happi, you should be happy. > Praeterea censeo "0xCA" scribere Erlang posse. > > > Index: lib/stdlib/src/io_lib_format.erl > =================================================================== > RCS file: > /it/project/fo/hipe/repository/otp/lib/stdlib/src/io_lib_format.erl,v > retrieving revision 1.1.1.1 > retrieving revision 1.4 > diff -u -r1.1.1.1 -r1.4 > --- lib/stdlib/src/io_lib_format.erl 26 Mar 2001 18:36:34 -0000 1.1.1.1 > +++ lib/stdlib/src/io_lib_format.erl 27 Mar 2002 16:47:22 -0000 1.4 > @@ -101,11 +101,16 @@ > collect_cc([$p|Fmt], [A|Args]) -> {$p,[A],Fmt,Args}; > collect_cc([$W|Fmt], [A,Depth|Args]) -> {$W,[A,Depth],Fmt,Args}; > collect_cc([$P|Fmt], [A,Depth|Args]) -> {$P,[A,Depth],Fmt,Args}; > +collect_cc([$#|Fmt], [A,Base|Args]) -> {$#,[A,Base],Fmt,Args}; > +collect_cc([$B|Fmt], [A|Args]) -> {$B,[A],Fmt,Args}; > +collect_cc([$b|Fmt], [A|Args]) -> {$b,[A],Fmt,Args}; > collect_cc([$s|Fmt], [A|Args]) -> {$s,[A],Fmt,Args}; > collect_cc([$e|Fmt], [A|Args]) -> {$e,[A],Fmt,Args}; > collect_cc([$f|Fmt], [A|Args]) -> {$f,[A],Fmt,Args}; > collect_cc([$g|Fmt], [A|Args]) -> {$g,[A],Fmt,Args}; > collect_cc([$c|Fmt], [A|Args]) -> {$c,[A],Fmt,Args}; > +collect_cc([$x|Fmt], [A|Args]) -> {$x,[A],Fmt,Args}; > +collect_cc([$X|Fmt], [A|Args]) -> {$X,[A],Fmt,Args}; > collect_cc([$~|Fmt], Args) -> {$~,[],Fmt,Args}; > collect_cc([$n|Fmt], Args) -> {$n,[],Fmt,Args}; > collect_cc([$i|Fmt], [A|Args]) -> {$i,[A],Fmt,Args}. > @@ -155,6 +160,20 @@ > term(io_lib:write(A, Depth), F, Adj, P, Pad); > control($P, [A,Depth], F, Adj, P, Pad, I) when integer(Depth) -> > print(A, Depth, F, Adj, P, Pad, I); > +control($#, [A,Base], F, Adj, P, Pad, I) when integer(Base), > + 2 =< Base, > + Base =< 16-> > + string(int_to_base(A, Base), F, Adj, P, Pad); > +control($B, [A], F, Adj, P, Pad, I) -> > + string( > + if A < 0 -> [$- | int_to_base(-A, [], 2)]; > + true -> int_to_base(A, [], 2) > + end, > + F, Adj, P, Pad); > +control($b, [A], F, Adj, none, Pad, I) -> > + string(int_to_binary(A, 32), F, Adj, none, Pad); > +control($b, [A], F, Adj, P, Pad, I) -> > + string(int_to_binary(A, P), F, Adj, P, Pad); > control($s, [A], F, Adj, P, Pad, I) when atom(A) -> > string(atom_to_list(A), F, Adj, P, Pad); > control($s, [L], F, Adj, P, Pad, I) -> > @@ -168,6 +187,10 @@ > fwrite_g(A, F, Adj, P, Pad); > control($c, [A], F, Adj, P, Pad, I) when integer(A) -> > char(A band 255, F, Adj, P, Pad); > +control($x, [A], F, Adj, P, Pad, I) when integer(A) -> > + string(int_to_hex(A), F, Adj, P, Pad); > +control($X, [A], F, Adj, P, Pad, I) when integer(A) -> > + string(int_to_Hex(A), F, Adj, P, Pad); > control($~, [], F, Adj, P, Pad, I) -> char($~, F, Adj, P, Pad); > control($n, [], F, Adj, P, Pad, I) -> newline(F, Adj, P, Pad); > control($i, [A], F, Adj, P, Pad, I) -> []. > @@ -388,3 +411,58 @@ > flat_length([H|T], L) -> > flat_length(T, L + 1); > flat_length([], L) -> L. > + > +int_to_hex(N) -> int_to_hex(N, $a-10). > +int_to_Hex(N) -> int_to_hex(N, $A-10). > + > +int_to_hex(N, LetterBase) -> > + if N < 0 -> [$-, $0, $x | int_to_hex(-N, [], LetterBase)]; > + true -> [$0, $x | int_to_hex(N, [], LetterBase)] > + end. > + > +int_to_hex(N, Tail, LetterBase) -> > + NewN = N bsr 4, > + Digit = N band 15, > + Char = > + if Digit < 10 -> Digit+$0; > + true -> Digit+LetterBase > + end, > + NewTail = [Char | Tail], > + if NewN =:= 0 -> NewTail; > + true -> int_to_hex(NewN, NewTail, LetterBase) > + end. > + > +int_to_binary(N, Wordsize) -> > + if N < 0 -> > + Bits = int_to_base(-N, [],2), > + pad(length(Bits),Bits,Wordsize,$1); > + true -> > + Bits = int_to_base(N, [], 2), > + pad(length(Bits),Bits,Wordsize,$0) > + end. > + > +pad(N,Bits,Wordsize, Pad) -> > + if N < Wordsize -> > + pad(N+1,[Pad|Bits],Wordsize,Pad); > + true -> > + Bits > + end. > + > + > +int_to_base(N, Base) -> > + if N < 0 -> [$- | integer_to_list(Base)] > + ++ [$# | int_to_base(-N, [], Base)]; > + true -> integer_to_list(Base) ++ [$# | int_to_base(N, [], Base)] > + end. > + > +int_to_base(N, Tail, Base) -> > + NewN = N div Base, > + Digit = N - (NewN*Base), > + Char = > + if Digit < 10 -> Digit+$0; > + true -> Digit+$a-10 > + end, > + NewTail = [Char | Tail], > + if NewN =:= 0 -> NewTail; > + true -> int_to_base(NewN, NewTail, Base) > + end. > From raimo.niskanen@REDACTED Sun Mar 30 03:21:09 2003 From: raimo.niskanen@REDACTED (Raimo Niskanen) Date: Sun, 30 Mar 2003 03:21:09 +0200 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang References: Message-ID: I am about to add your requested functionality to io_lib:format, so I thought about adding these BIFs too, but it turned out that it was hard to decide what they should do, exactly: Erlang-style prefix or not, lowercase or UPPERCASE or selectable and how to select, how to select any-base for list_to_integer/2, etc. It started to seem that an option list was needed with quite some options, and then they suddenly did seem too complicated to be BIFs. So I hope it will do to use something like lists:flatten(io_lib:format("~16b", [Integer])). If it is necessary for performance reasons, we might add these BIFs later. / Raimo Niskanen, Erlang/OTP James Hague wrote: > I've often thought Erlang should have the BIFs: > > integer_to_list(Base, Integer) > list_to_integer(Base, List) > > In addition to the arity-1 versions that currently exist. From bernardp@REDACTED Sun Mar 30 08:23:42 2003 From: bernardp@REDACTED (Pierpaolo BERNARDI) Date: Sun, 30 Mar 2003 08:23:42 +0200 Subject: Error prone behavior of regexp. / Emacs mode. References: Message-ID: <022f01c2f68d$e13406a0$0ef36850@c1p4e3> Several functions in regexp behave like this: 22> regexp:match("foo",xxx). nomatch That is, if the r.e. is not a list, it is assumed to be an already parsed r.e. with no safety check whatsoever. I tripped in this doing by mistake: RE = regexp:parse([$t,$r,$e,$$]), lists:map(fun(P)-> ... {ok,S3,_} = regexp:sub(P,RE,"tr?"), Surely my fault, but the module could easily be more helpful. ----- On another topic, the emacs mode misparses strings ending in $. In "foo$", $" is parsed as a character, compromising the indentation of the rest of the file. Before I start digging in the emacs mode, maybe someone has already fixed this? P. From ncharpentier@REDACTED Sun Mar 30 10:11:43 2003 From: ncharpentier@REDACTED (Nicolas Charpentier) Date: Sun, 30 Mar 2003 10:11:43 +0200 Subject: question about orber Message-ID: <01a701c2f694$00fb3110$99b63551@CHARPI> Hi, I'm beginner with orber. I want to specify the object key of my servant to be able to use the "corbaloc" style URL by I don't see this in the documentation. Please, someone could help me ? Thanks, Nicolas Charpentier From thomasl_erlang@REDACTED Sun Mar 30 13:22:11 2003 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Sun, 30 Mar 2003 03:22:11 -0800 (PST) Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang In-Reply-To: Message-ID: <20030330112211.6234.qmail@web13307.mail.yahoo.com> Let me add that number_to_list/1 list_to_number/1 would be useful (esp. the latter). Possibly also constant_to_list/1 list_to_constant/1 Best, Thomas --- Raimo Niskanen wrote: > I am about to add your requested functionality to > io_lib:format, so I > thought about adding these BIFs too, but it turned > out that it was hard > to decide what they should do, exactly: Erlang-style > prefix or not, > lowercase or UPPERCASE or selectable and how to > select, how to select > any-base for list_to_integer/2, etc. > > It started to seem that an option list was needed > with quite some > options, and then they suddenly did seem too > complicated to be BIFs. > > So I hope it will do to use something like > lists:flatten(io_lib:format("~16b", [Integer])). > > If it is necessary for performance reasons, we might > add these BIFs later. > > / Raimo Niskanen, Erlang/OTP > > > > James Hague wrote: > > I've often thought Erlang should have the BIFs: > > > > integer_to_list(Base, Integer) > > list_to_integer(Base, List) > > > > In addition to the arity-1 versions that currently > exist. > __________________________________________________ Do you Yahoo!? Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop! http://platinum.yahoo.com From kent@REDACTED Sun Mar 30 20:38:13 2003 From: kent@REDACTED (Kent Boortz) Date: 30 Mar 2003 20:38:13 +0200 Subject: R9B-1 Compilation errors on OpenBSD 3.3-Current (as of Mar 23, 2003) In-Reply-To: <20030330005414.GA24953@vailsys.com> References: <20030330005414.GA24953@vailsys.com> Message-ID: Rick Pettit writes: > Just got the following when attempting to install OTP R9B-1. This is after > running a vanilla ./configure (i.e. w/no args): This has been answered recently, see http://www.erlang.org/ml-archive/erlang-questions/200303/msg00439.html kent From rpettit@REDACTED Sun Mar 30 22:44:44 2003 From: rpettit@REDACTED (Rick Pettit) Date: Sun, 30 Mar 2003 14:44:44 -0600 Subject: R9B-1 Compilation errors on OpenBSD 3.3-Current (as of Mar 23, 2003) In-Reply-To: References: <20030330005414.GA24953@vailsys.com> Message-ID: <20030330204444.GC24953@vailsys.com> On Sun, Mar 30, 2003 at 08:38:13PM +0200, Kent Boortz wrote: > > Rick Pettit writes: > > Just got the following when attempting to install OTP R9B-1. This is after > > running a vanilla ./configure (i.e. w/no args): > > This has been answered recently, see > > http://www.erlang.org/ml-archive/erlang-questions/200303/msg00439.html Thanks. I applied the patch, and made it _farther_ in the compilation, but now die in building os_mon: gmake[2]: Entering directory `/home/rpettit/downloads/otp_src_R9B-1/lib/os_mon/c_src' gmake -f i386-unknown-openbsd3.3/Makefile TYPE=opt gmake[3]: Entering directory `/home/rpettit/downloads/otp_src_R9B-1/lib/os_mon/c_src' gcc -c -o ../priv/obj/i386-unknown-openbsd3.3/memsup.o -g -O2 -I/home/rpettit/downloads/otp_src_R9B-1/erts/i386-unknown-openbsd3.3 -DHAVE_CONFIG_H memsup.c memsup.c:98: vm/vm_param.h: No such file or directory gmake[3]: *** [../priv/obj/i386-unknown-openbsd3.3/memsup.o] Error 1 gmake[3]: Leaving directory `/home/rpettit/downloads/otp_src_R9B-1/lib/os_mon/c_src' gmake[2]: *** [opt] Error 2 gmake[2]: Leaving directory `/home/rpettit/downloads/otp_src_R9B-1/lib/os_mon/c_src' gmake[1]: *** [opt] Error 2 gmake[1]: Leaving directory `/home/rpettit/downloads/otp_src_R9B-1/lib/os_mon' gmake: *** [opt] Error 2 *** Error code 2 Stop in /home/rpettit/downloads/otp_src_R9B-1 (line 157 of Makefile). Again, after extracting the tarball I did the following: prompt> ./configure prompt> make This is on a machine running: OpenBSD 3.3 (GENERIC) #42: Tue Mar 25 16:50:16 MST 2003 deraadt@REDACTED:/usr/src/sys/arch/i386/compile/GENERIC cpu0: Intel Pentium III (Coppermine) ("GenuineIntel" 686-class) 848 MHz I apologize if this has already been covered. Going back now to check list archives again... Thanks for your help. -Rick From kent@REDACTED Sun Mar 30 23:30:30 2003 From: kent@REDACTED (Kent Boortz) Date: 30 Mar 2003 23:30:30 +0200 Subject: R9B-1 Compilation errors on OpenBSD 3.3-Current (as of Mar 23, 2003) In-Reply-To: <20030330204444.GC24953@vailsys.com> References: <20030330005414.GA24953@vailsys.com> <20030330204444.GC24953@vailsys.com> Message-ID: Rick Pettit writes: > gcc -c -o ../priv/obj/i386-unknown-openbsd3.3/memsup.o -g -O2 -I/home/rpettit/downloads/otp_src_R9B-1/erts/i386-unknown-openbsd3.3 -DHAVE_CONFIG_H memsup.c > memsup.c:98: vm/vm_param.h: No such file or directory . . > I apologize if this has already been covered. Going back now to check list > archives again... This error I haven't seen. If you don't plan to use os_mon you can disable the build of that part using % touch /home/rpettit/downloads/otp_src_R9B-1/lib/os_mon/SKIP after the configure. kent From dne@REDACTED Mon Mar 31 01:33:04 2003 From: dne@REDACTED (Daniel =?iso-8859-1?q?N=E9ri?=) Date: Mon, 31 Mar 2003 01:33:04 +0200 Subject: R9B-1 Compilation errors on OpenBSD 3.3-Current (as of Mar 23, 2003) References: <20030330005414.GA24953@vailsys.com> <20030330204444.GC24953@vailsys.com> Message-ID: <877kagpgzz.fsf@nowhere.mayonnaise.net> Rick Pettit writes: > gcc -c -o ../priv/obj/i386-unknown-openbsd3.3/memsup.o -g -O2 -I/home/rpettit/downloads/otp_src_R9B-1/erts/i386-unknown-openbsd3.3 -DHAVE_CONFIG_H memsup.c > memsup.c:98: vm/vm_param.h: No such file or directory [snip] > This is on a machine running: > > OpenBSD 3.3 (GENERIC) #42: Tue Mar 25 16:50:16 MST 2003 I'm afraid this is one is my fault -- try removing the include of altogether. It's a result of my creating the os_mon port on a machine full of left-overs from various OpenBSD releases since 2.4, i.e. since before the change to UVM. Regards, -- Daniel Neri dne@REDACTED From nick@REDACTED Mon Mar 31 09:49:00 2003 From: nick@REDACTED (Niclas Eklund) Date: Mon, 31 Mar 2003 09:49:00 +0200 (MEST) Subject: question about orber In-Reply-To: <01a701c2f694$00fb3110$99b63551@CHARPI> Message-ID: Hello! You can find corbaname/corbaloc in chapter 7.3 (Interoperable Namingservice): http://www.erlang.org/doc/r9b/lib/orber-3.3/doc/html/ch_naming_service.html#7.3 You should also look at orbDefaultInitRef/orbInitRef in chapter 5.2 (Configuration). Which version do you use? /Nick On Sun, 30 Mar 2003, Nicolas Charpentier wrote: > Hi, > I'm beginner with orber. I want to specify the object key of my servant to > be able to use > the "corbaloc" style URL by I don't see this in the documentation. > Please, someone could help me ? > Thanks, > Nicolas Charpentier From raimo.niskanen@REDACTED Mon Mar 31 13:30:56 2003 From: raimo.niskanen@REDACTED (Raimo Niskanen) Date: Mon, 31 Mar 2003 13:30:56 +0200 Subject: odd problem with distributed erlang system References: <200303261828.h2QISaK01757@kestrel.sage.att.com> Message-ID: I have had a probably related problem. It was on Debian 3.0 (Linux 2.4.18 kernel) with OTP R9B and an automounted NFS volume. I had lots of problems to make the automounter use the mount options I wanted, partly because the automounter I used (amd) seems to not use the mount command, but a library API, so when I was done I had changed automounters, written some weird scripts, etc. But if I try to get down to the core of the problem: Writing a file on the NFS volume took forever (some 10..100 times slower than local disk). The file was opened with file:open(Name, [write, delayed_write, binary]) so small writes were buffered up to 64 KBytes (default for delayed_write). The writes were small, one line at the time. (This is probably the way disk_log does it too, by the way) What happened was that the file driver buffered write request up to 64 KBytes, but to minimize copying they are queued, and later written using writev() with a vector of 1024 (on the Linux in question) small buffers. Some code in the Linux kernel that writes the data on the NFS filesystem (or the NFS code itself) then chops this up into 1024 write requests over NFS instead of holding the writev request together. The NFS volume was synchronously monted which resulted in about 4 NFS messages back and forth for each write request. Performance sucked. The solution was to not mount the volume synchronously, i.e I added the mount options: "async,actimeou=0". The "actimeout=0" flag sets attribute caching timeout to 0, which is pretty syncronous, and will do for me. With these mount options the NFS filesystem realizes that it can bundle those 1024 small buffers into one write request, with some handshaking around it, and it goes as fast as one can expect. / Raimo Niskanen, Erlang/OTP Garry Hodgson wrote: > i'm trying to debug a strange problem we're seeing in one > of our systems. we've got a number of linux clusters, all > running vanilla redhat 7.x, and we only see this on one > of them. the application is a pretty basic one, where we > have a master node that starts up processes on other compute > nodes. each of these others is runs an erlang port process > which invokes an external program to handle queries. the whole > thing is accessed through a web site which does queries of the > master server. the master forwards the query to the appropriate > child. each type of information server is started on a different > node, in on-demand order. > > the problem is this: the first query comes in, causing a server, > say, foo, to run on node1. all is good. a different query comes > in which needs a baz server, which gets started on node2. this query > will run *realllllly* slow, eventually likely timing out before it returns > a result (which it will do eventually). when i say slow, i'm talking > minutes. the really odd thing is that the child process is writing to > a log file (nfs mounted from master), using the erlang dblog stuff, > and debug messages that occur in the same function, only a few lines > apart, come in several minutes apart. > > the problem is independent of the order in which the nodes start, > or the servers start, or which subserver runs on whoich node, etc. > we've eliminated (i think) all the obvious cases. it really feels > like a machine configuration problem. this cluster is in a secure > lab, and has gone through a few rounds of network rearrangements. > the problem doesn't occur on any of the other similar systems we've > deployed, and we can't recreate it in our development systems. > > so, does anybody have any ideas about what to look for, or what kinds > of things could make erlang run so slow on machine? it feels like a > timeout of some sort, but we've looked at the obvious name lookup > things and such (does erlang require dns? we're using local /etc/host > for name resolution). is there something else internal that we might > be waiting on? > > any ideas, suggestions, or pointers to useful test cases would be > greatly appreciated. it's awkward to debug since we have only > restricted access to the broken system. > > thanks for your help. > From tony@REDACTED Mon Mar 31 13:44:09 2003 From: tony@REDACTED (Tony Rogvall) Date: Mon, 31 Mar 2003 13:44:09 +0200 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang References: <1048988965.9852@DNS02> Message-ID: <3E882A09.4090809@rogvall.com> Raimo Niskanen wrote: > > I am about to add your requested functionality to io_lib:format, so I > thought about adding these BIFs too, but it turned out that it was hard > to decide what they should do, exactly: Erlang-style prefix or not, > lowercase or UPPERCASE or selectable and how to select, how to select > any-base for list_to_integer/2, etc. > > It started to seem that an option list was needed with quite some > options, and then they suddenly did seem too complicated to be BIFs. > Here is one suggestion for R9C integer_to_list(Integer, Base) where integer(Integer) and Base = bin | oct | hex or dec - The prefix is not needed sice it is a constant op to cons "16#" or whatever as a prefix. - The case is not very important for hex numbers since most "readers" can read both upper an lower case, correct me I you ever seen any software (not your own:-) that care about case in hex numbers! . I vote for uppercase, since that what is what I have seen most. If it should be a problem then we can add 'heX' as uppercase option. I wonder how many times I have written integer_to_hex? I am sure it must be 100 times... When we are at it, why not do the same thing for list_to_integer? I suggest: list_to_integer(List, Base) (base = bin | oct | hex | dec ) possibly allowing base spec in the list_to_integer/1 i.e list_to_integer("16#1234") Raimo you can give me a call, I will be glad to help you :-) > So I hope it will do to use something like > lists:flatten(io_lib:format("~16b", [Integer])). > > If it is necessary for performance reasons, we might add these BIFs later. > Why wait ? I do not think we can talk us out of this one :-) /Tony -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 3237 bytes Desc: S/MIME Cryptographic Signature URL: From raimo.niskanen@REDACTED Mon Mar 31 14:31:45 2003 From: raimo.niskanen@REDACTED (Raimo Niskanen) Date: Mon, 31 Mar 2003 14:31:45 +0200 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang References: , <1048988965.9852@DNS02>, <3E882A09.4090809@rogvall.com> Message-ID: Some comments and some problems. Since Erlang supports the Base#Integer syntax i think that Base in: integer_to_list(Integer, Base) should be 2..16, not atoms. The same for: list_to_integer(List, Base) But what should happen if you call list_to_integer("16#1f", 8), and how should you specify any base. I guess the answers are: badarg on the first and list_to_integer("16#1f", undefined) on the second question. And to add the prefix in the Right(tm) way is a bit awkward: List = case integer_to_list(Integer, 16) of [$-|L] -> "-16#"++L; L -> "16#"++L end / Raimo Tony Rogvall wrote: > Raimo Niskanen wrote: > >> >> I am about to add your requested functionality to io_lib:format, so I >> thought about adding these BIFs too, but it turned out that it was >> hard to decide what they should do, exactly: Erlang-style prefix or >> not, lowercase or UPPERCASE or selectable and how to select, how to >> select any-base for list_to_integer/2, etc. >> >> It started to seem that an option list was needed with quite some >> options, and then they suddenly did seem too complicated to be BIFs. >> > Here is one suggestion for R9C > > integer_to_list(Integer, Base) > > where integer(Integer) and Base = bin | oct | hex or dec > > - The prefix is not needed sice it is a constant op to cons "16#" or > whatever as a prefix. > > - The case is not very important for hex numbers since most "readers" > can read both upper an lower case, correct me I you ever seen any > software (not your own:-) that care about case in hex numbers! . I vote > for uppercase, since that what is what I have seen most. If it should be > a problem then we can add 'heX' as uppercase option. > > I wonder how many times I have written integer_to_hex? I am sure it must > be 100 times... > > When we are at it, why not do the same thing for list_to_integer? > I suggest: > list_to_integer(List, Base) (base = bin | oct | hex | dec ) > > possibly allowing base spec in the list_to_integer/1 i.e > list_to_integer("16#1234") > > > Raimo you can give me a call, I will be glad to help you :-) > >> So I hope it will do to use something like >> lists:flatten(io_lib:format("~16b", [Integer])). >> >> If it is necessary for performance reasons, we might add these BIFs >> later. >> > > Why wait ? I do not think we can talk us out of this one :-) > > /Tony From joe@REDACTED Mon Mar 31 14:50:43 2003 From: joe@REDACTED (Joe Armstrong) Date: Mon, 31 Mar 2003 14:50:43 +0200 (CEST) Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang .) In-Reply-To: Message-ID: On Thu, 27 Mar 2003, James Hague wrote: > I've often thought Erlang should have the BIFs: > > integer_to_list(Base, Integer) > list_to_integer(Base, List) > > In addition to the arity-1 versions that currently exist. > (-: What what what .... wot ... what's this all this integer stuff .. If we generalise over non-integer bases to can easily make (say) an avoirdupois converter, so that: integer_to_list([20,4,2,14,16,16], 456789) would then convert 456789 drams to (tons,quarters,hundredweight,stones,pounds,ounces,drams) and so on ... *very* useful for calculating with common units - think about it for a few micro-Fortnight's .... Non-integer bases would give logs and things Ln = fun(X) -> list_to_number(10, number_to_base(2.7138, X)) end, ... We could then have base pi numbers for easy calculation of geometric quantities, And negative bases would give complex numbers, etc /Joe :-) From enano@REDACTED Mon Mar 31 14:32:12 2003 From: enano@REDACTED (Miguel Barreiro Paz) Date: Mon, 31 Mar 2003 14:32:12 +0200 (CEST) Subject: odd problem with distributed erlang system In-Reply-To: References: <200303261828.h2QISaK01757@kestrel.sage.att.com> Message-ID: > It was on Debian 3.0 (Linux 2.4.18 kernel) with OTP R9B and an > automounted NFS volume. I had lots of problems to make the automounter > use the mount options I wanted, partly because the automounter I used > (amd) seems to not use the mount command, but a library API, so when I > was done I had changed automounters, written some weird scripts, etc. NFS on Linux has traditionally been a weak spot. It's much much better today. My experience on nfs on linux: - dump amd and use autofs instead - force rsize and wsize to 8192 if autofs doesn't do it for you - use NFSv3 (yes, it's marked "experimental", but has been in use here for a _long_ time without worry. Maybe we just were lucky) - mount "hard" or "hard,intr" - NFSv3 over TCP is still a little bit unreliable in my humble experience. - Async mounts are perfectly OK in a LAN for most purposes. - use jumbo frames if you're on 1000Base-* and hardware allows (1 ether frame per 8KB NFS datagram is nice) - tcpdump is your friend, as you already know :-) > The solution was to not mount the volume synchronously, i.e I added the > mount options: "async,actimeou=0". The "actimeout=0" flag sets attribute > caching timeout to 0, which is pretty syncronous, and will do for me. Not quite the same as "sync" but good enough unless someone runs a mail spool or something similarly insane on that fs. From tony@REDACTED Mon Mar 31 15:33:50 2003 From: tony@REDACTED (Tony Rogvall) Date: Mon, 31 Mar 2003 15:33:50 +0200 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang References: , <1048988965.9852@DNS02>, <3E882A09.4090809@rogvall.com> <1049114703.23309@DNS02> Message-ID: <3E8843BE.30601@rogvall.com> Raimo Niskanen wrote: > > Some comments and some problems. Since Erlang supports the Base#Integer > syntax i think that Base in: > integer_to_list(Integer, Base) > should be 2..16, not atoms. > I just thought it would look nice, but I can buy 2..16 (btw do you know any one using base 13 for output? and since we only alow 2..16 its kind of crippled anyway) > The same for: > list_to_integer(List, Base) > Oh well. > But what should happen if you call list_to_integer("16#1f", 8), and how > should you specify any base. I guess the answers are: badarg on the > first and list_to_integer("16#1f", undefined) on the second question. > Like you said, do NOT allow base syntax in the list_to_integer/2 (why should you?) but maybe in list_to_integer/1 (if that does not break anything, it could!) > And to add the prefix in the Right(tm) way is a bit awkward: > List = case integer_to_list(Integer, 16) of > [$-|L] -> "-16#"++L; > L -> "16#"++L > end My oppinon is that we ignore the prefix stuff completly just to get things on it's way. I myself have never sent any output in base syntax (anyone?). /Tony -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 3237 bytes Desc: S/MIME Cryptographic Signature URL: From bernardp@REDACTED Mon Mar 31 16:34:33 2003 From: bernardp@REDACTED (Pierpaolo BERNARDI) Date: Mon, 31 Mar 2003 16:34:33 +0200 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang References: <1048988965.9852@DNS02> <3E882A09.4090809@rogvall.com> Message-ID: <042101c2f792$e28be4e0$d0f06850@c1p4e3> From: "Tony Rogvall" > Here is one suggestion for R9C > > integer_to_list(Integer, Base) > > where integer(Integer) and Base = bin | oct | hex or dec > > - The prefix is not needed sice it is a constant op to cons "16#" or > whatever as a prefix. What about negative integers? BTW, I find this behaviour of the erlang parser puzzling: 51> 16#-123. -123 52> 16#. 0 Is this intended? what's its rationale? > When we are at it, why not do the same thing for list_to_integer? > I suggest: > list_to_integer(List, Base) (base = bin | oct | hex | dec ) When you are at it, why don't you allow underscores in numbers, like in Ada and Ocaml? I am using the following: -export([digit_val/1, digit_val/2, list_to_integer_/1, list_to_integer_/2]). %%% list_to_integer_("1_23_45") -> 12345 %%% list_to_integer_("_1_23_45") -> error %%% list_to_integer_("1__23_45") -> error %%% list_to_integer_("1_23_45_") -> error %%% list_to_integer_("89AB_CDEF",16) -> 2309737967 list_to_integer_(L) -> list_to_integer_(L,10). list_to_integer_([$+|T],Base) -> list_to_integer_pos(T,Base); list_to_integer_([$-|T],Base) -> -list_to_integer_pos(T,Base); list_to_integer_(L,Base) -> list_to_integer_pos(L,Base). list_to_integer_pos(L=[C|_],Base) when C =/= $_ -> list_to_integer_pos(L,0,Base). list_to_integer_pos([],Acc,Base) -> Acc; list_to_integer_pos("_"++(L=[C|_]),Acc,Base) when C =/= $_ -> list_to_integer_pos(L,Acc,Base); list_to_integer_pos([C|L],Acc,Base) -> list_to_integer_pos(L,Acc*Base+digit_val(C,Base),Base). digit_val(C) -> digit_val(C,10). %%% digit_val($F,16) -> 15 %%% digit_val($f,16) -> 15 %%% digit_val($3) -> 3 %%% digit_val($Z) -> false digit_val(C,Base) when Base =< 10 -> case C >= $0 andalso C < $0 + Base of false -> false; true -> C - $0 end; digit_val(C,Base) when Base > 10 -> case digit_val(C,10) of false -> Base1 = Base - 10, case (C >= $A andalso C < $A + Base1) of false -> case (C >= $a andalso C < $a + Base1) of false -> false; true -> C - $a + 10 end; true -> C - $A + 10 end; V -> V end. P. From bernardp@REDACTED Mon Mar 31 17:04:39 2003 From: bernardp@REDACTED (Pierpaolo BERNARDI) Date: Mon, 31 Mar 2003 17:04:39 +0200 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang References: <1048988965.9852@DNS02> <3E882A09.4090809@rogvall.com> <042101c2f792$e28be4e0$d0f06850@c1p4e3> Message-ID: <047501c2f796$f0df0d20$d0f06850@c1p4e3> From: "Pierpaolo BERNARDI" > BTW, I find this behaviour of the erlang parser puzzling: > > 51> 16#-123. > -123 > 52> 16#. > 0 > > Is this intended? what's its rationale? I mean, I know the correct syntax, I am wondering why this doesn't raise an error. I was cheking if by chance I had overlooked a bit of syntax and 16#-123 was valid. P. From richardc@REDACTED Mon Mar 31 18:17:47 2003 From: richardc@REDACTED (Richard Carlsson) Date: Mon, 31 Mar 2003 18:17:47 +0200 (MET DST) Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang In-Reply-To: <042101c2f792$e28be4e0$d0f06850@c1p4e3> References: <1048988965.9852@DNS02> <3E882A09.4090809@rogvall.com> <042101c2f792$e28be4e0$d0f06850@c1p4e3> Message-ID: On Mon, 31 Mar 2003, Pierpaolo BERNARDI wrote: > When you are at it, why don't you allow underscores in numbers, > like in Ada and Ocaml? Especially since this is actually specified in the old Standard Erlang specification draft by Barklund and Virding. (Which these days is partly outdated, but still contains a lot of not-yet-implemented things.) /Richard Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) E-mail: Richard.Carlsson@REDACTED WWW: http://user.it.uu.se/~richardc/ "Having users is like optimization: the wise course is to delay it." -- Paul Graham From cpressey@REDACTED Mon Mar 31 20:03:22 2003 From: cpressey@REDACTED (Chris Pressey) Date: Mon, 31 Mar 2003 12:03:22 -0600 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang In-Reply-To: <3E8843BE.30601@rogvall.com> References: <1048988965.9852@DNS02> <3E882A09.4090809@rogvall.com> <1049114703.23309@DNS02> <3E8843BE.30601@rogvall.com> Message-ID: <20030331120322.40c58cb6.cpressey@catseye.mb.ca> On Mon, 31 Mar 2003 15:33:50 +0200 Tony Rogvall wrote: > My oppinon is that we ignore the prefix stuff completly just to get > things on it's way. I myself have never sent any output in base syntax > (anyone?). > > /Tony I think generating prefixes as part of integer_to_list would be a Bad Thing because people are obviously going to be using this for generating e.g. md5 fingerprints and other general cases, not just (not even primarily) for generating Erlang source code. -Chris From ncharpentier@REDACTED Mon Mar 31 20:41:07 2003 From: ncharpentier@REDACTED (Nicolas Charpentier) Date: Mon, 31 Mar 2003 20:41:07 +0200 Subject: question about orber References: Message-ID: <005d01c2f7b5$1d488b70$12b63551@CHARPI> Hi, thanks for your answer First I'm using OTP R9 with orber 3.3. In fact, I have an existing application based on CORBA written in a "common" language (C++ or Java), and I want to rewrite one of my server in Erlang. Some applications use "corbaloc" string to contact this server, so we activate the servant with an persistent IOR (using the right policy of the POA). With this activation, we are able to specify the object key ( the key_string in the orber BNF notation). Reading this document, I can imagine that using corba:add_initial_service(XXX, Servant). specify a pseudo object key, but maybe I'm wrong ? Is there any "poa-like" in orber ? Regards, Nicolas Charpentier. > > Hello! > > You can find corbaname/corbaloc in chapter 7.3 (Interoperable > Namingservice): > > http://www.erlang.org/doc/r9b/lib/orber-3.3/doc/html/ch_naming_service.html# 7.3 > > You should also look at orbDefaultInitRef/orbInitRef in chapter 5.2 > (Configuration). > > Which version do you use? > > /Nick > > On Sun, 30 Mar 2003, Nicolas Charpentier wrote: > > > Hi, > > I'm beginner with orber. I want to specify the object key of my servant to > > be able to use > > the "corbaloc" style URL by I don't see this in the documentation. > > Please, someone could help me ? > > Thanks, > > Nicolas Charpentier > > > > From rpettit@REDACTED Mon Mar 31 20:52:17 2003 From: rpettit@REDACTED (Rick Pettit) Date: Mon, 31 Mar 2003 12:52:17 -0600 Subject: R9B-1 Compilation errors on OpenBSD 3.3-Current (as of Mar 23, 2003) In-Reply-To: <877kagpgzz.fsf@nowhere.mayonnaise.net> References: <20030330005414.GA24953@vailsys.com> <20030330204444.GC24953@vailsys.com> <877kagpgzz.fsf@nowhere.mayonnaise.net> Message-ID: <20030331185217.GC30095@vailsys.com> On Mon, Mar 31, 2003 at 01:33:04AM +0200, Daniel N?ri wrote: > Rick Pettit writes: > > > gcc -c -o ../priv/obj/i386-unknown-openbsd3.3/memsup.o -g -O2 -I/home/rpettit/downloads/otp_src_R9B-1/erts/i386-unknown-openbsd3.3 -DHAVE_CONFIG_H memsup.c > > memsup.c:98: vm/vm_param.h: No such file or directory > > [snip] > > > This is on a machine running: > > > > OpenBSD 3.3 (GENERIC) #42: Tue Mar 25 16:50:16 MST 2003 > > I'm afraid this is one is my fault -- try removing the include of > altogether. It's a result of my creating the os_mon > port on a machine full of left-overs from various OpenBSD releases > since 2.4, i.e. since before the change to UVM. That did the trick...thanks! -Rick From cpressey@REDACTED Mon Mar 31 21:35:03 2003 From: cpressey@REDACTED (Chris Pressey) Date: Mon, 31 Mar 2003 13:35:03 -0600 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang .) In-Reply-To: References: Message-ID: <20030331133503.2e3fe0d2.cpressey@catseye.mb.ca> On Mon, 31 Mar 2003 14:50:43 +0200 (CEST) Joe Armstrong wrote: > If we generalise over non-integer bases to can easily make (say) an > avoirdupois converter, so that: > > integer_to_list([20,4,2,14,16,16], 456789) > > would then convert 456789 drams to > (tons,quarters,hundredweight,stones,pounds,ounces,drams) > > and so on ... *very* useful for calculating with common units - > think about it for a few micro-Fortnight's .... Hm! Despite your slightly facetious tone I think you have touched on one of the biggest blind spots in software engineering, something that has been a thorn in my side for more than a couple of years. So of course I'm going to rant about it. I have yet to see a programming language that doesn't model basic numbers as scalar values (or matrices or sets of scalars). Yet, I don't see *any* scalar values in the world around me. They *all* have units of measurement. But, you may well say, what's the big deal? We *have* to make some concessions to translate a model from the real world onto a computer - why is dropping the units of measurement not justifiable? Two reasons: the Gimli Glider[1] and the Mars Climate Orbiter[2]. The latter resulted in an immense loss of property; the former would have resulted in the loss of life, had the pilots not been as skilled as they were, and had the Gimli airstrip not have had the foresight to be located in Gimli. Looking at these mixups you may well conclude, we should simply abandon imperial measurement in favour of metric (good luck!) Unfortunately, that would only help mitigate the problem; it doesn't help solve it. Think of how many times you've had to look up the timer manpage to see if a given parameter is in milliseconds or microseconds. If the basic numeric type of Erlang (or in fact any other programming language) was rich enough to include the units of measurement, there would be no need for such confusion and doc-hunting - and I submit that the language would become that much more expressive: receive {update_distance, D} when D is_in m -> {ok, whatever(D)} after 5 sec -> {error, timeout} end For a while I tried designing a new language around measurements. It was only a partial success, and I was encouraged to modify an existing language instead, for correctness issues - but when trying that with Erlang, I was discouraged from modifying the existing language, for familiarity / predictability issues. I'm not sure which path I'll take next time. -Chris [1] http://www.wadenelson.com/gimli.html [2] http://mars.jpl.nasa.gov/msp98/news/mco990930.html From twanvds@REDACTED Mon Mar 31 23:20:54 2003 From: twanvds@REDACTED (Twan van der Schoot) Date: Mon, 31 Mar 2003 23:20:54 +0200 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang .) Message-ID: <01C2F7DC.2DF175A0.twanvds@xs4all.nl> Hi Chris, On Monday, March 31, 2003 9:35 PM, Chris Pressey wrote: > > Yet, I don't see *any* scalar values in the world around me. They *all* > have units of measurement. I'm sorry, but quite a number of constants in physical are dimensionless. And these have a "scalar" nature. But in a typical programming context, what about an ordinal number like an index in an array? And just counting of elements in a list? Do you want to count the number of elements, like 23_element, or 23_list, in case that list is comprised of lists? Besides, one introduces the requirement for a kind of type-system (i.c. dimension/unit checking and derivation). For the usual arithmatical expressions this may be not a problem. But what unit has a list of, say, metres? And the second question then pops up immediately. Does one want to base such a measurement system on the structure of the dimension or should it be a level more concrete and should one use a concrete unit standard (like SI or BSI or ANSI). Eventhough it would make doc-hunting less necessary, it is much too concrete to be "sufficently" generic for a universal programming langauge. BTW: Are you acquainted with the HP48? That nifty calculator allows you to enter number extended with units and all arthimatic behaves nice. So, I guess that leaving scalars in favour of "unit objects" is not a concept for a universal programming language. But I do think it would be great to have facilities in a programming language which make it attractive to have a standard library available which lowers the threshold to implement /applications/ utilising unit objects as the main representation of a measurement. What these facilities precisely should be without unduly interference with the basic clarity of the programming language, I don't know. br Twan van der Schoot. > > But, you may well say, what's the big deal? We *have* to make some > concessions to translate a model from the real world onto a computer - > why is dropping the units of measurement not justifiable? > > Two reasons: the Gimli Glider[1] and the Mars Climate Orbiter[2]. > > The latter resulted in an immense loss of property; the former would > have resulted in the loss of life, had the pilots not been as skilled as > they were, and had the Gimli airstrip not have had the foresight to be > located in Gimli. > > Looking at these mixups you may well conclude, we should simply abandon > imperial measurement in favour of metric (good luck!) > > Unfortunately, that would only help mitigate the problem; it doesn't > help solve it. Think of how many times you've had to look up the timer > manpage to see if a given parameter is in milliseconds or microseconds. > > If the basic numeric type of Erlang (or in fact any other programming > language) was rich enough to include the units of measurement, there > would be no need for such confusion and doc-hunting - and I submit that > the language would become that much more expressive: > > receive > {update_distance, D} when D is_in m -> > {ok, whatever(D)} > after 5 sec -> > {error, timeout} > end > > For a while I tried designing a new language around measurements. It > was only a partial success, and I was encouraged to modify an existing > language instead, for correctness issues - but when trying that with > Erlang, I was discouraged from modifying the existing language, for > familiarity / predictability issues. I'm not sure which path I'll take > next time. > > -Chris > > [1] http://www.wadenelson.com/gimli.html > [2] http://mars.jpl.nasa.gov/msp98/news/mco990930.html