From vladdu@REDACTED Fri Dec 1 00:03:20 2000 From: vladdu@REDACTED (Vlad Dumitrescu) Date: Fri, 01 Dec 2000 00:03:20 +0100 Subject: os:type() Message-ID: why is there a warning about using this function? one of my plans of future activity include trying to write a version of gs working directly with Windows (without tcl/tk). And of course I need to know if the node is running on Windows... regards, Vlad _____________________________________________________________________________________ Get more from the Web. FREE MSN Explorer download : http://explorer.msn.com From thomasl@REDACTED Fri Dec 1 10:27:53 2000 From: thomasl@REDACTED (Thomas Lindgren) Date: Fri, 1 Dec 2000 10:27:53 +0100 Subject: threads - use them as much as you can In-Reply-To: <402DD461F109D411977E0008C791C312565407@imp02mbx.one2one.co.uk> (message from Sean Hinde on Thu, 30 Nov 2000 17:35:52 -0000) References: <402DD461F109D411977E0008C791C312565407@imp02mbx.one2one.co.uk> Message-ID: <200012010927.KAA00893@lammgam.bluetail.com> > In R7B (the current release) there is a new feature which introduces a pool > of native threads for i/o operations but this is disabled by default. This > will get around the hanging problem /.../ Some web server research indicates that (on some OS:es) the entire OS process hangs on, say, disk I/O. The solution they proposed is to run disk I/O in a separate process. I'm not sure what Erlang/OTP does. (The web server is Flash, developed at Rice by Vivek Pai, Peter Druschel et al.) A great thing about Erlang is that _if_ this is an issue, then the runtime system can be implemented to do the right thing on every OS. Every Erlang application will then take advantage of the 'best practice', without rewriting a single line of code. Contrast this with 'rolling your own' in C. Thomas -- Thomas Lindgren thomas+junk@REDACTED Alteon WebSystems "National differences and antagonism between peoples are daily more and more vanishing, owing to the development of the bourgeoisie, to freedom of commerce, to the world market, to uniformity in the mode of production and in the conditions of life corresponding thereto." -- Communist Manifesto From etxuwig@REDACTED Fri Dec 1 11:08:30 2000 From: etxuwig@REDACTED (Ulf Wiger) Date: Fri, 1 Dec 2000 11:08:30 +0100 (MET) Subject: the OO metaphor In-Reply-To: Message-ID: On Thu, 30 Nov 2000, Vlad Dumitrescu wrote: >$inherit_api (or something similar) would be a nice and clean way to >handle this issue. Perhaps, in response to Bjarnes post, it could be called $reuse_api() or something, to avoid getting our feet stuck in the OO mud. >On the other hand, interfaces that are shared like this create also >problems: for example, what happens if an interface that is extended >by many other has to be changed in a non-compatible way? There are >solutions, of course - the point is that there may be more things to >think about than one sees first... I think we have these same problems today, and then some. Of course, one significant change would be that it would become easier to reuse the API of other modules, which would probably make programmers use it more. But I've never been a fan of the "let's make this difficult so that people will stay away from it" philosophy. (: Today, you have two options: 1. Copy and paste the code from one module to another - obvious problem: if you find a bug in the implementation, you have to change the code in multiple places 2. Write a function, f() -> OtherMod:f() - problem: if the implementation changes incompatibly in OtherMod, your API will break. - problem: if functions are added to OtherMod, you must also change your module (if they were functions that you also need to support - advantage: code reuse is explicit With a function like $reuse_api(), - code reuse is still explicit, but perhaps less so - you can opt to have functions dynamically added to your API, by specifying that "all functions in API M are also part of this API. - Incompatible changes in a reused API will break other APIs, but this is hard to solve without resorting to (1): copy and paste. One significant disadvantage, though, would be that we'd lose the ability to easily track whether interfaces have changed, as they could change "indirectly". At AXD 301, we have a convention to keep separate interface modules, which only contain "pointers" to implementation functions in other modules. The main purpose of this is to highlight the API, and make it easy to see if it has changed (the revision of the API module changes.) But of course, the two approaches can coexist. Dynamic APIs would be useful if you write generic dispatch functions or behaviours. Personally, I really dislike the type of inheritance that e.g. Java has, where you have to chase around in several code modules to find out what a method really does. I think programs should be expressive and explicit to the greatest extent possible. For example, one should always think twice before using constructs like apply(M,F,A), or Process = OtherMod:lookup_process_name(...), Process ! Msg. I've come across it every now and then in various programs, and it almost always makes fast code browsing nearly impossible. Sometimes, these constructs are invaluable, but in the vast majority of cases, you can do the same thing explicitly without losing anything. One final point (I may be shooting down my own suggestions, but then so be it): Anytime you add something to a programming language, you must think carefully about wether it: - will make the language harder to learn - will shift the focus of the language A good language should _encourage_ programmers to write code in an elegant fashion. For example, whether or not one can employ functional programming in Java is really quite uninteresting: the important point is that Java the language doesn't encourage you to do so. I think that, to a great extent, Erlang does encourage people to write pretty good programs. This is one of its greates strengths. /Uffe -- Ulf Wiger tfn: +46 8 719 81 95 Senior System Architect mob: +46 70 519 81 95 Strategic Product & System Management ATM Multiservice Networks Data Backbone & Optical Services Division Ericsson Telecom AB From etxuwig@REDACTED Fri Dec 1 11:12:47 2000 From: etxuwig@REDACTED (Ulf Wiger) Date: Fri, 1 Dec 2000 11:12:47 +0100 (MET) Subject: threads - use them as much as you can In-Reply-To: <200012010927.KAA00893@lammgam.bluetail.com> Message-ID: On Fri, 1 Dec 2000, Thomas Lindgren wrote: > >> In R7B (the current release) there is a new feature which introduces a pool >> of native threads for i/o operations but this is disabled by default. This >> will get around the hanging problem /.../ > >Some web server research indicates that (on some OS:es) the entire OS >process hangs on, say, disk I/O. The solution they proposed is to run >disk I/O in a separate process. I'm not sure what Erlang/OTP does. In OTP R7B, you can run disk I/O in a separate thread. Thus, if the disk is slow, only the Erlang process requesting the I/O will have to wait. I'm using this in CCviewer, my web server/code browser. It made a significant difference. Now, I'm using 10 I/O threads, and trying to keep up with the maximum number of concurrent requests to the server (so far, 10 simultaneous requests is the record, while the average is 1.1) /Uffe -- Ulf Wiger tfn: +46 8 719 81 95 Senior System Architect mob: +46 70 519 81 95 Strategic Product & System Management ATM Multiservice Networks Data Backbone & Optical Services Division Ericsson Telecom AB From Peter.Andersson@REDACTED Fri Dec 1 12:32:41 2000 From: Peter.Andersson@REDACTED (Peter Andersson) Date: Fri, 01 Dec 2000 11:32:41 +0000 Subject: the OO metaphor References: Message-ID: <3A278C59.FD2553DF@eei.ericsson.se> Ulf Wiger wrote: > > One final point (I may be shooting down my own suggestions, but then > so be it): Anytime you add something to a programming language, you > must think carefully about wether it: > > - will make the language harder to learn > - will shift the focus of the language I definitely agree with this. Maybe it's not such a bad idea to use an interface specification tool from which you can generate your interface code stubs. Keep your implementation in one place (no copy-paste) and generate the interface code to it from your specs. This can enable API reusage and you still get explicit stubs (f()-> OtherMod:f()) which make simple code browsing possible. You can of course still easily get inconsistency between i/f and implementation, but it might be a lot easier to control. I mentioned before that UML has already been used for this in an Erlang project. I believe it should be possible to make a specification tool that uses a more logical mapping between the interface specifications and the Erlang implementation (as far as processes and data types are concerned, for example) than what you get with UML. The Erlang Interface Specification Tool, EIST, perhaps!? :-) (Or maybe as part of a more extensive tool based on an event modelling language). As far as OO constructs are concerned (we've discussed a few in this thread), I think these are only interesting (or should I say fun) to discuss as something that can be implemented in a control framework application for "OO-like" systems. They should not be proposed as extensions to the Erlang language or even as OTP components. Both Bjarne and Ulf's latest mails stress the importance of that! Regards /Peter From Sean.Hinde@REDACTED Fri Dec 1 12:50:49 2000 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Fri, 1 Dec 2000 11:50:49 -0000 Subject: the OO metaphor Message-ID: <402DD461F109D411977E0008C791C31256540D@imp02mbx.one2one.co.uk> Ulf Wiger wrote: > Perhaps, in response to Bjarnes post, it could be called $reuse_api() > or something, to avoid getting our feet stuck in the OO mud. > With a function like $reuse_api(), > - code reuse is still explicit, but perhaps less so > - you can opt to have functions dynamically added to your API, > by specifying that "all functions in API M are also part of > this API. > - Incompatible changes in a reused API will break other APIs, but > this is hard to solve without resorting to (1): copy and paste. These sort of things would become much cleaner if we had Richard O'Keefe's idea of 'internal exports' (so for example the functions currently exported for gen_server callbacks wouldn't become part of the API). - 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 Fri Dec 1 13:16:31 2000 From: luke@REDACTED (Luke Gorrie) Date: 01 Dec 2000 13:16:31 +0100 Subject: export_to (Was: Re: the OO metaphor) In-Reply-To: Sean Hinde's message of "Fri, 1 Dec 2000 11:50:49 -0000" References: <402DD461F109D411977E0008C791C31256540D@imp02mbx.one2one.co.uk> Message-ID: Sean Hinde writes: > These sort of things would become much cleaner if we had Richard O'Keefe's > idea of 'internal exports' (so for example the functions currently exported > for gen_server callbacks wouldn't become part of the API). Could someone explain to me how in practice you actually get in trouble from not having export_to? I think that when I'm looking for a function, I either look in a manpage (where internal exports should be undocumented), or the exports in a source file. If I see a comment like "%% Internal exports", I know not to use them. I can't think of a case where I'd end up calling something that's not exported "for me". Maybe if you use module_info/0 for looking up functions you can get in trouble, but I guess most people only do that for throw-away use in the shell if at all. So, is it some quick-hack temptation of "Hey, I could just call foo:handle_call(...) directly to do this!" that causes the problems, or is there some more accidental cause, or..? Cheers, Luke (who has some hazy recollection of having called a handle_call directly, come to think of it.. :-)) From etxuwig@REDACTED Fri Dec 1 13:33:44 2000 From: etxuwig@REDACTED (Ulf Wiger) Date: Fri, 1 Dec 2000 13:33:44 +0100 (MET) Subject: export_to (Was: Re: the OO metaphor) In-Reply-To: Message-ID: On 1 Dec 2000, Luke Gorrie wrote: >Could someone explain to me how in practice you actually get in >trouble from not having export_to? As you say, disciplined programmers don't get into trouble. >I think that when I'm looking for a function, I either look in a >manpage (where internal exports should be undocumented), or the >exports in a source file. If I see a comment like "%% Internal >exports", I know not to use them. I can't think of a case where I'd >end up calling something that's not exported "for me". I would think that it's more a matter of making it very explicit that certain functions are only exported for a single purpose. Not only are you not supposed to call them - you're not even able to. In this way, it's similar to having an explicit -export(...) clause, instead of just inserting comments like "%% internal functions". >Maybe if you use module_info/0 for looking up functions you can get >in trouble, but I guess most people only do that for throw-away use >in the shell if at all. Hehe, I'd like to see some code that actually does something useful by calling module info, and then simply going through the list of exported functions and calling them, just to see what would happen. >So, is it some quick-hack temptation of "Hey, I could just call >foo:handle_call(...) directly to do this!" that causes the problems, >or is there some more accidental cause, or..? I've seen direct calls to handle_call(...) just to reuse the implementation, but they have been from within the same module, so that doesn't apply here. It's still a hideous practice. /Uffe -- Ulf Wiger tfn: +46 8 719 81 95 Senior System Architect mob: +46 70 519 81 95 Strategic Product & System Management ATM Multiservice Networks Data Backbone & Optical Services Division Ericsson Telecom AB From Chandrashekhar.Mullaparthi@REDACTED Fri Dec 1 13:35:20 2000 From: Chandrashekhar.Mullaparthi@REDACTED (Chandrashekhar Mullaparthi) Date: Fri, 1 Dec 2000 12:35:20 -0000 Subject: export_to (Was: Re: the OO metaphor) Message-ID: <402DD461F109D411977E0008C791C31202A797F6@imp02mbx.one2one.co.uk> To me, it seems like the only advantage is that in a large project, some programmer might disregard certain rules and call functions which are "marked" internal exports. This might break the code when these internal exports are removed/changed etc. Though this might become a pain when you want to quickly test some function and it is marked as an internal export. But I feel the same - it just doesn't seem terribly necessary. > -----Original Message----- > From: Luke Gorrie [mailto:luke@REDACTED] > Sent: 1 December 2000 12:17 > To: Sean Hinde > Cc: 'Ulf Wiger'; Vlad Dumitrescu; erlang-questions@REDACTED > Subject: export_to (Was: Re: the OO metaphor) > > > Sean Hinde writes: > > > These sort of things would become much cleaner if we had > Richard O'Keefe's > > idea of 'internal exports' (so for example the functions > currently exported > > for gen_server callbacks wouldn't become part of the API). > > Could someone explain to me how in practice you actually get in > trouble from not having export_to? > > I think that when I'm looking for a function, I either look in a > manpage (where internal exports should be undocumented), or the > exports in a source file. If I see a comment like "%% Internal > exports", I know not to use them. I can't think of a case where I'd > end up calling something that's not exported "for me". > > Maybe if you use module_info/0 for looking up functions you can get in > trouble, but I guess most people only do that for throw-away use in > the shell if at all. > > So, is it some quick-hack temptation of "Hey, I could just call > foo:handle_call(...) directly to do this!" that causes the problems, > or is there some more accidental cause, or..? > > Cheers, > Luke (who has some hazy recollection of having called a handle_call > directly, come to think of it.. :-)) > 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 Chandrashekhar.Mullaparthi@REDACTED Fri Dec 1 13:48:47 2000 From: Chandrashekhar.Mullaparthi@REDACTED (Chandrashekhar Mullaparthi) Date: Fri, 1 Dec 2000 12:48:47 -0000 Subject: export_to (Was: Re: the OO metaphor) Message-ID: <402DD461F109D411977E0008C791C31202A797F7@imp02mbx.one2one.co.uk> > I've seen direct calls to handle_call(...) just to reuse the > implementation, but they have been from within the same module, so > that doesn't apply here. It's still a hideous practice. > I've lost my appetite for lunch now. 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 kent@REDACTED Fri Dec 1 13:56:22 2000 From: kent@REDACTED (Kent Boortz) Date: 01 Dec 2000 13:56:22 +0100 Subject: patches In-Reply-To: Alexis =?iso-8859-1?q?L=EA-Qu=F4c's?= message of "Thu, 30 Nov 2000 11:37:46 -0500" References: <87vgt5fztb.fsf@western.ird.idealx.com> <001001c05aeb$df3041b0$38fea8c0@neomeo.com> Message-ID: > A newbie question: Are there any issues with the BEAM files being > different? I'm not very familiar with the Erlang build process > (aside from having run ./configure; make; make install), but it > seems that having different bootstraping code could lead to > different results. There is a small risk that we fail to realize that a change does lead to different results. There is no automatic way to detect that an upgrade of the bootstrap compilers is needed. But most changes in the compilers before a new major release are small, i.e. bug fixes. The bootstrap compilers only compile code in the Erlang/OTP system and the compiler bugs found so far after R7B-0 only affect new constructs not used in the Erlang/OTP system itself. kent From thomasl@REDACTED Fri Dec 1 13:57:07 2000 From: thomasl@REDACTED (Thomas Lindgren) Date: Fri, 1 Dec 2000 13:57:07 +0100 Subject: export_to (Was: Re: the OO metaphor) In-Reply-To: (message from Luke Gorrie on 01 Dec 2000 13:16:31 +0100) References: <402DD461F109D411977E0008C791C31256540D@imp02mbx.one2one.co.uk> Message-ID: <200012011257.NAA01035@lammgam.bluetail.com> > Could someone explain to me how in practice you actually get in > trouble from not having export_to? One advantage I can think of is for automated tools, such as xref, to detect problems. It also means we can locally, within a module, know that certain functions are _only_ used by direct remote calls. In a similar vein to "export_to", I'd like to have something like this: -export([...]). %% functions visible outside the module -apply([....]). %% functions that can be metacalled -spawn([....]). %% functions that can be spawned The "internal exports" would show up in -apply or -spawn, but not in -export. Some shorthand could be provided as well (-compile(export_all) = export+apply+spawn?). Thomas -- Thomas Lindgren thomas+junk@REDACTED Alteon WebSystems "National differences and antagonism between peoples are daily more and more vanishing, owing to the development of the bourgeoisie, to freedom of commerce, to the world market, to uniformity in the mode of production and in the conditions of life corresponding thereto." -- Communist Manifesto From Sean.Hinde@REDACTED Fri Dec 1 14:02:20 2000 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Fri, 1 Dec 2000 13:02:20 -0000 Subject: export_to (Was: Re: the OO metaphor) Message-ID: <402DD461F109D411977E0008C791C31256540E@imp02mbx.one2one.co.uk> > Could someone explain to me how in practice you actually get in > trouble from not having export_to? I was thinking from several points of view: 1) Code understanding - It is not just the gen_server callbacks which one sees with these properties. In gen_fsm for example there are all the functions which are named after the states - in a big one it can be hard to see the wood from the trees. Also in some of the big OTP apps there are often little sub processes kicked off for various reasons which also result in more "internal" exports. 2) To make systems for code browsing look prettyier / mean more. I guess this includes automated tools for presenting an overall view of a large complicated system without cluttering the picture with extraneous stuff. 3) Ulf's reason! - 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 Fri Dec 1 14:32:54 2000 From: luke@REDACTED (Luke Gorrie) Date: 01 Dec 2000 14:32:54 +0100 Subject: export_to (Was: Re: the OO metaphor) In-Reply-To: Ulf Wiger's message of "Fri, 1 Dec 2000 13:33:44 +0100 (MET)" References: Message-ID: Ulf Wiger writes: > Hehe, I'd like to see some code that actually does something useful by > calling module info, and then simply going through the list of > exported functions and calling them, just to see what would happen. What a fine idea! I present "modinfo": No more reading tedious documentation or understanding source code, from now on Erlang programmers can learn new APIs with easy-to-use commands like: (emacs@REDACTED)2> modinfo:probe(random). [{random,seed,[]}, {random,seed,[[integer,integer,integer]]}, {random,uniform,[]}, {random,uniform,[[integer],[float]]}, {random,module_info,[]}, {random,module_info,[]}] Or if you just want to check the arguments of a particular function: (emacs@REDACTED)3> modinfo:probe_fun(lists, map, 2). {lists,map,[[fun1,string],[fun1,list]]} Optionally can be used to automatically generate programs by probing side-effecty modules :-) Cut here. -module(modinfo). -author('luke@REDACTED'). -compile(export_all). % *grin* %% Call each function of Mod with lots of argument permutations, and %% return a list of what doesn't crash. probe(Mod) -> [FunsWithArity] = [Exports || {exports, Exports} <- Mod:module_info()], [probe_fun(Mod, Fun, Arity) || {Fun, Arity} <- FunsWithArity]. %% Call Mod:Fun/Arity with lots of argument permutations and show %% which ones don't crash. probe_fun(Mod, Fun, Arity) -> {Mod, Fun, [Types || {ok, Types} <- call_fun(Mod, Fun, Arity)]}. call_fun(Mod, Fun, Arity) -> Searchspace = combos(Arity), [try_call(Mod, Fun, Args) || Args <- Searchspace]. try_call(Mod, Fun, Args) -> case catch apply(Mod, Fun, values(Args)) of {'EXIT', _} -> error; _ -> {ok, types(Args)} end. values(ArgList) -> [Value || {Type, Value} <- ArgList]. types(ArgList) -> [Type || {Type, Value} <- ArgList]. combos(0) -> []; combos(1) -> [[Arg] || Arg <- args()]; combos(N) -> [[X|Y] || X <- args(), Y <- combos(N-1)]. %% {Type, Value} of some arguments to try args() -> [{integer, 1}, {float, 1.0}, {string, "foo"}, {list, [a, b, c]}, {atom, foo}, {ref, make_ref()}, {pid, self()}, {tuple, {a, b}}, {fun0, fun() -> ok end}, {fun1, fun(X) -> X end}, {fun2, fun(X, Y) -> X end}]. From richardc@REDACTED Fri Dec 1 14:36:26 2000 From: richardc@REDACTED (Richard Carlsson) Date: Fri, 1 Dec 2000 14:36:26 +0100 (MET) Subject: export_to (Was: Re: the OO metaphor) In-Reply-To: <200012011257.NAA01035@lammgam.bluetail.com> Message-ID: On Fri, 1 Dec 2000, Thomas Lindgren wrote: > In a similar vein to "export_to", I'd like to have something like > this: > > -export([...]). %% functions visible outside the module > -apply([....]). %% functions that can be metacalled > -spawn([....]). %% functions that can be spawned > > The "internal exports" would show up in -apply or -spawn, but not in -export. > Some shorthand could be provided as well > (-compile(export_all) = export+apply+spawn?). > > Thomas This should not be needed, since you can nowadays write: spawn(fun () -> my_nonexported function(X1, ..., Xn) end) There should now be no reason to export a function name that is not expected to be called from other modules. (Counterexamples, anyone?) Furthermore, I think it is a mistake to introduce an "export to" declaration, because it requires of the programmer to foresee the future uses of his module. It is one thing to, as in most OO languages, be able to limit the use of a function (method) to a specific *category" of other modules: those in the same class, or those in the same package, etc. But consider the problem in C++ when a function has not been declared as virtual, making it impossible to use dynamic method binding in a future application. Of course, C++ has "friend" declarations, which is analogous to the "export_to" idea, but I find it doubtful whether they are really motivadet considering the above problem - Java for instance does fine without "friends". /Richard Carlsson Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) E-mail: Richard.Carlsson@REDACTED WWW: http://www.csd.uu.se/~richardc/ From rv@REDACTED Fri Dec 1 14:20:58 2000 From: rv@REDACTED (Robert Virding) Date: Fri, 01 Dec 2000 14:20:58 +0100 Subject: export_to (Was: Re: the OO metaphor) In-Reply-To: Your message of "01 Dec 2000 13:16:31 +0100." Message-ID: <200012011320.OAA24519@trana.bluetail.com> Luke Gorrie writes: >Sean Hinde writes: > >> These sort of things would become much cleaner if we had Richard O'Keefe's >> idea of 'internal exports' (so for example the functions currently exported >> for gen_server callbacks wouldn't become part of the API). > >Could someone explain to me how in practice you actually get in >trouble from not having export_to? Here is one paper where Richard explains export_to and other things. It is a TeX file, if anyone wants the DVI or PostScript files please tell me. I have also attached the example files he mentions. Some of this stuff should definitely get into the system. Robert -------------- next part -------------- %% Copyright (C) 1990, Ellemtel Telecommunications Systems Laboratories %% File : user.erl %% Author : Robert Virding %% Purpose : Basic standard i/o server for user interface port. %% Edited : January 2000 by Richard A. O'Keefe %% Reason : To demonstrate all-functions-findable Erlang. -module(user). -copyright('Copyright (c) 1991-97 Ericsson Telecom AB'). -vsn('$Revision: /main/release/5'). -export([ start/0, start/1, start_out/0, server/1, server/2 ]). -use(init, [ % Knows how to tell if we want a shell get_argument/1 ]). -use(shell, [ % Knows how to start a shell start/0 ]). -use(lists, [ % Knows how to test membership member/2 % should be a guard test now. ]). -use(io_lib, [ deep_char_list/1, format/2, write/1 ]). -import_static(io_msgs, [ #done/2, #fwrite/2, #get_until/2, #io_request/3, #more/1, #put_chars/1, #requests/1 ]). -pid_name(user). %% %% The basic server and start-up. %% start(Closure) -> % Closure() should return a PID, for a case Closure() of % process that will act as the I/O port. Pid when pid(Pid) -> pid_name_spawn(user, fun() -> process_flag(trap_exit, true), link(Pid), run(Pid) end); Other -> {not_a_pid,Other} end. start() -> start_port([eof]). start_out() -> % Output-only version of start/0 start_port([out]). start_port(PortSettings) -> pid_name_spawn(user, fun() -> process_flag(trap_exit, true), run(open_port({fd,0,1}, PortSettings)) end). % P is the Pid returned by Closure() in start(Closure) or % the Port opened by the other versions of start... % The split into run/1 and catch_loop/2 is so that a BEL % character can fire up a new server_loop/3, or not. run(P) -> case init:get_argument(noshell) of {ok, [_|_]} -> % non-empty list => noshell server_loop(P, -1, []); _ -> group_leader(self(), self()), catch_loop(P, shell:start()) end. catch_loop(Port, Shell) -> case catch server_loop(Port, 7, []) of new_shell -> exit(Shell, kill), catch_loop(Port, shell:start()); {'EXIT',R} -> exit(R) end. throw_new_shell_if_abort_in_input(AbCh, _) when AbCh < 0 -> true; throw_new_shell_if_abort_in_input(AbCh, Bytes) -> case lists:member(AbCh, Bytes) of true -> throw(new_shell); _ -> true end. % Port is the PID or Port we want to receive input from. % AbCh is the Abort Character (-1 if none). % Buf0 is the input characters currently buffered. server_loop(Port, AbCh, Buf0) -> receive {Port,{data,Bytes}} -> throw_new_shell_if_abort_in_inputs(AbCh, Bytes), server_loop(Port, Buf0 ++ Bytes); #io_request(From,ReplyAs,Request) -> Buf = io_request(Request, From, ReplyAs, Port, AbCh, Buf0), server_loop(Port, AbCh, Buf); {Port,eof} -> put(eof, true), server_loop(Port, AbCh, Buf0); %% Ignore messages from port here. {'EXIT',Port,badsig} -> %Ignore badsig errors server_loop(Port, AbCh, Buf0); {'EXIT',Port,What} -> %Port has exited exit(What); _ -> %Ignore other messages server_loop(Port, AbCh, Buf0) end. %% NewBuf = io_request(Request, FromPid, ReplyAs, Port, AbCh, OldBuf) io_request(Req, From, ReplyAs, Port, AbCh, Buf0) -> case io_request(Req, Port, AbCh, Buf0) of {ok,Reply,Buf} -> io_reply(From, ReplyAs, Reply), Buf; {error,Reply,Buf} -> io_reply(From, ReplyAs, Reply), Buf; {exit,What} -> send_port(Port, close), exit(What) end. put_chars(Chars, Port, Buf) -> case io_lib:deep_char_list(Chars) of %Check deep list true -> put_port(Chars, Port), {ok,ok,Buf}; false -> {error,{error,put_chars},Buf} end. /* io_request(Request, Port, AbCh, Buf) returns one of {exit,What} fatal error {error,Reply,Buf1} non-fatal error, Buf1 is updated Buf {ok,Reply,Buf1} success, Buf1 is updated Buf. */ io_request(#put_chars(Chars), Port, _, Buf) -> put_chars(Chars, Port, Buf); io_request(#fwrite(Format,Args), Port, _, Buf) -> put_chars(catch io_lib:fwrite(Format, Args), Port, Buf); io_request(#get_until(Prompt,Closure), Port, AbCh, Buf) -> case get(eof) of undefined -> get_until(Prompt, Closure, Port, AbCh, Buf); true when Buf == [] -> {ok, eof, Buf}; _ -> get_until(Prompt, Closure, Port, AbCh, Buf) end; io_request(#requests(Requests), Port, AbCh, Buf) -> io_requests(Requests, {ok,ok,Buf}, Port, AbCh); io_request(R, Port, Buf) -> %Unknown request {ok,{error,{request,R}},Buf}. %Ignore but give error (?) %% Status = io_requests(RequestList, PrevStat, Port, AbCh) %% Process a list of output requests as long as the previous status is 'ok'. io_requests([R|Rs], {ok,_,Buf}, Port, AbCh) -> io_requests(Rs, io_request(R, Port, AbCh, Buf), Port, AbCh); io_requests([_|_], Error, _) -> Error; io_requests([], Status, _) -> Status. %% put_port(DeepList, Port) %% Take a deep list of characters, flatten and output them to the %% port. But the code does NOT flatten the list! put_port(List, Port) -> send_port(Port, {command, List}). %% send_port(Port, Command) send_port(Port, Command) -> Port ! {self(),Command}. %% io_reply(From, ReplyAs, Reply) %% The function for sending i/o command acknowledgement. %% The ACK contains the return value. io_reply(From, ReplyAs, Reply) -> From ! #io_reply(ReplyAs,Reply). /* get_until(Prompt, Closure, Port, AbCh, OldBuf) accepts characters from the input port as long as the applied function returns #more(_). It does not block output until input has been received. Returns: {ok,Result,NewBuf} {error,Result,NewBuf} {exit,Reason} */ get_until(Prompt, Closure, Port, AbCh, Buf) -> prompt(Port, Prompt), get_until1(Prompt, Closure, Port, AbCh, Buf). get_until1(Prompt, Closure, Port, AbCh, []) -> receive %% Input cases {Port,{data,Bytes}} -> throw_new_shell_if_abort_in_input(AbCh, Bytes), get_until2(catch Closure([], Bytes), Closure, Port, AbCh); {Port, eof} -> put(eof, true), {ok, eof, []}; %% Catch io_requests whoseRequest is one of the two output requests. #io_request(From,ReplyAs,R = #put_chars(_)) -> get_until1_out(R, From, ReplyAs, Prompt, Closure, Port, AbCh); #io_request(Form,ReplyAs,R = #fwrite(_,_)) -> get_until1_out(R, From, ReplyAs, Prompt, Closure, Port, AbCh); %% Fatal errors. {'EXIT',From,What} when node(From) == node() -> {exit,What} end; get_until1(Prompt, Closure, Port, AbCh, Buf) -> get_until2(catch Closure([], Buf), Closure, Port, AbCh). get_until1_out(Req, From, ReplyAs, Prompt, Closure, Port, AbCh) -> io_request(#put_chars("^R\n"), Port, AbCh, []), %"Cancel" prompt io_request(Req, From, ReplyAs, Port, AbCh, []), %No new buf here! get_until(Prompt, Closure, Port, AbCh, []). get_until2(#more(Cont), Closure, Port, AbCh) -> case get(eof) of undefined -> receive {Port,{data,Bytes}} -> throw_new_shell_if_abort_in_input(AbCh, Bytes), get_until2(catch Closure(Cont,Bytes), Closure, Port, AbCh); {Port, eof} -> put(eof, true), get_until2(catch Closure(Cont,eof), Closure, Port, AbCh); {'EXIT',From,What} when node(From) == node() -> {exit,What} end; _ -> get_until2(catch Closure(Cont,eof), Closure, Port, AbCh) end; get_until2(#done(Result,Buf), _, _, _) -> {ok,Result,Buf}; get_until2(_, _, _) -> {error,{error,get_until},[]}. %% prompt(Port, Prompt) %% Print Prompt onto port Port, special case just atoms and print unquoted. prompt(Port, Prompt) when atom(Prompt) -> put_port(atom_to_list(Prompt), Port); prompt(Port, {format,Format,Args}) -> case catch io_lib:format(Format, Args) of {'EXIT',_} -> put_port("???", Port); List -> put_port(List, Port) end; prompt(Port, Prompt) -> put_port(io_lib:write(Prompt), Port). /* I have eliminated put(noshell)/get(noshell). I'd like to eliminate the put/get on eof as well. */ -------------- next part -------------- %% Copyright (C) 1990, Ellemtel Telecommunications Systems Laboratories %% File : io.erl %% Author : Robert Virding %% Purpose : Standard i/o server interface functions. %% Revised : 2000.02.08 -module(io). -copyright('Copyright (c) 1991-97 Ericsson Telecom AB'). -vsn('$Revision: /main/release/2'). -export([put_chars/1,put_chars/2,nl/0,nl/1, get_chars/2,get_chars/3,get_line/1,get_line/2]). -export([write/1,write/2,read/1,read/2]). -export([fwrite/1,fwrite/2,fwrite/3,fread/2,fread/3, format/1,format/2,format/3]). -export([scan_erl_exprs/1,scan_erl_exprs/2,scan_erl_exprs/3, scan_erl_form/1,scan_erl_form/2,scan_erl_form/3, parse_erl_exprs/1,parse_erl_exprs/2,parse_erl_exprs/3, parse_erl_form/1,parse_erl_form/2,parse_erl_form/3]). -export([request/1,request/2,requests/1,requests/2]). -import_static(io_msgs, [ #io_request/4, #io_reply/3, #put_chars/1, #fwrite/2, #get_until/2, #get_chars/2, #get_line/1, #fread/2, #format/2, #write/1, #requests/1 ]). -use(io_lib, [ collect_chars/3, collect_line/2, fread/3 nl/0 ]). -use(erl_parse, [ parse_exprs/1, parse_form/1, parse_term/1 ]). -use(erl_scan, [ tokens/3 ]). %% %% User interface. %% %% Writing and reading characters. put_chars(Chars) -> put_chars(default_output(), Chars). put_chars(Io, Chars) -> request(Io, #put_chars(Chars)). nl() -> nl(default_output()). nl(Io) -> request(Io, #put_chars(io_lib:nl())). get_chars(Prompt, N) -> get_chars(default_input(), Prompt, N). get_chars(Io, Prompt, N) -> request(Io, #get_chars(Prompt,N)). get_line(Prompt) -> get_line(default_input(), Prompt). get_line(Io, Prompt) -> request(Io, #get_line(Prompt)). %% Writing and reading Erlang terms. write(Term) -> write(default_output(), Term). write(Io, Term) -> request(Io, #write(Term)). read(Prompt) -> read(default_input(), Prompt). read(Io, Prompt) -> case scan_erl_exprs(Io, Prompt, 1) of {ok,Toks,EndLine} -> erl_parse:parse_term(Toks); {error,E,EndLine} -> {error,E}; {eof,EndLine} -> eof; Other -> Other end. %% Formatted writing and reading. fwrite(Format) -> fwrite(Format, []). fwrite(Format, Args) -> fwrite(default_output(), Format, Args). fwrite(Io, Format, Args) -> request(Io, #fwrite(Format,Args)). fread(Prompt, Format) -> fread(default_input(), Prompt, Format). fread(Io, Prompt, Format) -> request(Io, #fread(Prompt,Format)). format(Format) -> format(Format, []). format(Format, Args) -> format(default_output(), Format, Args). format(Io, Format, Args) -> request(Io, #fwrite(Format,Args)). %% Scanning Erlang code. scan_erl_exprs(Prompt) -> scan_erl_exprs(default_input(), Prompt, 1). scan_erl_exprs(Io, Prompt) -> scan_erl_exprs(Io, Prompt, 1). scan_erl_exprs(Io, Prompt, StartLine) -> request(Io, #get_until(Prompt, fun (B, C) -> erl_scan:tokens(B, C, StartLine) end)). scan_erl_form(Prompt) -> scan_erl_form(default_input(), Prompt, 1). scan_erl_form(Io, Prompt) -> scan_erl_form(Io, Prompt, 1). scan_erl_form(Io, Prompt, Pos0) -> scan_erl_exprs(Io, Prompt, Pos0). %% Parsing Erlang code. parse_erl_exprs(Prompt) -> parse_erl_exprs(default_input(), Prompt, 1). parse_erl_exprs(Io, Prompt) -> parse_erl_exprs(Io, Prompt, 1). parse_erl_exprs(Io, Prompt, Pos0) -> case scan_erl_exprs(Io, Prompt, Pos0) of {ok,Toks,EndPos} -> case erl_parse:parse_exprs(Toks) of {ok,Exprs} -> {ok,Exprs,EndPos}; {error,E} -> {error,E,EndPos} end; Other -> Other end. parse_erl_form(Prompt) -> parse_erl_form(default_input(), Prompt, 1). parse_erl_form(Io, Prompt) -> parse_erl_form(Io, Prompt, 1). parse_erl_form(Io, Prompt, Pos0) -> case scan_erl_exprs(Io, Prompt, Pos0) of {ok,Toks,EndPos} -> case erl_parse:parse_form(Toks) of {ok,Exprs} -> {ok,Exprs,EndPos}; {error,E} -> {error,E,EndPos} end; Other -> Other end. %% Miscellaneous functions. request(Request) -> request(default_output(), Request). request(Io, Request) -> case io_request(Io, io_request(Request)) of {error, E} -> {error, E}; _ -> wait_io_reply(Io) end. requests(Requests) -> %Requests as atomic action requests(default_output(), Requests). requests(Io, Requests) -> %Requests as atomic action case io_request(Io, #requests(io_requests(Requests))) of {error, E} -> {error, E}; _ -> wait_io_reply(Io) end. default_input() -> group_leader(). default_output() -> group_leader(). io_request(standard_io, Request) -> group_leader() ! #io_request(self(),standard_io,Request); io_request(Io, Request) -> case catch Io ! #io_request(self(),Io,Request) of {'EXIT', R} -> {error, arguments}; X -> X end. wait_io_reply(From) -> wait_io_reply(From, status_p(From)). wait_io_reply(From, undefined) -> {error, terminated}; wait_io_reply(From, _) -> receive #io_reply(From,Reply) -> Reply; {'EXIT',From,Reason} -> %In case we are trapping exits {error,terminated} end. status_p(P) when pid(P), node(P) == node() -> process_info(P, status); status_p(undefined) -> undefined; status_p(standard_io) -> status_p(group_leader()); status_p(N) when atom(N) -> status_p(whereis(N)); status_p(_) -> {status, remote}. %% io_requests(Requests) %% Transform requests into correct i/o server messages. Only handle the %% one we KNOW must be changed, others, including incorrect ones, are %% passed straight through. Perform a flatten on the request list. %% NB: it would be nice to list _all_ the valid requests here and reject %% any bad ones. io_requests(Rs) -> io_requests(Rs, [], []). io_requests(#requests(Rs), Cont, Tail) -> io_requests(Rs), Cont, Tail); io_requests([R|Rs], Cont, Tail) -> [io_request(R)|io_requests(Rs, Cont, Tail)]; io_requests([], [Rs|Cont], Tail) -> io_requests(Rs, Cont, Tail); io_requests([], [], Tail) -> []. io_request( #format(F,A)) -> #fwrite(F, A); io_request( #write(Term)) -> #fwrite('~w',[Term]); io_request( nl) -> #put_chars(io_lib:nl()); io_request( #get_chars(P,N)) -> #get_until(P, fun (B,C) -> io_lib:collect_chars(B, C, N) end); io_request( #get_line(P)) -> #get_until(P, fun (B,C) -> io_lib:collect_line(B, C) end); io_request( #fread(P,F)) -> #get_until(P, fun (B,C) -> io_lib:fread(B, C, Format); /* io_request(R = #put_chars(_)) -> R; io_request(R = #get_until(_,_)) -> R; io_request(R = #fwrite(_,_)) -> R; */ io_request(R) -> R. % Pass junk straight through. -------------- next part -------------- -module(io_msgs). -author('ok@REDACTED'). -static. % -import_static & -use_static allowed. -export_to([io, user, file], [ % Private protocol #io_request/4, #io_reply/3 ]). -export([ % To I/O parser modules #done/2 #more/1 ]). -export([ % Public and private #put_chars/1, #fwrite/2, #get_until/2, #requests/1 ]). -export([ % Public protocol #get_chars/2, #get_line/1, #fread/2, #format/2, #write/1 ]). /* The I/O messages can be divided into three groups: 1. Requests that anyone can pass to the io module, but which are mapped to something else. They are thus in the public protocol but not the private protocol. 2. Requests that the io module sends to the server processes, but which are not to be used by other code. They are thus in the private protocol but not the public protocol. 3. Requests which are in both the public protocol and the private protocol. It is particularly important for the io module to check these before sending them on, because most of the time they will be ok, but occasionally an error will erupt deep in a distant process if we don't watch out. One good reason for the public protocol to exist is so that a batch of requests can be done "atomically". There is a problem with that, and io:requests/[1,2] are not described in the documentation for the io module. VERY IMPORTANT NOTE: None of these patterns should have 'EXIT' or anything that looks like a Port as their first element. Server modules should take care to use PIDs for ports, rather than registered names (should they be available). */ /* Group 3: public and private */ #put_chars(Chars) /* when deep_char_list(Chars) */ -> {put_chars,Chars}. /* The argument should be a deep char list. When should this be checked? It would be nice to check in the io module so that the server process could assume it was valid, but there are other things that can be bad like format/argument mismatch and closure failures in get_until calls, so it is best to have a uniform convention that error checks are done in the receiver. There are error reporting issues in the design that may need reconsideration. */ #get_until(Prompt,Closure) when closure(Closure) -> {get_until,Prompt,Closure}. /* This is used to accept characters from an input port as long as the Closure wants more input. The Closure is called as Closure(Buf, Bytes) Buf is current buffered input, and Bytes the next chunk, or Closure(Buf, eof) Buf is current buffer, no more input! and should return either {more,NewBuf} continue, NewBuf combines Buf,Bytes {done,Result,NewBuf} stop, Result is desired result, and NewBuf the characters left over. Note that Closure("", eof) will NOT be called; the result is always eof when that would have happened. The results of Closure are not sent as messages, nevertheless they are an important aspect of the protocol, so they are defined here. */ #more(Cont) /* when char_list(Cont) */ -> {more,Cont}. #done(Result, NewBuf) /* when char_list(NewBuf) */ -> {done,Result,NewBuf}. #fwrite(Format,Args) when list(Args) -> {fwrite,Format,Args}. /* Format should be an atom or a string; it should be a well formed format and the list of Args should agree with it. As noted above, this is checked by the receiver, not the sender. The same message is used for calls to `format'. */ #requests(Requests) when list(Requests) -> {requests,Requests}. /* In the public protocol, Requests is a list of requests from the public protocol, including nested #requests(_). In the private protocol, Requests is a list of requests from the private protocol. The io module translates from public requests to private ones before sending this message. All of the (translated) requests are done by a server before it returns to its main loop. This WOULD constitute an atomic request were it not for the fact that user:get_until1/5 will let output requests overtake an input request that is waiting for more input. The really nasty thing there is that it will only let _unrelated_ output requests overtake an input request. */ /* Group 1: public only */ #get_chars(Prompt,N) when integer(N), N >= 0 -> {get_chars,Prompt,N}. /* The result should be a list of up to N characters, with fewer than N only if end of file is reached. Implemented using get_until. */ #get_line(Prompt) -> {get_line,Prompt}. /* The result should be a list of characters, comprising a complete line of input. Implemented using get_until. */ #fread(Prompt,Format) -> {fread,Prompt,Format}. #format(Format,Args) when list(Args) -> {format,Format,Args}. /* Format should be an atom or a string; it should be a well formed format and the list of Args should agree with it. This is converted to #fwrite() before passing on to the receiver. */ #write(Term) -> {write,Term}. /* This is converted to #fwrite('~w',[Term]). */ /* Group 2: private */ #io_request(From, ReplyAs, Request) when pid(From) -> {io_request,From,ReplyAs,Request}. /* From identifies the process the reply should be sent to. ReplyAs is basically a tag; it is passed back unchanged in the reply. Request is the actual request. */ #io_reply(ReplyAs, Reply) -> {io_reply,ReplyAs,Reply}. /* This is the reply that is sent back to From. The form of the Reply is described with each Request. */ -------------- next part -------------- A non-text attachment was scrubbed... Name: FINDABLE.TEX Type: application/x-tex Size: 51753 bytes Desc: findable.tex URL: -------------- next part -------------- Robert Virding Tel: +46 (0)8 545 55 017 Alteon Web Systems Email: rv@REDACTED S:t Eriksgatan 44 WWW: http://www.bluetail.com/~rv SE-112 34 Stockholm, SWEDEN "Folk s?ger att jag inte bryr mig om n?gonting, men det skiter jag i". From thomasl@REDACTED Fri Dec 1 15:17:55 2000 From: thomasl@REDACTED (Thomas Lindgren) Date: Fri, 1 Dec 2000 15:17:55 +0100 Subject: export_to (Was: Re: the OO metaphor) In-Reply-To: (message from Richard Carlsson on Fri, 1 Dec 2000 14:36:26 +0100 (MET)) References: Message-ID: <200012011417.PAA01655@lammgam.bluetail.com> > There should now be no reason to export a function name that is not > expected to be called from other modules. (Counterexamples, anyone?) The only thing I can think of offhand is the rpc library. Perhaps spawn(Node,Fun) should be used rather than the ordinary rpc library. Or the rpc library should be retooled to use fun:s instead of mod/fun/args. Note that separating -export and -spawn/-apply also guarantees that -export:ed functions are not spawned or applied unless explicitly so declared. A tool like xref can then guarantee that nobody is breaking interfaces by directly calling some module that is intended to be 'local' to an application. Program analyzers and similar tools can be less conservative as well. Thomas -- Thomas Lindgren thomas+junk@REDACTED Alteon WebSystems "National differences and antagonism between peoples are daily more and more vanishing, owing to the development of the bourgeoisie, to freedom of commerce, to the world market, to uniformity in the mode of production and in the conditions of life corresponding thereto." -- Communist Manifesto From joe@REDACTED Fri Dec 1 17:24:17 2000 From: joe@REDACTED (Joe Armstrong) Date: Fri, 1 Dec 2000 17:24:17 +0100 (CET) Subject: Erlang wiki lives again Message-ID: The Erlang wiki lives again (at long last) - now almost totally rewritten (again sigh :-) (I know). This time I hope it will be much longer lived than the last one. Just point your browser at http://www.bluetail.com:5999/ Tell me if it doesnt work -- Joe Armstrong, Alteon WebSystems, tel: +46 8-545 550 00 S:t Eriksgatan 44, IV, fax: +46 8-545 550 50 SE-112 32 Stockholm, Sweden info: www.bluetail.com From crd@REDACTED Fri Dec 1 17:30:23 2000 From: crd@REDACTED (Craig Dickson) Date: Fri, 1 Dec 2000 08:30:23 -0800 Subject: Erlang wiki lives again References: Message-ID: <010201c05bb4$02144e60$a201140a@inkpad> One word: FIREWALL. Why can't it be on port 80 where web servers belong? Craig ----- Original Message ----- From: "Joe Armstrong" To: Sent: Friday, 1 December 2000 08:24 am Subject: Erlang wiki lives again > > The Erlang wiki lives again (at long last) - now almost totally rewritten (again > sigh :-) (I know). > > This time I hope it will be much longer lived than the last one. > > Just point your browser at http://www.bluetail.com:5999/ > > Tell me if it doesnt work > > -- > Joe Armstrong, > Alteon WebSystems, tel: +46 8-545 550 00 > S:t Eriksgatan 44, IV, fax: +46 8-545 550 50 > SE-112 32 Stockholm, Sweden info: www.bluetail.com > From luke@REDACTED Fri Dec 1 17:32:08 2000 From: luke@REDACTED (Luke Gorrie) Date: 01 Dec 2000 17:32:08 +0100 Subject: Erlang wiki lives again In-Reply-To: Joe Armstrong's message of "Fri, 1 Dec 2000 17:24:17 +0100 (CET)" References: Message-ID: Joe Armstrong writes: > Tell me if it doesnt work Might be a good idea to disallow characters like ')' ',' etc in URLs (i.e. terminate them if you hit one) so that you can have links like: Foo bar (http://www.foo.com/bar/) is ... From joe@REDACTED Fri Dec 1 18:56:13 2000 From: joe@REDACTED (Joe Armstrong) Date: Fri, 1 Dec 2000 18:56:13 +0100 (CET) Subject: Erlang wiki lives again In-Reply-To: <010201c05bb4$02144e60$a201140a@inkpad> Message-ID: Because www.bluetail.com port 80 is used by our apache server. Can you really only access port 80 servers? - otherwise we'll have to fix another address or arrange to re-direct (say) http://www.bluetail.com/wikie/XXX .. requests to port 80 as if they had been requests to http://www.bluetail.com:5999/XXX Ummm - how do you do that? /Joe > One word: FIREWALL. > > Why can't it be on port 80 where web servers belong? > > Craig > > ----- Original Message ----- > From: "Joe Armstrong" > To: > Sent: Friday, 1 December 2000 08:24 am > Subject: Erlang wiki lives again > > > > > > The Erlang wiki lives again (at long last) - now almost totally rewritten > (again > > sigh :-) (I know). > > > > This time I hope it will be much longer lived than the last one. > > > > Just point your browser at http://www.bluetail.com:5999/ > > > > Tell me if it doesnt work > > > > -- > > Joe Armstrong, > > Alteon WebSystems, tel: +46 8-545 550 00 > > S:t Eriksgatan 44, IV, fax: +46 8-545 550 50 > > SE-112 32 Stockholm, Sweden info: www.bluetail.com > > > From crd@REDACTED Fri Dec 1 19:07:02 2000 From: crd@REDACTED (Craig Dickson) Date: Fri, 1 Dec 2000 10:07:02 -0800 Subject: Erlang wiki lives again References: Message-ID: <017201c05bc1$84a38aa0$a201140a@inkpad> Joe wrote: > Can you really only access port 80 servers? - otherwise we'll have to fix > another address or arrange to re-direct > > (say) http://www.bluetail.com/wikie/XXX .. requests to port 80 > > as if they had been requests to http://www.bluetail.com:5999/XXX If that can be done, it would be nice. I can do 80 and 143 -- that's it. At least until the end of December, at which point I'm out of this place. If it were just me, I probably wouldn't say anything, since it's just a short-term issue for me, but fascist network admins can't be _that_ uncommon. If my company has some, surely other companies must also. Having an important community resource like the Bluetail wiki be potentially inaccessible to people bothers me. In any case, I think it's great that there is a wikie again. Thanks for putting it back up. Craig From bertil@REDACTED Fri Dec 1 19:26:26 2000 From: bertil@REDACTED (Bertil Askelid) Date: Fri, 1 Dec 2000 10:26:26 -0800 Subject: Erlang wiki lives again In-Reply-To: (message from Joe Armstrong on Fri, 1 Dec 2000 18:56:13 +0100 (CET)) References: Message-ID: <200012011826.KAA09173@Askelid.com> <> Date: Fri, 1 Dec 2000 18:56:13 +0100 (CET) <> From: Joe Armstrong <> Subject: Re: Erlang wiki lives again <> <> <> Because www.bluetail.com port 80 is used by our apache server. <> <> Can you really only access port 80 servers? - otherwise we'll have to fix <> another address or arrange to re-direct <> <> (say) http://www.bluetail.com/wikie/XXX .. requests to port 80 <> <> as if they had been requests to http://www.bluetail.com:5999/XXX <> <> Ummm - how do you do that? <> <> /Joe From ppetru@REDACTED Fri Dec 1 21:00:20 2000 From: ppetru@REDACTED (Petru Paler) Date: Fri, 1 Dec 2000 22:00:20 +0200 Subject: Erlang wiki lives again In-Reply-To: ; from joe@bluetail.com on Fri, Dec 01, 2000 at 06:56:13PM +0100 References: <010201c05bb4$02144e60$a201140a@inkpad> Message-ID: <20001201220019.C3857@ppetru.net> On Fri, Dec 01, 2000 at 06:56:13PM +0100, Joe Armstrong wrote: > Because www.bluetail.com port 80 is used by our apache server. > > Can you really only access port 80 servers? - otherwise we'll have to fix > another address or arrange to re-direct > > (say) http://www.bluetail.com/wikie/XXX .. requests to port 80 > > as if they had been requests to http://www.bluetail.com:5999/XXX > > Ummm - how do you do that? You use apache's mod_proxy (in the standard distribution, but not enabled by default) and mod_rewrite (same situation) and do something like: RewriteEngine On RewriteRule ^/wikie/(.*)$ http://127.0.0.1:5999/$1 [L,P] -- Petru Paler, mailto:ppetru@REDACTED http://www.ppetru.net - ICQ: 41817235 From dne@REDACTED Fri Dec 1 21:53:27 2000 From: dne@REDACTED (Daniel Neri) Date: 01 Dec 2000 21:53:27 +0100 Subject: Erlang wiki lives again In-Reply-To: Bertil Askelid's message of "Fri, 1 Dec 2000 10:26:26 -0800" References: <200012011826.KAA09173@Askelid.com> Message-ID: <877l5jhni0.fsf@nowhere.mayonnaise.net> Bertil Askelid writes: > <> From: Joe Armstrong [snip] > <> Ummm - how do you do that? > <> > <> /Joe > > But then you're back on square one. You need another IP address (either on a separate machine/NIC or by aliasing the original one). Regards, --Daniel -- Daniel Neri dne@REDACTED From josh@REDACTED Sat Dec 2 02:34:52 2000 From: josh@REDACTED (Josh Snyder) Date: Fri, 01 Dec 2000 19:34:52 -0600 Subject: Culture shock Message-ID: <3A2851BC.10B6EE82@vailsys.com> I'm a newcomer to Erlang and functional programming as a whole. I have a question about how you keep the flow of control readable. It appears that for each potentially unbounded loop, the Erlang program is forced into calling a new function and then immediately ending for tail recursion. This prevents me from using my usual imperative language structure. One in which you can see the entire program structure by analyzing the sub-procedure names in a "main function". A recommendation in the Erlang style guide is to use functions in place of if's and case's when nested conditionals start edging the code to far to the right. When replacing nested for's, if's, and case's with tail recursive functions, the usual start and loop or init and loop functions just don't cut it. Tail recursion looks uncannily like the infamous goto statements, where calling functions comes to look a lot like jumping around labels. How do you keep the pasta out of Erlang code? -Josh ------------- Joshua J. D. Snyder josh@REDACTED From Sean.Hinde@REDACTED Sat Dec 2 13:37:22 2000 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Sat, 2 Dec 2000 12:37:22 -0000 Subject: Performance of dict and ets Message-ID: <402DD461F109D411977E0008C791C312565416@imp02mbx.one2one.co.uk> Hi, I've been doing some performance comparison between the new R7B dict module and ets which I thought I'd share. My benchmark program creates the table/dict, stores 20,000 elements in it with keys 1..20000, then runs through all keys again and reads then deletes each entry. If I store lists of varying lengths I get the following results (microsecs per op on a 167MHz SPARC) list length ets_rd_del ets_write ets_tot dict_rd_del dict_write Dict_tot 1 13 12 25 54 62 117 100 43 30 73 55 62 117 200 71 42 113 54 64 119 300 102 60 162 55 62 117 400 140 73 213 55 63 118 As expected dict is the same speed across the board, but ets shows linear growth with the size of the term being stored. Storing any less than 20,000 rows doesn't seem to make much difference. In the write case the breakeven is at about 300 elements in the list, in the read/delete case at about 130 elements. Overall breakeven is at 230 approx If I store a binary it becomes a bit more interesting... The dict module performs identically to it's lists case. The ets module gives the startling result that almost irrespective of the size of the binary each op takes only around 14 microsecs. This seems to imply that storing a binary in an ets table involves no copying... My first guess is that the copying involved in storing something in an ets table is an instantaneous term_to_binary type operation rather than anything inherent in transferring data to ets??? Can anyone explain this ets copying business fully? Thanks, - Sean BTW while playing with this I added a couple of functions to dict which retrieve and delete the entry in one operation. This is about 20% faster than doing them separately (which may be worth it for someone :~) ) ------Cut-------- -export([find_erase/2, fetch_erase/2]). %% find_erase(Key, Dictionary) -> {ok, Value, Dictionary} | error find_erase(Key, D0) -> Slot = get_slot(D0, Key), case on_bucket(fun (B0) -> find_erase_key(Key, B0) end, D0, Slot) of {D1,error} -> error; {D1, Val} -> D2 = maybe_contract(D1, 1), % I think this is always true {ok, Val, D2} end. find_erase_key(Key, [?kv(Key,Val)|Bkt]) -> {Bkt,Val}; find_erase_key(Key, [E|Bkt0]) -> {Bkt1,Val} = find_erase_key(Key, Bkt0), {[E|Bkt1],Val}; find_erase_key(Key, []) -> {[],error}. %% fetch_erase(Key, Dictionary) -> {Value, Dictionary} fetch_erase(Key, D0) -> Slot = get_slot(D0, Key), {D1, Val} = on_bucket(fun (B0) -> fetch_erase_key(Key, B0) end, D0, Slot), D2 = maybe_contract(D1, 1), {Val, D2}. fetch_erase_key(Key, [?kv(Key,Val)|Bkt]) -> {Bkt,Val}; fetch_erase_key(Key, [E|Bkt0]) -> {Bkt1,Val} = fetch_erase_key(Key, Bkt0), {[E|Bkt1],Val}. 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 joe@REDACTED Sat Dec 2 14:04:03 2000 From: joe@REDACTED (Joe Armstrong) Date: Sat, 2 Dec 2000 14:04:03 +0100 (CET) Subject: Erlang wiki lives again In-Reply-To: <010201c05bb4$02144e60$a201140a@inkpad> Message-ID: The Erlang wiki can now be reached through: http://www.bluetail.com/wiki/ or http://www.bluetail.com:5999/ This is thanks to a tip from Petru Paler (see his earlier posting) /Joe -- Joe Armstrong, Alteon WebSystems, tel: +46 8-545 550 00 S:t Eriksgatan 44, IV, fax: +46 8-545 550 50 SE-112 32 Stockholm, Sweden info: www.bluetail.com On Fri, 1 Dec 2000, Craig Dickson wrote: > One word: FIREWALL. > > Why can't it be on port 80 where web servers belong? > > Craig > > ----- Original Message ----- > From: "Joe Armstrong" > To: > Sent: Friday, 1 December 2000 08:24 am > Subject: Erlang wiki lives again > > > > > > The Erlang wiki lives again (at long last) - now almost totally rewritten > (again > > sigh :-) (I know). > > > > This time I hope it will be much longer lived than the last one. > > > > Just point your browser at http://www.bluetail.com:5999/ > > > > Tell me if it doesnt work > > > > -- > > Joe Armstrong, > > Alteon WebSystems, tel: +46 8-545 550 00 > > S:t Eriksgatan 44, IV, fax: +46 8-545 550 50 > > SE-112 32 Stockholm, Sweden info: www.bluetail.com > > > From Sean.Hinde@REDACTED Sat Dec 2 14:18:54 2000 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Sat, 2 Dec 2000 13:18:54 -0000 Subject: threads - use them as much as you can Message-ID: <402DD461F109D411977E0008C791C312565417@imp02mbx.one2one.co.uk> > > In R7B (the current release) there is a new feature which > introduces a pool > > of native threads for i/o operations but this is disabled > by default. This > > will get around the hanging problem /.../ I thought some more about my original reply and should probably add that during testing I have absolutely hammered mnesia with database writes to a disc_copies table at full speed, while at the same time having another node performing timed reads at 100 per second on the same table (all on a single processor 167 MHz SPARC :o) ). The worst blocking I got under standard Unix File System was a pause of 5 seconds which only occurred occasionally during the mnesia log dump. The vast majority of reads were returned in millisecs. Using Veritas File system (or I guess any of the other new journaling file systems) I never managed to get the disk writing node to block my reads for more than 1.5 seconds under these conditions (again 1 in thousands). My conclusion was that the Erlang VM does a pretty incredible job of managing this real time stuff - far far better than quite a number of commercial databases I have come across. Note that this was without multithreaded i/o... And It's getting better, better all the time. - 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 bjorn@REDACTED Sat Dec 2 17:31:36 2000 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 02 Dec 2000 17:31:36 +0100 Subject: Performance of dict and ets In-Reply-To: Sean Hinde's message of "Sat, 2 Dec 2000 12:37:22 -0000" References: <402DD461F109D411977E0008C791C312565416@imp02mbx.one2one.co.uk> Message-ID: Sean Hinde writes: > Hi, > > I've been doing some performance comparison between the new R7B dict module > and ets which I thought I'd share. > > My benchmark program creates the table/dict, stores 20,000 elements in it > with keys 1..20000, then runs through all keys again and reads then deletes > each entry. > > If I store lists of varying lengths I get the following results (microsecs > per op on a 167MHz SPARC) > > list length ets_rd_del ets_write ets_tot dict_rd_del > dict_write Dict_tot > 1 13 12 25 54 62 117 > 100 43 30 73 55 62 117 > 200 71 42 113 54 64 119 > 300 102 60 162 55 62 117 > 400 140 73 213 55 63 118 > > As expected dict is the same speed across the board, but ets shows linear > growth with the size of the term being stored. > > Storing any less than 20,000 rows doesn't seem to make much difference. > > In the write case the breakeven is at about 300 elements in the list, in the > read/delete case at about 130 elements. Overall breakeven is at 230 approx > > If I store a binary it becomes a bit more interesting... > > The dict module performs identically to it's lists case. > > The ets module gives the startling result that almost irrespective of the > size of the binary each op takes only around 14 microsecs. This seems to > imply that storing a binary in an ets table involves no copying... Yes, see below. > > My first guess is that the copying involved in storing something in an ets > table is an instantaneous term_to_binary type operation rather than anything > inherent in transferring data to ets??? > > Can anyone explain this ets copying business fully? Terms in an ets table are in the same term format as on process heap, not in the external term format. Copying a term to an ets table takes the same time as copying a term to another process. Copying a term out of a an ets table should be slighly faster, because we use a special copy routine that depends on the term being stored in a continous memory block. Binaries are not copied. Binaries are referenced-counted memory chunks outside all process heaps. There is only a small reference to it stored on the process heap. When you store a binary in an ets table, only the reference to the binary is copied. We call this type of binary refc binaries. In R7, small binaries (less than 64 bytes) are usually stored on the heap and copied when sent or stored in ets tables. We call these binaries heap binaries. We expect heap binaries to be faster than refc binaries, because there is less book-keeping, both when creating binaries and in garbage collection. There are also sub binaries (also new in R7), which are created when you split binaries either using the bit syntax or by the calling the split_binary BIF. A sub binary contains a reference to either a refc binary or a heap binary, and an offset and a length to specify part of the original binary. > > Thanks, > > - Sean /Bj?rn -- 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 Sat Dec 2 18:16:47 2000 From: kent@REDACTED (Kent Boortz) Date: 02 Dec 2000 18:16:47 +0100 Subject: Culture shock In-Reply-To: Josh Snyder's message of "Fri, 01 Dec 2000 19:34:52 -0600" References: <3A2851BC.10B6EE82@vailsys.com> Message-ID: > Tail recursion looks uncannily like the infamous goto statements, where > calling functions comes to look a lot like jumping around labels. How > do you keep the pasta out of Erlang code? Most Erlang program I have read written by skilled Erlang programmers don't have the above problem so I think it is possible to keep the "pasta" out of Erlang code. But this is a bit of a problem for languages like Erlang and Prolog, you find yourself spending lots of time trying to find clever names for the "extra functions" you have to use for "iterations inside iterations". The lazy approach creating function names for "iterative sub functions" is by adding a number to the "main" function. This sure doesn't improve the readability. A good name for a "sub function" can improve the readability for the program compared to an iterative language. Still, I find this to be a problem and there are several ways to address it. The list module contains several iterators that take a data type "functional objects" (Funs) as an argument. A iteration like . . foo(List, []), % Function call to start new iteration level . foo([], Acc) -> Acc; foo([H | T], Acc) -> foo(T, NewAcc). can be replaced by an inline solution . . Fun = fun(H, Acc) -> NewAcc end, lists:foldl(Fun, [], List). . Also you tend to write more "generic" help functions in Erlang and there are some in the Erlang standard library for common "generic behaviors". Many Erlang programs uses the same base loop, something like loop(State) -> receive {message_a, Data, Sender} -> Sender ! {reply_a, .....} % send back a reply loop(NewState); {message_b, Data, Sender} -> loop(NewState); % no reply to this message . . end. Using the generic behavior support the same code may look like -behaviour(gen_server). . . handle_call({message_a, Data}, State) -> {reply, {reply_a, .....}, NewState}; handle_call({message_b, Data}, State) -> {noreply, NewState}; . . The disadvantage with using Funs and "generic behaviors" is that they sometimes makes the code even harder to understand. But the advantage is often higher. Using Funs and the list iterators the right way makes loops easier to read and the generic behaviours in the standard library adds values like support for runtime code upgrades, debugging etc. Ref: http://www.erlang.org/doc/r7b/doc/extensions/funs.html http://www.erlang.org/doc/r7b/doc/design_principles/part_frame.html http://www.erlang.org/doc/r7b/lib/stdlib-1.9.1/doc/html/gen_server.html kent From tobbe@REDACTED Sat Dec 2 20:43:39 2000 From: tobbe@REDACTED (Torbjorn Tornkvist) Date: 02 Dec 2000 20:43:39 +0100 Subject: Culture shock In-Reply-To: Josh Snyder's message of "Fri, 01 Dec 2000 19:34:52 -0600" References: <3A2851BC.10B6EE82@vailsys.com> Message-ID: An explanation of functional programming I've tried on students is to compare a function with a black-box containing some machinery which takes some input (via the input arguments) and produce a result (the returned result). Example 1: X Y | | +---------+ | plus/2 | X+Y=Z +---------+ | Z By combining 'boxes' you form larger boxes and voila, you have your program written. Example 2: X Y W | | | +-------+---+------+----+ | | | | | | +--+---+--+ | | | | plus/2 | | | | +----+----+ | | | | | | | | +----+ | plus/3 == X+Y+W=Z | | | | | +---+---+-+ | | | plus/2 | | | +----+----+ | | | | +----------+------------+ | Z So I guess, what I want to say is: think in boxes instead of control flow structures. BTW: Try to follow the rules: 1. The only way the affect the behaviour of a function is via the input arguments. 2. The only way for a function to affect its surrounding environment is via the returned result. 3. The same input will always give the same result. 4. Try to restrict the code that breaks rule 1,2,3 into one place. Just my naive thoughts on the topic (a Saturday night... :-) Cheers /Tobbe From kent@REDACTED Sun Dec 3 16:36:45 2000 From: kent@REDACTED (Kent Boortz) Date: 03 Dec 2000 16:36:45 +0100 Subject: The update R7B-1 is released Message-ID: This is a bug fix release R7B-1. You can download the full source distribution or the patch (*) that take R7B-0 up to R7B-1. There where smaller patches, 14 of them, released earlier. This release and large patch replaces those, i.e. if you have applied them earlier then you have patched up to R7B-1 already. http://www.erlang.org/download/otp_src_R7B-1.readme http://www.erlang.org/download/otp_src_R7B-1.tar.gz http://www.erlang.org/download/otp_src_R7B-0to1.patch.gz To patch you need a patch program that can handle the "unified" diff format. You apply the patch with % cd otp_src_R7B-0 % zcat ../otp_src_R7B-0to1.patch.gz | patch -p1 A FreeBSD package (4.X) and Linux RMP are planned to be released at the end of this week. There is no plan yet for when to release an update of the Windows binary release. kent (*) Read below about the difference between dowloading the full release and patching your old release. The release process for updates 1. We release fully tested source base releases. This is R7B-0, R8A-0, i.e. those ending in "-0". 2. We release selected source snapshots. This is snapshots that contains important changes and that passed the testing. These snapshots will be named R7B-1, R7B-2, ...... 3. We will release combined patches, i.e. one large patch that patch from R7B-0 to R7B-1, a second one from R7B-1 to R7B-2 etc. Note that the result after patching will not be *exactly* the same as the snapshot. Some precompiled BEAM files in the bootstrap part may differ. 4. When a move from one source release to the next require changes in the bootstrap compiler, then there will be no patch to upgrade. This forces a complete source release download with the correct binary BEAM files. 5. Binary releases for Linux, FreeBSD and Windows will be built from the complete source snapshots, i.e. not from a base source release with applied patches. From kent@REDACTED Sun Dec 3 16:36:45 2000 From: kent@REDACTED (Kent Boortz) Date: 03 Dec 2000 16:36:45 +0100 Subject: The update R7B-1 is released Message-ID: This is a bug fix release R7B-1. You can download the full source distribution or the patch (*) that take R7B-0 up to R7B-1. There where smaller patches, 14 of them, released earlier. This release and large patch replaces those, i.e. if you have applied them earlier then you have patched up to R7B-1 already. http://www.erlang.org/download/otp_src_R7B-1.readme http://www.erlang.org/download/otp_src_R7B-1.tar.gz http://www.erlang.org/download/otp_src_R7B-0to1.patch.gz To patch you need a patch program that can handle the "unified" diff format. You apply the patch with % cd otp_src_R7B-0 % zcat ../otp_src_R7B-0to1.patch.gz | patch -p1 A FreeBSD package (4.X) and Linux RMP are planned to be released at the end of this week. There is no plan yet for when to release an update of the Windows binary release. kent (*) Read below about the difference between dowloading the full release and patching your old release. The release process for updates 1. We release fully tested source base releases. This is R7B-0, R8A-0, i.e. those ending in "-0". 2. We release selected source snapshots. This is snapshots that contains important changes and that passed the testing. These snapshots will be named R7B-1, R7B-2, ...... 3. We will release combined patches, i.e. one large patch that patch from R7B-0 to R7B-1, a second one from R7B-1 to R7B-2 etc. Note that the result after patching will not be *exactly* the same as the snapshot. Some precompiled BEAM files in the bootstrap part may differ. 4. When a move from one source release to the next require changes in the bootstrap compiler, then there will be no patch to upgrade. This forces a complete source release download with the correct binary BEAM files. 5. Binary releases for Linux, FreeBSD and Windows will be built from the complete source snapshots, i.e. not from a base source release with applied patches. From hakan@REDACTED Mon Dec 4 10:35:17 2000 From: hakan@REDACTED (Hakan Mattsson) Date: Mon, 4 Dec 2000 10:35:17 +0100 (MET) Subject: export_to (Was: Re: the OO metaphor) In-Reply-To: Message-ID: On Fri, 1 Dec 2000, Richard Carlsson wrote: Richard> This should not be needed, since you can nowadays write: Richard> Richard> spawn(fun () -> my_nonexported function(X1, ..., Xn) end) Richard> Richard> There should now be no reason to export a function name that is not Richard> expected to be called from other modules. (Counterexamples, anyone?) What about code change? In order to manage code change without killing the process, fun's should only be used for short tasks. By using a fun as the topmost function in long lived server processes, you will effectively force a kill of the process at next code change. /H?kan From thomasl@REDACTED Mon Dec 4 10:45:11 2000 From: thomasl@REDACTED (Thomas Lindgren) Date: Mon, 4 Dec 2000 10:45:11 +0100 Subject: export_to (Was: Re: the OO metaphor) In-Reply-To: (message from Hakan Mattsson on Mon, 4 Dec 2000 10:35:17 +0100 (MET)) References: Message-ID: <200012040945.KAA00927@lammgam.bluetail.com> > In order to manage code change without killing the process, fun's > should only be used for short tasks. By using a fun as the topmost > function in long lived server processes, you will effectively force > a kill of the process at next code change. Good point, though the question it raises is whether the current code replacement semantics for fun:s is what we want. Wouldn't it be more useful if closures survived code change, for example? Why shouldn't they? Thomas -- Thomas Lindgren thomas+junk@REDACTED Alteon WebSystems "National differences and antagonism between peoples are daily more and more vanishing, owing to the development of the bourgeoisie, to freedom of commerce, to the world market, to uniformity in the mode of production and in the conditions of life corresponding thereto." -- Communist Manifesto From happi@REDACTED Mon Dec 4 10:56:19 2000 From: happi@REDACTED (Erik (Happi) Johansson) Date: Mon, 4 Dec 2000 10:56:19 +0100 Subject: export_to (Was: Re: the OO metaphor) In-Reply-To: Message-ID: H?kan Mattsson wrote: > On Fri, 1 Dec 2000, Richard Carlsson wrote: > > Richard> This should not be needed, since you can nowadays write: > Richard> > Richard> spawn(fun () -> my_nonexported function(X1, ..., Xn) end) > Richard> > Richard> There should now be no reason to export a function name > that is not > Richard> expected to be called from other modules. > (Counterexamples, anyone?) > > What about code change? > > In order to manage code change without killing the process, fun's > should only be used for short tasks. By using a fun as the topmost > function in long lived server processes, you will effectively force > a kill of the process at next code change. No, not if the fun only does a tail-call to the server loop. /Erik From mbj@REDACTED Mon Dec 4 11:08:16 2000 From: mbj@REDACTED (Martin Bjorklund) Date: Mon, 04 Dec 2000 11:08:16 +0100 Subject: export_to (Was: Re: the OO metaphor) In-Reply-To: Your message of "Mon, 4 Dec 2000 10:45:11 +0100" <200012040945.KAA00927@lammgam.bluetail.com> References: <200012040945.KAA00927@lammgam.bluetail.com> Message-ID: <20001204110816N.mbj@bluetail.com> Thomas Lindgren wrote: > > > In order to manage code change without killing the process, fun's > > should only be used for short tasks. By using a fun as the topmost > > function in long lived server processes, you will effectively force > > a kill of the process at next code change. > > Good point, though the question it raises is whether the current code > replacement semantics for fun:s is what we want. Wouldn't it be more > useful if closures survived code change, for example? Why shouldn't > they? If they did, you would be forced to handle versions of funs yourself, in the code. Some funs in your state might be very old (and buggy!) and some newer, even "the same" funs (just different incarnations). You'd have to take care of that in the code. I still think that funs are great for short-lived stuff, like looping over a list, but whenever the "fun" is stored in a state, I think the {Mod, Fun} (or {M,F,A}) syntax is the only way that works in practice, due the code loading problem. This is not a new problem, it has always been there (and that was one of the reasons funs were not part of the language for a long time). The only drawback with the current code loading mechanism is that while it's very elegant in theroy, in combination with gen_server et. al. it's ugly. The problem here is that gen_server always calls the call-back module with an external call, thus forcing a code change. Come to think of it, this could actually be solved by using a fun instead of the call-back module! Hey, klacke, we're back to 'generic' with the 'doit' function ;-) /martin From bjorn@REDACTED Mon Dec 4 11:12:58 2000 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 04 Dec 2000 11:12:58 +0100 Subject: export_to (Was: Re: the OO metaphor) In-Reply-To: Thomas Lindgren's message of "Mon, 4 Dec 2000 10:45:11 +0100" References: <200012040945.KAA00927@lammgam.bluetail.com> Message-ID: Actually, in Beam R5 and later versions, funs do survive ONE code change. That is, you can load a new version of a module and still call the old version version of the code through an old fun. However, you can't change the code a second time and still use the old fun. You would have to replace the fun to a fun based on the new version of the code (which is not possible to do if you spawned a fun directly). /Bj?rn Thomas Lindgren writes: > > In order to manage code change without killing the process, fun's > > should only be used for short tasks. By using a fun as the topmost > > function in long lived server processes, you will effectively force > > a kill of the process at next code change. > > Good point, though the question it raises is whether the current code > replacement semantics for fun:s is what we want. Wouldn't it be more > useful if closures survived code change, for example? Why shouldn't > they? > > Thomas > -- > Thomas Lindgren thomas+junk@REDACTED > Alteon WebSystems > > "National differences and antagonism between peoples are daily more and > more vanishing, owing to the development of the bourgeoisie, to > freedom of commerce, to the world market, to uniformity in the mode of > production and in the conditions of life corresponding thereto." > -- Communist Manifesto > > -- Bj?rn Gustavsson Ericsson Utvecklings AB bjorn@REDACTED ?T2/UAB/F/P BOX 1505 +46 8 727 56 87 125 25 ?lvsj? From bjorn@REDACTED Mon Dec 4 11:18:13 2000 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 04 Dec 2000 11:18:13 +0100 Subject: export_to (Was: Re: the OO metaphor) In-Reply-To: Martin Bjorklund's message of "Mon, 04 Dec 2000 11:08:16 +0100" References: <200012040945.KAA00927@lammgam.bluetail.com> <20001204110816N.mbj@bluetail.com> Message-ID: Martin Bjorklund writes: [...] > > The only drawback with the current code loading mechanism is that > while it's very elegant in theroy, in combination with gen_server > et. al. it's ugly. The problem here is that gen_server always calls > the call-back module with an external call, thus forcing a code > change. Come to think of it, this could actually be solved by using a > fun instead of the call-back module! Hey, klacke, we're back to > 'generic' with the 'doit' function ;-) Using a fun would be faster as well, since fun calls are faster than apply/3. > > > /martin > > > /Bj?rn -- Bj?rn Gustavsson Ericsson Utvecklings AB bjorn@REDACTED ?T2/UAB/F/P BOX 1505 +46 8 727 56 87 125 25 ?lvsj? From happi@REDACTED Mon Dec 4 11:15:39 2000 From: happi@REDACTED (Erik (Happi) Johansson) Date: Mon, 4 Dec 2000 11:15:39 +0100 Subject: export_to (Was: Re: the OO metaphor) In-Reply-To: <200012040945.KAA00927@lammgam.bluetail.com> Message-ID: Thomas Lindgren wrote: > Good point, though the question it raises is whether the current code > replacement semantics for fun:s is what we want. Wouldn't it be more > useful if closures survived code change, for example? Why shouldn't > they? This is an interesting question that you raise. (What should the code replacement semantics for fun:s be?) As it is today a fun survives code change as long as the code doesn't change to much :) The problem is what do you do with local calls from a fun, if the fun is allowed to live indefinitely then the code for the module containing the fun must also be kept indefinitely. With proper code GC this would not be a problem but the question is whether this is a price we are willing to pay. /Erik From etxuwig@REDACTED Mon Dec 4 12:00:28 2000 From: etxuwig@REDACTED (Ulf Wiger) Date: Mon, 4 Dec 2000 12:00:28 +0100 (MET) Subject: one-stop recruiting page Message-ID: I recently sat down and started searching the web for wanted ads mentioning Erlang. It was disheartening. Knowing that there is actually a demand for Erlang competence, I think something needs to be done to make this more visible. Personally, I'd like to see an "Erlang Programmers Wanted" page on http://www.erlang.org, where current links to open positions for Erlangers were collected. If, say, a student who encounters Erlang at school wants to know what the job market is for an Erlang expert, he/she might hit a search engine like I did - with the current state of affairs, he/she would hardly be encourage to continue. Having said this, I know that Erlang is doing well in schools that are teaching it. I recently heard that at KTH Haninge, an engineering school in Stockholm, the Erlang class had exactly as many applicants as the Advanced Java class. By cooperating, we can make this more visible. Comments are welcome. This is what I did: 1 Knowing that we are looking for Erlang programmers, I started searching for our ad. This was surprisingly difficult (I had to ask someone). Later, I learned that the Ericsson jobs page is being reorganized, and that it should appear in mid-December. (http://www.ericsson.se/SE/rekryt/teknik4947090.html) 2 I went to www.erlang.se, and followed the links to the companies that have certified consultants. Of the six companies listed, only Sj?land & Thyselius and Cesarini Consulting actually mention Erlang on their web pages; of these two, only Sj?land & Thyselius is looking for Erlang programmers (Cesarini Consulting is, as far as I know, a one-man company) 3 Searched the web via http://www.alltheweb.com and found the following additional info: - SICS (http://www.sics.se) is looking for people, and is working with Erlang. It wasn't entirely obvious that the positions listed actually involved work with Erlang, but there appeared to be a chance that it might be so. - WiseOne (http://www.wiseone.se) is looking for Erlang programmers - Ericsson in Gothenburg is looking for Erlang programmers (http://www.eritel.se/open/content.htm) (http://www.erv.ericsson.se/open/content.htm) - Telia Promotor (http://www.promotor.telia.se) is looking for Erlang programmers. - Erlang Technology, Inc (http://erlang.tech.com) is NOT looking for Erlang programmers... ironically. 4 Guessing that the company formerly known as Bluetail might be hiring, I looked at their page - indeed they are, but since it's a PHP page, it doesn't score well on search engines. /Uffe -- Ulf Wiger tfn: +46 8 719 81 95 Senior System Architect mob: +46 70 519 81 95 Strategic Product & System Management ATM Multiservice Networks Data Backbone & Optical Services Division Ericsson Telecom AB From happi@REDACTED Mon Dec 4 12:16:46 2000 From: happi@REDACTED (Erik (Happi) Johansson) Date: Mon, 4 Dec 2000 12:16:46 +0100 Subject: export_to (Was: Re: the OO metaphor) In-Reply-To: Message-ID: I wrote: > H?kan Mattsson wrote: > > In order to manage code change without killing the process, fun's > > should only be used for short tasks. By using a fun as the topmost > > function in long lived server processes, you will effectively force > > a kill of the process at next code change. > > No, not if the fun only does a tail-call to the server loop. Unfortunately, one still needs to export a function in order to get code change to work, but that has nothing to do with funs. Still, code change is a counterexample to Richard's hypothesis that: > There should now be no reason to export a function name > that is not expected to be called from other modules. (I should know better than writing emails early on Monday morning.) /Erik From joe@REDACTED Mon Dec 4 12:43:32 2000 From: joe@REDACTED (Joe Armstrong) Date: Mon, 4 Dec 2000 12:43:32 +0100 (CET) Subject: one-stop recruiting page In-Reply-To: Message-ID: On Mon, 4 Dec 2000, Ulf Wiger wrote: > > Personally, I'd like to see an "Erlang Programmers Wanted" page on > http://www.erlang.org, where current links to open positions for > Erlangers were collected. Or even http://www.bluetail.com/wiki/showPage?node=ErlangJobs :-) /Joe -- Joe Armstrong, Alteon WebSystems, tel: +46 8-545 550 00 S:t Eriksgatan 44, IV, fax: +46 8-545 550 50 SE-112 32 Stockholm, Sweden info: www.bluetail.com From etxuwig@REDACTED Mon Dec 4 12:59:34 2000 From: etxuwig@REDACTED (Ulf Wiger) Date: Mon, 4 Dec 2000 12:59:34 +0100 (MET) Subject: one-stop recruiting page In-Reply-To: Message-ID: On Mon, 4 Dec 2000, Joe Armstrong wrote: >On Mon, 4 Dec 2000, Ulf Wiger wrote: > >> >> Personally, I'd like to see an "Erlang Programmers Wanted" page on >> http://www.erlang.org, where current links to open positions for >> Erlangers were collected. > >Or even > >http://www.bluetail.com/wiki/showPage?node=ErlangJobs > >:-) This page looks good on my PC Netscape and on my PC IExplorer, but really crappy on my Unix Netscape, since the bg image stretches out for miles, and the text doesn't wrap. /Uffe -- Ulf Wiger tfn: +46 8 719 81 95 Senior System Architect mob: +46 70 519 81 95 Strategic Product & System Management ATM Multiservice Networks Data Backbone & Optical Services Division Ericsson Telecom AB From richardc@REDACTED Mon Dec 4 14:02:06 2000 From: richardc@REDACTED (Richard Carlsson) Date: Mon, 4 Dec 2000 14:02:06 +0100 (MET) Subject: export_to (Was: Re: the OO metaphor) In-Reply-To: Message-ID: On Mon, 4 Dec 2000, Erik (Happi) Johansson wrote: > Unfortunately, one still needs to export a function in order to get > code change to work, but that has nothing to do with funs. > Still, code change is a counterexample to Richard's hypothesis that: > > > There should now be no reason to export a function name I should have qualified that statement with "except for the purpose of supporting code change". Maybe it would be enough to, in addition to the normal export declarations, also have a form of "private" export declaration? Anyhow, we need not distinguish between whether the call is done with "spawn" or "apply", which I think was sort of my main point. /Richard Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) E-mail: Richard.Carlsson@REDACTED WWW: http://www.csd.uu.se/~richardc/ From rv@REDACTED Mon Dec 4 16:02:45 2000 From: rv@REDACTED (Robert Virding) Date: Mon, 04 Dec 2000 16:02:45 +0100 Subject: Performance of dict and ets In-Reply-To: Your message of "Sat, 02 Dec 2000 12:37:22 GMT." <402DD461F109D411977E0008C791C312565416@imp02mbx.one2one.co.uk> Message-ID: <200012041502.QAA28499@trana.bluetail.com> Sean Hinde writes: >Hi, > >I've been doing some performance comparison between the new R7B dict module >and ets which I thought I'd share. >... I did some tests a while back when Richard Carlsson presented his gb_trees package which gave some very good results compared to dict and orddict. As Bj?rn described ets copies so to do a fair comparison I make sure I also copy when testing other databases. These are some results from my tests. I run twice through a set of insert, lookup, update if the value is an integer and finally delete on all the values. It is interesting to see what happens the second time when overwriting the old values. I test ets, dict, orddict, gb_trees, pets (Process ETS, like dict but with an ets compatible interface) and sysHashTab (early dict/ets like package from Ulf Wiger, my version couldn't do delete) inserting a tuple of N atoms. The times are average microsecs per operation. ets dict gb_trees pets --- ---- -------- ---- Size = 13 Insert 9.50 46.1 125 47.0 Lookup 3.50 4.24 7.64 4.00 Insert 5.90 28.0 21.1 31.8 Lookup 3.81 3.76 5.16 3.85 Delete 4.80 19.0 5.81 18.8 Size = 26 Insert 9.30 56.7 153 49.5 Lookup 6.80 4.64 7.27 3.90 Insert 7.60 37.9 22.0 43.8 Lookup 5.96 4.02 5.59 3.82 Delete 2.75 21.1 6.04 21.7 Size = 52 Insert 14.5 59.5 121 64.5 Lookup 7.35 4.05 5.50 3.93 Insert 5.90 57.1 38.8 65.3 Lookup 8.22 3.82 5.14 3.87 Delete 2.82 31.7 10.4 25.5 Gb_trees has different functions for insert/lookup/delete depending on whether you *KNOW* there is already data with that key. To be fair we use a variant which doesn't know for insert/lookup but knows for delete. This explains why insertion is much faster the second time, also why delete is much faster than dict/pets. We also see that for objects larger than about 20 element tuples lookup is faster using dict. However for really big databases you don't really want to store them in the process heaps because of the way BEAM heaps are managed. However, one reason for using dict/pets is the nice meta functions fold/filter/merge/update which all work without copying. The ets versions will copy. Robert P.S. Pets hasn't been released, but it is internally very similar to dict. P.P.S. Orddict has been sped up using some better code I got from Richard Carlsson, should be in R8. It is, however, no alternative with this many elements. From Sean.Hinde@REDACTED Mon Dec 4 18:38:26 2000 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Mon, 4 Dec 2000 17:38:26 -0000 Subject: Performance of dict and ets Message-ID: <402DD461F109D411977E0008C791C31256542E@imp02mbx.one2one.co.uk> Hi, Thanks for sharing the results.. > I did some tests a while back when Richard Carlsson presented his > gb_trees package which gave some very good results compared > to dict and > orddict. As Bj?rn described ets copies so to do a fair comparison I > make sure I also copy when testing other databases. These are some > results from my tests. Was the version of dict in your tests the latest one using hash? > However, one reason for using dict/pets is the nice meta functions > fold/filter/merge/update which all work without copying. The ets > versions will copy. I also very much like the filter mechanism, and also like the mechanism in dict where one can append new entries to an existing entry without reading it, appending the new value, and then writing the new value back in. - 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 sam@REDACTED Mon Dec 4 20:04:54 2000 From: sam@REDACTED (Samuel Tardieu) Date: Mon, 4 Dec 2000 20:04:54 +0100 Subject: gen_tcp:accept/{1,2} in passive mode? Message-ID: <2000-12-04-20-04-54+trackit+sam@inf.enst.fr> I use gen_tcp:accept{1,2} a lot when doing servers, and I don't like the fact that I cannot passively wait for connections, in a gen_server for example. How do you deal with code change and a process being blocked in an accept call? You can always use a timeout, but in this case you generate some load when you exit the timeout just in case code needs to be changed. Wouldn't it be possible to set the accepting socket in passive mode, and receive a message {Port, {accept, NewSocket, Origin}} for example when a new connection arrives? Sam From peter@REDACTED Mon Dec 4 20:30:58 2000 From: peter@REDACTED (Peter H|gfeldt) Date: Mon, 4 Dec 2000 20:30:58 +0100 (MET) Subject: gen_tcp:accept/{1,2} in passive mode? In-Reply-To: <2000-12-04-20-04-54+trackit+sam@inf.enst.fr> Message-ID: Sam, we have internally an inofficial FAQ which considers your problem: Q.11 : One process in my application is typically hanging in a call to gen_tcp:accept/1 waiting for a connection request. How do I perform code change for that process? A: Let the implementation be such that another process holds the listen socket and is linked to the process hanging in gen_tcp:accept/1. Specify an update code upgrade instruction with a very short timeout, which will cause the process to be killed almost immediately by the release handler, before the new version of the call-back module for the process is loaded. Then let the other process restart the process calling gen_tcp:accept/1. /Peter ------------------------------------------------------------------------- Peter H?gfeldt e-mail : peter@REDACTED Open Telecom Platform Phone: : +46 (8) 727 57 58 Ericsson Utvecklings AB Mobile : +46 070-519 57 51 S-126 25 STOCKHOLM Fax: : +46 (8) 727 5775 Office address: Armborstv?gen 1, ?lvsj? On Mon, 4 Dec 2000, Samuel Tardieu wrote: > I use gen_tcp:accept{1,2} a lot when doing servers, and I don't like the > fact that I cannot passively wait for connections, in a gen_server for example. > How do you deal with code change and a process being blocked in an accept > call? You can always use a timeout, but in this case you generate some > load when you exit the timeout just in case code needs to be changed. > > Wouldn't it be possible to set the accepting socket in passive mode, and > receive a message {Port, {accept, NewSocket, Origin}} for example when > a new connection arrives? > > Sam > > From tony@REDACTED Mon Dec 4 22:43:00 2000 From: tony@REDACTED (Tony Rogvall) Date: Mon, 04 Dec 2000 22:43:00 +0100 Subject: Bit syntax endianness confusion References: <3.0.32.20001130093112.01049ee0@volition-inc.com> Message-ID: <3A2C0FE4.47ACFB6C@bluetail.com> James Hague wrote: > Suppose I have a binary that contains a 32-bit word stored in big endian > (network) order. This word contains three fields in this order: 10 bits, > 4 bits, and 18 bits. Matching this is easy: > > <> = Binary. > > Now, suppose this word is stored in little endian order. How would I match > it? This isn't right: > > <> = Binary. > > Or is it? Actually, how would the following be interpeted: > > <> = Binary. > > where the first and last fields are little endian but the middle one isn't? > I get the impression that the "little" qualifier reverses bitfields, but I > need something higher level than that. I want to be able to say that the > entire word is stored in little endian order. > > Do I need to do some swizzling first, by interpreting the binary as four > bytes, creating a new binary with the bytes reversed, and then matching > against the original pattern? > > James This "problem" was addressed by us (klacke and me) in the original proposal of the Bit syntax. The source of such bit combinations mostly arise from C language bit fields. Our solution was to have sub group bit syntax expression. Then you could solve your problem by writing something like: << <> : 4/little >> Expression like yours above does not make much sense (Field1:4/little) since only byte sequences are affected by the endian order. I am sure the OTP team will extend the bit syntax with a lot of nice features in the future ;-) /Tony -------------- next part -------------- A non-text attachment was scrubbed... Name: tony.vcf Type: text/x-vcard Size: 333 bytes Desc: Card for Tony Rogvall URL: From Lon.Willett@REDACTED Mon Dec 4 23:27:06 2000 From: Lon.Willett@REDACTED (Lon Willett) Date: Mon, 4 Dec 2000 22:27:06 GMT Subject: ASN.1 enhancements: DER, open types, ... Message-ID: <200012042227.WAA15667@emile.sse.ie> Hi, I've been playing with the Erlang/OTP ASN.1 compiler lately, and have found some deficiencies (for my uses). So I'm thinking about hacking it up a bit, and am wondering what the protocol for this is. Is there some code master I should be in touch with? Is there a development copy of the source somewhere that I should work from? Can I talk someone else into doing this for me? More specifically, my wish-list includes: * DER encoding -- this shouldn't be too hard, although it is difficult to be sure that one hasn't missed something (DER is hard to test, as compared to plain BER). I've noticed a several problems here; the compiler in its current form is definitely unusable for crypto-signing purposes. * Open types -- as far as I can tell, there isn't support for any open types in the compiler (tell me if I'm doing something wrong). There appears to be some code in place to deal with them, but it seems to be incomplete. Ideally, of course, I would like support for the full "Information object specification". I could get by just fine with TYPE-IDENTIFIER and INSTANCE OF, or with ANY [DEFINED BY]. Support for ANY might be a good idea anyway, even if it isn't part of the standard any more. It provides a general escape mechanism to let the caller take over the encoding/decoding, which is useful in those cases where the compiler is, for whatever reason, inadequate. It also should be simple enought to implement (at least with BER, I'm not familiar with PER). I've often had to use it for this reason with other compilers. * BIT STRING -- the current implementation seems to be oriented around the use of short bit strings for a list of options (which is one important case). But it is common in the crypto standards for BLOBs (e.g. encrypted data) to be specified as BIT STRINGs. So not only is the inefficiency of converting to/from a list of zeros and ones bad enough that it might be a problem, but the inconvenience is non-trivial too. A compiler option to choose how one wants non-enumerated bit strings represented as erlang terms would be nice. From Lon.Willett@REDACTED Mon Dec 4 23:36:34 2000 From: Lon.Willett@REDACTED (Lon Willett) Date: Mon, 4 Dec 2000 22:36:34 GMT Subject: ASN.1 compiler enhancements: DER, open types, ... Message-ID: <200012042236.WAA15708@emile.sse.ie> [Oops. I had some mailer problems, and this message got mangled the first time I sent it. So here it is again. Sorry for the repeat.] Hi, I've been playing with the Erlang/OTP ASN.1 compiler lately, and have found some deficiencies, at least as regards my intended usage. So I'm thinking about hacking it up, and am wondering what the protocol for this is. Is there some source-code master that I should be in touch with? Is there a more recent (development) copy of the source than what is in the latest open source OTP release? Has someone else already done this? Does anyone else want the results I produce? Can I talk someone else into doing this for me? (Wishful thinking, that last one :-)) More specifically, my requirements are: * DER encoding -- this shouldn't be too hard to implement, although it is difficult to be sure that one hasn't forgotten something (DER is hard to test, as compared to plain BER). I've noticed several problems here; the compiler in its current form is definitely unusable for digital-signing purposes. * Open types -- as far as I can tell, there isn't any functioning support for open types in the compiler (tell me if I'm doing something wrong). There appears to be some code to deal with them, but it seems to be incomplete. Ideally, of course, I would like support for the full "Information Object Specification" (X.681). I could get by with just TYPE-IDENTIFIER and INSTANCE OF, or with ANY [DEFINED BY]. Support for ANY might be a good idea anyway, even if it isn't part of the standard any more. It provides a general escape mechanism to let the caller take over the encoding/decoding, when, for whatever reason, it is necessary (most often because the compiler doesn't handle something correctly, but there are some other special cases as well). I've often used it for this with other ASN.1 compilers. It also should be simple to implement (at least with BER, I'm not familiar with PER). Comments anyone? * BIT STRINGs -- the current implementation seems to be oriented around the use of short bit strings for a list of options (which is one important case). But it is a fairly common practice in the crypto standards to specify some fairly hefty BLOBs as BIT STRINGs. Not only is the inefficiency of converting to/from a list of zeros and ones bad enough that it might be a problem, but the inconvenience of doing this conversion isn't trivial either. A compiler option to choose the erlang representation of non-enumerated bit strings would be nice. For example, using the "ber_bin" option, the decode could just use a sub-binary of the input as the bit string representation (well, usually anyway), which is probably what one would want to pass to a crypto driver anyway. Of course, if ANY was supported, then one could just specify the BLOBs as ANY, and then do the encoding/decoding oneself, using whatever erlang term format was convenient (an example of the point above). But it still would be nicer if the compiler did the work. * Character strings -- this is a real can of worms. I don't think it is possible to solve all the problems here (given what a mess the standard is), but there are a few simple and very useful functions that would help handle the worst cases (e.g. convert BMPString to some more manageable representation, perhaps UTF-8. And BTW, UTF8String ought to be built-in). So I'm digging in and getting ready to hack (I haven't yet done more than take a quick glance at the sources). Anyone who has an interest should let me know. Cheers, Lon Willett From andrew@REDACTED Tue Dec 5 06:49:44 2000 From: andrew@REDACTED (Andrew Wallace) Date: Tue, 05 Dec 2000 16:49:44 +1100 Subject: one-stop recruiting page References: Message-ID: <3A2C81F8.5E547262@lodbroker.com> Add www.lodbroker.com to that list. I think we're always looking, the weather's nice at the moment. Cheers, Andrew Ulf Wiger wrote: > > I recently sat down and started searching the web for wanted ads > mentioning Erlang. It was disheartening. > > Knowing that there is actually a demand for Erlang competence, > I think something needs to be done to make this more visible. > > Personally, I'd like to see an "Erlang Programmers Wanted" page on > http://www.erlang.org, where current links to open positions for > Erlangers were collected. > > If, say, a student who encounters Erlang at school wants to know what > the job market is for an Erlang expert, he/she might hit a search > engine like I did - with the current state of affairs, he/she would > hardly be encourage to continue. > > Having said this, I know that Erlang is doing well in schools that are > teaching it. I recently heard that at KTH Haninge, an engineering > school in Stockholm, the Erlang class had exactly as many applicants > as the Advanced Java class. By cooperating, we can make this more > visible. > > Comments are welcome. > > This is what I did: > > 1 Knowing that we are looking for Erlang programmers, I started > searching for our ad. This was surprisingly difficult (I had to > ask someone). Later, I learned that the Ericsson jobs page > is being reorganized, and that it should appear in mid-December. > (http://www.ericsson.se/SE/rekryt/teknik4947090.html) > > 2 I went to www.erlang.se, and followed the links to the > companies that have certified consultants. Of the six companies > listed, only Sj?land & Thyselius and Cesarini Consulting actually > mention Erlang on their web pages; of these two, only Sj?land & > Thyselius is looking for Erlang programmers (Cesarini Consulting > is, as far as I know, a one-man company) > > 3 Searched the web via http://www.alltheweb.com and found the > following additional info: > > - SICS (http://www.sics.se) is looking for people, and is working > with Erlang. It wasn't entirely obvious that the positions > listed actually involved work with Erlang, but there appeared to > be a chance that it might be so. > > - WiseOne (http://www.wiseone.se) is looking for Erlang programmers > > - Ericsson in Gothenburg is looking for Erlang programmers > (http://www.eritel.se/open/content.htm) > (http://www.erv.ericsson.se/open/content.htm) > > - Telia Promotor (http://www.promotor.telia.se) is looking for > Erlang programmers. > > - Erlang Technology, Inc (http://erlang.tech.com) is NOT looking > for Erlang programmers... ironically. > > 4 Guessing that the company formerly known as Bluetail might be > hiring, I looked at their page - indeed they are, but since it's > a PHP page, it doesn't score well on search engines. > > /Uffe > -- > Ulf Wiger tfn: +46 8 719 81 95 > Senior System Architect mob: +46 70 519 81 95 > Strategic Product & System Management ATM Multiservice Networks > Data Backbone & Optical Services Division Ericsson Telecom AB From thomas@REDACTED Tue Dec 5 09:02:10 2000 From: thomas@REDACTED (Thomas Arts) Date: Tue, 05 Dec 2000 09:02:10 +0100 Subject: Parsing big files References: Message-ID: <3A2CA102.40E2EE11@cslab.ericsson.se> I have got a large file which consists of about 2 million lines. The aim is to parse this file, change the format a little and write it back to disk. No surprise that file:read_file(FileName) helps the erlang runtime system to get out of memory. I need a file:open, and thereafter read the file in parts and write the changed parts to disk. I wonder if someone already wrote a transformation program for such large files. I want the scanner to present a scanned line at a time, such that I can write a line at a time, but it would be nice if I don't have to do the bookkeeping on the byte level. /Thomas From joe@REDACTED Tue Dec 5 09:42:58 2000 From: joe@REDACTED (Joe Armstrong) Date: Tue, 5 Dec 2000 09:42:58 +0100 (CET) Subject: Parsing big files In-Reply-To: <3A2CA102.40E2EE11@cslab.ericsson.se> Message-ID: Ho thomas why not post your request to: http://www.bluetail.com/wiki/showPage?node=ErlangModulesWanted Go there and click on "Edit this page" /Joe -- Joe Armstrong, Alteon WebSystems, tel: +46 8-545 550 00 S:t Eriksgatan 44, IV, fax: +46 8-545 550 50 SE-112 32 Stockholm, Sweden info: www.bluetail.com From etxuwig@REDACTED Tue Dec 5 10:03:08 2000 From: etxuwig@REDACTED (Ulf Wiger) Date: Tue, 5 Dec 2000 10:03:08 +0100 (MET) Subject: Parsing big files In-Reply-To: <3A2CA102.40E2EE11@cslab.ericsson.se> Message-ID: Hi Thomas, I've attached a file that seems to do the job. Example: 1> fileio:lines("fileio.erl","fileio.erl.out", fun(Str) -> ["=== ",Str] end). ok > head -5 fileio.erl.out === -module(fileio). === -author('etxuwig@REDACTED'). === === %%-compile(export_all). === -export([lines/3]). On Tue, 5 Dec 2000, Thomas Arts wrote: > >I have got a large file which consists of about 2 million lines. >The aim is to parse this file, change the format a little and >write it back to disk. > >No surprise that file:read_file(FileName) helps the erlang runtime >system to get out of memory. I need a file:open, and thereafter >read the file in parts and write the changed parts to disk. > >I wonder if someone already wrote a transformation program for >such large files. I want the scanner to present a scanned >line at a time, such that I can write a line at a time, but it >would be nice if I don't have to do the bookkeeping on the >byte level. > >/Thomas > -- Ulf Wiger tfn: +46 8 719 81 95 Senior System Architect mob: +46 70 519 81 95 Strategic Product & System Management ATM Multiservice Networks Data Backbone & Optical Services Division Ericsson Telecom AB -------------- next part -------------- -module(fileio). -author('etxuwig@REDACTED'). %%-compile(export_all). -export([lines/3]). %%% lines(InFile, OutFile, Fun : fun/1) -> ok | {error, Reason} %%% %%% Process InFile one line at a time. Each line is passed to Fun, and %%% the return value (a possibly deep list of chars) is written to OutFile. %%% Don't forget the newline. %%% Example: %%% %%% 2> fileio:lines("fileio.erl","fileio.erl.out", %%% fun(Str) -> ["=== ",Str] end). %%% ok %%% %%% would produce the following output in fileio.erl.out: %%% %%% > head -5 fileio.erl.out %%%=== -module(fileio). %%%=== -author('etxuwig@REDACTED'). %%%=== %%%=== %%-compile(export_all). %%%=== -export([lines/3]). lines(InFile, OutFile, Fun) -> case file:open(InFile, [read]) of {ok, In} -> case file:open(OutFile, [write]) of {ok, Out} -> process_files(In, Out, Fun); {error, Reason} -> file:close(In), {error, {Reason, OutFile}} end; {error, Reason} -> {error, {Reason, InFile}} end. process_files(In, Out, Fun) -> Result = (catch process(In, Out, Fun)), file:close(In), file:close(Out), Result. process(In, Out, Fun) -> case io:get_line(In, "") of eof -> ok; Line -> ok = io:put_chars(Out, Fun(Line)), process(In, Out, Fun) end. From cahill@REDACTED Tue Dec 5 08:56:33 2000 From: cahill@REDACTED (cahill) Date: Tue, 05 Dec 2000 07:56:33 +0000 Subject: Connecting to an External SQL database using erlang Message-ID: <3A2C9FB1.759661DE@ocean.ucc.ie> Is there any existing code written for erlang, which will let you connect to an external sql database? I have seen the Master Thesis report, this is fairly dated, and i have seen a post saying it does not work today. Has anyone been doing any work with SQL and ERLANG ?? thanx in advance adrian From hakan@REDACTED Tue Dec 5 10:31:09 2000 From: hakan@REDACTED (Hakan Mattsson) Date: Tue, 5 Dec 2000 10:31:09 +0100 (MET) Subject: Connecting to an External SQL database using erlang In-Reply-To: <3A2C9FB1.759661DE@ocean.ucc.ie> Message-ID: On Tue, 5 Dec 2000, cahill wrote: cahill> Has anyone been doing any work with SQL and ERLANG ?? Take a look at the ODBC binding: http://www.erlang.org/doc/r7b/lib/odbc-0.8.2/doc/index.html /H?kan --- H?kan Mattsson Ericsson Computer Science Laboratory http://www.ericsson.se/cslab/~hakan From bob@REDACTED Tue Dec 5 15:35:43 2000 From: bob@REDACTED (Bob) Date: Tue, 5 Dec 2000 04:35:43 -1000 Subject: Connecting to an External SQL database using erlang Message-ID: <200012051427.eB5ERKE51094@hades.cslab.ericsson.net> > Is there any existing code written for erlang, which will let you > connect to an external sql database? > Aloha Adrian, Attached is a module for MySQL that I use with httpd. There are all sorts of things 'wrong' and unfinished with it. But it works pretty well. It's also lacking in documentation, so feel free to ask. Below, is the typical call that I used to query. Hope this helps. bob P.S. Thanks to all for their contributations to the OO metaphor thread over the past week or two. Very educational. %always returns colcount,row count,cols,rows % sql_fetch(Info,Sql)-> case mysql:fetch(Info#mod.dbPid,"Stocks",Sql) of {records,ColCount,RowCount,Cols,Rows}->{ColCount,RowCount,Cols,Rows}; {timeout,_} -> ioDebug(sqlTimeout), ioDebug(list_to_atom(Sql)), {0,0,[""],["timeout"]}; {error,_} -> ioDebug(sqlError), ioDebug(list_to_atom(Sql)), {0,0,[""],["db error"]}; {ok} -> {0,0,[""],["ok"]}; _ -> ioDebug(sqlUnknownError), ioDebug(list_to_atom(Sql)), {0,0,[""],["unknown db error"]} end. -------------- next part -------------- A non-text attachment was scrubbed... Name: mysql.erl Type: application/octet-stream Size: 16009 bytes Desc: mysql.erl (Erlang Source File) URL: From cahill@REDACTED Tue Dec 5 16:16:08 2000 From: cahill@REDACTED (cahill) Date: Tue, 05 Dec 2000 15:16:08 +0000 Subject: ODBC drivers Message-ID: <3A2D06B8.8B5FE7DA@ocean.ucc.ie> How do i get ERLANG to connect to a mysql database. I have looked at the ODBC page on erlang , but if refers to installing your odbc drivers. Where can i download these from ?? Anyone any ideas?? They would be greatfully appreciated. Adrian From sam@REDACTED Tue Dec 5 18:08:35 2000 From: sam@REDACTED (Samuel Tardieu) Date: Tue, 5 Dec 2000 18:08:35 +0100 Subject: ASN1 compiler internal error Message-ID: <2000-12-05-18-08-36+trackit+sam@inf.enst.fr> I do not know where I can send bug reports. The following attached file (it is only 27KB) triggers an internal error in OTP R7B-1 when compiled with asn1ct:compile/1. Sam -------------- next part -------------- GCC-PROTOCOL DEFINITIONS AUTOMATIC TAGS ::= BEGIN -- Export all symbols -- ========================================================================== -- Part 1: Elements of which messages are composed -- ========================================================================== ChannelID ::= INTEGER (1..65535) StaticChannelID ::= INTEGER (1..1000) -- Those assigned by specifications DynamicChannelID ::= INTEGER (1001..65535) -- Those created and deleted by MCS UserID ::= DynamicChannelID TokenID ::= INTEGER (1..65535) StaticTokenID ::= INTEGER (1..16383) -- Those assigned by specifications DynamicTokenID ::= INTEGER (16384..65535) -- Those assigned by the registry Time ::= INTEGER (-2147483647..2147483647) -- Time in seconds Handle ::= INTEGER (0..4294967295) -- 32-bit value H221NonStandardIdentifier ::= OCTET STRING (SIZE (4..255)) -- First four octets shall be country code and -- Manufacturer code, assigned as specified in -- H.221 Annex A for NS-cap and NS-comm Key ::= CHOICE -- Identifier of a standard or non-standard object { object OBJECT IDENTIFIER, h221NonStandard H221NonStandardIdentifier } NonStandardParameter ::= SEQUENCE { key Key, data OCTET STRING } TextString ::= BMPString (SIZE (0..255)) -- Basic Multilingual Plane of ISO/IEC 10646-1 (Unicode) simpleTextFirstCharacter UniversalString ::= {0, 0, 0, 0} simpleTextLastCharacter UniversalString ::= {0, 0, 0, 255} SimpleTextString ::= BMPString (SIZE (0..255)) (FROM (simpleTextFirstCharacter..simpleTextLastCharacter)) SimpleNumericString ::= NumericString (SIZE (1..255)) (FROM ("0123456789")) DialingString ::= NumericString (SIZE (1..16)) (FROM ("0123456789")) SubAddressString ::= NumericString (SIZE (1..40)) (FROM ("0123456789")) ExtraDialingString ::= TextString (SIZE (1..255)) (FROM ("0123456789#*,")) UserData ::= SET OF SEQUENCE { key Key, value OCTET STRING OPTIONAL } Password ::= SEQUENCE { numeric SimpleNumericString, text SimpleTextString OPTIONAL, ... } PasswordSelector ::= CHOICE { numeric SimpleNumericString, text SimpleTextString, ... } ChallengeResponseItem ::= CHOICE { passwordString PasswordSelector, responseData UserData, ... } ChallengeResponseAlgorithm ::= CHOICE { passwordInTheClear NULL, nonStandardAlgorithm NonStandardParameter, ... } ChallengeItem ::= SEQUENCE { responseAlgorithm ChallengeResponseAlgorithm, challengeData UserData, ... } ChallengeRequest ::= SEQUENCE { challengeTag INTEGER, challengeSet SET OF ChallengeItem, -- Set of algorithms offered for response ... } ChallengeResponse ::= SEQUENCE { challengeTag INTEGER, responseAlgorithm ChallengeResponseAlgorithm, -- Specific algorithm selected from the set of -- items presented in the ChallengeRequest responseItem ChallengeResponseItem, ... } PasswordChallengeRequestResponse ::= CHOICE { passwordInTheClear PasswordSelector, challengeRequestResponse SEQUENCE { challengeRequest ChallengeRequest OPTIONAL, challengeResponse ChallengeResponse OPTIONAL, ... }, ... } ConferenceName ::= SEQUENCE { numeric SimpleNumericString, text SimpleTextString OPTIONAL, ... } ConferenceNameSelector ::= CHOICE { numeric SimpleNumericString, text SimpleTextString, ... } ConferenceNameModifier ::= SimpleNumericString Privilege ::= ENUMERATED { terminate (0), ejectUser (1), add (2), lockUnlock (3), transfer (4), ... } TerminationMethod ::= ENUMERATED { automatic (0), manual (1), ... } ConferencePriorityScheme ::= CHOICE { nonStandardScheme NonStandardParameter, ... } ConferencePriority ::= SEQUENCE { priority INTEGER (0..65535), scheme ConferencePriorityScheme, ... } NetworkAddress ::= SEQUENCE (SIZE (1..64)) OF CHOICE -- Listed in order of use { aggregatedChannel SEQUENCE { transferModes SEQUENCE -- One or more { speech BOOLEAN, voice-band BOOLEAN, digital-56k BOOLEAN, digital-64k BOOLEAN, digital-128k BOOLEAN, digital-192k BOOLEAN, digital-256k BOOLEAN, digital-320k BOOLEAN, digital-384k BOOLEAN, digital-512k BOOLEAN, digital-768k BOOLEAN, digital-1152k BOOLEAN, digital-1472k BOOLEAN, digital-1536k BOOLEAN, digital-1920k BOOLEAN, packet-mode BOOLEAN, frame-mode BOOLEAN, atm BOOLEAN, ... }, internationalNumber DialingString, subAddress SubAddressString OPTIONAL, extraDialing ExtraDialingString OPTIONAL, highLayerCompatibility SEQUENCE { telephony3kHz BOOLEAN, telephony7kHz BOOLEAN, videotelephony BOOLEAN, videoconference BOOLEAN, audiographic BOOLEAN, audiovisual BOOLEAN, multimedia BOOLEAN, ... } OPTIONAL, ... }, transportConnection SEQUENCE { nsapAddress OCTET STRING (SIZE (1..20)), transportSelector OCTET STRING OPTIONAL }, nonStandard NonStandardParameter, ... } NodeType ::= ENUMERATED { terminal (0), multiportTerminal (1), mcu (2), ... } NodeProperties ::= SEQUENCE { managementDevice BOOLEAN, -- Is the node a device such as a reservation system peripheralDevice BOOLEAN, -- Is the node a peripheral to a primary node ... } AsymmetryIndicator ::= CHOICE { callingNode NULL, calledNode NULL, unknown INTEGER (0..4294967295) -- Uniformly distributed 32-bit random number } AlternativeNodeID ::= CHOICE { h243NodeID OCTET STRING (SIZE (2)), ... } ConferenceDescriptor ::= SEQUENCE { conferenceName ConferenceName, conferenceNameModifier ConferenceNameModifier OPTIONAL, conferenceDescription TextString OPTIONAL, lockedConference BOOLEAN, passwordInTheClearRequired BOOLEAN, networkAddress NetworkAddress OPTIONAL, ..., defaultConferenceFlag BOOLEAN } NodeRecord ::= SEQUENCE { superiorNode UserID OPTIONAL, -- Not present only for the Top GCC Provider nodeType NodeType, nodeProperties NodeProperties, nodeName TextString OPTIONAL, participantsList SEQUENCE OF TextString OPTIONAL, siteInformation TextString OPTIONAL, networkAddress NetworkAddress OPTIONAL, alternativeNodeID AlternativeNodeID OPTIONAL, userData UserData OPTIONAL, ... } SessionKey ::= SEQUENCE { applicationProtocolKey Key, sessionID ChannelID OPTIONAL } ChannelType ::= ENUMERATED { static (0), dynamicMulticast (1), dynamicPrivate (2), dynamicUserId (3) } ApplicationRecord ::= SEQUENCE { applicationActive BOOLEAN, -- Active/Inactive flag conductingOperationCapable BOOLEAN, -- Maximum one per node per session startupChannel ChannelType OPTIONAL, applicationUserID UserID OPTIONAL, -- User ID assigned to the Application Protocol Entity nonCollapsingCapabilities SET OF SEQUENCE { capabilityID CapabilityID, applicationData OCTET STRING OPTIONAL } OPTIONAL, ... } CapabilityID ::= CHOICE { standard INTEGER (0..65535), -- Assigned by Application Protocol specifications nonStandard Key } CapabilityClass ::= CHOICE { logical NULL, unsignedMin INTEGER (0..MAX), -- Capability value unsignedMax INTEGER (0..MAX), -- Capability value ... } EntityID ::= INTEGER (0..65535) ApplicationInvokeSpecifier ::= SEQUENCE { sessionKey SessionKey, expectedCapabilitySet SET OF SEQUENCE { capabilityID CapabilityID, capabilityClass CapabilityClass, ... } OPTIONAL, startupChannel ChannelType OPTIONAL, mandatoryFlag BOOLEAN, -- TRUE indicates required Application Protocol Entity ... } RegistryKey ::= SEQUENCE { sessionKey SessionKey, resourceID OCTET STRING (SIZE (0..64)) } RegistryItem ::= CHOICE { channelID DynamicChannelID, tokenID DynamicTokenID, parameter OCTET STRING (SIZE (0..64)), vacant NULL, ... } RegistryEntryOwner ::= CHOICE { owned SEQUENCE { nodeID UserID, -- Node ID of the owning node entityID EntityID -- Entity ID of the owning }, -- Appliction Protocol Entity notOwned NULL -- There is no current owner } RegistryModificationRights ::= ENUMERATED { owner (0), session (1), public (2) } -- ========================================================================== -- Part 2: PDU Messages -- ========================================================================== UserIDIndication ::= SEQUENCE { tag INTEGER, ... } ConferenceCreateRequest ::= SEQUENCE { -- MCS-Connect-Provider request user data conferenceName ConferenceName, convenerPassword Password OPTIONAL, password Password OPTIONAL, lockedConference BOOLEAN, listedConference BOOLEAN, conductibleConference BOOLEAN, terminationMethod TerminationMethod, conductorPrivileges SET OF Privilege OPTIONAL, conductedPrivileges SET OF Privilege OPTIONAL, nonConductedPrivileges SET OF Privilege OPTIONAL, conferenceDescription TextString OPTIONAL, callerIdentifier TextString OPTIONAL, userData UserData OPTIONAL, ..., conferencePriority ConferencePriority OPTIONAL } ConferenceCreateResponse ::= SEQUENCE { -- MCS-Connect-Provider response user data nodeID UserID, -- Node ID of the sending node tag INTEGER, result ENUMERATED { success (0), userRejected (1), resourcesNotAvailable (2), rejectedForSymmetryBreaking (3), lockedConferenceNotSupported (4), ... }, userData UserData OPTIONAL, ... } ConferenceQueryRequest ::= SEQUENCE { -- MCS-Connect-Provider request user data nodeType NodeType, asymmetryIndicator AsymmetryIndicator OPTIONAL, userData UserData OPTIONAL, ... } ConferenceQueryResponse ::= SEQUENCE { -- MCS-Connect-Provider response user data nodeType NodeType, asymmetryIndicator AsymmetryIndicator OPTIONAL, conferenceList SET OF ConferenceDescriptor, result ENUMERATED { success (0), userRejected (1), ... }, userData UserData OPTIONAL, ..., waitForInvitationFlag BOOLEAN OPTIONAL, noUnlistedConferenceFlag BOOLEAN OPTIONAL } ConferenceJoinRequest ::= SEQUENCE { -- MCS-Connect-Provider request user data as well as -- MCS-Send-Data on Node ID Channel of Top GCC sent -- by the receiver of the MCS-Connect-Provider conferenceName ConferenceNameSelector OPTIONAL, -- Required when part of MCS-Connect-Provider conferenceNameModifier ConferenceNameModifier OPTIONAL, tag INTEGER OPTIONAL, -- Filled in when sent on Node ID Channel of Top GCC password PasswordChallengeRequestResponse OPTIONAL, convenerPassword PasswordSelector OPTIONAL, callerIdentifier TextString OPTIONAL, userData UserData OPTIONAL, ... } ConferenceJoinResponse ::= SEQUENCE { -- MCS-Connect-Provider response user data as well as -- MCS-Send-Data on Node ID Channel of -- the receiver of the MCS-Connect-Provider nodeID UserID OPTIONAL, -- Node ID of directly connected node only topNodeID UserID, -- Node ID of Top GCC Provider tag INTEGER, conferenceNameAlias ConferenceNameSelector OPTIONAL, passwordInTheClearRequired BOOLEAN, lockedConference BOOLEAN, listedConference BOOLEAN, conductibleConference BOOLEAN, terminationMethod TerminationMethod, conductorPrivileges SET OF Privilege OPTIONAL, -- No privilege shall be listed more than once conductedPrivileges SET OF Privilege OPTIONAL, -- No privilege shall be listed more than once nonConductedPrivileges SET OF Privilege OPTIONAL, -- No privilege shall be listed more than once conferenceDescription TextString OPTIONAL, password PasswordChallengeRequestResponse OPTIONAL, result ENUMERATED { success (0), userRejected (1), invalidConference (2), invalidPassword (3), invalidConvenerPassword (4), challengeResponseRequired (5), invalidChallengeResponse (6), ... }, userData UserData OPTIONAL, ... } ConferenceInviteRequest ::= SEQUENCE { -- MCS-Connect-Provider request user data conferenceName ConferenceName, nodeID UserID, -- Node ID of the sending node topNodeID UserID, -- Node ID of Top GCC Provider tag INTEGER, passwordInTheClearRequired BOOLEAN, lockedConference BOOLEAN, listedConference BOOLEAN, conductibleConference BOOLEAN, terminationMethod TerminationMethod, conductorPrivileges SET OF Privilege OPTIONAL, -- No privilege shall be listed more than once conductedPrivileges SET OF Privilege OPTIONAL, -- No privilege shall be listed more than once nonConductedPrivileges SET OF Privilege OPTIONAL, -- No privilege shall be listed more than once conferenceDescription TextString OPTIONAL, callerIdentifier TextString OPTIONAL, userData UserData OPTIONAL, ..., conferencePriority ConferencePriority OPTIONAL } ConferenceInviteResponse ::= SEQUENCE { -- MCS-Connect-Provider response user data result ENUMERATED { success (0), userRejected (1), ... }, userData UserData OPTIONAL, ... } ConferenceAddRequest ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel of Top GCC or -- Node ID Channel of Adding MCU if specified networkAddress NetworkAddress, requestingNode UserID, tag INTEGER, addingMCU UserID OPTIONAL, userData UserData OPTIONAL, ... } ConferenceAddResponse ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel of requester tag INTEGER, result ENUMERATED { success (0), invalidRequester (1), invalidNetworkType (2), invalidNetworkAddress (3), addedNodeBusy (4), networkBusy (5), noPortsAvailable (6), connectionUnsuccessful (7), ... }, userData UserData OPTIONAL, ... } ConferenceLockRequest ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel of Top GCC -- No parameters ... } ConferenceLockResponse ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel of requester result ENUMERATED { success (0), invalidRequester (1), alreadyLocked (2), ... }, ... } ConferenceLockIndication ::= SEQUENCE { -- MCS-Uniform-Send-Data on GCC-Broadcast-Channel -- or MCS-Send-Data on Node ID Channel -- No parameters ... } ConferenceUnlockRequest ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel of Top GCC -- No parameters ... } ConferenceUnlockResponse ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel of requester result ENUMERATED { success (0), invalidRequester (1), alreadyUnlocked (2), ... }, ... } ConferenceUnlockIndication ::= SEQUENCE { -- MCS-Uniform-Send-Data on GCC-Broadcast-Channel -- or MCS-Send-Data on Node ID Channel -- No parameters ... } ConferenceTerminateRequest ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel of Top GCC reason ENUMERATED { userInitiated (0), timedConferenceTermination (1), ... }, ... } ConferenceTerminateResponse ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel of requester result ENUMERATED { success (0), invalidRequester (1), ... }, ... } ConferenceTerminateIndication ::= SEQUENCE { -- MCS-Uniform-Send-Data on GCC-Broadcast-Channel reason ENUMERATED { userInitiated (0), timedConferenceTermination (1), ... }, ... } ConferenceEjectUserRequest ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel of Top GCC nodeToEject UserID, -- Node ID of the node to eject reason ENUMERATED { userInitiated (0), ... }, ... } ConferenceEjectUserResponse ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel of requester nodeToEject UserID, -- Node ID of the node to eject result ENUMERATED { success (0), invalidRequester (1), invalidNode (2), ... }, ... } ConferenceEjectUserIndication ::= SEQUENCE { -- MCS-Uniform-Send-Data on GCC-Broadcast-Channel nodeToEject UserID, -- Node ID of the node to eject reason ENUMERATED { userInitiated (0), higherNodeDisconnected (1), higherNodeEjected (2), ... }, ... } ConferenceTransferRequest ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel of Top GCC conferenceName ConferenceNameSelector, -- Name of conference to transfer to conferenceNameModifier ConferenceNameModifier OPTIONAL, networkAddress NetworkAddress OPTIONAL, transferringNodes SET (SIZE (1..65536)) OF UserID OPTIONAL, password PasswordSelector OPTIONAL, ... } ConferenceTransferResponse ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel of requester conferenceName ConferenceNameSelector, -- Name of conference to transfer to conferenceNameModifier ConferenceNameModifier OPTIONAL, transferringNodes SET (SIZE (1..65536)) OF UserID OPTIONAL, result ENUMERATED { success (0), invalidRequester (1), ... }, ... } ConferenceTransferIndication ::= SEQUENCE { -- MCS-Uniform-Send-Data on GCC-Broadcast-Channel conferenceName ConferenceNameSelector, -- Name of conference to transfer to conferenceNameModifier ConferenceNameModifier OPTIONAL, networkAddress NetworkAddress OPTIONAL, transferringNodes SET (SIZE (1..65536)) OF UserID OPTIONAL, -- List of Node IDs, -- not present if destined for all nodes password PasswordSelector OPTIONAL, ... } RosterUpdateIndication ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel or -- MCS-Uniform-Send-Data on GCC-Broadcast-Channel fullRefresh BOOLEAN, -- Conference Roster and all -- ApplicationProtocol Sessions refreshed nodeInformation SEQUENCE { nodeRecordList CHOICE { noChange NULL, refresh SET (SIZE (1..65536)) OF SEQUENCE -- One for each node in the conference; -- no node shall be listed more than once { nodeID UserID, -- Node ID of the node nodeRecord NodeRecord }, update SET (SIZE (1..65536)) OF SEQUENCE -- One for each node changing its node record; -- no node shall be listed more than once { nodeID UserID, -- Node ID of the node nodeUpdate CHOICE { addRecord NodeRecord, replaceRecord NodeRecord, removeRecord NULL, ... } }, ... }, rosterInstanceNumber INTEGER (0..65535), nodesAdded BOOLEAN, -- Nodes have been added since last instance nodesRemoved BOOLEAN, -- Nodes have been removed since last instance ... } , applicationInformation SET (SIZE (0..65535)) OF SEQUENCE -- One for each Application Protocol Session; -- all Application Protocol Sessions if full refresh; -- no Application Protocol Session shall be -- listed more than once { sessionKey SessionKey, applicationRecordList CHOICE { noChange NULL, refresh SET (SIZE (0..65535)) OF SEQUENCE -- One for each node with the -- Application Protocol Session enrolled; -- no node shall be listed more than once { nodeID UserID, -- Node ID of node entityID EntityID, -- ID for this Application Protocol Entity at this node applicationRecord ApplicationRecord }, update SET (SIZE (1..65536)) OF SEQUENCE -- One for each node modifying its Application Record; -- no node shall be listed more than once { nodeID UserID, -- Node ID of node entityID EntityID, -- ID for this Application Protocol Entity at this node applicationUpdate CHOICE { addRecord ApplicationRecord, replaceRecord ApplicationRecord, removeRecord NULL, ... } }, ... }, applicationCapabilitiesList CHOICE { noChange NULL, refresh SET OF SEQUENCE { capabilityID CapabilityID, capabilityClass CapabilityClass, numberOfEntities INTEGER (1..65536), -- Number of Application Protocol Entities -- which issued the capability ... }, ... }, rosterInstanceNumber INTEGER (0..65535), peerEntitiesAdded BOOLEAN, -- Peer Entities have been added since last instance peerEntitiesRemoved BOOLEAN, -- Peer Entities have been removed since last instance ... }, ... } ApplicationInvokeIndication ::= SEQUENCE { -- MCS-Send-Data or MCS-Uniform-Send-Data -- on GCC-Broadcast-Channel or Node ID Channel applicationProtocolEntiyList SET (SIZE (1..65536)) OF ApplicationInvokeSpecifier, destinationNodes SET (SIZE (1..65536)) OF UserID OPTIONAL, -- List of Node IDs, -- not presesnt if destined for all nodes ... } RegistryRegisterChannelRequest ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel of Top GCC entityID EntityID, key RegistryKey, channelID DynamicChannelID, ... } RegistryAssignTokenRequest ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel of Top GCC entityID EntityID, key RegistryKey, ... } RegistrySetParameterRequest ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel of Top GCC entityID EntityID, key RegistryKey, parameter OCTET STRING (SIZE (0..64)), modificationRights RegistryModificationRights OPTIONAL, ... } RegistryRetrieveEntryRequest ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel of Top GCC entityID EntityID, key RegistryKey, ... } RegistryDeleteEntryRequest ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel of Top GCC entityID EntityID, key RegistryKey, ... } RegistryMonitorEntryRequest ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel of Top GCC entityID EntityID, key RegistryKey, ... } RegistryMonitorEntryIndication ::= SEQUENCE { -- MCS-Uniform-Send-Data on GCC-Broadcast-Channel key RegistryKey, item RegistryItem, -- Contents: channel, token, parameter, or empty owner RegistryEntryOwner, modificationRights RegistryModificationRights OPTIONAL, ... } RegistryAllocateHandleRequest ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel of Top GCC entityID EntityID, numberOfHandles INTEGER (1..1024), ... } RegistryAllocateHandleResponse ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel of requester entityID EntityID, numberOfHandles INTEGER (1..1024), firstHandle Handle, result ENUMERATED { successful (0), noHandlesAvailable (1), ... }, ... } RegistryResponse ::= SEQUENCE { -- MCS-Send-Data on Node ID Channel of requester entityID EntityID, -- Entity ID of the requesting Application Protocol Entity primitiveType ENUMERATED { registerChannel (0), assignToken (1), setParameter (2), retrieveEntry (3), deleteEntry (4), monitorEntry (5), ... }, key RegistryKey, -- Database index item RegistryItem, -- Contents: channel, token, parameter, or vacant owner RegistryEntryOwner, modificationRights RegistryModificationRights OPTIONAL, result ENUMERATED { successful (0), belongsToOther (1), tooManyEntries (2), inconsistentType (3), entryNotFound (4), entryAlreadyExists (5), invalidRequester (6), ... }, ... } ConductorAssignIndication ::= SEQUENCE { -- MCS-Uniform-Send-Data on GCC-Broadcast-Channel conductingNode UserID, ... } ConductorReleaseIndication ::= SEQUENCE { -- MCS-Uniform-Send-Data on GCC-Broadcast-Channel -- No parameters ... } ConductorPermissionAskIndication ::= SEQUENCE { -- MCS-Uniform-Send-Data on GCC-Broadcast-Channel grantFlag BOOLEAN, -- TRUE to request permission grant, FALSE to release ... } ConductorPermissionGrantIndication ::= SEQUENCE { -- MCS-Uniform-Send-Data on GCC-Broadcast-Channel permissionList SEQUENCE (SIZE (0..65535)) OF UserID, -- Node ID of nodes granted permission waitingList SEQUENCE (SIZE (1..65536)) OF UserID OPTIONAL, -- Node ID of nodes waiting form permission ... } ConferenceTimeRemainingIndication ::= SEQUENCE { -- MCS-Send-Data on GCC-Broadcast-Channel timeRemaining Time, nodeID UserID OPTIONAL, ... } ConferenceTimeInquireIndication ::= SEQUENCE { -- MCS-Send-Data on GCC-Convener-Channel nodeSpecificTimeFlag BOOLEAN, -- FALSE for conference-wide, TRUE for node-specific ... } ConferenceTimeExtendIndication ::= SEQUENCE { -- MCS-Send-Data on GCC-Convener-Channel timeToExtend Time, nodeSpecificTimeFlag BOOLEAN, -- FALSE for conference-wide, TRUE for node-specific ... } ConferenceAssistanceIndication ::= SEQUENCE { -- MCS-Uniform-Send-Data on GCC-Broadcast-Channel userData UserData OPTIONAL, ... } TextMessageIndication ::= SEQUENCE { -- MCS-Send-Data or MCS-Uniform-Send-Data message TextString, -- on GCC-Broadcast-Channel or Node ID Channel ... } FunctionNotSupportedResponse ::= SEQUENCE { request RequestPDU } NonStandardPDU ::= SEQUENCE { data NonStandardParameter, ... } -- ========================================================================== -- Part 3: Messages sent as MCS-Connect-Provider user data -- ========================================================================== ConnectData ::= SEQUENCE { t124Identifier Key, -- This shall be set to the value {itu recommendation t 124 version(0) 1} connectPDU OCTET STRING } ConnectGCCPDU ::= CHOICE { conferenceCreateRequest ConferenceCreateRequest, conferenceCreateResponse ConferenceCreateResponse, conferenceQueryRequest ConferenceQueryRequest, conferenceQueryResponse ConferenceQueryResponse, conferenceJoinRequest ConferenceJoinRequest, conferenceJoinResponse ConferenceJoinResponse, conferenceInviteRequest ConferenceInviteRequest, conferenceInviteResponse ConferenceInviteResponse, ... } -- ========================================================================== -- Part 4: Messages sent using MCS-Send-Data or MCS-Uniform-Send-Data -- ========================================================================== GCCPDU ::= CHOICE { request RequestPDU, response ResponsePDU, indication IndicationPDU } RequestPDU ::= CHOICE { conferenceJoinRequest ConferenceJoinRequest, conferenceAddRequest ConferenceAddRequest, conferenceLockRequest ConferenceLockRequest, conferenceUnlockRequest ConferenceUnlockRequest, conferenceTerminateRequest ConferenceTerminateRequest, conferenceEjectUserRequest ConferenceEjectUserRequest, conferenceTransferRequest ConferenceTransferRequest, registryRegisterChannelRequest RegistryRegisterChannelRequest, registryAssignTokenRequest RegistryAssignTokenRequest, registrySetParameterRequest RegistrySetParameterRequest, registryRetrieveEntryRequest RegistryRetrieveEntryRequest, registryDeleteEntryRequest RegistryDeleteEntryRequest, registryMonitorEntryRequest RegistryMonitorEntryRequest, registryAllocateHandleRequest RegistryAllocateHandleRequest, nonStandardRequest NonStandardPDU, ... } ResponsePDU ::= CHOICE { conferenceJoinResponse ConferenceJoinResponse, conferenceAddResponse ConferenceAddResponse, conferenceLockResponse ConferenceLockResponse, conferenceUnlockResponse ConferenceUnlockResponse, conferenceTerminateResponse ConferenceTerminateResponse, conferenceEjectUserResponse ConferenceEjectUserResponse, conferenceTransferResponse ConferenceTransferResponse, registryResponse RegistryResponse, registryAllocateHandleResponse RegistryAllocateHandleResponse, functionNotSupportedResponse FunctionNotSupportedResponse, nonStandardResponse NonStandardPDU, ... } IndicationPDU ::= CHOICE { userIDIndication UserIDIndication, conferenceLockIndication ConferenceLockIndication, conferenceUnlockIndication ConferenceUnlockIndication, conferenceTerminateIndication ConferenceTerminateIndication, conferenceEjectUserIndication ConferenceEjectUserIndication, conferenceTransferIndication ConferenceTransferIndication, rosterUpdateIndication RosterUpdateIndication, applicationInvokeIndication ApplicationInvokeIndication, registryMonitorEntryIndication RegistryMonitorEntryIndication, conductorAssignIndication ConductorAssignIndication, conductorReleaseIndication ConductorReleaseIndication, conductorPermissionAskIndication ConductorPermissionAskIndication, conductorPermissionGrantIndication ConductorPermissionGrantIndication, conferenceTimeRemainingIndication ConferenceTimeRemainingIndication, conferenceTimeInquireIndication ConferenceTimeInquireIndication, conferenceTimeExtendIndication ConferenceTimeExtendIndication, conferenceAssistanceIndication ConferenceAssistanceIndication, textMessageIndication TextMessageIndication, nonStandardIndication NonStandardPDU, ... } END From jamesh@REDACTED Tue Dec 5 18:30:29 2000 From: jamesh@REDACTED (James Hague) Date: Tue, 5 Dec 2000 11:30:29 -0600 Subject: Parsing big files Message-ID: Ulf's example is the way to go--processing a line at a time--but I thought I'd mention that with R7 it can be memory efficient to load and parse text files as *binaries*, not as text. This prevents the 8x blow-up you get when a file is turned into raw text. You can deal with much larger files this way. James From jamesh@REDACTED Tue Dec 5 18:50:34 2000 From: jamesh@REDACTED (James Hague) Date: Tue, 5 Dec 2000 11:50:34 -0600 Subject: Bit syntax endianness confusion Message-ID: Tony Rogvall wrote: >Expression like yours above does not make much >sense (Field1:4/little) since only byte sequences >are affected by the endian order. Yes, I suspected as much. Since I'm dealing with a file of N fields of fixed size (specifically 64 bits), it is easy to do a swizzle up front with this code: byteswap(B) -> list_to_binary(lists:reverse(binary_to_list(B))). preprocess(B) -> preprocess(B, []). preprocess(<>, Acc) -> preprocess(Rest, [byteswap(B)|Acc]); preprocess(<<>>, Acc) -> list_to_binary(lists:reverse(Acc)). Using binary patterns directly in byteswap is faster for the case when the input binary is 4 bytes, but I didn't test the 8 byte case. Either version is plenty fast for the disassembler I'm working on. It would be nice to be able to specify an overall endianess for a pattern, maybe like this: <>/little James From dne@REDACTED Tue Dec 5 22:03:12 2000 From: dne@REDACTED (Daniel Neri) Date: 05 Dec 2000 22:03:12 +0100 Subject: ODBC drivers In-Reply-To: cahill's message of "Tue, 05 Dec 2000 15:16:08 +0000" References: <3A2D06B8.8B5FE7DA@ocean.ucc.ie> Message-ID: <87sno2insf.fsf@nowhere.mayonnaise.net> cahill writes: > but if refers to installing your odbc drivers. Where can i download > these from ?? I've never tried it myself, but I suppose you could check out MyODBC: http://www.mysql.com/downloads/api-myodbc.html Best wishes, --Daniel -- Daniel Neri dne@REDACTED From scott@REDACTED Tue Dec 5 22:46:21 2000 From: scott@REDACTED (Scott Lystig Fritchie) Date: Tue, 05 Dec 2000 15:46:21 -0600 Subject: ODBC drivers In-Reply-To: Message of "05 Dec 2000 22:03:12 +0100." <87sno2insf.fsf@nowhere.mayonnaise.net> Message-ID: <200012052146.PAA99470@snookles.snookles.com> >>>>> "dn" == Daniel Neri writes: dn> I've never tried it myself, but I suppose you could check out dn> MyODBC: I've used the unixODBC driver manager with MySQL (open source), PostgreSQL (open source), and Clustra (commercial). I've found a couple of bugs, but the folks maintaining it have been very responsive. Overall, it's very usable. It contains all the headers required to compile ODBC applications on UNIX platforms. The Intersolv driver manager, at least the one bundled with recent versions of Solaris, requires that you obtain the necessary header files from the Microsoft SDK. If you're working with Solaris/SPARC machines, you may already have the Intersolv driver manager installed in /opt/ISLIodbc. Or it is sitting on the OS media shipped with the box. The unixODBC source distribution comes with ODBC drivers for MiniSQL, MySQL, and PostgreSQL. This makes compilation & installation easier if you're using one of those databases. It's possible, in theory, to have an application use an ODBC driver library directly, without an intermediate ODBC driver manager such as unixODBC or Intersolv or other commercial products. I haven't figured out such magic, since both unixODBC and Intersolv's have been working well. The ODBC library distributed with Erlang/OTP is a, well, brute-force implementation. All of the peculiarities of the C API are also exposed to the Erlang developer. IMO, it's icky: the "impedence mismatch" that is so miniscule with Mnesia is instead *so* big with the current ODBC library. I'd like to reimplement it to make the library more Erlang-friendly, but my boss squashed that idea until I've finished other things first. Oh well. -Scott From alexis@REDACTED Wed Dec 6 00:40:56 2000 From: alexis@REDACTED (=?iso-8859-1?Q?Alexis_L=EA-Qu=F4c?=) Date: Tue, 5 Dec 2000 18:40:56 -0500 Subject: Deployment of Erlang code on numerous nodes Message-ID: Greetings, I'm trying to come up with a scheme to deploy erlang code to tens (even hundreds) of machines, assuming that the machines have the erlang run-time (e.g. the erlang rpm) installed and a simple startup script. From there the machines should be able to load the code they need, access a configuration database (stored in Mnesia for instance) for various parameters and start running. Are there any facilities that implement that kind of functionality? Is it the right thing to do in the first place? Rather than writing perl scripts to fetch the code by ftp and so on to deploy, I'd rather have as many things defined within Erlang itself. Alexis Le-Quoc P.S. : The question is also available on the erlang wiki - QuestionsAndAnswers. From rv@REDACTED Wed Dec 6 10:49:47 2000 From: rv@REDACTED (Robert Virding) Date: Wed, 06 Dec 2000 10:49:47 +0100 Subject: Parsing big files In-Reply-To: Your message of "Tue, 05 Dec 2000 11:30:29 CST." Message-ID: <200012060949.KAA03379@trana.bluetail.com> "James Hague" writes: >Ulf's example is the way to go--processing a line at a time--but I thought >I'd mention that with R7 it can be memory efficient to load and parse text >files as *binaries*, not as text. This prevents the 8x blow-up you get when >a file is turned into raw text. You can deal with much larger files this >way. That depends if you need to deal with whole files of can process a chunk at a time. With Ulf's method you only take in small pieces at a time so there is no real blow-up. The original message noted that reading in the whole file as a binary caused the runtime system to run out of memory. Anyway if you are going to parse the contents you my have to convert it into lines, or whatever, which are lists, and then you have not really won that much. So far the builtin scanning modules cannot handle binaries. Robert From tobbe@REDACTED Wed Dec 6 10:41:00 2000 From: tobbe@REDACTED (Torbjorn Tornkvist) Date: 06 Dec 2000 10:41:00 +0100 Subject: ASN.1 compiler enhancements: DER, open types, ... In-Reply-To: Lon Willett's message of "Mon, 4 Dec 2000 22:36:34 GMT" References: <200012042236.WAA15708@emile.sse.ie> Message-ID: Since no one else has answered... > Is there some source-code master that I should be in touch with ? OTP responsible for ASN.1 is: kenneth@REDACTED It is probably a good idea to coordinate your work with him. > Does anyone else want the results I produce? Yes ! I think all (Erlang) contributions are most welcome by the readers of this list. Cheers /Tobbe (Ps. Why not create a project page at http://www.bluetail.com/wiki/ ) From cesarini@REDACTED Wed Dec 6 10:51:42 2000 From: cesarini@REDACTED (Francesco Cesarini) Date: Wed, 06 Dec 2000 09:51:42 +0000 Subject: Deployment of Erlang code on numerous nodes References: Message-ID: <3A2E0C2E.5AF2A26E@terminus.ericsson.se> Hi Alexis, what you want to do makes perfect sense.. To load the code off another node, you should set the -loader flag (when starting erl) to inet, and -hosts IP to point where your boot server is running : from the erl man page: [loader] Specifies the name of the loader used to load Erlang modules into the system. See erl_prim_loader(3). Loader can be efile (use the local file system), or inet (load using the boot_server on another Erlang node). If Loader is something else, the user supplied Loader port program is started. If the -loader flag is omitted efile is assumed. To start the system, you should encapsulate everything into OTP applications, create a few rel files and create boot files to start your system. You can then use local configuration files, or retrieve your data from other nodes using distributed mnesia tables, a global server or rpc:s. If you want to deploy hundreds of Erlang nodes, you would have to some how partition your network, as Erlang nodes will by default create fully meshed networks, and result in a an overhead when keeping the links up. There are ways of handling this either with cookie manipulation or by setting some flags and default parameters at startup. SOunds like cool stuff you guys are putting together... Regards, Francesco > I'm trying to come up with a scheme to deploy erlang code to tens (even > hundreds) of machines, assuming that the machines have the erlang run-time > (e.g. the erlang rpm) installed and a simple startup script. From there the > machines should be able to load the code they need, access a configuration > database (stored in Mnesia for instance) for various parameters and start > running. Are there any facilities that implement that kind of > functionality? Is it the right thing to do in the first place? Rather than > writing perl scripts to fetch the code by ftp and so on to deploy, I'd > rather have as many things defined within Erlang itself. > > Alexis Le-Quoc > > P.S. : The question is also available on the erlang wiki - > QuestionsAndAnswers. -- Francesco Cesarini Erlang/OTP consultant Cellular: INT+44-7776 250381 ECN: 832-707192 From cesarini@REDACTED Wed Dec 6 12:02:40 2000 From: cesarini@REDACTED (Francesco Cesarini) Date: Wed, 06 Dec 2000 11:02:40 +0000 Subject: Erlang Jobs in the UK... was: one-stop recruiting page References: Message-ID: <3A2E1CD0.7FEC05B@terminus.ericsson.se> Well, on popular demand as there apparently is a need.. :-) If you want to work with the real thing... The AXD301 switch, but find Sweden to be too cold, Ericsson Intracom in Leicester, UK (one hour north of London) might be an option. They are looking for happy motivated software engineers with Erlang/OTP experience... This is the job ad they have out at the moment. If interested, send your CVs to Andy Davies @ andy@REDACTED :-) Francesco --- Environment: Engineering group of approximately 45 engineers, working on data communications products for network infrastructure. Software engineering group comprises of approximately 15 people. Core technologies are Frame Relay and ATM. Other WAN and LAN technologies are developed including Ethernet, TCP/IP, X.25, SNA, and ISDN. Development environment in `C' or Erlang under UNIX on Sun Sparc stations. Target environments include Erlang /OTP on Sparcs, or PowerPC, Motorola 68020/030/302 and Intel i960 embedded processors. Tools environment includes Objectime for design, ClearCase for configuration management and Framemaker for documentation. Activities: The complete software development life cycle including, specification, analysis, design, code and test. Real-time target applications, data protocols through to Web based user interface. Personality: Must be able to work with little supervision, show ingenuity and learn quickly. Must be interested in trying new languages and should be interested in up to date technology. Must have good inter-personal skills for interfacing with peer group and ideally should have team leader potential. Qualifications: A good science/engineering degree or equivalent, preferably a 1st or 2i. Approximately 5 + years experience of software development, to include `C' experience and UNIX usage. Knowledge of data communications protocols would be an advantage. Rewards: Salary dependent on relevant experience. Flexi-time. Performance related bonus scheme. Pension. Other standard Ericsson Terms and Conditions. Ulf Wiger wrote: > > I recently sat down and started searching the web for wanted ads > mentioning Erlang. It was disheartening. > > Knowing that there is actually a demand for Erlang competence, > I think something needs to be done to make this more visible. > > Personally, I'd like to see an "Erlang Programmers Wanted" page on > http://www.erlang.org, where current links to open positions for > Erlangers were collected. > > If, say, a student who encounters Erlang at school wants to know what > the job market is for an Erlang expert, he/she might hit a search > engine like I did - with the current state of affairs, he/she would > hardly be encourage to continue. > > Having said this, I know that Erlang is doing well in schools that are > teaching it. I recently heard that at KTH Haninge, an engineering > school in Stockholm, the Erlang class had exactly as many applicants > as the Advanced Java class. By cooperating, we can make this more > visible. > > Comments are welcome. > > This is what I did: > > 1 Knowing that we are looking for Erlang programmers, I started > searching for our ad. This was surprisingly difficult (I had to > ask someone). Later, I learned that the Ericsson jobs page > is being reorganized, and that it should appear in mid-December. > (http://www.ericsson.se/SE/rekryt/teknik4947090.html) > > 2 I went to www.erlang.se, and followed the links to the > companies that have certified consultants. Of the six companies > listed, only Sj?land & Thyselius and Cesarini Consulting actually > mention Erlang on their web pages; of these two, only Sj?land & > Thyselius is looking for Erlang programmers (Cesarini Consulting > is, as far as I know, a one-man company) > > 3 Searched the web via http://www.alltheweb.com and found the > following additional info: > > - SICS (http://www.sics.se) is looking for people, and is working > with Erlang. It wasn't entirely obvious that the positions > listed actually involved work with Erlang, but there appeared to > be a chance that it might be so. > > - WiseOne (http://www.wiseone.se) is looking for Erlang programmers > > - Ericsson in Gothenburg is looking for Erlang programmers > (http://www.eritel.se/open/content.htm) > (http://www.erv.ericsson.se/open/content.htm) > > - Telia Promotor (http://www.promotor.telia.se) is looking for > Erlang programmers. > > - Erlang Technology, Inc (http://erlang.tech.com) is NOT looking > for Erlang programmers... ironically. > > 4 Guessing that the company formerly known as Bluetail might be > hiring, I looked at their page - indeed they are, but since it's > a PHP page, it doesn't score well on search engines. > > /Uffe > -- > Ulf Wiger tfn: +46 8 719 81 95 > Senior System Architect mob: +46 70 519 81 95 > Strategic Product & System Management ATM Multiservice Networks > Data Backbone & Optical Services Division Ericsson Telecom AB -- Francesco Cesarini Erlang/OTP consultant Cellular: INT+44-7776 250381 ECN: 832-707192 From aba3600@REDACTED Wed Dec 6 12:44:50 2000 From: aba3600@REDACTED (aba3600@REDACTED) Date: Wed, 6 Dec 2000 05:44:50 -0600 (CST) Subject: Erlang Jobs in the UK... was: one-stop recruiting page In-Reply-To: <3A2E1CD0.7FEC05B@terminus.ericsson.se> Message-ID: I am starting Monday with Ericsson Research & Development in Richardson, Texas because: 1. I have some Erlang Experience, including a Masters thesis that concerns Erlang and 2. the job market really sucks for employers, and I am marginally competent. P.S. I am changing my eMail in 2 weeks, and need to unsubscribe my old eMail and subscribe a new eMail. Does anyone know how to help me with this? Andy Allen http://www.Andy-Allen.com On Wed, 6 Dec 2000, Francesco Cesarini wrote: > Date: Wed, 06 Dec 2000 11:02:40 +0000 > From: Francesco Cesarini > To: erlang-questions@REDACTED > Subject: Erlang Jobs in the UK... was: one-stop recruiting page > > Well, on popular demand as there apparently is a need.. :-) If you want > to work with the real thing... The AXD301 switch, but find Sweden to be > too cold, Ericsson Intracom in Leicester, UK (one hour north of London) > might be an option. They are looking for happy motivated software > engineers with Erlang/OTP experience... This is the job ad they have out > at the moment. If interested, send your CVs to Andy Davies @ > andy@REDACTED > > :-) > Francesco > > --- > Environment: > Engineering group of approximately 45 engineers, working on data > communications products for network infrastructure. Software engineering > group comprises of approximately 15 people. > > Core technologies are Frame Relay and ATM. Other WAN and LAN > technologies are developed including Ethernet, TCP/IP, X.25, SNA, and > ISDN. Development environment in `C' or Erlang under UNIX on Sun Sparc > stations. Target environments include Erlang /OTP on Sparcs, or PowerPC, > Motorola 68020/030/302 and Intel i960 embedded processors. Tools > environment includes Objectime for design, ClearCase for configuration > management and Framemaker for documentation. > > Activities: > The complete software development life cycle including, specification, > analysis, design, code and test. Real-time target applications, data > protocols through to Web based user interface. > > Personality: > Must be able to work with little supervision, show ingenuity and learn > quickly. Must be interested in trying new languages and should be > interested in up to date technology. Must have good inter-personal > skills for interfacing with peer group and ideally should have team > leader potential. > > Qualifications: > A good science/engineering degree or equivalent, preferably a 1st or 2i. > Approximately 5 + years experience of software development, to include > `C' experience and UNIX usage. Knowledge of data communications > protocols would be an advantage. > > Rewards: > Salary dependent on relevant experience. Flexi-time. Performance related > bonus scheme. Pension. Other standard Ericsson Terms and Conditions. > > > Ulf Wiger wrote: > > > > I recently sat down and started searching the web for wanted ads > > mentioning Erlang. It was disheartening. > > > > Knowing that there is actually a demand for Erlang competence, > > I think something needs to be done to make this more visible. > > > > Personally, I'd like to see an "Erlang Programmers Wanted" page on > > http://www.erlang.org, where current links to open positions for > > Erlangers were collected. > > > > If, say, a student who encounters Erlang at school wants to know what > > the job market is for an Erlang expert, he/she might hit a search > > engine like I did - with the current state of affairs, he/she would > > hardly be encourage to continue. > > > > Having said this, I know that Erlang is doing well in schools that are > > teaching it. I recently heard that at KTH Haninge, an engineering > > school in Stockholm, the Erlang class had exactly as many applicants > > as the Advanced Java class. By cooperating, we can make this more > > visible. > > > > Comments are welcome. > > > > This is what I did: > > > > 1 Knowing that we are looking for Erlang programmers, I started > > searching for our ad. This was surprisingly difficult (I had to > > ask someone). Later, I learned that the Ericsson jobs page > > is being reorganized, and that it should appear in mid-December. > > (http://www.ericsson.se/SE/rekryt/teknik4947090.html) > > > > 2 I went to www.erlang.se, and followed the links to the > > companies that have certified consultants. Of the six companies > > listed, only Sj?land & Thyselius and Cesarini Consulting actually > > mention Erlang on their web pages; of these two, only Sj?land & > > Thyselius is looking for Erlang programmers (Cesarini Consulting > > is, as far as I know, a one-man company) > > > > 3 Searched the web via http://www.alltheweb.com and found the > > following additional info: > > > > - SICS (http://www.sics.se) is looking for people, and is working > > with Erlang. It wasn't entirely obvious that the positions > > listed actually involved work with Erlang, but there appeared to > > be a chance that it might be so. > > > > - WiseOne (http://www.wiseone.se) is looking for Erlang programmers > > > > - Ericsson in Gothenburg is looking for Erlang programmers > > (http://www.eritel.se/open/content.htm) > > (http://www.erv.ericsson.se/open/content.htm) > > > > - Telia Promotor (http://www.promotor.telia.se) is looking for > > Erlang programmers. > > > > - Erlang Technology, Inc (http://erlang.tech.com) is NOT looking > > for Erlang programmers... ironically. > > > > 4 Guessing that the company formerly known as Bluetail might be > > hiring, I looked at their page - indeed they are, but since it's > > a PHP page, it doesn't score well on search engines. > > > > /Uffe > > -- > > Ulf Wiger tfn: +46 8 719 81 95 > > Senior System Architect mob: +46 70 519 81 95 > > Strategic Product & System Management ATM Multiservice Networks > > Data Backbone & Optical Services Division Ericsson Telecom AB > > Sincerely, Andy Allen Recycled Electrons email: andy@REDACTED From etxuwig@REDACTED Wed Dec 6 13:00:02 2000 From: etxuwig@REDACTED (Ulf Wiger) Date: Wed, 6 Dec 2000 13:00:02 +0100 (MET) Subject: Erlang and robotics (was Re: Erlang Jobs in the UK... (was: ...)) In-Reply-To: Message-ID: On Wed, 6 Dec 2000, aba3600@REDACTED wrote: >I am starting Monday with Ericsson Research & Development in Richardson, >Texas because: Good for you. (: >http://www.Andy-Allen.com Interesting. I wonder, what is your view of Erlang's suitability for robotics work? I would think that for most types of robots, the real-time properties of Erlang ought to be quite sufficient, and the ability to handle complex concurrent problems ought to be attractive. Throw in the ECOMP Erlang Processor, which is slowly materializing, and there might be some very interesting potential. Your comments are welcome. /Uffe -- Ulf Wiger tfn: +46 8 719 81 95 Senior System Architect mob: +46 70 519 81 95 Strategic Product & System Management ATM Multiservice Networks Data Backbone & Optical Services Division Ericsson Telecom AB From aba3600@REDACTED Wed Dec 6 14:18:09 2000 From: aba3600@REDACTED (aba3600@REDACTED) Date: Wed, 6 Dec 2000 07:18:09 -0600 (CST) Subject: Erlang for Robotics In-Reply-To: Message-ID: > Interesting. I wonder, what is your view of Erlang's suitability for > robotics work? > > I would think that for most types of robots, the real-time properties > of Erlang ought to be quite sufficient, and the ability to handle > complex concurrent problems ought to be attractive. > > Throw in the ECOMP Erlang Processor, which is slowly materializing, > and there might be some very interesting potential. > > Your comments are welcome. My number one gripe with Erlang is that I do not have a good example of a single port program in Erlang, and the matching end in every common compiler for every OS available. Is this possible? Do they need different Erlang sections for each langauge? Finally, I only have this one gripe about linux. I have books of gripes about every other language. It's just hard to beat the I/O capacity of "C" when talking to a home-brew ISA digital I/O card, or the power of a VB library when doing video capture via a TWAIN driver. Sincerely, Andy Allen From etxuwig@REDACTED Wed Dec 6 14:42:14 2000 From: etxuwig@REDACTED (Ulf Wiger) Date: Wed, 6 Dec 2000 14:42:14 +0100 (MET) Subject: Erlang for Robotics In-Reply-To: Message-ID: On Wed, 6 Dec 2000, aba3600@REDACTED wrote: >My number one gripe with Erlang is that I do not have a good example of a >single port program in Erlang, and the matching end in every common >compiler for every OS available. > >Is this possible? Do they need different Erlang sections for each >langauge? Don't know exactly what you're getting at without more specifics, but there shouldn't have to be any difference on the Erlang side. If you'd use IDL to specify your API between Erlang and the outside, you would get a well-defined interface. Then again, if you really want high I/O throughput, you might want to compromise on generality... >Finally, I only have this one gripe about linux. I have books of gripes >about every other language. It's just hard to beat the I/O capacity of "C" >when talking to a home-brew ISA digital I/O card, or the power of a VB >library when doing video capture via a TWAIN driver. You'd put the I/O part in a linked-in driver, and send user-friendly messages to an Erlang process. What would be the typical message-handling capacity requirement for various types of robot? As far as the high-level power of VB for certain tasks, well, it's simply a matter of resources, I guess. User-friendly prefab solutions take time and money to develop, and there simply aren't that many Erlang programmers around to do that... yet. (: I don't know how VB components are best reused by Erlang hackers. /Uffe -- Ulf Wiger tfn: +46 8 719 81 95 Senior System Architect mob: +46 70 519 81 95 Strategic Product & System Management ATM Multiservice Networks Data Backbone & Optical Services Division Ericsson Telecom AB From jamesh@REDACTED Wed Dec 6 15:54:13 2000 From: jamesh@REDACTED (James Hague) Date: Wed, 6 Dec 2000 08:54:13 -0600 Subject: Parsing big files In-Reply-To: <200012060949.KAA03379@trana.bluetail.com> Message-ID: >The original message noted that reading in the whole file as a binary >caused the runtime system to run out of memory. Ah, I missed that :) > So far the builtin scanning modules cannot handle binaries. I assumed the poster was writing his own scanner. I wrote my own scanner a while back for a compiler (by hand; I didn't use the unofficial Erlang tool), and I suspect it would have been fairly easy to make it operate on binary input, rather than a list. That would be an interesting experiment. James From Peter.Andersson@REDACTED Wed Dec 6 16:18:26 2000 From: Peter.Andersson@REDACTED (Peter Andersson) Date: Wed, 06 Dec 2000 15:18:26 +0000 Subject: Alternatives to records Message-ID: <3A2E58C2.4860110B@eei.ericsson.se> Hi, I'm looking for a data representation to use as an alternative to Erlang records in a particular application of mine. I want the possibility to reference data elements by means of labels rather than positions. The reason for not using records in the first place is that, in this case, I want the possibility to retrieve the data dynamically, like "get_value(Key, Record)", which is impossible with records (since the names must be hardcoded). I would prefer to handle the data in a "side-effect-free" fashion, i.e. not use explicit tables for storage, but pass the values around as arguments. The structures will never contain many or large elements but there will be *many* of the structures being created on multiple processes during the lifetime of the application and they will be accessed frequently. Insert/lookup must be efficient! I'm thinking a simple list of key-value tuples ([{key1,Val1},...]) would be the best choice, since the lists should never be really big (the simplest anyway, with already existing support by the lists:key* functions). I thought I'd post this question to the list, though. (I'm often surprised how much there is to learn from the discussions here - the detailed ones as well as the more general ones!). Are there any other alternative representations worth considering? Or are there perhaps ways to reference Erlang record elements dynamically that I haven't thought of or found out about (not using the tuple representation, that is)? Regards /Peter From joe@REDACTED Wed Dec 6 17:32:01 2000 From: joe@REDACTED (Joe Armstrong) Date: Wed, 6 Dec 2000 17:32:01 +0100 (CET) Subject: Stand Alone Erlang Message-ID: I have made a new version of stand alone erlang. The *entire* erlang kit necessary to run stand alone applications reduces to three files. *beam_evm* The shared library 551Kb bytes *ecc* The Erlang compiler (837Kb) *elink* The Erlang linker loader (20Kb) Individual application need just beam_evm and the code for the application in question. Download from: http://www.bluetail.com/~joe/sae_r7b/sae.html Discussion and followups on the WIKI Please at http://www.bluetail.com/wiki/showPage?node=StandAloneErlang Have fun. /Joe -- Joe Armstrong, Alteon WebSystems, tel: +46 8-545 550 00 S:t Eriksgatan 44, IV, fax: +46 8-545 550 50 SE-112 32 Stockholm, Sweden info: www.bluetail.com From rv@REDACTED Wed Dec 6 16:33:36 2000 From: rv@REDACTED (Robert Virding) Date: Wed, 06 Dec 2000 16:33:36 +0100 Subject: Performance of dict and ets In-Reply-To: Your message of "Mon, 04 Dec 2000 17:38:26 GMT." <402DD461F109D411977E0008C791C31256542E@imp02mbx.one2one.co.uk> Message-ID: <200012061533.eB6FXam30600@duva.bluetail.com> Sean Hinde writes: >Hi, > >... > >Was the version of dict in your tests the latest one using hash? Yes, dict and pets both used hashing, same algorithm but pets used it in more of an ets like fashion. >I also very much like the filter mechanism, and also like the mechanism in >dict where one can append new entries to an existing entry without reading >it, appending the new value, and then writing the new value back in. I know that can be very practical at times, as the generic update version. Robert From etxuwig@REDACTED Wed Dec 6 16:38:23 2000 From: etxuwig@REDACTED (Ulf Wiger) Date: Wed, 6 Dec 2000 16:38:23 +0100 (MET) Subject: Alternatives to records In-Reply-To: <3A2E58C2.4860110B@eei.ericsson.se> Message-ID: Personally, I tend to use {Key,Value} lists more and more as an alternative to records, especially when I want to handle a variety of options in an API function - as this is often the case for me, I tend to carry the options list with me, and use expressions like: X = get_opt(Key, Options, DefaultValue) Personally, I'd prefer it if I could have a hash object on the process heap. Then, I wouldn't have to worry about the cost of doing lots of linear searches in my code. I have no good idea of how such a hash object should be represented syntactically. I've not seen any new exciting symbols pop up on my keyboard lately... Perhaps simply through a set of functions (after all, Erlang is a functional language)? set(Options) -> Set (HashObject) list_to_set([tuple()], SetOptions) -> Set lookup_in_set(Set, Key) -> tuple() insert_in_set(Set, tuple()) -> NewSet delete_from_set(Set, Key) -> NewSet Of course, any of the Erlang-based access structures have this type of semantics, so there may not be a need for anything new - except perhaps that these access structures are often hard to read when you look at a crash report or a trace message. A set() datatype could be nicely formatted in a manner similar to a list by the runtime system. /Uffe On Wed, 6 Dec 2000, Peter Andersson wrote: > >Hi, > >I'm looking for a data representation to use as an alternative to Erlang records >in a particular application of mine. I want the possibility to reference data >elements by means of labels rather than positions. > >The reason for not using records in the first place is that, in this case, I >want the possibility to retrieve the data dynamically, like "get_value(Key, >Record)", which is impossible with records (since the names must be hardcoded). >I would prefer to handle the data in a "side-effect-free" fashion, i.e. not use >explicit tables for storage, but pass the values around as arguments. The >structures will never contain many or large elements but there will be *many* of >the structures being created on multiple processes during the lifetime of the >application and they will be accessed frequently. Insert/lookup must be >efficient! > >I'm thinking a simple list of key-value tuples ([{key1,Val1},...]) would be the >best choice, since the lists should never be really big (the simplest anyway, >with already existing support by the lists:key* functions). I thought I'd post >this question to the list, though. (I'm often surprised how much there is to >learn from the discussions here - the detailed ones as well as the more general >ones!). Are there any other alternative representations worth considering? Or >are there perhaps ways to reference Erlang record elements dynamically that I >haven't thought of or found out about (not using the tuple representation, that >is)? > >Regards > > /Peter > -- Ulf Wiger tfn: +46 8 719 81 95 Senior System Architect mob: +46 70 519 81 95 Strategic Product & System Management ATM Multiservice Networks Data Backbone & Optical Services Division Ericsson Telecom AB From richardc@REDACTED Wed Dec 6 16:38:56 2000 From: richardc@REDACTED (Richard Carlsson) Date: Wed, 6 Dec 2000 16:38:56 +0100 (MET) Subject: Alternatives to records In-Reply-To: <3A2E58C2.4860110B@eei.ericsson.se> Message-ID: On Wed, 6 Dec 2000, Peter Andersson wrote: > I'm looking for a data representation to use as an alternative to > Erlang records in a particular application of mine. I want the > possibility to reference data elements by means of labels rather than > positions. > [...] For small sets of keys (up to a dozen or so), using a list is faster than other data structures because of its very small traversation overhead. Using ordered lists of tuples {Tag, ...} and a lookup function utilizing the fact that the key is the first element and that the lists are ordered should be a good way of doing it. /Richard Carlsson Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) E-mail: Richard.Carlsson@REDACTED WWW: http://www.csd.uu.se/~richardc/ From Sean.Hinde@REDACTED Wed Dec 6 16:29:43 2000 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Wed, 6 Dec 2000 15:29:43 -0000 Subject: Alternatives to records Message-ID: <402DD461F109D411977E0008C791C312565449@imp02mbx.one2one.co.uk> Hi Peter, I just started to use dict in my app following all the help on the list over the last few days. This can be passed round, is fast and seems to do what you want. Also try gb_trees. I guess there is also the bi-annual request for Richard O'Keefe's new type of record to throw in here. I never got to grips with the details or even know where the paper can be accessed these days.. - Sean > I'm looking for a data representation to use as an > alternative to Erlang records > in a particular application of mine. I want the possibility > to reference data > elements by means of labels rather than positions. = 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 thomas@REDACTED Wed Dec 6 17:19:52 2000 From: thomas@REDACTED (Thomas Arts) Date: Wed, 06 Dec 2000 17:19:52 +0100 Subject: Parsing big files References: Message-ID: <3A2E6728.9CF0F60F@cslab.ericsson.se> James Hague wrote: > > So far the builtin scanning modules cannot handle binaries. > > I assumed the poster was writing his own scanner. I wrote my own scanner a > while back for a compiler (by hand; I didn't use the unofficial Erlang > tool), and I suspect it would have been fairly easy to make it operate on > binary input, rather than a list. That would be an interesting experiment. no, I used erl_scan basically, since the text scanned was very Erlang-like. The files I try to deal with can be as large as several 100 Mbytes. I don't think it is worth trying to optimise the scanner for that, since in the most optimal case I still need to store two times 100 MBytes in memory in the naive way of reading the file once, modifying it and storing it again. /Thomas From Peter.Andersson@REDACTED Wed Dec 6 18:16:11 2000 From: Peter.Andersson@REDACTED (Peter Andersson) Date: Wed, 06 Dec 2000 17:16:11 +0000 Subject: records and macros from the shell Message-ID: <3A2E745B.FC3B55D8@eei.ericsson.se> Hi again, I wrote a simple little program a while back that I find useful now and then. It's a program that lets you declare records, define macros and include header files from the Erlang shell, similar to what you would do in a normal Erlang source file. You can then evaluate a sequence of Erlang expressions in the shell using normal record and macro syntax. I find this especially useful for testing functions that take records as input, directly from the shell. For this I would, for example, first include a header file with the program, then evaluate an expression calling the function in question. (An expression to be evaluated is written to a temporary file together with the current definitions and is then executed, so it's not extremely fast). The program can "steal" declarations and definitions from a source file as well. I thought I'd post it if someone's interested. It hasn't been updated in a while, but it seemed to work ok last time I used it. Again, it's really simple so it shouldn't take long for you to update or modify if you wish. (It's intentionally free from comments *only* to make it a bit more challenging to understand! :-). I have attached the code and an interface description (+ a messy example). Cheers /Peter -------------- next part -------------- %%%---------------------------------------------------------------------- %%% File : p.erl %%% Author : Andersson, Peter %%% Purpose : %%% Created : 15 Sep 1998 by Andersson, Peter %%%---------------------------------------------------------------------- -module(p). -author('peppe@REDACTED'). -export([include/1, record/2, define/2, steal/1, e/1, e/2, f/0, finclude/0, frecord/0, fdefine/0, fsteal/0, finclude/1, frecord/1, fdefine/1]). -define(TabName, p_decls). %% include header include(Hs) -> case Hs of [Head | _] when list(Head) -> lists:foreach(fun(H) -> declare(header, H) end, Hs), true; Head -> declare(header, Head) end. %% steal from source file steal(File) -> case file:open(File, read) of {ok, Port} -> Ts = scan(Port, 1, []), extract_and_decl(Ts), true; _ -> no_such_file end. %% declare record record(Name, Rec) -> declare(record, {Name, Rec}). %% declare macro define(Name, Def) when atom(Name) -> io:format("~nDEF ERROR: Macro must be string~n"), error; define(Name, Def) when list(Name) -> declare(macro, {Name, Def}). declare(Key, Data) -> case catch ets:match_object(?TabName, {Key, Data}) of {'EXIT', _} -> ets:new(?TabName, [bag, public, named_table]), ets:insert(?TabName, {Key, Data}); [_] -> not_again; [] -> ets:insert(?TabName, {Key, Data}) end. %% "forget all" f() -> catch ets:delete(?TabName). finclude() -> ets:delete(?TabName, header). frecord() -> ets:delete(?TabName, record). fdefine() -> ets:delete(?TabName, macro). fsteal() -> ets:delete(?TabName, steal). %% "forget specific" finclude(H) -> catch ets:match_delete(?TabName, {header, H}). frecord(R) -> catch ets:match_delete(?TabName, {record, {R, '_'}}). fdefine(M) -> catch ets:match_delete(?TabName, {macro, {M, '_'}}). %% evaluate expression e(Expr) -> e(Expr, remove). e(Expr, SaveFile) -> case ets:info(?TabName, name) of undefined -> ets:new(?TabName, [public, bag, named_table]); _ -> ok end, file:delete("p_eval.erl"), file:delete("p_eval.jam"), file:delete("p_eval.beam"), {ok, Port} = file:open("p_eval.erl", write), %% create file io:format(Port, "-module(p_eval).~n", []), io:format(Port, "-export([eval/0]).~n", []), %% includes lists:foreach(fun({_, H}) -> io:format(Port, "-include(\"~s\").~n", [H]) end, ets:lookup(?TabName, header)), %% macros lists:foreach(fun({_, {N,D}}) -> io:format(Port, "-define(~s, ~s).~n", [N, D]) end, ets:lookup(?TabName, macro)), %% records lists:foreach(fun({_, {N,R}}) -> io:format(Port, "-record(~s, ~s).~n", [N, R]) end, ets:lookup(?TabName, record)), %% steals lists:foreach(fun({_, Defs}) -> lists:foreach(fun({Form,E}) -> io:format(Port,Form,E) end, Defs) end, ets:lookup(?TabName, steal)), %% eval function io:format(Port, "~neval() -> ~n ~s.~n~n", [Expr]), file:close(Port), %% compile file code:soft_purge(p_eval), Result = case compile:file(p_eval, [report_errors]) of error -> io:format("~nEVAL ERROR: compilation fails~n"), error; _ -> code:load_file(p_eval), %% evaluate expr p_eval:eval() end, case SaveFile of remove -> file:delete("p_eval.erl"), file:delete("p_eval.jam"), file:delete("p_eval.beam"); _ -> ok end, Result. %% steal functions scan(P, L, SoFar) -> case io:scan_erl_form(P, '', L) of {ok, Ts, L1} -> scan(P, L1, SoFar++Ts); {eof, L1} -> SoFar end. %% valid pp stmnt extract_and_decl([{'-',LM}, T , {'(',LP} | Ts]) -> {Extract,PP} = case T of {atom,L,record} -> {true,record}; {atom,L,define} -> {true,define}; _ -> {false,void} end, if Extract == true -> {Acc,Rest} = extract_spec(Ts, [], 1), Def = convert([ {'-',LM}, {atom,0,PP}, {'(',LP} | Acc ], []), declare(steal, Def), extract_and_decl(Rest); true -> extract_and_decl(Ts) end; extract_and_decl([ _| Ts]) -> extract_and_decl(Ts); extract_and_decl([]) -> done. extract_spec([T | Ts], Acc, PC) when PC/=0 -> PC1 = case T of {'(',_} -> PC+1; {')',_} -> PC-1; _ -> PC end, extract_spec(Ts, [T|Acc], PC1); extract_spec([{dot,L} | Ts], Acc, PC) when PC==0 -> {lists:reverse([{'.',L} | Acc]),Ts}; extract_spec(_, _, _) -> exit('unbalanced parenthesis'). convert([T | Ts], Acc) -> C = case T of {X,_} -> X; {_,_,X} -> X; _ -> exit('unknown token') end, convert(Ts, [get_format(C) | Acc]); convert([], Acc) -> lists:reverse([{"~n",[]} | Acc]). get_format(Term) when atom(Term) -> {"~s",[atom_to_list(Term)]}; get_format(Term) when number(Term) -> {"~w",[Term]}; get_format(Term) when list(Term) -> % string {"~p",[Term]}; get_format(Term) -> exit(cannot_be_matched). -------------- next part -------------- Module 'p' Peter Andersson, 2000-12-06 === INTERFACE === Func: include(File) Descr: Includes File (string). Func: include(Files) Descr: Includes Files = [File1, File2, ...]. Func: define(Macro, Def) Desrc: Defines Macro (constant or function, string) as Def (string). Func: record(Name, Def) Descr: Defines record with name Name (atom) as Def (string). Func: steal(File) Descr: Extracts all record-, macro- and constant definitions from File. Func: f() Descr: Forgets all definitions. Func: finclude(), fdefine(), frecord() Desrc: Forgets all includes/defines/records. Func: finclude(File), fdefine(Macro), frecord(Name) Descr: Forgets specific definition (see types above). Func: fsteal() Descr: Forgets all "stolen" definitions. Func: e(Expr) Descr: Evaluates arbitrary expression Expr (string). === EXAMPLES === (in the Erlang shell) %%% definitions 1> p:include("ph.hrl"). true 2> p:record(r1, "{a, b=void}"). true 3> p:define("C", "42"). true 4> p:define("out(F,A)", "io:format(F,A)"). true %%% evaluate expression 5> p:e(" R = #r1{a=#ph_r{}}, 5> R1 = R#r1{b=?ph_m(?C)}, 5> ?out(\"~n- ~p - ~p -~n\", [R1#r1.a, R1#r1.b]), 5> ?C/2 "). - {ph_r,1,ok} - 84 - 21.0000 %%% "steal" definitions 1> p:steal("ph.erl"). true 2> p:e(" R = #ph_sr{}, ph:foo(R#ph_sr{x=?ph_sm(42)}) "). 21.0000 ------ file ph.hrl ----- -define(ph_m(X), X*2). -record(ph_r, {x=1, y=ok}). ------------------------ ------ file ph.erl ----- -module(ph). -export([foo/1]). -define(ph_sm(X), X/2). -record(ph_sr, {x,y}). foo(R) -> R#ph_sr.x. ------------------------ From tgahling@REDACTED Wed Dec 6 18:59:53 2000 From: tgahling@REDACTED (Tony Gahlinger) Date: Wed, 06 Dec 2000 12:59:53 -0500 Subject: make breaks when trying to install R7B-1 Message-ID: <3A2E7E99.C31E19FC@ieee.org> I really wanted to re-install R7B-0 but couldn't find it on the standard sites. So why not be brave, figures I. Ok, got past ./configure on my Slackware 7.?, which identifies my host system as i586-pc-linux-gnu. But make blows up. Suggestions? /usr/local/otp_src_R7B-1# make cd erts && ERL_TOP=/usr/local/otp_src_R7B-1 make NO_START_SCRIPTS=true opt make[1]: Entering directory `/usr/local/otp_src_R7B-1/erts' make[2]: Entering directory `/usr/local/otp_src_R7B-1/erts/emulator' make -f i586-pc-linux-gnu/Makefile TYPE=opt make[3]: Entering directory `/usr/local/otp_src_R7B-1/erts/emulator' make[3]: i586-pc-linux-gnu/Makefile: No such file or directory make[3]: *** No rule to make target `i586-pc-linux-gnu/Makefile'. Stop. make[3]: Leaving directory `/usr/local/otp_src_R7B-1/erts/emulator' make[2]: *** [opt] Error 2 make[2]: Leaving directory `/usr/local/otp_src_R7B-1/erts/emulator' make[2]: Entering directory `/usr/local/otp_src_R7B-1/erts/etc' make[3]: Entering directory `/usr/local/otp_src_R7B-1/erts/etc/common' make -f i586-pc-linux-gnu/Makefile TYPE=opt make[4]: Entering directory `/usr/local/otp_src_R7B-1/erts/etc/common' make[4]: i586-pc-linux-gnu/Makefile: No such file or directory make[4]: *** No rule to make target `i586-pc-linux-gnu/Makefile'. Stop. make[4]: Leaving directory `/usr/local/otp_src_R7B-1/erts/etc/common' make[3]: *** [opt] Error 2 make[3]: Leaving directory `/usr/local/otp_src_R7B-1/erts/etc/common' make[2]: *** [opt] Error 2 make[2]: Leaving directory `/usr/local/otp_src_R7B-1/erts/etc' make[2]: Entering directory `/usr/local/otp_src_R7B-1/erts/epmd' Makefile:19: /usr/local/otp_src_R7B-1/make/i586-pc-linux-gnu/otp.mk: No such file or directory make[2]: *** No rule to make target `/usr/local/otp_src_R7B-1/make/i586-pc-linux-gnu/otp.mk'. Stop. make[2]: Leaving directory `/usr/local/otp_src_R7B-1/erts/epmd' make[1]: *** [opt] Error 2 make[1]: Leaving directory `/usr/local/otp_src_R7B-1/erts' make: *** [emulator] Error 2 /usr/local/otp_src_R7B-1# --Tony ----------------------------------------------------------- Tony Gahlinger & Associates Inc. Telecommunication Consultants and Software Development 48 Combermere Crescent, Waterloo ON N2L 5B1 519-888-6267 Fax: 519-888-9127 ----------------------------------------------------------- From aba3600@REDACTED Wed Dec 6 19:04:10 2000 From: aba3600@REDACTED (aba3600@REDACTED) Date: Wed, 6 Dec 2000 12:04:10 -0600 (CST) Subject: Erlang for Robotics In-Reply-To: Message-ID: > >Finally, I only have this one gripe about linux. I have books of gripes Did I say Linux? I meant Erlang Sincerely, Andy Allen From joe@REDACTED Wed Dec 6 20:07:13 2000 From: joe@REDACTED (Joe Armstrong) Date: Wed, 6 Dec 2000 20:07:13 +0100 (CET) Subject: Why are beam files so large? Message-ID: In building my SAE I noticed that the beam files in R7B seem to have grown somewhat and are about twice the size of earlier versions. Are they compressed by default? - can I strip the string tables etc? - can I reduce the size? /Joe -- Joe Armstrong, Alteon WebSystems, tel: +46 8-545 550 00 S:t Eriksgatan 44, IV, fax: +46 8-545 550 50 SE-112 32 Stockholm, Sweden info: www.bluetail.com From dg@REDACTED Wed Dec 6 22:28:31 2000 From: dg@REDACTED (David Gould) Date: Wed, 6 Dec 2000 13:28:31 -0800 Subject: Parsing big files In-Reply-To: <200012060949.KAA03379@trana.bluetail.com>; from rv@bluetail.com on Wed, Dec 06, 2000 at 10:49:47AM +0100 References: <200012060949.KAA03379@trana.bluetail.com> Message-ID: <20001206132831.A20329@archimedes.oak.suse.com> On Wed, Dec 06, 2000 at 10:49:47AM +0100, Robert Virding wrote: > > So far the builtin scanning modules cannot handle binaries. I would really really like to see something like a perlre compatible regex module that handled binaries. See python for what this could look like in terms of api and results. My idea is to be able to say stuff like: words(B) -> re:split(" ", B). %% returns a list of binaries each being a text word. {Prefix, Matches, Rest} = re:match("(\w+)\s+=\s+(\w+)",Input) %% works on bins I realize it is not part of Erlangs true mission, but if this was a native code module or somesuch, Erlang could be be used in certain apps where perl would be the default choice. -dg -- David Gould dg@REDACTED SuSE, Inc., 580 2cd St. #210, Oakland, CA 94607 510.628.3380 "As I've gained more experience with Perl it strikes me that it resembles Lisp in many ways, albeit Lisp as channeled by an awk script on acid." -- Tim Moore , on comp.lang.lisp From kent@REDACTED Wed Dec 6 22:32:05 2000 From: kent@REDACTED (Kent Boortz) Date: 06 Dec 2000 22:32:05 +0100 Subject: Why are beam files so large? In-Reply-To: Joe Armstrong's message of "Wed, 6 Dec 2000 20:07:13 +0100 (CET)" References: Message-ID: A BEAM file now contains several structured sections. You can run erlc like % erlc +compressed +no_debug_info ........ to get them alot smaller. There are still sections left that can be removed, I don't know how. Check out the sections and the sizes with 1> beam_lib:info("foo.beam"). [{file,"foo.beam"}, {module,foo}, {chunks,[{"Atom",20,67}, {"Code",96,181}, {"StrT",288,31}, {"ImpT",328,28}, {"ExpT",364,52}, {"LocT",424,4}, {"Attr",436,81}, {"CInf",528,202}, {"Abst",740,492}]}] kent From kent@REDACTED Wed Dec 6 22:47:59 2000 From: kent@REDACTED (Kent Boortz) Date: 06 Dec 2000 22:47:59 +0100 Subject: make breaks when trying to install R7B-1 In-Reply-To: Tony Gahlinger's message of "Wed, 06 Dec 2000 12:59:53 -0500" References: <3A2E7E99.C31E19FC@ieee.org> Message-ID: > I really wanted to re-install R7B-0 but couldn't find it on the > standard sites. So why not be brave, figures I. Ok, got past > ./configure on my Slackware 7.?, which identifies my host system as > i586-pc-linux-gnu. But make blows up. The configure scripts needs improvements. The probable cause for your problem is that one of the configure scripts really has failed but did not terminate the complete run. Instead the next configure script runs hiding that there was an error and no make files where created. Look at your log from running "configure", some things to look for are SSL libraries was not found. If they are not installed, use "--without-ssl" or "--with-ssl=PATH". curses/termcap/termlib libraries or headers was not found. Install a curses or ncurses development package. X11 libraries or headers was not found If this still does not work and you prefer to reinstall R7B-0 you can still find it at http://www.erlang.org/download/otp_src_R7B-0.tar.gz kent From joe@REDACTED Thu Dec 7 10:52:27 2000 From: joe@REDACTED (Joe Armstrong) Date: Thu, 7 Dec 2000 10:52:27 +0100 (CET) Subject: Why are beam files so large? In-Reply-To: Message-ID: > A BEAM file now contains several structured sections. You can run > erlc like > > % erlc +compressed +no_debug_info ........ > > to get them alot smaller. There are still sections left that > can be removed, I don't know how. Check out the sections and > the sizes with > > 1> beam_lib:info("foo.beam"). > [{file,"foo.beam"}, > {module,foo}, > {chunks,[{"Atom",20,67}, > {"Code",96,181}, > {"StrT",288,31}, > {"ImpT",328,28}, > {"ExpT",364,52}, > {"LocT",424,4}, > {"Attr",436,81}, > {"CInf",528,202}, > {"Abst",740,492}]}] > > kent > This is very interesting .... Pretty nifty: Lets give it a whirl: > erlc packer.crl > ls -l packer.beam -rw-r--r-- 1 joe staff 1868 Dec 7 09:41 1> beam_lib:info("backer.beam"). [{file,"packer.beam"}, {module,packer}, {chunks,[{"Atom",20,210}, {"Code",240,354}, {"StrT",604,47}, {"ImpT",660,136}, {"ExpT",804,52}, {"LocT",864,28}, {"Attr",900,40}, {"CInf",948,180}, {"Abst",1136,729}]}] So far so good > erlc +compressed +no_debug_info packer.erl > ls -l packer.beam -rw-r--r-- 1 joe staff 830 Dec 7 09:42 Wow - a lot smaller, but ... >erl Erlang (BEAM) emulator version 5.0.1.1 [source] Eshell V5.0.1.1 (abort with ^G) 1> beam_lib:info("packer.beam"). {error,beam_lib,{missing_chunk,"packer.beam","FOR1"}} Questions: 1) How can I do the +compressed etc. stuff from Erlang i.e. not the shell compile:file("foo", [compressed]). Didn't work 2) Can I write "strip" that takes a module compiled with default options and away debug info and compresses the results ??? /Joe -- Joe Armstrong, Alteon WebSystems, tel: +46 8-545 550 00 S:t Eriksgatan 44, IV, fax: +46 8-545 550 50 SE-112 32 Stockholm, Sweden info: www.bluetail.com From bjorn@REDACTED Thu Dec 7 10:15:31 2000 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 07 Dec 2000 10:15:31 +0100 Subject: Why are beam files so large? In-Reply-To: Joe Armstrong's message of "Thu, 7 Dec 2000 10:52:27 +0100 (CET)" References: Message-ID: Joe Armstrong writes: [...] > Questions: > > 1) How can I do the +compressed etc. stuff from Erlang i.e. not the shell > > compile:file("foo", [compressed]). > > Didn't work It works for me. I get a compressed file. But you'll want to write compile:file("foo", [compressed,no_debug_info]). if you want the file to get much smaller. > > 2) Can I write "strip" that takes a module compiled with default > options and away debug info and compresses the results ??? Yes. I've included an example. We plan to include similar capability in beam_lib in R8. beam_strip:release(Root) compresses all beam files in a complete OTP release. Root should be the same sort of path which code:root_dir/0 returns. beam_strip:files(Files) takes a list of beam files. beam_strip:file(File) takes the name of a single beam file. Note that beam_lib (and thus my example) can't read compressed files. If you have compressed files including debug info, you must uncompress them first. This can be done with gunzip or by writing some Erlang cod to do it. > > /Joe > Here is a description of the beam format: http://www.ericsson.se/cslab/~bjorn/beam_file_format.html /Bj?rn -module(beam_strip). -export([release/1,files/1,file/1]). -import(lists, [foreach/2]). release(Root) -> files(filelib:wildcard(filename:join(Root, "lib/*/ebin/*.beam"))). files(Fs) -> foreach(fun file/1, Fs). file(Name) -> {ok,{Mod,Chunks}} = beam_lib:chunks(Name, ["Atom","Code","StrT","ImpT", "ExpT","Attr","CInf"]), Stripped = build_module(Chunks), {ok,Fd} = file:open(Name, [raw,binary,write,compressed]), ok = file:write(Fd, Stripped), file:close(Fd). build_module(Chunks0) when list(Chunks0) -> Chunks = build_chunks(Chunks0), Size = size(Chunks), 0 = Size rem 4, % Assertion: correct padding? <<"FOR1",(Size+4):32,"BEAM",Chunks/binary>>. build_chunks(Chunks) -> build_chunks(Chunks, []). build_chunks([{Id,Data}|Chunks], Acc) -> build_chunks(Chunks, [build_chunk(Id, Data)|Acc]); build_chunks([], Acc) -> list_to_binary(Acc). %% Build a correctly padded chunk. build_chunk(Id, Contents) when list(Id), length(Id) == 4 -> build_chunk(list_to_binary(Id), Contents); build_chunk(Id, Contents) when size(Id) =:= 4, binary(Contents) -> Size = size(Contents), [<>,Contents|pad(Size)]; build_chunk(Id, Contents) when list(Contents) -> build_chunk(Id, list_to_binary(Contents)). pad(Size) -> case Size rem 4 of 0 -> []; Rem -> lists:duplicate(4 - Rem, 0) end. -- Bj?rn Gustavsson Ericsson Utvecklings AB bjorn@REDACTED ?T2/UAB/F/P BOX 1505 +46 8 727 56 87 125 25 ?lvsj? From qramika@REDACTED Thu Dec 7 10:17:55 2000 From: qramika@REDACTED (Karlsson Mikael) Date: Thu, 7 Dec 2000 10:17:55 +0100 (MET) Subject: Parsing big files Message-ID: <200012070917.KAA18053@nic.era-a.ericsson.se> I think this is a good idea, considering how many protocols are string-based today. Why not call the module perlang :-) By the way, do the SuSE Linux distributions include Erlang ? /Mikael On Wed, 6 Dec 2000 13:28:31 -0800, David Gould > > On Wed, Dec 06, 2000 at 10:49:47AM +0100, Robert Virding wrote: > > > > So far the builtin scanning modules cannot handle binaries. > > I would really really like to see something like a perlre compatible regex > module that handled binaries. See python for what this could look like in > terms of api and results. My idea is to be able to say stuff like: > > words(B) -> > re:split(" ", B). %% returns a list of binaries each being a text word. > > {Prefix, Matches, Rest} = re:match("(\w+)\s+=\s+(\w+)",Input) %% works on bins > > I realize it is not part of Erlangs true mission, but if this was a native > code module or somesuch, Erlang could be be used in certain apps where perl > would be the default choice. > > -dg > > -- > David Gould dg@REDACTED > SuSE, Inc., 580 2cd St. #210, Oakland, CA 94607 510.628.3380 > "As I've gained more experience with Perl it strikes me that it > resembles Lisp in many ways, albeit Lisp as channeled by an awk > script on acid." -- Tim Moore , > on comp.lang.lisp From bertil@REDACTED Thu Dec 7 10:49:31 2000 From: bertil@REDACTED (Bertil Karlsson) Date: Thu, 07 Dec 2000 10:49:31 +0100 Subject: ASN.1 enhancements: DER, open types, ... References: <200012042227.WAA15667@emile.sse.ie> Message-ID: <3A2F5D2B.D72E394C@cslab.ericsson.se> Hello, Since June 2000 I am a member of the OTP-team, and I am developing the ASN.1 compiler together with Kenneth Lundin ... Lon Willett wrote: > More specifically, my wish-list includes: > > * Open types -- as far as I can tell, there isn't support for any > open types in the compiler (tell me if I'm doing something wrong). > There appears to be some code in place to deal with them, but it > seems to be incomplete. > > Ideally, of course, I would like support for the full "Information > object specification". I could get by just fine with > TYPE-IDENTIFIER and INSTANCE OF, or with ANY [DEFINED BY]. > > Support for ANY might be a good idea anyway, even if it isn't part > of the standard any more. It provides a general escape mechanism > to let the caller take over the encoding/decoding, which is useful > in those cases where the compiler is, for whatever reason, > inadequate. It also should be simple enought to implement (at > least with BER, I'm not familiar with PER). I've often had to use > it for this reason with other compilers. At present we are working on an extension of the ASN.1 compiler to manage Information Objects (ITU-T specification X.681). However do we not have any plans to support ANY, since it no longer is a part of the ASN.1 standard. /Bertil -- ------------------------ Bertil Karlsson Ericsson Utvecklings AB Box 1505 SE-125 25 ?lvsj? SWEDEN ------------------------ From mickael.remond@REDACTED Thu Dec 7 10:58:07 2000 From: mickael.remond@REDACTED (Mickael Remond) Date: 07 Dec 2000 10:58:07 +0100 Subject: one-stop recruiting page In-Reply-To: Ulf Wiger's message of "Mon, 4 Dec 2000 12:00:28 +0100 (MET)" References: Message-ID: <87bsuo8seo.fsf@western.ird.idealx.com> On Mon, 4 Dec 2000, etxuwig@REDACTED wrote: > > I recently sat down and started searching the web for wanted ads > mentioning Erlang. It was disheartening. > > Knowing that there is actually a demand for Erlang competence, > I think something needs to be done to make this more visible. I think this is a very good idea. > Personally, I'd like to see an "Erlang Programmers Wanted" page on > http://www.erlang.org, where current links to open positions for > Erlangers were collected. I agree with you. Erlang.org is the best place but maybe it is extra work for the maintainer. The Erlang Wiki could also be a good place. > If, say, a student who encounters Erlang at school wants to know what > the job market is for an Erlang expert, he/she might hit a search > engine like I did - with the current state of affairs, he/she would > hardly be encourage to continue. > ... You should add our company to the list of company recruiting Erlang developpers: IDEALX (France). We have many developpment in Erlang and are looking to increase our Erlang teams. -- Micka?l R?mond - mickael.remond@REDACTED - http://IDEALX.com - +33 (1) 44 42 00 38 From mickael.remond@REDACTED Thu Dec 7 11:12:28 2000 From: mickael.remond@REDACTED (Mickael Remond) Date: 07 Dec 2000 11:12:28 +0100 Subject: ASN.1 enhancements: DER, open types, ... In-Reply-To: Bertil Karlsson's message of "Thu, 07 Dec 2000 10:49:31 +0100" References: <200012042227.WAA15667@emile.sse.ie> <3A2F5D2B.D72E394C@cslab.ericsson.se> Message-ID: <874s0g8rqr.fsf@western.ird.idealx.com> On Thu, 07 Dec 2000, bertil@REDACTED wrote: > At present we are working on an extension of the ASN.1 compiler to > manage Information Objects (ITU-T specification X.681). However do we > not have any plans to support ANY, since it no longer is a part of the > ASN.1 standard. We have the same problem with the ANY keyword. On the "ANY" side: It is one of the keyword use in the CSTA phase 1, use in some (old ?) autocom. CSTA phase 1 rely unfortunately on an old version of the ASN.1 standard. I think the problem is becoming somewhat tricky... -- Micka?l R?mond - mickael.remond@REDACTED - http://IDEALX.com - +33 (1) 44 42 00 38 From bertil@REDACTED Thu Dec 7 10:54:45 2000 From: bertil@REDACTED (Bertil Karlsson) Date: Thu, 07 Dec 2000 10:54:45 +0100 Subject: ASN1 compiler internal error References: <2000-12-05-18-08-36+trackit+sam@inf.enst.fr> Message-ID: <3A2F5E65.761C2795@cslab.ericsson.se> Hello, Thank you for noticing us on this problem. It is due to a bug on the UniversalString type. /Bertil Samuel Tardieu wrote: > > I do not know where I can send bug reports. The following attached file (it > is only 27KB) triggers an internal error in OTP R7B-1 when compiled with > asn1ct:compile/1. > > Sam -- ------------------------ Bertil Karlsson Ericsson Utvecklings AB Box 1505 SE-125 25 ?lvsj? SWEDEN ------------------------ From Sean.Hinde@REDACTED Thu Dec 7 17:35:11 2000 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Thu, 7 Dec 2000 16:35:11 -0000 Subject: gen_tcp:connect incorrect error message Message-ID: <402DD461F109D411977E0008C791C312565454@imp02mbx.one2one.co.uk> Hi, While debugging a duff bit of my code I found this behaviour: 84>gen_tcp:connect("hostname", 4567, [{packet, asn1}, active]). {'EXIT',badarg} The docs suggest I should get {error, Reason} not {'EXIT', Reason}. - 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 dg@REDACTED Thu Dec 7 18:57:09 2000 From: dg@REDACTED (David Gould) Date: Thu, 7 Dec 2000 09:57:09 -0800 Subject: Parsing big files In-Reply-To: <200012070917.KAA18053@nic.era-a.ericsson.se>; from qramika@era-a.ericsson.se on Thu, Dec 07, 2000 at 10:17:55AM +0100 References: <200012070917.KAA18053@nic.era-a.ericsson.se> Message-ID: <20001207095709.A24082@archimedes.oak.suse.com> On Thu, Dec 07, 2000 at 10:17:55AM +0100, Karlsson Mikael wrote: > I think this is a good idea, considering how many protocols > are string-based today. > > Why not call the module perlang :-) Eeek. I think perlre will do fine, maybe even try to use the python style interfaces, but of course without the "in Python most things are objects unless they are not" OO ness. I guess the other point is that it needs to be fast. > By the way, do the SuSE Linux distributions include Erlang ? I am working on trying to get it included (very slowly). Space on the CDs is precious and so I have to both package it and then find room for it, which may mean dropping something else and does mean getting some others to agree. Still, we have Haskell, so why not? -dg -- David Gould dg@REDACTED SuSE, Inc., 580 2cd St. #210, Oakland, CA 94607 510.628.3380 "As I've gained more experience with Perl it strikes me that it resembles Lisp in many ways, albeit Lisp as channeled by an awk script on acid." -- Tim Moore , on comp.lang.lisp From harald@REDACTED Mon Dec 11 14:13:58 2000 From: harald@REDACTED (Harald Sondergaard) Date: Tue, 12 Dec 2000 00:13:58 +1100 Subject: PPDP 2001: Call for Papers Message-ID: <200012111314.AAA03065@mundook.cs.mu.OZ.AU> Third International Conference on PRINCIPLES AND PRACTICE OF DECLARATIVE PROGRAMMING Firenze, Italy, 5-7 September 2001 CALL FOR PAPERS PPDP 2001 aims to stimulate research on the use of declarative methods in programming and on the design, implementation and application of programming languages that support such methods. Topics of interest include any aspect related to understanding, integrating and extending programming paradigms such as those for functional, logic, constraint and object-oriented programming; concurrent extensions and mobile computing; type theory; support for modularity; use of logical methods in the design of program development tools; program analysis and verification; abstract interpretation; development of implementation methods; application of the relevant paradigms and associated methods in industry and education. This list is not exhaustive: submissions describing new and interesting ideas relating broadly to declarative programming are encouraged. The technical program of the conference will combine presentations of the accepted papers with invited talks and advanced tutorials. PPDP 2001 is part of a federation of colloquia known as Principles, Logics and Implementations of high-level programming languages (PLI 2001) which includes the ACM SIGPLAN International Conference on Functional Programming (ICFP 2001). The colloquia will run from 2 to 8 September, 2001. The venue for the conference is Firenze (Florence), one of Europe's most attractive cities, famous for its churches, galleries and museums. For more details, see the conference web site. Important Dates: Submission 15 March 2001 Notification 7 May 2001 Final Version 11 June 2001 Affiliated Workshops: Proposals are being solicited for PLI 2001 affiliated workshops. Details about the submission of proposals are available at http://music.dsi.unifi.it/pli01/wkshops. Web Sites and Email Contact: PPDP 2001: http://music.dsi.unifi.it/pli01/ppdp PLI 2001: http://music.dsi.unifi.it/pli01 mailto:ppdp01@REDACTED Conference Chair: Rocco De Nicola, Universita di Firenze http://www.dsi.unifi.it/~denicola/ mailto:denicola@REDACTED Program Chair: Harald Sondergaard, The University of Melbourne http://www.cs.mu.oz.au/~harald/ mailto:harald@REDACTED Program Committee: Maria Alpuente, Univ. Politecnica de Valencia, ES Yves Caseau, Bouygues, FR Michael Codish, Ben-Gurion Univ. of the Negev, IL Saumya Debray, Univ. of Arizona, US Conal Elliott, Microsoft Research, US Sandro Etalle, Univ. Maastricht, NL Roberto Giacobazzi, Univ. di Verona, IT Michael Leuschel, Univ. of Southampton, GB John Lloyd, Australian National Univ., AU Torben Mogensen, Kobenhavns Univ., DK Alan Mycroft, Cambridge Univ., GB Gopalan Nadathur, Univ. of Minnesota, US Martin Odersky, Ecole Polyt. Fed. Lausanne, CH Catuscia Palamidessi, Penn State Univ., US Andreas Podelski, Max-Planck-Inst. Informatik, DE Kostis Sagonas, Uppsala Univ., SE Christian Schulte, Univ. des Saarlandes, DE Michael Schwartzbach, Aarhus Univ., DK Harald Sondergaard, Univ. of Melbourne, AU Peter J. Stuckey, Univ. of Melbourne, AU From cahill@REDACTED Mon Dec 11 21:31:19 2000 From: cahill@REDACTED (cahill) Date: Mon, 11 Dec 2000 20:31:19 +0000 Subject: erlang odbc Makefile Message-ID: <3A353996.F615C48B@ocean.ucc.ie> I am having difficulty with installing the odbc module for the erlang runtime system. I have installed iodbc and myodbc and have a database running. From what i understand, i have to edit the makefile on the lib/odbc/ directory of the erlang directory and 'make' it. Is this correct ?? I have set the environment variable. And ran 'make' , and got the following errors. Has anyone encountered such problems, or knows how to fix them. Could you also let me know what kind of changes must be made to the Makefile. thanx in advance adrian Error : Makefile:18: /make/target.mk: No such file or directory Makefile:19: /make//otp.mk: No such file or directory Makefile:35: /make/otp_subdir.mk: No such file or directory make: *** No rule to make target `/make/otp_subdir.mk'. Stop. lib/odbc> echo $ERL_TOP /usr/local/wisdom-desktop-users/01/cahill/Project/otp_src_R7B-0 From voudheus@REDACTED Mon Dec 11 22:26:23 2000 From: voudheus@REDACTED (Karel Van Oudheusden) Date: Mon, 11 Dec 2000 22:26:23 +0100 Subject: General questions about the power of Erlang Message-ID: <3A35467E.105AE62@imec.be> Hello, I am hesitating on using Erlang (for designing and implementing multimedia client server Internet applications). Would somebody please answer (some of) the following questions for me: 1) If I look at the evolution from Java to Java for real-time (RT), the programmer will be able to specifiy physical memory desires in the Java for RT API. The reason for this is because the Java for RT API will permit the programmer to use "Java physical memory objects". This is a new class added to the Java RT API. I am wandering whether I am able to do physical memory management in Erlang too? If I'm not mistaken, the semantics of Erlang were not designed for this purpose as opposed to concurrency and distribution which is well supported indeed. If I am not able to specify physical (or even virtual) memory management constraints in Erlang, I still assume that I can change some functionality behind the scenes to obtain the same effect. Does anybody have any experience on this subject? Please enlighten me. The reason for this question is because I plan to implement multimedia applications. These applications contain lots of dynamic data structures which I want to handle optimally with dynamic memory management. 2) I have worked with Ada95 previously. I read that Erlang was developed with Ada and the functional paradigm as the main sources of inspiration. This is great, however, my experience with Ada95 is that it behaves differently on different platforms even though it is not supposed to do this. As a matter of fact, it is well known by know that the Ada specifications are not supported to a full extent on all platforms that can run Ada95. I was wandering whether Erlang does behave correctly on for instance Windows and if so, does it behave in the same manner as on Linux? It is for me hard to believe that Erlang actually works well on Windows platforms since we are talking here about (soft) real-time applications. Or am I missing something here? 3) I read in the FAQ that application types, such as image processing and signal processing, are not meant to be implemented in Erlang. (They would perform badly if they were implemented in Erlang.) I am wandering if research is being done on defining a new "Erlang approach" for these types of applications. So instead of concurrent, distributed and hot code loadable applications, a new kind of Erlang semantics could be developed for data dominated, real-time, multimedia processing applications. Regards, Karel. From maurice@REDACTED Tue Dec 12 02:43:58 2000 From: maurice@REDACTED (Maurice Castro) Date: Tue, 12 Dec 2000 12:43:58 +1100 (EST) Subject: General questions about the power of Erlang In-Reply-To: <3A35467E.105AE62@imec.be> from Karel Van Oudheusden at "Dec 11, 2000 10:26:23 pm" Message-ID: <200012120143.MAA15213@parallel.serc.rmit.edu.au> > Hello, > > > I am hesitating on using Erlang (for designing and implementing > multimedia client server Internet applications). > Would somebody please answer (some of) the following questions for me: > > > 1) If I look at the evolution from Java to Java for real-time (RT), the > programmer will be able to specifiy physical memory desires in the Java > for RT API. The reason for this is because the Java for RT API will > permit the programmer to use "Java physical memory objects". This is a > new class added to the Java RT API. > > I am wandering whether I am able to do physical memory management in > Erlang too? > If I'm not mistaken, the semantics of Erlang were not designed for this > purpose as opposed to concurrency and distribution which is well > supported indeed. > > If I am not able to specify physical (or even virtual) memory management > constraints in Erlang, I still assume that I can change some > functionality behind the scenes to obtain the same effect. > > Does anybody have any experience on this subject? Please enlighten me. > The reason for this question is because I plan to implement multimedia > applications. These applications contain lots of dynamic data > structures which I want to handle optimally with dynamic memory > management. > In Erlang you can make applications run in either fixed or bounded space. Using a generalised form of tail recursion called last call optimisation you can ensure that your programs do not generate continually growing stacks. Naturally lists can grow in size depending on their contents, but the programmer has the option of testing the `size' of such a data item and deciding how to handle growth in such a case. In general what are regarded as good programming practices in Erlang will give you a stable space bounded program. Furthermore, at least up until the recent past, Erlang's garbage collection has been vastly better than that found in Java. > > 3) I read in the FAQ that application types, such as image processing > and signal processing, are not meant to be implemented in Erlang. (They > would perform badly if they were implemented in Erlang.) > I am wandering if research is being done on defining a new "Erlang > approach" for these types of applications. So instead of concurrent, > distributed and hot code loadable applications, a new kind of Erlang > semantics could be developed for data dominated, real-time, multimedia > processing applications. > Actually Erlang has a well defined approach to these application types: Write then in a suitable language and call them from Erlang. Erlang has supported external programs for a long time and the advent of linked in drivers has made access to programs in other languages even faster. Maurice Castro From sam@REDACTED Tue Dec 12 10:41:47 2000 From: sam@REDACTED (Samuel Tardieu) Date: Tue, 12 Dec 2000 10:41:47 +0100 Subject: General questions about the power of Erlang In-Reply-To: <3A35467E.105AE62@imec.be>; from voudheus@imec.be on Mon, Dec 11, 2000 at 10:26:23PM +0100 References: <3A35467E.105AE62@imec.be> Message-ID: <2000-12-12-10-41-47+trackit+sam@inf.enst.fr> On 11/12, Karel Van Oudheusden wrote: | 2) I have worked with Ada95 previously. I read that Erlang was | developed with Ada and the functional paradigm as the main sources of | inspiration. This is great, however, my experience with Ada95 is that | it behaves differently on different platforms even though it is not | supposed to do this. As a matter of fact, it is well known by know that | the Ada specifications are not supported to a full extent on all | platforms that can run Ada95. Where did you read that Erlang was developed with Ada? (I'm very interested if you can give me such a reference, being an Erlang and Ada fan) Concerning the lack of support, I am surprised of what you write (hoping it is not a troll that I would be feeding :-) The GNAT compiler supports the complete Ada language (including all the annexes) and is known to be the most reliable Ada compiler. Moreover, it is free software, and based on GCC: you get the very same code on any platform, the platform-specific glue is quite small. | I was wandering whether Erlang does behave correctly on for instance | Windows and if so, does it behave in the same manner as on Linux? What do you call "behave correctly"? Yes, Erlang works on both Windows on Linux, and does its duty :) | It is for me hard to believe that Erlang actually works well on Windows | platforms since we are talking here about (soft) real-time | applications. Or am I missing something here? What prevents you from building soft real-time applications on Windows? "best-effort" will always be "best-effort", even on a pityful platform which offers no guarantee. I have even seen people doing soft real-time in Java, with zero guarantee of the scheduling policy. | 3) I read in the FAQ that application types, such as image processing | and signal processing, are not meant to be implemented in Erlang. (They | would perform badly if they were implemented in Erlang.) | I am wandering if research is being done on defining a new "Erlang | approach" for these types of applications. So instead of concurrent, | distributed and hot code loadable applications, a new kind of Erlang | semantics could be developed for data dominated, real-time, multimedia | processing applications. My feeling is that those specific parts are best built through a port: you can use your preferred compiled/fast/optimized language to do the image/processing part. Sam From aa@REDACTED Tue Dec 12 11:15:08 2000 From: aa@REDACTED (Adam Aquilon) Date: Tue, 12 Dec 2000 11:15:08 +0100 Subject: How to read/poll disk_log wrap-logs? Message-ID: <001201c06424$67b158d0$072a010a@cellpt.se> Hi all! I'm feeling pretty stupid right now and I would appreciate anyone helping me out. I've been trying to setup a small reader for a log created as a 'disk_log' internal format wrap log (more than one wrap file). The behaviour I'm after is a reader that will can run in a separate VM from the process(es) writing to the wrap log. In other words, I don't want any other communication between the reader and the writers than the log files themselves. The reader should open the wrap log in 'read_only' mode and start doing sequential reads of the log data from the top. When it hits the end of the (circular) log, it should start polling for new data. I've tried to create this behaviour using both the disk_log:chunk/2,3 functions as well as the separate 'wrap_log_reader' module, but none of those mechanisms seem to work. When these read functions return eof, there seems to be now way of making them follow the "write pointer" used by the writing VM, back to the first log file (or in some cases even to the next file in the log). I'm sure *someone* must have written the kind of reader I'm looking for, or otherwise managed to manuever disk_log or wrap_log_reader into doing what I want, so please help me out. Regards, Adam _________________________________________________________ Adam Aquilon CellPoint Systems AB Office: +46 8 6332729 Phone: +46 8 6332700 Mobile: +46 70 7294121 Fax: +46 8 358790 Email: aa@REDACTED Kronoborgsgr?nd 7, http://www.cellpt.com S-164 46 Kista, SWEDEN From voudheus@REDACTED Tue Dec 12 11:22:20 2000 From: voudheus@REDACTED (Karel Van Oudheusden) Date: Tue, 12 Dec 2000 11:22:20 +0100 Subject: General questions about the power of Erlang References: <3A35467E.105AE62@imec.be> <2000-12-12-10-41-47+trackit+sam@inf.enst.fr> Message-ID: <3A35FC5C.60BB2041@imec.be> In response to Samuel Tardieu's email: > > Where did you read that Erlang was developed with Ada? (I'm very interested > if you can give me such a reference, being an Erlang and Ada fan) Ada and the functional paradigm were the main sources of inspiration for developing Erlang. (I got this from Bjarne Dackers thesis on Erlang). I am not saying that Erlang was developed with Ada. > > | I was wandering whether Erlang does behave correctly on for instance > | Windows and if so, does it behave in the same manner as on Linux? > > What do you call "behave correctly"? Yes, Erlang works on both Windows on > Linux, and does its duty :) > > | It is for me hard to believe that Erlang actually works well on Windows > | platforms since we are talking here about (soft) real-time > | applications. Or am I missing something here? > > What prevents you from building soft real-time applications on Windows? > "best-effort" will always be "best-effort", even on a pityful platform > which offers no guarantee. I have even seen people doing soft real-time > in Java, with zero guarantee of the scheduling policy. > It is exactly the scheduling which I am concerned about. In Ada (what about Erlang?) the programmer is for instance allowed to specify certain scheduling desires. These are however not similarly executed on the different platforms (which is of course not surprising to some extent). But in DOS for instance, the programmer even has to explicitly add dispatching points to his code for the scheduling to work with respect to the Ada reference manual (cfr. GNU for DOS). I am not going to go into detail on this here (perhaps a personal email is more suitable since this concerns Ada). My question was whether similar (hard to debug) problems arise with Erlang in regards to the scheduling of the various light weight processes. Another question I have is the following. Erlang has had a lot of success in ATM switches. Are these hard real-time (embedded) applications? Is there a good mathcing between the ATM hardware and the Erlang code? Or is this the same application domain as what Erlang is now made open source for: general purpose programming (regardless of platform) for Internet applications? I appologize for the perhaps unclear stated questions. But any feedback is welcome (even if I expect something differently). regards, Karel. From etxuwig@REDACTED Tue Dec 12 11:29:43 2000 From: etxuwig@REDACTED (Ulf Wiger) Date: Tue, 12 Dec 2000 11:29:43 +0100 (MET) Subject: General questions about the power of Erlang In-Reply-To: <3A35467E.105AE62@imec.be> Message-ID: On Mon, 11 Dec 2000, Karel Van Oudheusden wrote: >I am hesitating on using Erlang (for designing and implementing >multimedia client server Internet applications). >Would somebody please answer (some of) the following questions for me: Of course you have to look at the specifics of your application, but the words "multimedia client server Internet applications" sure ring like Erlang to me. (: >1) If I look at the evolution from Java to Java for real-time (RT), >the programmer will be able to specifiy physical memory desires in >the Java for RT API. The reason for this is because the Java for RT >API will permit the programmer to use "Java physical memory >objects". This is a new class added to the Java RT API. > >I am wandering whether I am able to do physical memory management in >Erlang too? Personally, I feel that Java for real-time is messing with a lot of stuff that it could leave alone if the underlying model were more sound... However, I can see that some applications have a need for specific memory management. You won't see that in Erlang, I wager, but I would suggest that you write some prototypes before you decide that Erlang isn't up to the job. As Maurice mentioned, memory management in Erlang has been vastly better than Java's memory management. Quite often, you can find that Erlang makes some things very easy that are (sometimes extremely) hard in other languages. If you find a way to mix Erlang and e.g. C code, you may arrive at a very stable and efficient platform. >If I am not able to specify physical (or even virtual) memory management >constraints in Erlang, I still assume that I can change some >functionality behind the scenes to obtain the same effect. There are a couple of things to consider: - If you work with images, the logical way to deal with them in Erlang is with the "binary" datatype. Binaries are allocated once, as read-only BLOBs, and pointers are passed around instead of passing the whole object. When deriving new binaries from old ones, Erlang tries to minimize copying. - One can always write a linked-in driver in C, which handles, e.g., a bitmap. Using the port_control function, Erlang code can call the C code synchronously. >2) I have worked with Ada95 previously. I read that Erlang was >developed with Ada and the functional paradigm as the main sources of >inspiration. This is great, however, my experience with Ada95 is that >it behaves differently on different platforms even though it is not >supposed to do this. As a matter of fact, it is well known by know that >the Ada specifications are not supported to a full extent on all >platforms that can run Ada95. > >I was wandering whether Erlang does behave correctly on for instance >Windows and if so, does it behave in the same manner as on Linux? I can't really speak for Ada, except to say that you are correct in that Ada was one of the languages studied by the Ericsson Computer Science Lab in the experiments that led up to Erlang. One conclusion from the Ada experiment was that message passing had to be asynchronous. Erlang works the same on all OSes in the sense that the semantics are exactly the same. For most Erlang applications, the virtual machine offers the familiar environment with lightweight preemptive multitasking. The OS will make itself known occasionally, by interrupting the virtual machine. This usually affects the Erlang processes in the same way as if they had to wait for one or two other Erlang processes. Some operating systems exhibit blocking behaviour once in a while. I've seen Solaris block for up to 10 minutes when accessing the file system through a ClearCase client. To avoid this, you can try to reduce the number of components that can cause the system to block, or run a real-time operating system. Erlang, for example, runs well on VxWorks, a real-time OS, which allows you to set real-time priority on the Erlang virtual machine. Still Erlang processes will not notice this except for the reduced risk that bad things (blocking) will happen. >It is for me hard to believe that Erlang actually works well on Windows >platforms since we are talking here about (soft) real-time >applications. Or am I missing something here? On Windows NT, you can give the Erlang VM higher priority. On Windows 98, you can pray that they whole system won't crash. If you program in Erlang, you can put two PCs on the same network and make your application distributed with little effort. Then, you can load share and protect your application through redundancy. If you want realtime performance on Windows, check out the VenturCom RTX kernel (http://www.venturcom.com/products/vci_products/rtx/rtx_index.html) Erlang offers no special support for this, however. >3) I read in the FAQ that application types, such as image processing >and signal processing, are not meant to be implemented in Erlang. (They >would perform badly if they were implemented in Erlang.) Erlang was designed to be good at building telecom applications. It has been found good at several other type of applications as well, Image processing is not common in telecom or datacom systems (the type of applications built by Ericsson.) It's quite possible that Erlang will become radically better at such applications, as e.g. compilers improve. The amount of copying that today makes certain applications behave very poorly might be reduced with smart use of destructive update of data structures behind the scenes, but now we're talking R8 or later. >I am wandering if research is being done on defining a new "Erlang >approach" for these types of applications. So instead of concurrent, >distributed and hot code loadable applications, a new kind of Erlang >semantics could be developed for data dominated, real-time, multimedia >processing applications. There is always research. (: One good thing about Erlang is that the released versions are of the highest quality. Sometimes, one would perhaps like more experimental versions to play with. There are Erlang implementations that take a different approach on performance. You could look at HIPE (http://www.csd.uu.se/projects/hipe/), which seems to be the only accessible alternative (the ETOS link doesn't work). /Uffe -- Ulf Wiger tfn: +46 8 719 81 95 Senior System Architect mob: +46 70 519 81 95 Strategic Product & System Management ATM Multiservice Networks Data Backbone & Optical Services Division Ericsson Telecom AB From etxuwig@REDACTED Tue Dec 12 11:41:04 2000 From: etxuwig@REDACTED (Ulf Wiger) Date: Tue, 12 Dec 2000 11:41:04 +0100 (MET) Subject: General questions about the power of Erlang In-Reply-To: <3A35FC5C.60BB2041@imec.be> Message-ID: On Tue, 12 Dec 2000, Karel Van Oudheusden wrote: >It is exactly the scheduling which I am concerned about. In Ada >(what about Erlang?) the programmer is for instance allowed to >specify certain scheduling desires. These are however not similarly >executed on the different platforms (which is of course not >surprising to some extent). It appears as if Ada has more in common with Java than with Erlang in this respect. Erlang's scheduling semantics are carefully preserved on all platforms. >Another question I have is the following. Erlang has had a lot of >success in ATM switches. Are these hard real-time (embedded) >applications? Is there a good mathcing between the ATM hardware and >the Erlang code? Or is this the same application domain as what >Erlang is now made open source for: general purpose programming >(regardless of platform) for Internet applications? The common way to build robust and scalable datacom and telecom switches is to divide the system in to control processors and device processors, where the device processors perform simple, hard real-time (or "wire-speed") tasks, and the control processors take care of the more complex (soft real-time) functions. Typical control processor functions would be: - Starting, stopping, monitoring, blocking, deblocking, and upgrading system components - Serving operators with a management interface (HTTP, CORBA, SNMP or other in various combinations) - Ensuring high availability through redundancy and load sharing - Handling signalling protocols and performing address and route analysis Erlang shines on the control system functions. There is some work on moving Erlang closer to the "fast-path", but in today's systems, we implement this in C. /Uffe -- Ulf Wiger tfn: +46 8 719 81 95 Senior System Architect mob: +46 70 519 81 95 Strategic Product & System Management ATM Multiservice Networks Data Backbone & Optical Services Division Ericsson Telecom AB From bjarne@REDACTED Tue Dec 12 12:20:36 2000 From: bjarne@REDACTED (Bjarne =?iso-8859-1?Q?D=E4cker?=) Date: Tue, 12 Dec 2000 12:20:36 +0100 Subject: General questions about the power of Erlang References: <3A35467E.105AE62@imec.be> <2000-12-12-10-41-47+trackit+sam@inf.enst.fr> <3A35FC5C.60BB2041@imec.be> Message-ID: <3A360A04.B0F4C822@erix.ericsson.se> Hello Karel Van Oudheusden wrote: > > Ada and the functional paradigm were the main sources of inspiration for > developing Erlang. (I got this from Bjarne Dackers thesis on Erlang). I am > not saying that Erlang was developed with Ada. What we have said before is that Erlang combines two traditions: - Languages like Modula, Chill and Ada which have modules (packages) and processes (tasks). The sequential paradigm for these languages, however, is more like Pascal or PL/I. - Untyped functional languages. Best regards Bjarne From Chandrashekhar.Mullaparthi@REDACTED Tue Dec 12 13:14:40 2000 From: Chandrashekhar.Mullaparthi@REDACTED (Chandrashekhar Mullaparthi) Date: Tue, 12 Dec 2000 12:14:40 -0000 Subject: How to read/poll disk_log wrap-logs? Message-ID: <402DD461F109D411977E0008C791C31202A79835@imp02mbx.one2one.co.uk> Have you tried using the Report Browser tool?? Check the SASL documentation for rb. cheers, Chandru > -----Original Message----- > From: Adam Aquilon [mailto:aa@REDACTED] > Sent: 12 December 2000 10:15 > To: Erlang-Questions > Subject: How to read/poll disk_log wrap-logs? > > > Hi all! > > I'm feeling pretty stupid right now and I would appreciate anyone > helping me out. > > I've been trying to setup a small reader for a log created as > a 'disk_log' internal format wrap log (more than one wrap file). > > The behaviour I'm after is a reader that will can run in a separate VM > from the process(es) writing to the wrap log. In other words, I don't > want any other communication between the reader and the writers than > the log files themselves. > > The reader should open the wrap log in 'read_only' mode and start > doing sequential reads of the log data from the top. When it hits the > end of the (circular) log, it should start polling for new data. > > I've tried to create this behaviour using both the disk_log:chunk/2,3 > functions as well as the separate 'wrap_log_reader' module, but none > of those mechanisms seem to work. When these read functions return > eof, there seems to be now way of making them follow the "write > pointer" used by the writing VM, back to the first log file (or in > some cases even to the next file in the log). > > I'm sure *someone* must have written the kind of reader I'm looking > for, or otherwise managed to manuever disk_log or > wrap_log_reader into > doing what I want, so please help me out. > > Regards, > Adam > > _________________________________________________________ > Adam Aquilon CellPoint Systems AB > Office: +46 8 6332729 Phone: +46 8 6332700 > Mobile: +46 70 7294121 Fax: +46 8 358790 > Email: aa@REDACTED Kronoborgsgr?nd 7, > http://www.cellpt.com S-164 46 Kista, SWEDEN > 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 Chandrashekhar.Mullaparthi@REDACTED Tue Dec 12 13:51:56 2000 From: Chandrashekhar.Mullaparthi@REDACTED (Chandrashekhar Mullaparthi) Date: Tue, 12 Dec 2000 12:51:56 -0000 Subject: erlang odbc Makefile Message-ID: <402DD461F109D411977E0008C791C31202A79838@imp02mbx.one2one.co.uk> Adrian, >From the documentation for installing ODBC: To install the ODBC module you need to: - Install your ODBC software package (ODBC Driver Manager and Driver). - Edit the Makefile in the src directory of the odbc application. The Makefile may need to be adapted to use correct paths and compiler command and options. (In R7B, this is $ROOTDIR/lib/odbc-0.8.2/src) - Run the Makefile. You seem to have got the wrong Makefile. cheers, Chandru > -----Original Message----- > From: cahill [mailto:cahill@REDACTED] > Sent: 11 December 2000 20:31 > To: erlang-questions@REDACTED > Subject: erlang odbc Makefile > > > I am having difficulty with installing the odbc module for the erlang > runtime system. I have installed iodbc and myodbc and have a database > running. From what i understand, i have to edit the makefile on the > lib/odbc/ directory of the erlang directory and 'make' it. Is this > correct ?? > > I have set the environment variable. And ran 'make' , and got the > following errors. > Has anyone encountered such problems, or knows how to fix them. Could > you also let me know what kind of changes must be made to the > Makefile. > > thanx in advance adrian > > > Error : > Makefile:18: /make/target.mk: No such file or directory > Makefile:19: /make//otp.mk: No such file or directory > Makefile:35: /make/otp_subdir.mk: No such file or directory > make: *** No rule to make target `/make/otp_subdir.mk'. Stop. > lib/odbc> echo $ERL_TOP > /usr/local/wisdom-desktop-users/01/cahill/Project/otp_src_R7B-0 > 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 aa@REDACTED Tue Dec 12 15:05:20 2000 From: aa@REDACTED (Adam Aquilon) Date: Tue, 12 Dec 2000 15:05:20 +0100 Subject: How to read/poll disk_log wrap-logs? In-Reply-To: <402DD461F109D411977E0008C791C31202A79835@imp02mbx.one2one.co.uk> Message-ID: <001d01c06444$90093490$072a010a@cellpt.se> Hi! > Have you tried using the Report Browser tool?? Check the SASL > documentation for rb. Well... I cannot use 'rb' since I don't use SASL. The log I'm trying to read was created with "vanilla" disk_log calls, it isn't one of the "SASL-type" logs. I use my own records that are written as the disk_log "internal format". I just wanted to use disk_log for efficient, wrapped output to local disk. (For the record, I tried anyway, but you cannot name the file that 'rb' should read, it must use some other method (default name?) to select which log to read from.) Any other suggestions? /Adam From mbj@REDACTED Tue Dec 12 15:48:13 2000 From: mbj@REDACTED (Martin Bjorklund) Date: Tue, 12 Dec 2000 15:48:13 +0100 Subject: How to read/poll disk_log wrap-logs? In-Reply-To: Your message of "Tue, 12 Dec 2000 11:15:08 +0100" <001201c06424$67b158d0$072a010a@cellpt.se> References: <001201c06424$67b158d0$072a010a@cellpt.se> Message-ID: <20001212154813N.mbj@bluetail.com> "Adam Aquilon" wrote: > Hi all! > > I'm feeling pretty stupid right now and I would appreciate anyone > helping me out. > > I've been trying to setup a small reader for a log created as > a 'disk_log' internal format wrap log (more than one wrap file). > > The behaviour I'm after is a reader that will can run in a separate VM > from the process(es) writing to the wrap log. In other words, I don't > want any other communication between the reader and the writers than > the log files themselves. > > The reader should open the wrap log in 'read_only' mode and start > doing sequential reads of the log data from the top. When it hits the > end of the (circular) log, it should start polling for new data. > > I've tried to create this behaviour using both the disk_log:chunk/2,3 > functions as well as the separate 'wrap_log_reader' module, but none > of those mechanisms seem to work. When these read functions return > eof, there seems to be now way of making them follow the "write > pointer" used by the writing VM, back to the first log file (or in > some cases even to the next file in the log). Actually, this looks like a bug. It looks like it works fine as long as the new items gets written to the same file, but when wrapping to a new file, the reader doesn't follow. It shouldn't be too hard to fix in disk_log_1.erl. I don't have time to look into this right now... somebody else?? /martin From jamesh@REDACTED Tue Dec 12 16:00:11 2000 From: jamesh@REDACTED (James Hague) Date: Tue, 12 Dec 2000 09:00:11 -0600 Subject: General questions about the power of Erlang In-Reply-To: <3A360A04.B0F4C822@erix.ericsson.se> Message-ID: > What we have said before is that Erlang > combines two traditions: > > - Languages like Modula, Chill and Ada > which have modules (packages) and > processes (tasks). The sequential > paradigm for these languages, however, > is more like Pascal or PL/I. > > - Untyped functional languages. Plus the syntax of Prolog! James From vladdu@REDACTED Tue Dec 12 23:05:29 2000 From: vladdu@REDACTED (Vlad Dumitrescu) Date: Tue, 12 Dec 2000 23:05:29 +0100 Subject: Simulation with Erlang Message-ID: Hi all! It feels like it should be Friday, but the week is till young *sigh* As some of you might remember, I am considering to use Erlang in a robotics application. Since the hardware is way too expensive (unless I find a good-hearted sponsor!) I thought I'd try to simulate it with a program. So far so good. The problem I stumbled upon is how to handle simulation time. My thought was to have processes run free, and a supervisor one (the "world") to check on them and collisions and such. But that is a completely different paradigm than the one I used before (the "objects" are run in the "world" thread, under it's control) and I can't make it work. More precisely, the Erlang multitasking strategy gives no control over when to yield execution. An Erlang "timeslice" might include very different lengths of "simulation time". A solution I came up with is to have the world doing the synchronization by sending "tick" messages to each object. But that gives a lot of traffic! And it's not elegant at all. Can anyone give me some hints of whether it is possible to synchronize everything in a clean way, and if yes, how? Or at least some pointers for where to look further. thanks in advance, Vlad _____________________________________________________________________________________ Get more from the Web. FREE MSN Explorer download : http://explorer.msn.com From bauerd@REDACTED Wed Dec 13 01:03:12 2000 From: bauerd@REDACTED (David W. Bauer Jr.) Date: Tue, 12 Dec 2000 19:03:12 -0500 (EST) Subject: Simulation with Erlang In-Reply-To: Message-ID: You may want to try a scheme where each process receives messages in timestamp order.. this would at least insure in order processing of incoming messages from other processes. Something like a timestamp-priority relationship on messages. How synchronized must the system be? David ~~~ ~~ ~~~~ _o URL: http://www.david-bauer.com ~~~ ~~~~ ~~ _'|<,_ ~~~~ ~~~ ~~~~ (*)/ (*) On Tue, 12 Dec 2000, Vlad Dumitrescu wrote: #Hi all! # #It feels like it should be Friday, but the week is till young *sigh* # #As some of you might remember, I am considering to use Erlang in a robotics #application. Since the hardware is way too expensive (unless I find a #good-hearted sponsor!) I thought I'd try to simulate it with a program. So #far so good. # #The problem I stumbled upon is how to handle simulation time. My thought was #to have processes run free, and a supervisor one (the "world") to check on #them and collisions and such. But that is a completely different paradigm #than the one I used before (the "objects" are run in the "world" thread, #under it's control) and I can't make it work. # #More precisely, the Erlang multitasking strategy gives no control over when #to yield execution. An Erlang "timeslice" might include very different #lengths of "simulation time". # #A solution I came up with is to have the world doing the synchronization by #sending "tick" messages to each object. But that gives a lot of traffic! And #it's not elegant at all. # #Can anyone give me some hints of whether it is possible to synchronize #everything in a clean way, and if yes, how? Or at least some pointers for #where to look further. # #thanks in advance, #Vlad #_____________________________________________________________________________________ #Get more from the Web. FREE MSN Explorer download : http://explorer.msn.com # # From etxuwig@REDACTED Wed Dec 13 09:43:40 2000 From: etxuwig@REDACTED (Ulf Wiger) Date: Wed, 13 Dec 2000 09:43:40 +0100 (MET) Subject: Simulation with Erlang In-Reply-To: Message-ID: On Tue, 12 Dec 2000, Vlad Dumitrescu wrote: >The problem I stumbled upon is how to handle simulation time. My >thought was to have processes run free, and a supervisor one (the >"world") to check on them and collisions and such. But that is a >completely different paradigm than the one I used before (the >"objects" are run in the "world" thread, under it's control) and I >can't make it work. Thomas Arts and I recently had a discussion on how to perform model analysis on running product code. We agreed that one problem was that you cannot "step" the system (using e.g. breakpoints, you can step one process, but this throws all timing dependencies out of whack.) Our idea was to run two OS threads in the Erlang VM: one that controls the internal Erlang clock, and one that runs the Erlang scheduler; the thread that controls the clock tells the scheduler thread when to execute the next reduction, and increments the internal notion of time, so that erlang:now(), the timeout queue, and the calendar functions operate realistically. I don't know how hard this would be, but over a cup of coffee, it didn't seem that hard. (: >More precisely, the Erlang multitasking strategy gives no control >over when to yield execution. An Erlang "timeslice" might include >very different lengths of "simulation time". A few comments: - The upcoming Erlang processor will schedule on clock cycles, which should give very even scheduling - I'm trying to get a prestudy going on porting Erlang natively to OSE Delta (http://www.enea.com/) This seems attractive, not only because OSE Delta is used extensively within Ericsson, but also because OSE threads have many of the characteristics of an Erlang process. However, the OSE kernel is fully preemptive, i.e. a thread can be interrupted even while executing a system call. I don't know if this is necessarily good or bad, but it seemed to bear on your question. - There is a BIF called erlang:yield(), which can be called by a process to yield execution to others. This can be used to compensate for strange side-effects of the (uneven) reduction-based scheduling. It is implementation-dependent, and not recommended for use, but... >A solution I came up with is to have the world doing the >synchronization by sending "tick" messages to each object. But that >gives a lot of traffic! And it's not elegant at all. Agree. >Can anyone give me some hints of whether it is possible to >synchronize everything in a clean way, and if yes, how? Or at least >some pointers for where to look further. I know of no clean way to implement another scheduling mechanism on top of the existing one. You _could_ try to run everything in one process (I can't believe I'm saying this) if you take great care to emulate the OTP behaviours. It would be possible, for example to make a multi-gen_fsm, which keeps process states in, say, the process dictionary, and calls different callback modules as if they were normal gen_fsm:s. This puts some restrictions on your FSMs (assuming you even have some): they can't assume that they "own" the process in which they execute, for example. Another way is to use something like dispatcher-1.0, which spawns off temporary gen_servers. This way, each gen_server or gen_fsm would have its own process, but the pid would change for each request/event. This might be useful for a simulation, but I wouldn't recommend it for a product. /Uffe -- Ulf Wiger tfn: +46 8 719 81 95 Senior System Architect mob: +46 70 519 81 95 Strategic Product & System Management ATM Multiservice Networks Data Backbone & Optical Services Division Ericsson Telecom AB From etxuwig@REDACTED Wed Dec 13 10:05:39 2000 From: etxuwig@REDACTED (Ulf Wiger) Date: Wed, 13 Dec 2000 10:05:39 +0100 (MET) Subject: Simulation with Erlang In-Reply-To: Message-ID: On Wed, 13 Dec 2000, Ulf Wiger wrote: >- The upcoming Erlang processor will schedule on clock cycles, which > should give very even scheduling Of course, this is not true... A process will still yield when waiting for a message, and might also yield when entering a wait state (e.g. fetching from memory.) This doesn't exactly amount to _even_ scheduling. However, preempting processes based on CPU cycles rather than reductions (function calls) seems more predictable. /Uffe -- Ulf Wiger tfn: +46 8 719 81 95 Senior System Architect mob: +46 70 519 81 95 Strategic Product & System Management ATM Multiservice Networks Data Backbone & Optical Services Division Ericsson Telecom AB From jflecomte@REDACTED Wed Dec 13 12:00:46 2000 From: jflecomte@REDACTED (Lecomte Jean François) Date: Wed, 13 Dec 2000 12:00:46 +0100 (CET) Subject: mnemosyne:string_to_handle pb ! Message-ID: <14903.22238.596613.849064@sagesse.ird.idealx.com> Hi, I do need to build a handle query using a string but when i tried to use the mnemosyne string_to_handle it fails ! Following code Q = mnemosyne:string_to_handle( "query [ X || X <- table ( jabber_personne ), X.age=22 ] end. "), mnesia:transaction(fun() -> mnemosyne:eval(Q) end). gives {aborted,{function_clause,[{mnemosyne,setup_query, [{'EXIT', {function_clause, [{erl_parse, normalise, [{call, 0, {atom, 0|...}, [{tuple|...}]}]}, {erl_parse,normalise_list,1}, {erl_parse,normalise,1}, {erl_parse,normalise_list,1}, {erl_parse,normalise,1}, {mnemosyne_lc, '-one_lc_to_handle/1-fun-1-', 2}, {lists,foldl,3}, {mnemosyne_lc, one_lc_to_handle, 1}| more]}}]}, {mnemosyne,cursor,2}, {mnemosyne,eval,1}, {mnesia_tm,apply_fun,2}, {mnesia_tm,execute_transaction,4}, {erl_eval,expr,3}, {erl_eval,exprs,4}, {shell,eval_loop,2}]}} but : query [ X || X <- table ( jabber_personne ), X.age=22 ] end, mnesia:transaction(fun() -> mnemosyne:eval(Q) end). works fine ! Any idea -- -- J-Fran?ois LECOMTE IDEALX S.A.S. From etxuwig@REDACTED Wed Dec 13 12:18:58 2000 From: etxuwig@REDACTED (Ulf Wiger) Date: Wed, 13 Dec 2000 12:18:58 +0100 (MET) Subject: mnemosyne:string_to_handle pb ! In-Reply-To: <14903.22238.596613.849064@sagesse.ird.idealx.com> Message-ID: I cannot help you with the exact problem, except to say that the following construct is _much_ more efficient: mnesia_transaction( fun() -> P = mnesia:table_info(jabber_personne, wild_pattern), mnesia:match_object(P#jabber_personne{age = 22}) end). Basically, mnemosyne should be avoided for all queries, unless you really need the cursor support, or you have very complex queries. /Uffe On Wed, 13 Dec 2000, Lecomte Jean Fran?ois wrote: >Hi, > >I do need to build a handle query using a string but when i tried to >use the mnemosyne string_to_handle it fails ! > >Following code > > Q = mnemosyne:string_to_handle( "query [ X || X <- table ( jabber_personne ), X.age=22 ] end. "), > mnesia:transaction(fun() -> mnemosyne:eval(Q) end). > >gives > >{aborted,{function_clause,[{mnemosyne,setup_query, > [{'EXIT', > {function_clause, > [{erl_parse, > normalise, > [{call, > 0, > {atom, > 0|...}, > [{tuple|...}]}]}, > {erl_parse,normalise_list,1}, > {erl_parse,normalise,1}, > {erl_parse,normalise_list,1}, > {erl_parse,normalise,1}, > {mnemosyne_lc, > '-one_lc_to_handle/1-fun-1-', > 2}, > {lists,foldl,3}, > {mnemosyne_lc, > one_lc_to_handle, > 1}| > more]}}]}, > {mnemosyne,cursor,2}, > {mnemosyne,eval,1}, > {mnesia_tm,apply_fun,2}, > {mnesia_tm,execute_transaction,4}, > {erl_eval,expr,3}, > {erl_eval,exprs,4}, > {shell,eval_loop,2}]}} > > > >but : > query [ X || X <- table ( jabber_personne ), X.age=22 ] end, > mnesia:transaction(fun() -> mnemosyne:eval(Q) end). > >works fine ! > >Any idea > > -- Ulf Wiger tfn: +46 8 719 81 95 Senior System Architect mob: +46 70 519 81 95 Strategic Product & System Management ATM Multiservice Networks Data Backbone & Optical Services Division Ericsson Telecom AB From etxuwig@REDACTED Wed Dec 13 14:44:24 2000 From: etxuwig@REDACTED (Ulf Wiger) Date: Wed, 13 Dec 2000 14:44:24 +0100 (MET) Subject: trouble building OTP R7B_1 Message-ID: I'm having trouble building OTP R7B_1 on my Solaris 7 workstation. The error messages look exactly like those that I encountered when trying to build OTP R6B - as I recall, I solved the problem then by downloading the prebuilt commercial version... As far as I can tell, make is looking for sparc-sun-solaris2.7/Makefile inside otp_src_R7B-1/erts/emulator. There is no such directory. /Uffe ... > make cd erts && ERL_TOP=/home/etxuwig/work/erlang/open_source/otp_src_R7B-1 make NO_START_SCRIPTS=true opt make[1]: Entering directory `/home/etxuwig/work/erlang/open_source/otp_src_R7B-1/erts' make[2]: Entering directory `/home/etxuwig/work/erlang/open_source/otp_src_R7B-1/erts/emulator' make -f sparc-sun-solaris2.7/Makefile TYPE=opt make[3]: Entering directory `/home/etxuwig/work/erlang/open_source/otp_src_R7B-1/erts/emulator' make[3]: sparc-sun-solaris2.7/Makefile: No such file or directory make[3]: *** No rule to make target `sparc-sun-solaris2.7/Makefile'. Stop. make[3]: Leaving directory `/home/etxuwig/work/erlang/open_source/otp_src_R7B-1/erts/emulator' make[2]: *** [opt] Error 2 make[2]: Leaving directory `/home/etxuwig/work/erlang/open_source/otp_src_R7B-1/erts/emulator' make[2]: Entering directory `/home/etxuwig/work/erlang/open_source/otp_src_R7B-1/erts/etc' make[3]: Entering directory `/home/etxuwig/work/erlang/open_source/otp_src_R7B-1/erts/etc/common' make -f sparc-sun-solaris2.7/Makefile TYPE=opt make[4]: Entering directory `/home/etxuwig/work/erlang/open_source/otp_src_R7B-1/erts/etc/common' make[4]: sparc-sun-solaris2.7/Makefile: No such file or directory make[4]: *** No rule to make target `sparc-sun-solaris2.7/Makefile'. Stop. make[4]: Leaving directory `/home/etxuwig/work/erlang/open_source/otp_src_R7B-1/erts/etc/common' make[3]: *** [opt] Error 2 make[3]: Leaving directory `/home/etxuwig/work/erlang/open_source/otp_src_R7B-1/erts/etc/common' make[2]: *** [opt] Error 2 make[2]: Leaving directory `/home/etxuwig/work/erlang/open_source/otp_src_R7B-1/erts/etc' make[2]: Entering directory `/home/etxuwig/work/erlang/open_source/otp_src_R7B-1/erts/epmd' Makefile:19: /home/etxuwig/work/erlang/open_source/otp_src_R7B-1/make/sparc-sun-solaris2.7/otp.mk: No such file or directory make[2]: *** No rule to make target `/home/etxuwig/work/erlang/open_source/otp_src_R7B-1/make/sparc-sun-solaris2.7/otp.mk'. Stop. make[2]: Leaving directory `/home/etxuwig/work/erlang/open_source/otp_src_R7B-1/erts/epmd' make[1]: *** [opt] Error 2 make[1]: Leaving directory `/home/etxuwig/work/erlang/open_source/otp_src_R7B-1/erts' make: *** [emulator] Error 2 ... > ls erts/emulator/ beam/ internal_doc/ Makefile.in sys/ zlib/ drivers/ Makefile Makefile.win32 utils/ -- Ulf Wiger tfn: +46 8 719 81 95 Senior System Architect mob: +46 70 519 81 95 Strategic Product & System Management ATM Multiservice Networks Data Backbone & Optical Services Division Ericsson Telecom AB From venneri@REDACTED Wed Dec 13 21:06:41 2000 From: venneri@REDACTED (b.venneri) Date: Wed, 13 Dec 2000 16:06:41 -0400 Subject: PLI 2001: call for workshop proposals Message-ID: CALL FOR WORKSHOP PROPOSALS Principles, Logics and Implementations of high-level programming languages (PLI 2001) Firenze, Italy September 3 - 7, 2001 http://music.dsi.unifi.it/pli01 PLI 2001, a federation of colloquia which includes ICFP 2001 (ACM-SIGPLAN International Conference on Functional Programming) and PPDP 2001 (ACM-SIGPLAN International Conference on Principles and Practice of Declarative Programming), will be held in Firenze, Italy, September 3-7 2001. Workshops affiliated to PLI 2001 will be held before, after or in parallel with the main conferences. Researchers and practitioners are invited to submit workshop proposals, that should be sent to the PLI 2001 Workshop Chair Betti Venneri mailto:venneri@REDACTED with "PLI01 Workshop Submission" in the subject header. Proposals should include * a short scientific justification of the proposed topic (somehow related to the colloquia), * names and contact information of the organizers, * expected number of participants and duration (the preference is for one day-long workshops), * estimated dates for paper submissions, notification of acceptance and final versions and any other relevant information (e.g., invited speakers, publication policy, etc.). THE DEADLINE FOR RECEIPT OF PROPOSALS IS JANUARY 8, 2001. Proposals will be evaluated by the PLI 2001 Workshop Chair, the ICFP and PPDP Program Chairs and Conference Chairs. Notification of acceptance will be made by February 2, 2001. The titles and brief information related to accepted workshop proposals will be included in the conference program and advertised in the call for participation. Workshop organizers will be responsible for producing a Call for papers and a Web site, for reviewing and making acceptance decisions on submitted papers, and for scheduling workshop activities in consultation with the local organizers. Workshop selection committee: Xavier Leroy (INRIA, France), ICFP 2001 Program Chair Benjamin C. Pierce (Univ. of Pennsylvania), ICFP 2001 Conference Chair Harald Sondergaard (Univ. of Melbourne), PPDP 2001 Program Chair Rocco De Nicola (Univ. of Firenze), PPDP 2001 Conference Chair Betti Venneri (Univ. of Firenze), PLI 2001 Workshop Chair. we From daniel.neri@REDACTED Wed Dec 13 16:32:53 2000 From: daniel.neri@REDACTED (Daniel Neri) Date: 13 Dec 2000 16:32:53 +0100 Subject: trouble building OTP R7B_1 In-Reply-To: Ulf Wiger's message of "Wed, 13 Dec 2000 14:44:24 +0100 (MET)" References: Message-ID: Ulf Wiger writes: > As far as I can tell, make is looking for > sparc-sun-solaris2.7/Makefile inside otp_src_R7B-1/erts/emulator. > There is no such directory. That's weird. It's supposed to have been created by the configure script(s). Are you sure "configure" terminated successfully? Regards, --Daniel -- Daniel Neri mailto:dn@REDACTED Sigicom AB, Sweden http://www.sigicom.com From jim@REDACTED Wed Dec 13 19:48:46 2000 From: jim@REDACTED (Jim Larson) Date: Wed, 13 Dec 2000 10:48:46 -0800 Subject: Simulation with Erlang In-Reply-To: Your message of "Wed, 13 Dec 2000 09:43:40 +0100." Message-ID: <200012131848.KAA27787@functor.Sendmail.COM> Take a look at the "Time Warp" multiprocessor simulation framework (sorry, my references aren't handy at the moment). Instead of requiring all concurrent entities of the simulation to run in lock-step, each goes at its own pace. The different simulation pieces interact with each other through timestamped messages. If a process receives a message with a timestamp earlier than its internal time, it is required to roll-back its internal clock and re-run its simulation with the new message factored in. If the process had sent out messages to other processes based on the rolled-back state, it has to send out anti-messages to have the other processes undo *their* work, and so on. A global "commit" algorithm detects the progress of the system as a whole, deciding when some results are safe and can't possibly be rolled-back. Jim From swight@REDACTED Wed Dec 13 20:12:11 2000 From: swight@REDACTED (s. n. wight) Date: Wed, 13 Dec 2000 11:12:11 -0800 Subject: mnemosyne:string_to_handle pb ! In-Reply-To: ; from etxuwig@etxb.ericsson.se on Wed, Dec 13, 2000 at 12:18:58PM +0100 References: <14903.22238.596613.849064@sagesse.ird.idealx.com> Message-ID: <20001213111211.A28059@verticalnet.com> I agree with Uffe on this for sure - the match_object function is beautiful and performs 90% of the query operations I need to do! But I had a very similar looking problem in September and Dan Gudmundsson sent out a simple patch which fixes this problem (YMMV!): http://www.erlang.org/ml-archive/erlang-questions/200009/msg00116.html Otherwise, heed Ulf's sound advice, below! -steve On Wed, Dec 13, 2000 at 12:18:58PM +0100, Ulf Wiger wrote: > > I cannot help you with the exact problem, except to say that > the following construct is _much_ more efficient: > > mnesia_transaction( > fun() -> > P = mnesia:table_info(jabber_personne, wild_pattern), > mnesia:match_object(P#jabber_personne{age = 22}) > end). > > Basically, mnemosyne should be avoided for all queries, unless > you really need the cursor support, or you have very complex queries. > > /Uffe > > On Wed, 13 Dec 2000, Lecomte Jean Fran?ois wrote: > > >Hi, > > > >I do need to build a handle query using a string but when i tried to > >use the mnemosyne string_to_handle it fails ! From bauerd@REDACTED Thu Dec 14 02:28:36 2000 From: bauerd@REDACTED (David W. Bauer Jr.) Date: Wed, 13 Dec 2000 20:28:36 -0500 (EST) Subject: Simulation with Erlang In-Reply-To: <200012131848.KAA27787@functor.Sendmail.COM> Message-ID: My roommate Shawn Pearce and I created the fastest known Time Warp simulator.. and what he is saying is correct, in that the rollback mechanism is the most efficient way known to handle out of order events in a speculative execution engine, however, it can also be extremely complicated to code. I would suggest that you first implement a state saving routine for reverse computations. Also, I would suggest that you might not want to use a Time Warp approach because of the GVT (global virtual time) mechanism. It requires the use of global variables and may not work exactly in the typical way as a TW sim would expect that GVT vars would be seen across all nodes simulataneously. It definitely could be done, but it is another issue to consider. I would also suggest that you take a more conservative approach in your simulation until you had it running, then begin to add fancier routines such as rollback. David ~~~ ~~ ~~~~ _o URL: http://www.david-bauer.com ~~~ ~~~~ ~~ _'|<,_ ~~~~ ~~~ ~~~~ (*)/ (*) On Wed, 13 Dec 2000, Jim Larson wrote: #Take a look at the "Time Warp" multiprocessor simulation framework #(sorry, my references aren't handy at the moment). Instead of #requiring all concurrent entities of the simulation to run in #lock-step, each goes at its own pace. The different simulation #pieces interact with each other through timestamped messages. # #If a process receives a message with a timestamp earlier than its #internal time, it is required to roll-back its internal clock and #re-run its simulation with the new message factored in. If the #process had sent out messages to other processes based on the #rolled-back state, it has to send out anti-messages to have the #other processes undo *their* work, and so on. # #A global "commit" algorithm detects the progress of the system as #a whole, deciding when some results are safe and can't possibly be #rolled-back. # #Jim # From cesarini@REDACTED Thu Dec 14 09:59:48 2000 From: cesarini@REDACTED (Francesco Cesarini) Date: Thu, 14 Dec 2000 08:59:48 +0000 Subject: Proper or well formed Lists Message-ID: <3A388C04.BC4497CE@terminus.ericsson.se> A well formed list follows the definition List = [Term|List] or []. Why where non proper (or well formed) lists (List = [Term|Term] ex: [hello|world]) allowed in the language in the first place? I am having a hard time seeing the need or intent with non well formed lists, other than a simplifying run-time evaluations and possibly the parsing. Wouldn't it have been better to have expressions not evaluating to a well formed list result in a run time error? Regards, Francesco -- Francesco Cesarini Erlang/OTP consultant Cellular: INT+44-7776 250381 ECN: 832-707192 http://welcome.to/cesarini.consulting From etxuwig@REDACTED Thu Dec 14 10:25:50 2000 From: etxuwig@REDACTED (Ulf Wiger) Date: Thu, 14 Dec 2000 10:25:50 +0100 (MET) Subject: Proper or well formed Lists In-Reply-To: <3A388C04.BC4497CE@terminus.ericsson.se> Message-ID: Well, one possible use of non-well-formed lists was explored a while ago on erlang-questions: lazy lists: http://www.erlang.org/ml-archive/erlang-questions/200010/msg00100.html It was decided not to open that Pandora's Box. Another use seems to be [byte() | binary()], which is accepted by the list_to_binary/1 BIF. It doesn't seem indispensable. I agree that there would be an advantage to have clearer errors in the cases where lists are supposed to be well-formed, but aren't. /Uffe On Thu, 14 Dec 2000, Francesco Cesarini wrote: >A well formed list follows the definition List = [Term|List] or []. >Why where non proper (or well formed) lists (List = [Term|Term] ex: >[hello|world]) allowed in the language in the first place? > >I am having a hard time seeing the need or intent with non well >formed lists, other than a simplifying run-time evaluations and >possibly the parsing. Wouldn't it have been better to have >expressions not evaluating to a well formed list result in a run >time error? > >Regards, >Francesco > -- Ulf Wiger tfn: +46 8 719 81 95 Senior System Architect mob: +46 70 519 81 95 Strategic Product & System Management ATM Multiservice Networks Data Backbone & Optical Services Division Ericsson Telecom AB From cesarini@REDACTED Thu Dec 14 10:35:48 2000 From: cesarini@REDACTED (Francesco Cesarini) Date: Thu, 14 Dec 2000 09:35:48 +0000 Subject: Proper or well formed Lists References: Message-ID: <3A389474.84DD8E00@terminus.ericsson.se> Ulf Wiger wrote: > > Well, one possible use of non-well-formed lists was explored a while > ago on erlang-questions: lazy lists: Yupp, but the creation of lazy lists became possible with the Erlang 4.4 extensions (in 95/96) when Funs where added to the language. I was wondering over the reasons behind the decision, as it was taken before that... Regards, Francesco -- Francesco Cesarini Erlang/OTP consultant Cellular: INT+44-7776 250381 ECN: 832-707192 http://welcome.to/cesarini.consulting From luke@REDACTED Thu Dec 14 10:47:08 2000 From: luke@REDACTED (Luke Gorrie) Date: 14 Dec 2000 10:47:08 +0100 Subject: Proper or well formed Lists In-Reply-To: Francesco Cesarini's message of "Thu, 14 Dec 2000 08:59:48 +0000" References: <3A388C04.BC4497CE@terminus.ericsson.se> Message-ID: Francesco Cesarini writes: > I am having a hard time seeing the need or intent with non well formed > lists, other than a simplifying run-time evaluations and possibly the > parsing. Wouldn't it have been better to have expressions not evaluating > to a well formed list result in a run time error? They've caused me the odd problem too. IIRC, the runtime sometimes generates lists in error messages like [...|more]. Some code I've used has fizzed when it ends up getting one of these (perhaps from a careless 'catch' or something) - particularly the java library for decoding erlang external format (in at least as or R5 or so), I think. Cheers, Luke From luke@REDACTED Thu Dec 14 11:44:33 2000 From: luke@REDACTED (Luke Gorrie) Date: 14 Dec 2000 11:44:33 +0100 Subject: servers with huge state terms Message-ID: Ahoy, I have a server process (gen_fsm) whose state is a very large term. This is a problem because when I get a crash report it's really long and hard to read - I've done things like ask xterm to have a thousand-line scrollback as a workaround. I'm tempted to move the larger parts of the state into an ets table (which would be pretty suitable, but I prefer the tuple) so that the server's state is more stringifyable - but does anyone know another approach for this sort of thing? Cheers, Luke From Chandrashekhar.Mullaparthi@REDACTED Thu Dec 14 12:04:41 2000 From: Chandrashekhar.Mullaparthi@REDACTED (Chandrashekhar Mullaparthi) Date: Thu, 14 Dec 2000 11:04:41 -0000 Subject: servers with huge state terms Message-ID: <402DD461F109D411977E0008C791C31202A7984C@imp02mbx.one2one.co.uk> A very dirty hack would be to convert the tuple to a list before storing it in your state and back to a tuple before using it! Chandru > -----Original Message----- > From: Luke Gorrie [mailto:luke@REDACTED] > Sent: 14 December 2000 10:45 > To: erlang-questions@REDACTED > Subject: servers with huge state terms > > > Ahoy, > > I have a server process (gen_fsm) whose state is a very large > term. This is a problem because when I get a crash report it's really > long and hard to read - I've done things like ask xterm to have a > thousand-line scrollback as a workaround. > > I'm tempted to move the larger parts of the state into an ets table > (which would be pretty suitable, but I prefer the tuple) so that the > server's state is more stringifyable - but does anyone know another > approach for this sort of thing? > > Cheers, > Luke > 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 vladdu@REDACTED Thu Dec 14 12:13:50 2000 From: vladdu@REDACTED (Vlad Dumitrescu) Date: Thu, 14 Dec 2000 12:13:50 +0100 Subject: Simulation with Erlang Message-ID: There were very interesting suggestions. I will think about it some more. TimeWarp seems a bit too complicated, I'd like to try something simpler first. I'd like to try to explain a little more what I am thinking about, and why use Erlang. Hopefully someone might become interested, and I'd get some help! :-) Imagine a robotics application, where the robot is not an usual one, but composed out of many small identical blocks that can move on each other or be locked onto each other, and they can communicate with their neighbours. It's a kind of robotic amoeba :-) There are two kinds of software in the system: a local OS per block, and a (hopefully distributed) high-level control application. Because of the distributed nature, I think Erlang would be a perfect platform. Since the cost of actually building this monster is prohibitive, it would be a good way to start with a simulation. And why not use Erlang for it too? Luckily, there are a lot of things that can be simplified in a simulation (not the least, the communication because TCP/IP won't work and finding a new network protocol is a big issue in itself; or maybe Bluetooth could be a solution?). A GUI could show what's happening - and also serve as a perfect marketing tool. That was a short description of my project. I've been thinking about it for a long time now, but there is very little work done. It's the fate of hoby-projects! :-) If anyone has ideas or suggestions, they are welcome! regards, Vlad _____________________________________________________________________________________ Get more from the Web. FREE MSN Explorer download : http://explorer.msn.com From rv@REDACTED Thu Dec 14 12:28:37 2000 From: rv@REDACTED (Robert Virding) Date: Thu, 14 Dec 2000 12:28:37 +0100 Subject: Proper or well formed Lists In-Reply-To: Your message of "Thu, 14 Dec 2000 08:59:48 GMT." <3A388C04.BC4497CE@terminus.ericsson.se> Message-ID: <200012141128.MAA10191@trana.bluetail.com> Francesco Cesarini writes: >A well formed list follows the definition List = [Term|List] or []. Why >where non proper (or well formed) lists (List = [Term|Term] ex: >[hello|world]) allowed in the language in the first place? > >I am having a hard time seeing the need or intent with non well formed >lists, other than a simplifying run-time evaluations and possibly the >parsing. Wouldn't it have been better to have expressions not evaluating >to a well formed list result in a run time error? The reason is mainly hereditary, the high-level languages we were used to when we started developing Erlang were Lisp and Prolog and both these languages allow this. Also the early versions of Erlang were Prolog interpreters. We did have some discussion about this but did really feel it important enough to warrant a change. Anyway think of the cool things you can do with it! Also think how much more efficient cons is. :-) Robert From matthias@REDACTED Thu Dec 14 16:44:35 2000 From: matthias@REDACTED (matthias@REDACTED) Date: Thu, 14 Dec 2000 16:44:35 +0100 (CET) Subject: trouble building OTP R7B_1 In-Reply-To: References: Message-ID: <14904.60131.163542.378870@corelatus.com> > Ulf Wiger writes: > > As far as I can tell, make is looking for > > sparc-sun-solaris2.7/Makefile inside otp_src_R7B-1/erts/emulator. > > There is no such directory. Daniel Neri writes: > That's weird. It's supposed to have been created by the configure > script(s). Are you sure "configure" terminated successfully? Just something more: I got surprised because R7B-0 worked out of the box whereas R7B-1 produced effects similar to what Ulf described until I added --without-ssl. It's easy to miss the warning among all the other output. The --without-ssl is mentioned in the README file. Matthias From Ciaran.Johnston@REDACTED Thu Dec 14 16:48:05 2000 From: Ciaran.Johnston@REDACTED (Ciaran Johnston) Date: Thu, 14 Dec 2000 15:48:05 +0000 Subject: Simulation with Erlang References: Message-ID: <3A38EBB4.A75217E0@eei.ericsson.se> Vlad Dumitrescu wrote: > > Imagine a robotics application, where the robot is not an usual one, but > composed out of many small identical blocks that can move on each other or > be locked onto each other, and they can communicate with their neighbours. > It's a kind of robotic amoeba :-) There are two kinds of software in the > system: a local OS per block, and a (hopefully distributed) high-level > control application. > > Because of the distributed nature, I think Erlang would be a perfect > platform. Since the cost of actually building this monster is prohibitive, > it would be a good way to start with a simulation. And why not use Erlang > for it too? > Just a little comment, I've only been using Erlang for a few months but before I even knew it existed I was involved in developing neural network applications in C and Fortran. It was a pain to say the least, and when I started using Erlang it occured to me that a lot of what I had been doing could have been simplified by an order of magnitude using this language. There are quite a few projects involving neural networks in robotics (eg. New Scientist (5 Dec. 1998): March Of the Biobots (p26) as the only reference I have to hand for an overview). A neural network is, in it's simplest form, many simple nodes interacting to create a complex system, which sounds to be very similar to what you are trying to create. It has the added bonus of being trainable to react to previously unhandled situations, which is pretty useful in the real world. Ciaran. -- Ciaran Johnston Ericsson Systems Expertise Ltd., Athlone Co. Westmeath Eire email: Ciaran.Johnston@REDACTED Phone: +353 902 31274 From jamesh@REDACTED Thu Dec 14 16:56:12 2000 From: jamesh@REDACTED (James Hague) Date: Thu, 14 Dec 2000 09:56:12 -0600 Subject: Proper or well formed Lists In-Reply-To: <200012141128.MAA10191@trana.bluetail.com> Message-ID: > The reason is mainly hereditary, the high-level languages we were used > to when we started developing Erlang were Lisp and Prolog and both these > languages allow this. Also the early versions of Erlang were Prolog > interpreters. We did have some discussion about this but did really > feel it important enough to warrant a change. Usually I see these kinds of lists in Lisp ("dotted lists" in Lisp lingo) for memory reasons. (cons A B) takes less space than '(A B) or (make-some-structure A B). It's also a poor-man's tuple :) Would there be a performance benefit if the run-time system knew that the cdr field of a cons was either [] or a valid pointer? What about for C-coded functions like reverse? James From sam@REDACTED Thu Dec 14 16:10:35 2000 From: sam@REDACTED (Samuel Tardieu) Date: Thu, 14 Dec 2000 16:10:35 +0100 Subject: Interrupting passive socket recv In-Reply-To: <402DD461F109D411977E0008C791C312565330@imp02mbx.one2one.co.uk>; from Sean.Hinde@one2one.co.uk on Tue, Nov 14, 2000 at 12:04:01PM -0000 References: <402DD461F109D411977E0008C791C312565330@imp02mbx.one2one.co.uk> Message-ID: <2000-12-14-16-10-35+trackit+sam@inf.enst.fr> On 14/11, Sean Hinde wrote: | Killing the recv process is also a bit nasty as well, though it does raise | the additional question of how one interrupts a gen_tcp:accept. This is an | issue for code upgrades as well as a general programming issue. The options | seem to be the same as documented for recv - timeout and retry to allow | space for other Erlang messages to be received - which is pretty horrible | (lost connections) I still don't like the timeout solution that I have to use in my own servers, but I don't understand in which case you would loose any connection. You do not *have* to call accept() all the time, it is what the socket backlog is here for, isn't it? From Sean.Hinde@REDACTED Thu Dec 14 17:28:09 2000 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Thu, 14 Dec 2000 16:28:09 -0000 Subject: Interrupting passive socket recv Message-ID: <402DD461F109D411977E0008C791C31256547D@imp02mbx.one2one.co.uk> Hmm, good point. You are right, the connections will sit in the listen queue until grabbed by accept. The only issue would be if the queue filled up... unlikely though possible under heavy load (There is a parameter {backlog, B} to listen(), defaulted to 5) It's still pretty horrible to kill or have to timeout all the time though. What do you set your timeout to out of interest? > I still don't like the timeout solution that I have to use in > my own servers, > but I don't understand in which case you would loose any > connection. You > do not *have* to call accept() all the time, it is what the > socket backlog is > here for, isn't it? > > - 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 sam@REDACTED Thu Dec 14 17:58:26 2000 From: sam@REDACTED (Samuel Tardieu) Date: Thu, 14 Dec 2000 17:58:26 +0100 Subject: Interrupting passive socket recv In-Reply-To: <402DD461F109D411977E0008C791C31256547D@imp02mbx.one2one.co.uk>; from Sean.Hinde@one2one.co.uk on Thu, Dec 14, 2000 at 04:28:09PM -0000 References: <402DD461F109D411977E0008C791C31256547D@imp02mbx.one2one.co.uk> Message-ID: <2000-12-14-17-58-26+trackit+sam@inf.enst.fr> On 14/12, Sean Hinde wrote: | It's still pretty horrible to kill or have to timeout all the time though. | What do you set your timeout to out of interest? I use 3 seconds in mod_erl, but I really disklike that (one of the first things I teach my students is to *never* do any busy waiting or things like that). This leads to this ugly structure, that allows the listening process to be but in a supervision tree (with a non-neglectable shutdown time, since it may take up to 3 seconds + epsilon to answer the system message). listener (Parent, Debug, State) -> receive {system, From, Msg} -> sys:handle_system_msg (Msg, From, Parent, ?MODULE, Debug, State); {'EXIT', Parent, Reason} -> exit (Reason); {get_modules, From} -> From ! {modules, [?MODULE]}, listener (Parent, Debug, State); _Other -> listener (Parent, Debug, State) after 0 -> case gen_tcp:accept (State#state.sock, 3000) of {ok, NS} -> {ok, Pid} = supervisor:start_child (eerl_workers, [NS, Debug]), gen_tcp:controlling_process (NS, Pid), listener (Parent, Debug, State); {error, timeout} -> listener (Parent, Debug, State); {error, Reason} -> exit (Reason) end end. From Sean.Hinde@REDACTED Thu Dec 14 18:23:42 2000 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Thu, 14 Dec 2000 17:23:42 -0000 Subject: gen_tcp:accept/{1,2} in passive mode? Message-ID: <402DD461F109D411977E0008C791C312565483@imp02mbx.one2one.co.uk> Peter, Any other top tips you might be able to share? - Sean > Sam, > > we have internally an inofficial FAQ which considers your problem: > > Q.11 : One process in my application is typically > hanging in a call to > gen_tcp:accept/1 waiting for a connection request. How > do I perform > code change for that process? > > A: Let the implementation be such that another process holds the > listen socket and is linked to the process hanging in > gen_tcp:accept/1. Specify an update code upgrade > instruction with > a very short timeout, which will cause the process to be > killed almost immediately by the release handler, before the new > version of the call-back module for the process is loaded. Then > let the other process restart the process calling > gen_tcp:accept/1. > > /Peter > > -------------------------------------------------------------- > ----------- > > Peter H?gfeldt e-mail : peter@REDACTED > Open Telecom Platform Phone: : +46 (8) 727 57 58 > Ericsson Utvecklings AB Mobile : +46 070-519 57 51 > S-126 25 STOCKHOLM Fax: : +46 (8) 727 5775 > Office address: Armborstv?gen 1, ?lvsj? > > On Mon, 4 Dec 2000, Samuel Tardieu wrote: > > > I use gen_tcp:accept{1,2} a lot when doing servers, and I > don't like the > > fact that I cannot passively wait for connections, in a > gen_server for example. > > How do you deal with code change and a process being > blocked in an accept > > call? You can always use a timeout, but in this case you > generate some > > load when you exit the timeout just in case code needs to > be changed. > > > > Wouldn't it be possible to set the accepting socket in > passive mode, and > > receive a message {Port, {accept, NewSocket, Origin}} for > example when > > a new connection arrives? > > > > Sam > > > > > 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 enano@REDACTED Thu Dec 14 18:30:09 2000 From: enano@REDACTED (Miguel Barreiro Paz) Date: Thu, 14 Dec 2000 18:30:09 +0100 (CET) Subject: trouble building OTP R7B_1 In-Reply-To: <14904.60131.163542.378870@corelatus.com> Message-ID: > Just something more: I got surprised because R7B-0 worked out of the > box whereas R7B-1 produced effects similar to what Ulf described until > I added --without-ssl. It's easy to miss the warning among all the > other output. Are you sure the software installed there has not changed since the R7B-0 build? It needed --without-ssl or ssl installed here to build properly. Regards, Miguel From sam@REDACTED Thu Dec 14 18:41:24 2000 From: sam@REDACTED (Samuel Tardieu) Date: Thu, 14 Dec 2000 18:41:24 +0100 Subject: Documentation/code inconsistency for gen_server? Message-ID: <2000-12-14-18-41-24+trackit+sam@inf.enst.fr> I was browsing through gen_server.erl while waiting for the end of an endless compilation, and noticed this fragment of code: | handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod, Time) -> | case catch apply(Mod, handle_call, [Msg, From, State]) of | [...] | {stop, Reason, Reply, NState} -> | {'EXIT', R} = | (catch terminate(Reason, Name, Msg, Mod, NState, [])), | reply(From, Reply), | exit(R); | [...] Also, at another place: | handle_common_reply(Reply, Parent, Name, Msg, Mod, State, Debug) -> | case Reply of | [...] | {stop, Reason, NState} -> | terminate(Reason, Name, Msg, Mod, NState, Debug); | [...] The doc (at least the man page) of gen_server says, concerning terminate: | The termination reason cannot be changed here. The | server will terminate due toReason regardless of | what was returned from this function. Does it mean the code is wrong? This may impact supervised processes, as they may exit without an error even if {stop, Reason, State} is returned, or with an unrelated error if {stop, Reason, Reply, State} is returned. From peter@REDACTED Thu Dec 14 19:16:49 2000 From: peter@REDACTED (Peter H|gfeldt) Date: Thu, 14 Dec 2000 19:16:49 +0100 (MET) Subject: application upgrade FAQ (was gen_tcp:accept/{1,2} in passive , mode) In-Reply-To: <402DD461F109D411977E0008C791C312565483@imp02mbx.one2one.co.uk> Message-ID: On Thu, 14 Dec 2000, Sean Hinde wrote: > Peter, > > Any other top tips you might be able to share? > > - Sean > Sean, please find attached the OTP internal FAQ regarding code replacement in HTML format. It is rather a QNA (Questions Never Asked). Links are broken, and you do not get the gif containing the Ericsson logo. It is provided "as is" under the usual conditions. Some of the tips might be wrong. /Peter ------------------------------------------------------------------------- Peter H?gfeldt e-mail : peter@REDACTED Open Telecom Platform Phone: : +46 (8) 727 57 58 Ericsson Utvecklings AB Mobile : +46 070-519 57 51 S-126 25 STOCKHOLM Fax: : +46 (8) 727 5775 Office address: Armborstv?gen 1, ?lvsj? -------------- next part -------------- OTP Application Upgrade FAQ Ericsson Blue Logotype
Prepared
UAB/F/P P. Högfeldt
No.
UAB/F-99:107
Approved
UAB/F/P P. Högfeldt
Checked
PLH
Date
1999-08-12
Rev
PA6
File
appup-faq.sgml

OTP Application Upgrade FAQ

1 Frequently Asked Questions

Q.1: I only updated the documentation. Shall the application version be incremented?

A: Yes.

Q.2: I only updated the documentation, and incremented the application version. Is the new version to be used for upgrade in run-time?

A: Probably not. However, the old .appup file will do, if only it is updated with the new application version.

Q.3: How does the release handler find the processes for which code change shall be performed?

A: By traversing the system supervision tree, and in particular by reading the child specifications of supervisors. See SASL User's Guide : Release Handling, Finding Processes.

Q.4: What is a .rel file?

A: It is the release resource file that contains a list of all application versions to be included in a release (see rel(4)). A .rel file is used as input to systools (see systools(3)) in order to generate .script and relup files.

Q.5: What is a .script file?

A: It is a boot script file (see script(4)). A .script file is a text file that describes how an Erlang system is started. It contains instructions for loading code, and instructions for which applications and processes to start.

Q.6: What is an .appup file?

A: It is an application upgrade file that defines how an application is upgraded or downgraded (see appup(4)). There is one .appup file for each version of an application.

Q.7 : What is a relup file?

A: It is a release upgrade file that specifies how to upgrade a node from old release versions to a new version, and how to downgrade from the new version to old release versions (see relup(4)).

Q.8 : What is a .boot file?

A: It is the binary version of a .script file.

Q.9 : Which are the input and output files for systools:make_script/1?

A: The input files are a .rel file, and all .app files of the applications listed in the .rel file. The output file is a .script file.

Q.10 : Which are the input and output files for systools:make_relup/3?

A: The input files are one or several .rel files, and all .app and .appup files of the applications listed in the .rel files. The output file is a relup file.

Q.11 : One process in my application is typically hanging in a call to gen_tcp:accept/1 waiting for a connection request. How do I perform code change for that process?

A: Let the implementation be such that another process holds the listen socket and is linked to the process hanging in gen_tcp:accept/1. Specify an update code upgrade instruction with a very short timeout, which will cause the process to be killed almost immediately by the release handler, before the new version of the call-back module for the process is loaded. Then let the other process restart the process calling gen_tcp:accept/1.

Q.12 : Can't I just put my processes under kernel_safe_sup?

A: No, the kernel supervisor kernel_safe_sup is only to be used by certain server processes in the kernel. You have to define a proper application, and start it through a call to application:start/1/2.

Q.13 : Should you expect upgrades and downgrades to be symmetrical in the sense that if you have succeeded in implementing a really smooth upgrade, the downgrade will be smooth as well?

A: No. The focus is on upgrades that add functionality or corrections in a backward compatible manner. If for instance an API has been extended in an upgrade, that extension will not be available after a downgrade. Still, just before your application is downgraded, there might be other applications pending on calls to the extension, which cannot be serviced after the downgrade is in effect.

Q.14 : I have a port program in an application, the code of which has to be updated. It uses native operating system sockets, and I would like to change its code, without closing existing connections. Is there any generic support for this in OTP?

A: No. You should have implemented code change functions in the old version of the port program, by having the possibility of transferring state information of the port program to the Erlang port controlling process, and then change to a new version of the port program by ordering the old version to exec (UNIX specific) the new version, and then let the new version obtain the state from the controlling process. That is not an easy thing to do.

Q.15: What does a `protocol change' mean?

A: By the `protocol' between two processes, we mean the syntax and semantics of all messages exchanged and recognized by the processes. Hence a `protocol change' of this set of messages. When the generic behaviours are used, the underlying messages are somewhat hidden, but roughly they are recognized forms of Request in gen_server:call/3 and the set of replies etc.

Q.16: What is the meaning of `backward compatible' ?

A: An new version of an implementation is backward compatible if (i) the client API of the old version is a subset or (possibly equal to) the client API of the new version, (ii) the client-server protocol of the old version is a subset of (possibly equal to) the client-server protocol of the new version.

If a function that is a member of both the old and the new version of a client API does not have the same set of return values for all permitted values of the arguments according to the old version of the API, then the new version is not backward compatible.

Q.17 : In my application I have an API module myapp that contains exported functions, that call client functions in call-back modules of the application. No process in my application uses this module. Should it still be included in the list of modules in child specifications.

A: No, but it should be listed in the .app file, and if the module is changed, there must be an load_module instruction for the module in the .appup file.

Q.18: In my gen_server call-back module mymod I have the following code:

name(FirstName, SurName) ->
    gen_server:call(my_proc, {name, {FirstName, SurName}}).

...

handle_call({name, {SurName, FirstName}}, _From, State) -> 
    ...
    

where FirstName and SurName have been mixed up. In correcting this bug, do I have to have a backward compatible correction?

A: No, since it is a bug.

Q.19: In one of the handle_call/3 clauses in a gen_server call-back module, I have a call to lists:map/2, the first argument of which is a fun that is defined in the same module. Is that safe when changing code?

A: Yes.

Q.20: I have a server with gen_server behaviour. Its task is to format reports according to one or serveral funs that are installed by clients when they open the formatting facility. Hence the funs becomes part of the state of the process. Is that safe?

A: No. The server will hold a reference to a fun not defined in its own module. If a client makes a code change the reference will be obsolete.

One way to avoid this situation is to disallow proper funs, and instead let each client give a reference to an exported function in the form {M, F}.

Q.21: I have an internal interface between two processes in an application. Is it alright to make a change that is not backward compatible?

A: Yes, provided both clients and servers in the application are updated to use the new version of the interface. However, if the application is distributed, and if it is likely that different versions will be running on a set of nodes, parts of the internal interface must be backward compatible. An example of this is a distributed application that is upgraded one node at a time.

Q.22: Is the protocol between client function and call-back functions in a module just internal stuff, that I am free to change as I like?

A: No, the protocol for a client function is not internal if the client function is part of an external API to be used by other applications.

Q.23: We have .appup files. Why do we not have .appdown files as well?

A: Well, an .appup file contains instructions both for upgrades and downgrades. Maybe a better name would have been .appchange.

Q.24: I have found a bug in the gen_server module, and I know how to correct it. How do perform smooth code change for the new version?

A: Load the new version, do suspend and resume on all processes with gen_server behaviour, and remove the old version.

Q.25: I have to make a change to the external interface of my application, and that change is certainly not backward compatible. My application is used by other OTP applications, and also by other applications using Erlang/OTP. How is an upgrade performed?

A: You have to have the permission of product management to introduce such a change.

An upgrade is specified as follows. All applications using your application through its external interface, have to state in their upgrade scripts that they depend on your application. Specifically, each updated module belonging to the other applications, has to have an update instruction with a dependency list containing the name of your external interface module, and all call-back modules of your application that are referenced from your interface module.

You must specify the dependency list in the release notes of your application.

Q.26 What is a code_change function and how it is used?

A: The code_change function is a call-back function in all gen_* behaviours. In a code_change function a process typically converts its state from the old to a new form compatible with the new code in case of an upgrade, and vice versa at downgrade. Furthermore, if applicable, it transforms storage formats and data base tables.

For examples of usage, see SASL User's Guide : Release Handling Examples.

Q.27 What do I have consider when transforming large tables in Mnesia?

A: Try to implement lazy transformation.

Q.28 What is a confic_change function?

A: When an application changes its configuration from one release to another, the config_change function is called. See application(3).

Q.29 I have a call-back module where I have defined handle_call/3 function. Should I have a last "catch all" clause? Example:

handle_call(Req, _From, State) ->
    %% Request not recognized
    {reply, {error, Req}, State}.
      

A: Yes. If you extend the protocol from one version to new version by adding a handle_call clause, then a downgrade from the new version to the previous version might result in that the old version does not recognize a protocol message that was formed just before the downgrade was done by a call to a client function in the new version.

Q.30: What do you mean my a `client function'?

A: In the example of Q.18 the name is a client function (and handle_call is a call-back function as defined in the gen_server behaviour).

Q.31:

A:


Copyright © 1991-1999 Ericsson Utvecklings AB
From bauerd@REDACTED Thu Dec 14 21:50:21 2000 From: bauerd@REDACTED (David W. Bauer Jr.) Date: Thu, 14 Dec 2000 15:50:21 -0500 (EST) Subject: Simulation with Erlang In-Reply-To: Message-ID: This may be blasphemous, but you are welcome to our TW code. I could even point you to the API documentation and help you to develop an application for the robot with it. What would be really interesting would be if you made an application in erlang, and used the engine in C. We could talk more about this if you like. This would give you rollback, GVT etc already done. You wouuld simply need to generate the events into the system. David ~~~ ~~ ~~~~ _o URL: http://www.david-bauer.com ~~~ ~~~~ ~~ _'|<,_ ~~~~ ~~~ ~~~~ (*)/ (*) On Thu, 14 Dec 2000, Vlad Dumitrescu wrote: #There were very interesting suggestions. I will think about it some more. #TimeWarp seems a bit too complicated, I'd like to try something simpler #first. # #I'd like to try to explain a little more what I am thinking about, and why #use Erlang. Hopefully someone might become interested, and I'd get some #help! :-) # #Imagine a robotics application, where the robot is not an usual one, but #composed out of many small identical blocks that can move on each other or #be locked onto each other, and they can communicate with their neighbours. #It's a kind of robotic amoeba :-) There are two kinds of software in the #system: a local OS per block, and a (hopefully distributed) high-level #control application. # #Because of the distributed nature, I think Erlang would be a perfect #platform. Since the cost of actually building this monster is prohibitive, #it would be a good way to start with a simulation. And why not use Erlang #for it too? # #Luckily, there are a lot of things that can be simplified in a simulation #(not the least, the communication because TCP/IP won't work and finding a #new network protocol is a big issue in itself; or maybe Bluetooth could be a #solution?). A GUI could show what's happening - and also serve as a perfect #marketing tool. # #That was a short description of my project. I've been thinking about it for #a long time now, but there is very little work done. It's the fate of #hoby-projects! :-) # #If anyone has ideas or suggestions, they are welcome! #regards, #Vlad #_____________________________________________________________________________________ #Get more from the Web. FREE MSN Explorer download : http://explorer.msn.com # # From mbj@REDACTED Fri Dec 15 08:32:16 2000 From: mbj@REDACTED (Martin Bjorklund) Date: Fri, 15 Dec 2000 08:32:16 +0100 Subject: Documentation/code inconsistency for gen_server? In-Reply-To: Your message of "Thu, 14 Dec 2000 18:41:24 +0100" <2000-12-14-18-41-24+trackit+sam@inf.enst.fr> References: <2000-12-14-18-41-24+trackit+sam@inf.enst.fr> Message-ID: <20001215083216M.mbj@bluetail.com> Samuel Tardieu wrote: > I was browsing through gen_server.erl while waiting for the end of an > endless compilation, and noticed this fragment of code: > > | handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod, Time) -> > | case catch apply(Mod, handle_call, [Msg, From, State]) of > | [...] > | {stop, Reason, Reply, NState} -> > | {'EXIT', R} = > | (catch terminate(Reason, Name, Msg, Mod, NState, [])), > | reply(From, Reply), > | exit(R); > | [...] > > Also, at another place: > > | handle_common_reply(Reply, Parent, Name, Msg, Mod, State, Debug) -> > | case Reply of > | [...] > | {stop, Reason, NState} -> > | terminate(Reason, Name, Msg, Mod, NState, Debug); > | [...] > > The doc (at least the man page) of gen_server says, concerning terminate: > > | The termination reason cannot be changed here. The > | server will terminate due toReason regardless of > | what was returned from this function. > > Does it mean the code is wrong? This may impact supervised processes, as > they may exit without an error even if {stop, Reason, State} is returned, > or with an unrelated error if {stop, Reason, Reply, State} is returned. No, I don't think the code is wrong. In both cases, the code calls gen_server:terminate/6, which always calls exit/1. In the first case, this exit is catched, to guarantee that a reply is sent, and then we exit with the same Reason. You could possibly argue that the doc is wrong, at leat it does not give the entire truth - the exit reason _can_ be chaneged, if Mod:terminate/2 itself calls exit/1. /martin From sam@REDACTED Fri Dec 15 10:08:30 2000 From: sam@REDACTED (Samuel Tardieu) Date: Fri, 15 Dec 2000 10:08:30 +0100 Subject: Documentation/code inconsistency for gen_server? In-Reply-To: <20001215083216M.mbj@bluetail.com>; from mbj@bluetail.com on Fri, Dec 15, 2000 at 08:32:16AM +0100 References: <2000-12-14-18-41-24+trackit+sam@inf.enst.fr> <20001215083216M.mbj@bluetail.com> Message-ID: <2000-12-15-10-08-30+trackit+sam@inf.enst.fr> On 15/12, Martin Bjorklund wrote: | You could possibly argue that the doc is wrong, at leat it does not | give the entire truth - the exit reason _can_ be chaneged, if | Mod:terminate/2 itself calls exit/1. Ok, so let's pretend that was my point :-))) *blush* From matthias@REDACTED Fri Dec 15 10:45:37 2000 From: matthias@REDACTED (matthias@REDACTED) Date: Fri, 15 Dec 2000 10:45:37 +0100 (CET) Subject: trouble building OTP R7B_1 In-Reply-To: References: <14904.60131.163542.378870@corelatus.com> Message-ID: <14905.59457.925279.575116@corelatus.com> > Are you sure the software installed there has not changed since > the R7B-0 build? It needed --without-ssl or ssl installed here to build > properly. I'm quite sure. I tried it out before posting, using a copy of R7B-0 from a CD I burnt before any patches existed. patch-R7B-0-005-ssl.diff.gz adds the ssl stuff, including the line in the README file which tells you to use --without-ssl; before that ssl isn't mentioned at all. Maybe you patched your R7B-0. Matthias From rv@REDACTED Fri Dec 15 11:54:08 2000 From: rv@REDACTED (Robert Virding) Date: Fri, 15 Dec 2000 11:54:08 +0100 Subject: Erlang not in this list! Message-ID: <200012151054.LAA14350@trana.bluetail.com> There is a Catalog of Free Compilers and Interpreters" at http:// www.idiom.com/free-compilers and to my horror I saw that Erlang is not included in this list. Somebody (else :-))should fix this! Robert From cahill@REDACTED Fri Dec 15 17:46:27 2000 From: cahill@REDACTED (cahill) Date: Fri, 15 Dec 2000 16:46:27 +0000 Subject: possible bug with erlang source + odbc Makefile Message-ID: <3A3A4AE3.70B4384D@ocean.ucc.ie> I downloaded the otp/erlang R7B-1, After running the ./configure --with-odbc=true --without-ssl make make install I found that it was not after installing the ODBC module at all. I tried this on a Linux i686 machine The error occurs in the lib/Makefile The following lines seem to be at fault: " ifeq ($(findstring sparc-sun-solaris,$(TARGET)),sparc-sun-solaris) OTHER_SUB_DIRECTORIES += odbc endif " This Condition statement is never satisfied. As a temporary solution i copied the line " OTHER_SUB_DIRECTORIES += odbc " outside the condtional statement, and the make successfully installed my odbc directory in the /lib/ I would like to thank Chandru, for helping me to resolve this bug.As i have been at this for days. Adrian From tony@REDACTED Sat Dec 16 00:16:21 2000 From: tony@REDACTED (Tony Rogvall) Date: Sat, 16 Dec 2000 00:16:21 +0100 Subject: Proper or well formed Lists References: <200012141128.MAA10191@trana.bluetail.com> Message-ID: <3A3AA645.1944FA7D@bluetail.com> Robert Virding wrote: > Francesco Cesarini writes: > >A well formed list follows the definition List = [Term|List] or []. Why > >where non proper (or well formed) lists (List = [Term|Term] ex: > >[hello|world]) allowed in the language in the first place? > > > >I am having a hard time seeing the need or intent with non well formed > >lists, other than a simplifying run-time evaluations and possibly the > >parsing. Wouldn't it have been better to have expressions not evaluating > >to a well formed list result in a run time error? > > The reason is mainly hereditary, the high-level languages we were used > to when we started developing Erlang were Lisp and Prolog and both these > languages allow this. Also the early versions of Erlang were Prolog > interpreters. We did have some discussion about this but did really > feel it important enough to warrant a change. > > Anyway think of the cool things you can do with it! Also think how > much more efficient cons is. :-) > > Robert I implemented a key-value dictionary on form [Key|Value] once :-) It is much more memory efficient. {Key,Value} is represented with three cells while [Key|Value] is represented with two, and [Key,Value] needs four cells! (Given that Key and Value are ground) The construct [a|b] even has a name, dotted pair (from lisp). /Tony -------------- next part -------------- A non-text attachment was scrubbed... Name: tony.vcf Type: text/x-vcard Size: 333 bytes Desc: Card for Tony Rogvall URL: From Pascal.Brisset@REDACTED Sat Dec 16 12:06:20 2000 From: Pascal.Brisset@REDACTED (Pascal Brisset) Date: Sat, 16 Dec 2000 12:06:20 +0100 Subject: Compiler bug in Erlang R7B-1 (bit syntax) Message-ID: <14907.19628.342363.333916@whynot.localdomain> A colleague of mine recently noticed the following problem with Erlang OTP R7B-1, compiler version 3.0.1.1. The following code: | -module(foo). | bar() -> case ok of ok -> X=0 end, <>. crashes the compiler with this error: | /home/pb/foo.erl:none: internal error in v3_codegen; | crash reason: {{case_clause,{'EXIT',{function_clause, | [{v3_codegen,fetch_reg,['X',[]]}, | {v3_codegen,'-saves/3-fun-0-',3}, | {lists,map,2}, | {v3_codegen,adjust_stack,4}, | {v3_codegen,match_cg,6}, | {v3_codegen,'-cg_list/5-fun-0-',3}, | {v3_codegen,flatmapfoldl,3}, | {v3_codegen,cg_list,5}| | more]}}}, | [{compile,'-select_passes/2-fun-2-',2}, | {compile,'-internal_comp/4-fun-1-',2}, | {compile,fold_comp,3}, | {compile,internal_comp,4}, | {compile,internal,3}]} I believe the problem is in v3_core.erl and can be corrected as follows: --- v3_core.erl.dist Sat Dec 16 11:39:06 2000 +++ v3_core.erl Sat Dec 16 11:47:05 2000 @@ -705,6 +705,8 @@ lit_vars(#c_var{name=V}, Vs) -> add_element(V, Vs); lit_vars(#c_cons{head=H,tail=T}, Vs) -> lit_vars(H, lit_vars(T, Vs)); +lit_vars(#c_bin{es=Es}, Vs) -> lit_list_vars(Es, Vs); +lit_vars(#c_bin_elem{val=V,size=S}, Vs) -> lit_vars(V, lit_vars(S, Vs)); lit_vars(#c_tuple{es=Es}, Vs) -> lit_list_vars(Es, Vs); lit_vars(Other, Vs) -> Vs. (I don't know whether #c_bin_elem.type should be scanned as well). -- Pascal Brisset From Xavier.Leroy@REDACTED Mon Dec 18 10:30:07 2000 From: Xavier.Leroy@REDACTED (Xavier Leroy) Date: Mon, 18 Dec 2000 10:30:07 +0100 Subject: call for papers ICFP 2001 Message-ID: <20001218103007.B32378@pauillac.inria.fr> ICFP 2001: Call for Papers ICFP 2001: International Conference on Functional Programming Firenze (Florence), Italy; 3-5 September 2001 associated with PLI 2001: Colloquium on Principles, Logics, and Implementations of High-Level Programming Languages Important dates: Submission deadline 15 March 2001, 18:00 UTC Notification of acceptance or rejection 11 May 2001 Final paper due 29 June 2001 Conference 3-5 September 2001 Scope: ICFP 2001 seeks original papers on the full spectrum of the art, science, and practice of functional programming. The conference invites submissions on all topics ranging from principles to practice, from foundations to features, and from abstraction to application. The scope covers all languages that encourage programming with functions, including both purely applicative and imperative languages, as well as languages that support objects and concurrency. Papers setting new directions in functional programming, or describing novel or exemplary applications of functional programming, are particularly encouraged. Topics of interest include, but are not limited to, the following: * Foundations: formal semantics, lambda calculus, type theory, monads, continuations, control, state, effects. * Design: modules and type systems, concurrency and distribution, components and composition, relations to object-oriented and logic programming, multiparadigm programming. * Implementation: abstract machines, compile-time and run-time optimization, just-in-time compilers, memory management, foreign-function and component interfaces. * Transformation and Analysis: abstract interpretation, partial evaluation, program transformation, theorem proving, specification and verification. * Applications: scientific and numerical computing, symbolic computing and artificial intelligence, systems programming, databases, graphic user interfaces, multimedia programming, web programming. * Experience: FP in education and industry, ramifications on other paradigms and computing disciplines. * Functional pearls: elegant, instructive examples of functional programming. Submission guidelines: Please refer to the submission Web site http://cristal.inria.fr/ICFP2001/ Program committee: General chair Program committee Benjamin Pierce Karl Crary, Carnegie Mellon University University of Pennsylvania Marc Feeley, University of Montr?al Giorgio Ghelli, University of Pisa Program chair Simon Peyton Jones, Microsoft Research John Hughes, Chalmers University Xavier Leroy Naoki Kobayashi, University of Tokyo INRIA Rocquencourt Julia Lawall, DIKU, U. Copenhagen Domaine de Voluceau, B.P. 105 Sheng Liang, Stratum8 78153 Le Chesnay, France John Reppy, Bell Labs, Lucent Technologies E-mail: Xavier.Leroy@REDACTED Scott Smith, John Hopkins University Fax: + 33 - 1 - 39 63 56 84 Carolyn Talcott, Stanford University Phone: + 33 - 1 - 39 63 55 61 Kwangkeun Yi, KAIST From ingvar.meyer@REDACTED Mon Dec 18 21:10:29 2000 From: ingvar.meyer@REDACTED (Ingvar) Date: Mon, 18 Dec 2000 14:10:29 -0600 Subject: erlang odbc Makefile Message-ID: <91l2be$jrv$1@news.du.uab.ericsson.se> Please have a look a the site: http://www.ericsson.se/cslab/~ingmey/ /Ingvar From luke@REDACTED Mon Dec 18 14:14:06 2000 From: luke@REDACTED (Luke Gorrie) Date: 18 Dec 2000 14:14:06 +0100 Subject: erlang odbc Makefile In-Reply-To: "Ingvar"'s message of "Mon, 18 Dec 2000 14:10:29 -0600" References: <91l2be$jrv$1@news.du.uab.ericsson.se> Message-ID: "Ingvar" writes: > Please have a look a the site: > http://www.ericsson.se/cslab/~ingmey/ The links are broken from here, but these work: http://www.ericsson.se/cslab/~ingmey/install_ODBC_unix.html http://www.ericsson.se/cslab/~ingmey/install_ODBC_windows.html Cheers, Luke From cahill@REDACTED Mon Dec 18 21:00:18 2000 From: cahill@REDACTED (cahill) Date: Mon, 18 Dec 2000 20:00:18 +0000 Subject: Missing Include Files Message-ID: <3A3E6CD1.D2D11F3@ocean.ucc.ie> Hi , I am trying to compile the Makefile in the /lib/odbc-0.8.2/src directory. It is missing some include file, or bunch of include files. I seem to have no include files in the /lib/odbc-0.8.2/include directory. This seems kind of odd. Can someone do a search of their include files which contain the following Constants: SQL_ALL_TABLE_TYPES SQL_SR_DELETE_TABLE SQL_SRJO_FULL_OUTER_JOIN The above are three of 1700 or so im missing. I have installed libiodbc and Myodbc. And i also have MySql installed. I ran the test in libiodbc which communictaes through MyODBC and connects to MySql , so for this reason i am assuming that is all fine. It appears to be the first line in the Makefile which is causing all the problems. It is trying to compile the 'C' file convert_macros.c .But this file isnt getting the imports needed. Has anyone encountered a similar problem, or can anyone send me their include files which contain the above Constants. Thanx in Advance Adrian From scott@REDACTED Mon Dec 18 22:02:33 2000 From: scott@REDACTED (Scott Lystig Fritchie) Date: Mon, 18 Dec 2000 15:02:33 -0600 Subject: Missing Include Files In-Reply-To: Message of "Mon, 18 Dec 2000 20:00:18 GMT." <3A3E6CD1.D2D11F3@ocean.ucc.ie> Message-ID: <200012182102.PAA70180@snookles.snookles.com> >>>>> "a" == cahill writes: a> Can someone do a search of their include files which contain the a> following Constants: SQL_ALL_TABLE_TYPES SQL_SR_DELETE_TABLE a> SQL_SRJO_FULL_OUTER_JOIN Although I'm not 100% certain, you'll find the header files defining those symbols in ODBC portion of the Microsoft SDK. They're also bundled with the unixODBC distribution. See http://www.unixodbc.org/. -Scott --- Scott Lystig Fritchie, Professional Governing: Is It Faked? From Jens.Peder.Terjesen@REDACTED Tue Dec 19 14:20:29 2000 From: Jens.Peder.Terjesen@REDACTED (Jens Peder Terjesen (ETO)) Date: Tue, 19 Dec 2000 14:20:29 +0100 Subject: mnemosyne:string_to_handle pb ! Message-ID: Hi. Is there an effective way to avoid queries when searching for unequality? Can the following query be rewritten? Q = query [ X || X <- table ( jabber_personne ), X.age/=22 ] end, mnesia:transaction(fun() -> mnemosyne:eval(Q) end). Jens -----Original Message----- From: Ulf Wiger [mailto:etxuwig@REDACTED] Sent: 13. desember 2000 12:19 To: Lecomte Jean Fran?ois Cc: erlang-questions@REDACTED Subject: Re: mnemosyne:string_to_handle pb ! I cannot help you with the exact problem, except to say that the following construct is _much_ more efficient: mnesia_transaction( fun() -> P = mnesia:table_info(jabber_personne, wild_pattern), mnesia:match_object(P#jabber_personne{age = 22}) end). Basically, mnemosyne should be avoided for all queries, unless you really need the cursor support, or you have very complex queries. /Uffe On Wed, 13 Dec 2000, Lecomte Jean Fran?ois wrote: >Hi, > >I do need to build a handle query using a string but when i tried to >use the mnemosyne string_to_handle it fails ! > >Following code > > Q = mnemosyne:string_to_handle( "query [ X || X <- table ( jabber_personne ), X.age=22 ] end. "), > mnesia:transaction(fun() -> mnemosyne:eval(Q) end). > >gives > >{aborted,{function_clause,[{mnemosyne,setup_query, > [{'EXIT', > {function_clause, > [{erl_parse, > normalise, > [{call, > 0, > {atom, > 0|...}, > [{tuple|...}]}]}, > {erl_parse,normalise_list,1}, > {erl_parse,normalise,1}, > {erl_parse,normalise_list,1}, > {erl_parse,normalise,1}, > {mnemosyne_lc, > '-one_lc_to_handle/1-fun-1-', > 2}, > {lists,foldl,3}, > {mnemosyne_lc, > one_lc_to_handle, > 1}| > more]}}]}, > {mnemosyne,cursor,2}, > {mnemosyne,eval,1}, > {mnesia_tm,apply_fun,2}, > {mnesia_tm,execute_transaction,4}, > {erl_eval,expr,3}, > {erl_eval,exprs,4}, > {shell,eval_loop,2}]}} > > > >but : > query [ X || X <- table ( jabber_personne ), X.age=22 ] end, > mnesia:transaction(fun() -> mnemosyne:eval(Q) end). > >works fine ! > >Any idea > > -- Ulf Wiger tfn: +46 8 719 81 95 Senior System Architect mob: +46 70 519 81 95 Strategic Product & System Management ATM Multiservice Networks Data Backbone & Optical Services Division Ericsson Telecom AB From mickael.remond@REDACTED Tue Dec 19 14:33:46 2000 From: mickael.remond@REDACTED (Mickael Remond) Date: 19 Dec 2000 14:33:46 +0100 Subject: Mnesia and Ericsson NDB Message-ID: <87n1ds4jt1.fsf@western.ird.idealx.com> I have read a few comments about Ericsson NDB (Network DataBase). Is there any relationship with Mnesia ? If not is Mnesia threaten by Ericsson commitment to NDB ? Thank you in advance for your answers. -- Micka?l R?mond - mickael.remond@REDACTED - http://IDEALX.com - +33 (1) 44 42 00 38 From petra@REDACTED Wed Dec 20 13:05:46 2000 From: petra@REDACTED (petra@REDACTED) Date: 20 Dec 2000 12:05:46 -0000 Subject: mnesia:transform_table Message-ID: <20001220120546.25305.qmail@www1.nameplanet.com> Hi! I have a problem when I try to do a mnesia:transform_table(Tab, Fun, NewAttributeList) -> {aborted, R} | {atomic, ok} In the fun I'm trying to doing a ets:lookup but it won't work, I get the message "Bad transform function" and lateron it says: "{badarg,{ets,lookup......." Can't you do a ets:lookup when your transforming mnesia? Does anyone know? Best regards, Petra Jansson -record(ets_record, {ets_key, ets_id}). -record(oldrecord, {key = 5, id = 6, newdata = 7}). init() -> Ets = ets:new(new_ets, []), ets:insert(Ets, #ets_record{ets_key = 1, ets_id = 99}), main(). main() -> Fun = fun({oldrecord, Key, Id}) -> #oldrecord{key = Key, id = Id, newdata = get_new_data()} end, Retur = mnesia:transform_table(oldrecord, Fun, record_info(fields, oldrecord)), io:format("Retur = ~p~n",[Retur]). get_new_data() -> Data = ets:lookup(ets_record, 1), io:format("Data = ~p~n", [Data]), Data. -- Get your firstname@REDACTED email for FREE at http://Nameplanet.com/?su From rv@REDACTED Wed Dec 20 14:57:37 2000 From: rv@REDACTED (Robert Virding) Date: Wed, 20 Dec 2000 14:57:37 +0100 Subject: Compiler bug in Erlang R7B-1 (bit syntax) In-Reply-To: Your message of "Sat, 16 Dec 2000 12:06:20 +0100." <14907.19628.342363.333916@whynot.localdomain> Message-ID: <200012201357.OAA19211@trana.bluetail.com> Pascal Brisset writes: >A colleague of mine recently noticed the following problem with Erlang >OTP R7B-1, compiler version 3.0.1.1. > >The following code: > >| -module(foo). >| bar() -> case ok of ok -> X=0 end, <>. > >crashes the compiler with this error: > ... > >I believe the problem is in v3_core.erl and can be corrected as follows: > >--- v3_core.erl.dist Sat Dec 16 11:39:06 2000 >+++ v3_core.erl Sat Dec 16 11:47:05 2000 >@@ -705,6 +705,8 @@ > > lit_vars(#c_var{name=V}, Vs) -> add_element(V, Vs); > lit_vars(#c_cons{head=H,tail=T}, Vs) -> lit_vars(H, lit_vars(T, Vs)); >+lit_vars(#c_bin{es=Es}, Vs) -> lit_list_vars(Es, Vs); >+lit_vars(#c_bin_elem{val=V,size=S}, Vs) -> lit_vars(V, lit_vars(S, Vs)); > lit_vars(#c_tuple{es=Es}, Vs) -> lit_list_vars(Es, Vs); > lit_vars(Other, Vs) -> Vs. > >(I don't know whether #c_bin_elem.type should be scanned as well). No, the fix is fine, there is no need to check anything but the val and size fields. Without the fix the compiler doesn't detect that X is used after the case, and, therefor, produces no code to export it. The patch will be in the next release. Robert From kahl@REDACTED Fri Dec 22 17:04:45 2000 From: kahl@REDACTED (Wolfram Kahl) Date: 22 Dec 2000 16:04:45 -0000 Subject: 2nd CFP: RelMiS 2001 Message-ID: <20001222160445.29431.qmail@heraklit.informatik.unibw-muenchen.de> [please post. apologies for multiple copies] SECOND CALL FOR PAPERS RelMiS 2001 - Relational Methods in Software ============================================ 7-8 April 2001, Genova, Italy http://ist.unibw-muenchen.de/RelMiS/ A Satellite Event to ETAPS 2001 Important Dates =============== Deadline for submission: 10 January 2001 Notification of acceptance: 9 February 2001 Final version due: 28 February 2001 Workshop dates: 7-8 April 2001 Workshop Topics =============== * Relational Specifications and Modelling: methods and tools, tabular methods, abstract data types * Relational Software Design and Development Techniques: relational refinement, heuristic approaches for derivation, correctness considerations, dynamic programming, greedy algorithms, catamorphisms, paramorphisms, hylomorphisms and related topics * Programming with Relations: prototyping, testing, fault tolerance, information systems, information coding * Implementing relational algebra with mixed representation of relations * Handling of Large Relations: problems of scale, innovative representations, distributed implementation Submissions =========== Submissions will be evaluated by the Program Committee for inclusion in the proceedings, which will be published in the ENTCS series. Papers must contain original contributions, be clearly written, and include appropriate reference to and comparison with related work. Papers should be submitted electronically as uuencoded PostScript files at the address relmis@REDACTED Preference will be given to papers that are no shorter than 10 and no longer than 15 pages. A separate message should also be sent, with a text-only one-page abstract and with mailing addresses (both postal and electronic), telephone number and fax number of the corresponding author. Final versions will have to be submitted as LaTeX source and have to adhere to the ENTCS style! Programme Committee =================== Rudolf Berghammer (Kiel), Jules Desharnais (Quebec), Wolfram Kahl (Munich), David L. Parnas (Hamilton), Gunther Schmidt (Munich) ------------- E-Mail: relmis@REDACTED Workshop home page: URL: http://ist.unibw-muenchen.de/RelMiS/ From mickael.remond@REDACTED Tue Dec 26 10:23:34 2000 From: mickael.remond@REDACTED (Mickael Remond) Date: 26 Dec 2000 10:23:34 +0100 Subject: Mnesia and Ericsson NDB Message-ID: <874rzrwn6x.fsf@western.ird.idealx.com> I repost this message as it does not seem to have reach the mailing list... I have read a few comments about Ericsson NDB (Network DataBase) and a lot of the database characteristics are already present in Mnesia (The only missing point might be: huge data volumes). Is there any relationship with Mnesia ? If not, is Mnesia threaten by Ericsson commitment to NDB ? Does someone know why Mnesia was not considered as a good basis for the NDB tool ? Thank you in advance for your answers. -- Micka?l R?mond - mickael.remond@REDACTED - http://IDEALX.com - +33 (1) 44 42 00 00 From bjarne@REDACTED Tue Dec 26 14:06:00 2000 From: bjarne@REDACTED (Bjarne =?iso-8859-1?Q?D=E4cker?=) Date: Tue, 26 Dec 2000 14:06:00 +0100 Subject: Mnesia and Ericsson NDB References: <874rzrwn6x.fsf@western.ird.idealx.com> Message-ID: <3A4897B8.370CF364@erix.ericsson.se> Hello > I have read a few comments about Ericsson NDB (Network DataBase) and a lot of > the database characteristics are already present in Mnesia (The only missing > point might be: huge data volumes). > > Is there any relationship with Mnesia ? No. It is a completely separate development starting from work on databases in the AXE 10 world. > If not, is Mnesia threaten by Ericsson commitment to NDB ? Does someone know > why Mnesia was not considered as a good basis for the NDB tool ? In a big company there are always lots of separate independent developments going on. Occasionally management jumps in and tries to coordinate and the effect is more like when a human mucks around with a stick in an ant-heap. The NDB development did not start by somebody trying to solve a database problem and then looked at different possible solutions. It started by somebody doing a PhD thesis in the database field and then got some innovation capital to try to market it. Merry Christmas and a Prosperous New Year to all Erlang fans ! Bjarne From bbergman@REDACTED Wed Dec 27 07:06:18 2000 From: bbergman@REDACTED (Brad Bergman) Date: Tue, 26 Dec 2000 22:06:18 -0800 (PST) Subject: Basic Mnesia Distribution Questions Message-ID: Hi, I'm trying to set up a simple distributed database with Mnesia for a project. I'm having trouble when I break the link between the nodes. Each seems to recognize that the other has stopped, but when I reestablish the link, neither node seems to recognize this. Both copies of the database continue to operate separately. I'd appreciate any basic advice on what I might be missing when setting this up. My Erlang skills are far from expert. Cheers, Brad _______________________ Brad Bergman University of BC Engineering Physics bbergman@REDACTED From sam@REDACTED Wed Dec 27 09:53:54 2000 From: sam@REDACTED (Samuel Tardieu) Date: Wed, 27 Dec 2000 09:53:54 +0100 Subject: Basic Mnesia Distribution Questions In-Reply-To: ; from bbergman@physics.ubc.ca on Tue, Dec 26, 2000 at 10:06:18PM -0800 References: Message-ID: <2000-12-27-09-53-54+trackit+sam@inf.enst.fr> On 26/12, Brad Bergman wrote: | I'm trying to set up a simple distributed database with Mnesia for a | project. I'm having trouble when I break the link between the nodes. Each | seems to recognize that the other has stopped, but when I reestablish the | link, neither node seems to recognize this. Both copies of the database | continue to operate separately. What do you mean by "reestablish the link"? If you mean "reestablish the network potential visibility of one node on the other one", then it is not enough. You have to use net_adm:ping/1 (or in fact any function that makes both nodes communicate) to have the nodes see (at the Erlang level) each other. From bbergman@REDACTED Thu Dec 28 04:07:52 2000 From: bbergman@REDACTED (Brad Bergman) Date: Wed, 27 Dec 2000 19:07:52 -0800 (PST) Subject: Basic Mnesia Distribution Questions In-Reply-To: Message-ID: > On 26/12, Brad Bergman wrote: > > | I'm trying to set up a simple distributed database with Mnesia for a > | project. I'm having trouble when I break the link between the nodes. Each > | seems to recognize that the other has stopped, but when I reestablish the > | link, neither node seems to recognize this. Both copies of the database > | continue to operate separately. > > What do you mean by "reestablish the link"? If you mean "reestablish the > network potential visibility of one node on the other one", then it is not > enough. You have to use net_adm:ping/1 (or in fact any function that makes > both nodes communicate) to have the nodes see (at the Erlang level) each other. > Thanks! Once this has occurred, though, I still find that the nodes are basically acting as if they were independent. I receive the inconsistent_database error message after the ping, but mnesia:info on both nodes indicates that the other node is stopped, and no updates are replicated. I have only been able to get mnesia working properly again by restarting erlang on one of the nodes, but I assume it must be possible to do it in a less disruptive way. I'm sure I'm just missing something. Thanks again, Brad From zoarre@REDACTED Thu Dec 28 06:12:49 2000 From: zoarre@REDACTED (Mike Roberts) Date: Wed, 27 Dec 2000 21:12:49 -0800 (PST) Subject: installing on winme? Message-ID: <20001228051249.9305.qmail@web2301.mail.yahoo.com> apologies for the bad post. :) first, erlang looks really cool. i bought the book and am reading up on it. has anyone else used erlang in a Win9x/Me environment? i try to install it and the install program freezes while copying (compiling?) the file mnemosyne_op.beam. i'm installing release R7B-0. i noticed in the archive that there's no intention to prepare a new release of R7B-1. is it likely for a novice to compile the new release with R7B-0 on windows (or perhaps in my case, R6B-0) if necessary? thanks in advance for any help. ===== Mike Roberts email __________________________________________________ Do You Yahoo!? Yahoo! Photos - Share your holiday photos online! http://photos.yahoo.com/ From Sean.Hinde@REDACTED Thu Dec 28 12:46:11 2000 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Thu, 28 Dec 2000 11:46:11 -0000 Subject: Basic Mnesia Distribution Questions Message-ID: <402DD461F109D411977E0008C791C3125654E0@imp02mbx.one2one.co.uk> Brad, > Thanks! Once this has occurred, though, I still find that the > nodes are > basically acting as if they were independent. I receive the > inconsistent_database error message after the ping, but mnesia:info on > both nodes indicates that the other node is stopped, and no > updates are > replicated. I have only been able to get mnesia working > properly again by > restarting erlang on one of the nodes, but I assume it must > be possible to > do it in a less disruptive way. I'm sure I'm just missing something. Welcome to the world of partitioned networks.. The problem is that neither node can know what updates have been carried out on the other node during the link outage. Given arbitrarily complex transactions it is very hard to imagine an algorithm which can work out what the combined resulting database should look like. Ericsson recommends exactly the procedure you followed - choose one of the nodes to be a master and restart the other. Depending on your application design this may or may not be disruptive (If you update and delete on both nodes during the outage you will lose some data..) Not many other solutions have even been proposed for this. There was one suggestion to do a regular checkpoint type activity - I'm not sure what happened to that. I also heard of someone who had an application which could be started before mnesia to detect the partitioned network and put the startup procedure on hold until the condition had gone away. There is also a command mnesia:set_master_nodes/1,2 which may be used to give more control over where table copies should be loaded from once the partitioned node has been restarted The eddie project (now on sourceforge.net) uses some clever scheme to automatically set master nodes and restart the other node(s) (it did last time I looked anyhow). There is a section in the mnesia user guide which explains partitioned networks quite well. I'm not aware that this problem has been solved for any available replicated database system like mnesia but if anyone knows better maybe they can share.. Solving this properly in the general case is utterly mind bending, but I have wondered whether one could come up with some scheme which logged updates/deletes locally and attempted to merge these by calling a user defined callback for each explicitly defined transaction/update type.. Thoughts? > Thanks again, > Brad > - 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 Fri Dec 29 06:17:18 2000 From: spearce@REDACTED (Shawn Pearce) Date: Fri, 29 Dec 2000 00:17:18 -0500 Subject: multi-attribute mnesia indexes? Message-ID: <20001229001718.G18405@spearce.org> We're working on an application that probably should be using Oracle. However, the dataset is small enough that we should be able to use mnesia (100,000 rows in a table). What we have run into is that we want to have 16 or so processes scanning the mnesia table, while another two are performing write transactions against it. First problem is that Mnesia is reporting its overloaded. The exact console message is: =ERROR REPORT==== 28-Dec-2000::23:55:46 === Mnesia('spearce@REDACTED'): ** ERROR ** Mnesia is overloaded: {dump_log, time_threshold} I dug in the archives and added these to my command line: -mnesia dump_log_load_regulation false \ -mnesia dump_log_write_threshold 100000 \ This cut back on the number of Mnesia error reports to one every few minutes, but they are still occuring. What the appliation is doing is, two generator processes are writing records into two mnesia tables, some 100,000 records at once. Both processes are running in a tight loop, kind of like what you see below: mk(0) -> done; mk(X) -> A = #foo{...}, B = #bar{...}, mnesia:transaction(fun() -> mnesia:write(A), mnesia:write(B) end), mk(X - 1). I started them by hand from the shell with: spawn(mymod, mk, [50000]). spawn(mymod, mk, [50000]). Rough calculation shows that mnesia is only doing 43 of these transactions per second with the system load such that it is. Now to add to the confusion, 16 other processes are running dirty_match_object operations against the tables at the same time the two generators are writing to them. One of the 16 processes reads only one column in an index, so we use dirty_index_read. The other 15 are busy with calls (many calls) to dirty_match_object. The pattern used is the wild pattern for the table (9 attributes), with 5 of the attributes filled in with a value. The other 4 were left alone. (To be wild cards.) None of these was the primary key (first attribute). Erlang uses 99% of the CPU to run this job. Right now, its up at 70 MB of RAM, as the tables are all disk_copies tables (so they are cached in RAM). Would switchig to disk_only tables help performance, getting rid of the cruft from RAM faster? My machine has 256 MB of RAM free, so swapping is not occuring at the OS level. So..... 1) What can I do differently to prevent mnesia from whining about its log files? 2) Is there anything I can do to increase the performance of my match operation? Would switching to mnemosyne help in this sitution? Does mnesia support multi-attribute indexes which would speed up the performance of the match_object operation? At present, my only other option is to switch to a real SQL database, as I can get true multi-column indexes there. -- Shawn. ``If this had been a real life, you would have received instructions on where to go and what to do.'' From voudheus@REDACTED Fri Dec 29 15:37:10 2000 From: voudheus@REDACTED (Karel Van Oudheusden) Date: Fri, 29 Dec 2000 15:37:10 +0100 Subject: multi-attribute mnesia indexes? References: <20001229001718.G18405@spearce.org> Message-ID: <3A4CA196.F9AA8B4E@imec.be> Hello, This mail does not contain an answer to your problems. However, since I am planning to do research on the topic you describe, I would appreciate it if you (or somebody else) would make your (or similar) source code publicly available. I am very keen on looking at it (and I will of course inform you of performance bottlenecks and optimizations). I am also interested in software projects in which large amounts of C code are used in combination with Erlang code. As a third remark, I would like to mention that the installation of Erlang R7B-1 on RedHat Linux 7.0 was successful. (My apologizes if this is not the right place to mention this). Greetings, Karel. Shawn Pearce wrote: > We're working on an application that probably should be using Oracle. > However, the dataset is small enough that we should be able to use > mnesia (100,000 rows in a table). What we have run into is that we > want to have 16 or so processes scanning the mnesia table, while another > two are performing write transactions against it. > > First problem is that Mnesia is reporting its overloaded. The exact > console message is: > > =ERROR REPORT==== 28-Dec-2000::23:55:46 === > Mnesia('spearce@REDACTED'): ** ERROR ** Mnesia is overloaded: {dump_log, time_threshold} > > I dug in the archives and added these to my command line: > > -mnesia dump_log_load_regulation false \ > -mnesia dump_log_write_threshold 100000 \ > > This cut back on the number of Mnesia error reports to one every few > minutes, but they are still occuring. > > What the appliation is doing is, two generator processes are writing > records into two mnesia tables, some 100,000 records at once. Both > processes are running in a tight loop, kind of like what you see below: > > mk(0) -> done; > mk(X) -> > A = #foo{...}, > B = #bar{...}, > mnesia:transaction(fun() -> > mnesia:write(A), > mnesia:write(B) > end), > mk(X - 1). > > I started them by hand from the shell with: > > spawn(mymod, mk, [50000]). > spawn(mymod, mk, [50000]). > > Rough calculation shows that mnesia is only doing 43 of these > transactions per second with the system load such that it is. > > Now to add to the confusion, 16 other processes are running > dirty_match_object operations against the tables at the same time the > two generators are writing to them. One of the 16 processes reads only > one column in an index, so we use dirty_index_read. The other 15 are > busy with calls (many calls) to dirty_match_object. The pattern used > is the wild pattern for the table (9 attributes), with 5 of the > attributes filled in with a value. The other 4 were left alone. (To > be wild cards.) None of these was the primary key (first attribute). > > Erlang uses 99% of the CPU to run this job. Right now, its up at 70 MB > of RAM, as the tables are all disk_copies tables (so they are cached > in RAM). Would switchig to disk_only tables help performance, getting > rid of the cruft from RAM faster? My machine has 256 MB of RAM free, > so swapping is not occuring at the OS level. > > So..... > > 1) What can I do differently to prevent mnesia from whining about its > log files? > > 2) Is there anything I can do to increase the performance of my match > operation? Would switching to mnemosyne help in this sitution? Does > mnesia support multi-attribute indexes which would speed up the > performance of the match_object operation? > > At present, my only other option is to switch to a real SQL database, > as I can get true multi-column indexes there. > > -- > Shawn. > > ``If this had been a real > life, you would have > received instructions > on where to go and what > to do.'' From mikl@REDACTED Sat Dec 30 16:33:24 2000 From: mikl@REDACTED (Mickael Remond) Date: 30 Dec 2000 16:33:24 +0100 Subject: float_to_list question Message-ID: <87wvchorej.fsf@louxor.home> I must be missing something but here is what I get from the float_to_list built-in function: 12> float_to_list(1.0). "1.00000000000000000000e+00" Ok. That seems nice. 13> float_to_list(1.1). "1.10000000000000008882e+00" Oh Oh. I was expecting: "1.10000000000000000000e+00" 14> float_to_list(1.2). "1.19999999999999995559e+00" Weird ! I was expecting: "1.20000000000000000000e+00" Can someone help me to understand this strange results ? -- Micka?l From mikl@REDACTED Sat Dec 30 17:19:42 2000 From: mikl@REDACTED (Mickael Remond) Date: 30 Dec 2000 17:19:42 +0100 Subject: Problem in finding the difference between string and list Message-ID: <87lmsxnaox.fsf@louxor.home> Hello, I have got some problems in testing the difference between string and list (In fact this is the same thing) to make an erlang interface to a string protocole. I must convert an Erlang structure to a specific syntax, explicitely showing the types... [{field1, "test"}, {field2, [12,13,14]}] should be converted to: [$field1=test(field2=@12@REDACTED@14)] knowing that $, @ and ( are expressing the type. What is the best way to work around this problem: - use of atom instead of string ? (But I have heard that they are not garbage collected) ? - use of binary type instead of string ? (Is there any problem with that ?) Thank you for your advice. -- Micka?l From bernardp@REDACTED Sat Dec 30 21:53:41 2000 From: bernardp@REDACTED (Pierpaolo BERNARDI) Date: Sat, 30 Dec 2000 21:53:41 +0100 (MET) Subject: float_to_list question In-Reply-To: <87wvchorej.fsf@louxor.home> Message-ID: On 30 Dec 2000, Mickael Remond wrote: > I must be missing something but here is what I get from the float_to_list > built-in function: ... > 13> float_to_list(1.1). > "1.10000000000000008882e+00" > > Oh Oh. I was expecting: > "1.10000000000000000000e+00" 1.1 and 1.2 are not representable with the standard floating point formats. The strings you get are (hopefully) the decimal representations of the floats closest to 1.1 and 1.2. P. From dne@REDACTED Sun Dec 31 01:07:49 2000 From: dne@REDACTED (Daniel Neri) Date: 31 Dec 2000 01:07:49 +0100 Subject: Problem in finding the difference between string and list In-Reply-To: Mickael Remond's message of "30 Dec 2000 17:19:42 +0100" References: <87lmsxnaox.fsf@louxor.home> Message-ID: <877l4hqwq2.fsf@nowhere.mayonnaise.net> Mickael Remond writes: > [{field1, "test"}, {field2, [12,13,14]}] should be converted to: You could add a "type tag" to resolve the ambiguities in the Erlang representation (assuming you invented that yourself): [{field1, {string,"test"}}, {field2, [12,13,14]}] > - use of binary type instead of string ? (Is there any problem with > that ?) None that I can think of. Regards, --Daniel -- Daniel Neri dne@REDACTED From kent@REDACTED Sun Dec 31 02:25:54 2000 From: kent@REDACTED (Kent Boortz) Date: 31 Dec 2000 02:25:54 +0100 Subject: float_to_list question In-Reply-To: Pierpaolo BERNARDI's message of "Sat, 30 Dec 2000 21:53:41 +0100 (MET)" References: Message-ID: > > I must be missing something but here is what I get from the float_to_list > > built-in function: > ... > > 13> float_to_list(1.1). > > "1.10000000000000008882e+00" > > > > Oh Oh. I was expecting: > > "1.10000000000000000000e+00" > > 1.1 and 1.2 are not representable with the standard floating point > formats. The strings you get are (hopefully) the decimal representations > of the floats closest to 1.1 and 1.2. Yes, this is true but we should maybe do better. We rely on the C call sprintf(buf, "%.20e", fp) to do the conversion. I think there are standard C libraries (glibc2?) that implement sprintf() to give shorter string representation with the same precision but many (most?) don't. There is an algorithm called "Dragon4" and there may be newer algorithms to print floats. kent Ref: "How to Print Floating-Point Numbers Accurately" by * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101]. http://www.kric.ac.kr:8080/pubs/articles/proceedings/pldi/93542/p112-steele/p112-steele.pdf http://rexx.hursley.ibm.com/decimal/decimal.htm http://www.codiciel.fr/netlib/ampl/solvers/dtoa.c Mozilla uses some code similar to this. http://rdf.mozilla.org/docs/refList/refNSPR/prdtoa.html http://puffin.external.hp.com/lxr/source/gcc/libio/floatconv.c SICStus Prolog has some code to print floats as short as possible. From kent@REDACTED Sun Dec 31 02:47:48 2000 From: kent@REDACTED (Kent Boortz) Date: 31 Dec 2000 02:47:48 +0100 Subject: float_to_list question In-Reply-To: Kent Boortz's message of "31 Dec 2000 02:25:54 +0100" References: Message-ID: Just forgot one reference, kent Ref: http://www.cs.indiana.edu/~dyb/papers/fpp-abstract.html http://riss.keris.or.kr:8080/pubs/articles/proceedings/pldi/231379/p108-burger/p108-burger.pdf http://tosca.cs.unict.it/~vs/LaP/haskell/haskell98-library-report/numeric.html From vances@REDACTED Sun Dec 31 06:47:33 2000 From: vances@REDACTED (Vance Shipley) Date: Sun, 31 Dec 2000 00:47:33 -0500 Subject: dbg_opt() Message-ID: Is it possible to turn on debugging after a process is started? If you pass the Options on startup to a generic behaviour it will create debug output: gen_fsm:start_link({local, testing}, foo, [], [{debug, [{log_to_file, "test.log"]}]) test.log: *DBG* testing got event 1 in state state2 *DBG* testing switched to state state1 *DBG* testing got event 2 in state state1 *DBG* testing switched to state state2 But if I don't specify any options at start up can I later turn debugging on? It seems I can not. :( -Vance -------------- next part -------------- A non-text attachment was scrubbed... Name: test.erl Type: application/octet-stream Size: 672 bytes Desc: not available URL: From mbj@REDACTED Sun Dec 31 13:57:11 2000 From: mbj@REDACTED (Martin Bjorklund) Date: Sun, 31 Dec 2000 13:57:11 +0100 Subject: dbg_opt() In-Reply-To: Your message of "Sun, 31 Dec 2000 00:47:33 -0500" References: Message-ID: <20001231135711W.mbj@bluetail.com> "Vance Shipley" wrote: > > Is it possible to turn on debugging after a process is > started? Yes, check the functions in the module 'sys', e.g. sys:log_to_file(). /martin From vladdu@REDACTED Sun Dec 31 15:07:16 2000 From: vladdu@REDACTED (Vlad Dumitrescu) Date: Sun, 31 Dec 2000 15:07:16 +0100 Subject: GS and GUIs Message-ID: A few questions before the year is over :-) I found a GUI builder for Tcl/Tk, named Visual Gipsy, and it's a lot easier to use it than write the GUI code by hand, test it, be dissapointed by the looks of the result, fix it, and so on... I think it would be nice if not only TclTk code would be produced, but also Erlang code, since gs and etk are both linked to Tk. Is there any tool to read a Tk GUI procedure and output the equivalent GS code? Or anything similar... Is it an interesting topic, or are most of you use mostly the command-line interface? I wish you a happy new year! Vlad _________________________________________________________________________ Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com. From vances@REDACTED Sun Dec 31 21:59:55 2000 From: vances@REDACTED (Vance Shipley) Date: Sun, 31 Dec 2000 15:59:55 -0500 Subject: GS and GUIs In-Reply-To: Message-ID: We started using etk as it appeared to be the successor to gs at the time. Neither gs nor etk seemed to be a really elegant approach to front ending our systems with a GUI. In the end the approach we took was to build a Tcl/Tk extension which links in the erl_interface library. With this approach the GUI is built entirely in standard Tcl/Tk and it uses message passing to interact with the Erlang processes. This allows us to use the latest versions of Tcl/Tk and it also means we can run the GUI on any system without the need to install Erlang/OTP. -Vance Motivity Telecom Inc.