From tpatro@REDACTED Mon Aug 1 07:49:29 2005 From: tpatro@REDACTED (Tamas Patrovics) Date: Mon, 1 Aug 2005 07:49:29 +0200 Subject: ESense 1.7 released In-Reply-To: References: Message-ID: Changes https://sourceforge.net/project/shownotes.php?group_id=139206&release_id=346133 Files https://sourceforge.net/projects/esense/ Homepage http://esense.sourceforge.net/ From bjorn@REDACTED Mon Aug 1 14:32:16 2005 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 01 Aug 2005 14:32:16 +0200 Subject: Meyer, OO and concurrency In-Reply-To: <200507180143.j6I1hYxX184022@atlas.otago.ac.nz> References: <200507180143.j6I1hYxX184022@atlas.otago.ac.nz> Message-ID: "Richard A. O'Keefe" writes: > Perhaps more interesting, the book provides NO PERFORMANCE GUARANTEES. > Nor can I find any discussion of performance in the on-line documentation > at www.erlang.se. For all we are told to the contrary, the process > dictionary might use linear search or worse. For example, in Prolog, > the 'recorded' data base only uses the principal functor of the key for > indexing, and if Erlang did the same, then using keys a..z would be > efficient but keys {a}..{z} would be inefficient. Nor are we advised > how much copying gets done. So we have *NO* idea how to use this > facility efficiently. > The process dictionary used to be implemented using linear search ON PURPOSE, to not encourage its use. > As far as I can tell from a quick scan of erl_process_dict.[ch], > process dictionaries are some kind of expanding hash table and hashing > depends on the whole key. They should be pretty good, BUT the fact > remains that this is not actually promised anywhere that I can find, > and there are still issues about copying. Some customer requested that we should make the process dictionary more efficient, and so we did. > > While I personally think that functional languages are better off without > assignment statements (unless 'tamed' by an effects system), you don't have > to agree with me about that to accept that the criticisms I have put forward > in this message show that the process dictionary, as currently defined, is > not as good an interface as it should have been, and is risky enough to > avoid unless you have a REALLY good reason to use it. > It is too late to change the interface, unfortunately. /Bjorn -- Bj?rn Gustavsson, Erlang/OTP, Ericsson AB From bjorn@REDACTED Mon Aug 1 14:45:04 2005 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 01 Aug 2005 14:45:04 +0200 Subject: Three wishes In-Reply-To: References: Message-ID: Roger Price writes: > Wish 1: No scope extrusion Too late to change. > > Wish 2: Block comments > > Some programming languages provide line comments, e.g. Erlang, TeX, > Scheme, whereas others provide block comments, e.g. ML, Haskell, SGML. > Both forms of comment have their uses, and I would like to be able to use > block comments as well as line comments in an Erlang program. I agree, I have also missed a block comment. > > Wish 3: ISO latin 9 > > If you are using the ISO latin 1 character set and can see the Euro > symbol, then you are not using ISO latin 1, but rather ISO latin 9 as > defined by ISO/IEC 8859-15 [1]. For example, on my Dell laptop the > following function call displays a Euro: > > 3> io:format ("~c~n", [$\244]) . > ? > ok > I don't see what this has to do with Erlang. What is shown is up to the operating system. Erlang does make some assumptions on what is visible characters and what is control character, and the compiler does some assumptions about upper and lower case letters. If Latin 1 and Latin 9 only matters in one character, it shouldn't be any concern for Erlang. /Bjorn -- Bj?rn Gustavsson, Erlang/OTP, Ericsson AB From alex.arnon@REDACTED Mon Aug 1 15:15:33 2005 From: alex.arnon@REDACTED (Alex Arnon) Date: Mon, 1 Aug 2005 16:15:33 +0300 Subject: Meyer, OO and concurrency In-Reply-To: References: <200507180143.j6I1hYxX184022@atlas.otago.ac.nz> Message-ID: <944da41d05080106151fced7c8@mail.gmail.com> On 01 Aug 2005 14:32:16 +0200, Bjorn Gustavsson wrote: > "Richard A. O'Keefe" writes: > > and there are still issues about copying. > > Some customer requested that we should make the process dictionary more > efficient, and so we did. > 1) I understood that the process dictionary is on-heap. So, what copying issues are there? 2) How is it implemented? Put another way, what performance impact will number of keys have? Cheers, Alex. From bjorn@REDACTED Mon Aug 1 15:16:51 2005 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 01 Aug 2005 15:16:51 +0200 Subject: ex11, plotting and Cairo ... In-Reply-To: References: Message-ID: "Vlad Dumitrescu" writes: > > One backend that is reasonably stable, reasonably portable and lends > itself to advanced graphics use is OpenGL. Esdl is a good start, just > look at Wings. The only drawback is that SDL only supports one > top-level window, but I know that Dan and the esdl team are working on > something. OpenGL is very low-level. We have a spent far too much time to implement windows, dialog boxes, menus, and even fonts on top of OpenGL. Also, some drivers on some platforms have bugs in basic OpenGL features (generally in features that games never use). Another drawback with SDL is that it is a game toolkit. On the Mac platform, a feature that Wings depends but generally not used in games are broken, forcing me to use an old version of SDL. /Bjorn -- Bj?rn Gustavsson, Erlang/OTP, Ericsson AB From bjorn@REDACTED Mon Aug 1 15:34:01 2005 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 01 Aug 2005 15:34:01 +0200 Subject: ERL_DRV_FLOAT ? In-Reply-To: <20050722172329.9E1A446DD6@bang.trapexit.org> References: <20050722172329.9E1A446DD6@bang.trapexit.org> Message-ID: None so far. Maybe R10B-7. /Bj?rn "joneksi" writes: > Which version of R10B? > > For some reason I started to make a cairo driver. And it does define the points as floats :( > > Jouni Ryn? > > > > bjorn at erix.ericsson.se wrote: > Probably an oversight, or that the implementor > thought that no one would ever want to pass back > floating point numbers from a driver. > > We'll probably add ERL_DRV_FLOAT in the R10B release. > > /Bjorn > > Mickael Remond writes: > > > Hello, > > > > I have working with edtk and erl_driver recently. I have seen that there > > is no ERL_DRV_FLOAT, to do float type transfer from C to Erlang, back > > and forth. > > > > I was wondering if there were any particular reason for that ? > > > > -- > > Micka?l R?mond > > http://www.erlang-projects.org/ > > > > -- > Bj?rn Gustavsson, Erlang/OTP, Ericsson AB > > > Post generated using Mail2Forum (http://m2f.sourceforge.net) > (end of quote) > > _________________________________________________________ > Sent using Mail2Forum (http://m2f.sourceforge.net) > -- Bj?rn Gustavsson, Erlang/OTP, Ericsson AB From hakan@REDACTED Mon Aug 1 15:50:48 2005 From: hakan@REDACTED (Hakan Mattsson) Date: Mon, 1 Aug 2005 15:50:48 +0200 (CEST) Subject: mnesia: inserting a large number of records In-Reply-To: <0e7901c593b6$23478db0$dc00a8c0@INSWITCH244> References: <003701c58ec1$68b8eff0$dc00a8c0@INSWITCH244> <20050727082402.GB81477@feeble.motivity.ca> <0e7901c593b6$23478db0$dc00a8c0@INSWITCH244> Message-ID: Sebastian, try mnesia:write_lock_table/1 first. It is simple to use and reduces the locking overhead substantially. I am attaching a simple test program, where the difference turned out to be almost a factor 50 with 10000 records a ~4000 bytes. But you should really measure on your own hardware with real data. Vance, did you try table locks? How much did you gain with your solution? /H?kan On Thu, 28 Jul 2005, Sebastian Bello wrote: SB> Date: Thu, 28 Jul 2005 17:51:29 -0300 SB> From: Sebastian Bello SB> To: erlang-questions@REDACTED SB> Subject: Re: mnesia: inserting a large number of records SB> SB> Vance, SB> SB> thank you very much for your response and your detailed description. The SB> solution looks a bit complicated to me, but I'll try some tests. SB> Thanks! SB> Sebastian- SB> SB> ----- Original Message ----- SB> From: "Vance Shipley" SB> To: "Sebastian Bello" SB> Cc: SB> Sent: Wednesday, July 27, 2005 5:24 AM SB> Subject: Re: mnesia: inserting a large number of records SB> SB> SB> > On Fri, Jul 22, 2005 at 10:29:36AM -0300, Sebastian Bello wrote: SB> > } SB> > } a programm reads records from a text file and inserts them in SB> > } a mnesia table. We are performing this insertions within a SB> > } transaction so in case of an error the whole file can be SB> > } reprocessed. The file holds approx. 5.000-10.000 records. SB> > } It seems the transaction time is not linear; I'm wondering if SB> > } there is a faster way to perform the insertions, maybe using SB> > } a table lock, I don't know. Any suggestions? SB> > SB> > Sebastian, SB> > SB> > I had a similiar challenge where we wanted to import large text SB> > files into a distributed mnesia database while it was in production. SB> > In our case we mostly needed to replace the existing copy so I SB> > came up with the following scheme: SB> > SB> > - create a new ram based table (e.g. foo_import) SB> > - use a write lock transaction fun with mnesia:ets/1 to SB> > insert records SB> > - use mnesia:change_table_copy_type/3 to change it to a SB> > disc based table on the local node only SB> > - activate a check point on this table table SB> > - backup this checkpoint using a custom mnesia_backup SB> > behaviour callback module to change the records on SB> > the fly to use the real table name (e.g. #foo_import{} SB> > to #foo{}). SB> > SB> > The idea is that you create the table in an ets context without SB> > lock overheads so that it is a fast operation (i.e. the user doesn't SB> > wait long) and then write it out to a binary backup file on disk. SB> > SB> > Now the user may use mnesia:restore/2 to replace the working SB> > table with the backup. You can do this while the system is running SB> > and transactions will block while it replaces the table. In our SB> > experience a couple seconds at worst. As I said we just replace SB> > the current table but you could just as easily insert the records SB> > into the existing table using the keep_tables option. I haven't SB> > tried this scheme so I can't say how it performs. For our purposes SB> > we changed the time it took to perform the import from many minutes, SB> > if not hours, to maybe twenty seconds. Aftet that as I said the SB> > table can be replaced in a couple seconds. SB> > SB> > -Vance -------------- next part -------------- -module(bulk). -compile(export_all). -record(t, {key, val}). go() -> Tab = t, Storage = disc_copies, Nodes = [node() | nodes()], N = 10000, Bulk = term_to_binary(lists:seq(1, 1000)), init(Tab, Storage, Nodes), io:format("Import ~p records a ~p bytes into ~p ~p\n", [N, size(Bulk), length(Nodes), Storage]), TabTime = run(Tab, N, Bulk, table), RecTime = run(Tab, N, Bulk, record), io:format("Table lock: ~p seconds\n", [TabTime / 1000000]), io:format("Record lock: ~p seconds\n", [RecTime / 1000000]), io:format("~p times improvement\n", [RecTime / TabTime]). run(Tab, N, Bulk, LockType) -> Fun = fun() -> case LockType of table -> mnesia:write_lock_table(Tab); record -> ignore end, import(N, Bulk), ok end, {atomic,ok} = mnesia:clear_table(Tab), {Time, {atomic,ok}} = timer:tc(mnesia, sync_transaction, [Fun]), Time. init(Tab, Storage, Nodes) -> rpc:multicall(Nodes, mnesia, stop, []), mnesia:delete_schema(Nodes), ok = mnesia:create_schema(Nodes), rpc:multicall(Nodes, mnesia, start, []), TabDef = [{Storage, Nodes}, {record_name, Tab}], {atomic,ok} = mnesia:create_table(Tab, TabDef). import(0, _Bulk) -> ok; import(N, Bulk) -> mnesia:write(t, #t{key = N, val = Bulk}, write), import(N - 1, Bulk). From bjorn@REDACTED Mon Aug 1 16:04:16 2005 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 01 Aug 2005 16:04:16 +0200 Subject: Meyer, OO and concurrency In-Reply-To: <944da41d05080106151fced7c8@mail.gmail.com> References: <200507180143.j6I1hYxX184022@atlas.otago.ac.nz> <944da41d05080106151fced7c8@mail.gmail.com> Message-ID: Alex Arnon writes: > On 01 Aug 2005 14:32:16 +0200, Bjorn Gustavsson wrote: > > "Richard A. O'Keefe" writes: > > > and there are still issues about copying. > > > > Some customer requested that we should make the process dictionary more > > efficient, and so we did. > > > > 1) I understood that the process dictionary is on-heap. So, what > copying issues are there? The keys and values are never copied, but there is some internal copying of cons cells when two or more keys hash to the same hash value. Copying is necessary to avoid creating references from the oldest generation heap to the youngest. > 2) How is it implemented? Put another way, what performance impact > will number of keys have? > 2a. It is a hash table. 2b. Not much. /Bj?rn -- Bj?rn Gustavsson, Erlang/OTP, Ericsson AB From alex.arnon@REDACTED Mon Aug 1 16:52:49 2005 From: alex.arnon@REDACTED (Alex Arnon) Date: Mon, 1 Aug 2005 17:52:49 +0300 Subject: Meyer, OO and concurrency In-Reply-To: References: <200507180143.j6I1hYxX184022@atlas.otago.ac.nz> <944da41d05080106151fced7c8@mail.gmail.com> Message-ID: <944da41d050801075216300e58@mail.gmail.com> On 01 Aug 2005 16:04:16 +0200, Bjorn Gustavsson wrote: > Alex Arnon writes: > > > On 01 Aug 2005 14:32:16 +0200, Bjorn Gustavsson wrote: > > > "Richard A. O'Keefe" writes: > > > > and there are still issues about copying. > > > > > > Some customer requested that we should make the process dictionary more > > > efficient, and so we did. > > > > > > > 1) I understood that the process dictionary is on-heap. So, what > > copying issues are there? > > The keys and values are never copied, but there is some internal copying of > cons cells when two or more keys hash to the same hash value. Copying is necessary > to avoid creating references from the oldest generation heap to the youngest. > > > 2) How is it implemented? Put another way, what performance impact > > will number of keys have? > > > > 2a. It is a hash table. 2b. Not much. > > /Bj?rn > > -- > Bj?rn Gustavsson, Erlang/OTP, Ericsson AB > Thank you. From bjarne@REDACTED Mon Aug 1 17:36:47 2005 From: bjarne@REDACTED (=?iso-8859-1?Q?Bjarne_D=E4cker?=) Date: Mon, 1 Aug 2005 17:36:47 +0200 Subject: Erlang workshop in Tallinn. Block reservations of hotels. Message-ID: <000c01c596ae$d4e3c520$710469d4@segeltorp> ----- Original Message ----- From: To: - - - - Cc: - - - Sent: Monday, August 01, 2005 5:27 PM Subject: TFP/ICFP/GPCE'05 block reservations of hotels Dear TFP/ICFP/GPCE registrant, Apologies, if you have already booked a hotel for yourself, in which case you can safely ignore this letter. We very strongly suggest that you make your hotel booking *** during this week (before Aug 5) ***. Our block reservations at various central hotels in Tallinn were originally valid until the early registration deadline of July 29. Unfortunately, some of these had been used very poorly, which means that very many of you must be without an individual reservation. We have now managed to extend our block reservations at Hotel Tallink, Meriton Grand Hotel Tallinn, Mihkli and Reval Express Hotell for very limited periods (until Aug 5 or 10 depending on the hotel). There are rooms available at all of those hotels at the moment and it would be a great pity to let the hard-to-find rooms and very favourable rates go wasted. These block reservations will not be extended further, as the hotels are in high demand and hence not interested in keeping reservations without guarantees indefinitely. Please therefore hurry with your reservations. After these four block reservations expire, you may find it *** very difficult and expensive *** to obtain a reservation at a hotel in the city center. We will not be able to help you with hotel bookings in any way whatsoever. All relevant information is available in the Accommodation section of the TFP/ICFP/GPCE local information pages at http://www.cs.ioc.ee/tfp-icfp-gpce05/ Yours sincerely, TFP/ICFP/GPCE'05 local organization --- Block reservation numbers / references: Hotel Tallink, 77194 Meriton Grand Hotel Tallinn, 41346 Mihkli, "TT? K?berneetika Instituut, 22.09." Reval Express Hotell, 360417 Please check the Accommodation section for further information and instructions. You MUST quote the reservation number / reference when requesting your room. From ke.han@REDACTED Mon Aug 1 18:01:15 2005 From: ke.han@REDACTED (ke.han) Date: Tue, 02 Aug 2005 00:01:15 +0800 Subject: Erlang REPOS 1.3 beta 1 In-Reply-To: <42EC819E.2030905@erlang-fr.org> References: <42EC819E.2030905@erlang-fr.org> Message-ID: <42EE474B.80204@redstarling.com> > > * Repos 1.3 is now based on Erlang/OTP R10B-6. Fantastic...I love what you're doing with REPOS!! I just downloaded the file, unpacked the iso, and tested out all your startup scripts with zero mods. Under Windows XP, everything worked perfect first time. thanks again...here's to hoping for more migration to REPOS and erlmerge. ke han From vances@REDACTED Mon Aug 1 20:11:21 2005 From: vances@REDACTED (Vance Shipley) Date: Mon, 1 Aug 2005 14:11:21 -0400 Subject: mnesia: inserting a large number of records In-Reply-To: References: <003701c58ec1$68b8eff0$dc00a8c0@INSWITCH244> <20050727082402.GB81477@feeble.motivity.ca> <0e7901c593b6$23478db0$dc00a8c0@INSWITCH244> Message-ID: <20050801181121.GB22823@blank.motivity.ca> On Mon, Aug 01, 2005 at 03:50:48PM +0200, Hakan Mattsson wrote: } } Vance, did you try table locks? How much did you gain } with your solution? I did not. The first part of my solution was to seperate the text file parsing out. That takes twenty seconds itself. I should have tried locking the table and then inserting the preprocessed data to see if that would have given acceptable performance. Our needs took me in a different direction however. For our use though we really wanted a facility to change the whole table quickly and easily. Each table is a complete related set of data. We swap out the table for a new version and if there is a problem we swap it back. We can maintain multiple versions of the table in backup files and change between them at will. Admittedly this is a different problem than Sebastian asked about. -Vance From ok@REDACTED Tue Aug 2 01:00:19 2005 From: ok@REDACTED (Richard A. O'Keefe) Date: Tue, 2 Aug 2005 11:00:19 +1200 (NZST) Subject: Meyer, OO and concurrency Message-ID: <200508012300.j71N0J2R296866@atlas.otago.ac.nz> I wrote: > > and there are still issues about copying. Alex Arnon wrote: 1) I understood that the process dictionary is on-heap. So, what copying issues are there? Remember, I was talking about the public interface and documentation. Nowhere in that documentation is it promised that "the process dictionary is on-heap". The issues about copying concern the fact that we don't *KNOW* whether/how much copying is done. For example, an entirely valid implementation of the process dictionary *interface* would involve a second process holding the data, with gets and puts done by sending messages to that other process. There is another issue as well: the efficient concurrent garbage collector for Erlang that was published relied on data in the heap not changing. But the process dictionary does change. So that has *some* effect on the structure and/or efficiency of the garbage collector. What/how much? We don't know. 2) How is it implemented? Read the source code and find out for yourself. That's what I did. My message even told you which file to look at. Put another way, what performance impact will number of keys have? As with all hash tables, it's unpredictable. It depends on what your keys are like and whether the hash function is good with them. There is no substitute for doing your own benchmarks. From mickael.remond@REDACTED Tue Aug 2 01:24:48 2005 From: mickael.remond@REDACTED (Mickael Remond) Date: Tue, 02 Aug 2005 01:24:48 +0200 Subject: ejabberd 0.9.8 Message-ID: <42EEAF40.9020004@erlang-fr.org> Hello, Just a quick notice to let you know that ejabberd, the Jabber/XMPP server written in Erlang has been released. More information on: http://www.process-one.net/en/projects/ejabberd/index.html Download is at: http://www.process-one.net/en/projects/ejabberd/download.html This release includes numerous improvments and is a good step toward version 1.0. Have fun ! -- Micka?l R?mond From kramer@REDACTED Tue Aug 2 07:23:01 2005 From: kramer@REDACTED (Reto Kramer) Date: Mon, 1 Aug 2005 22:23:01 -0700 Subject: Directory structure for non-OTP projects In-Reply-To: <42EAF10A.3030006@bates.id.au> References: <42DCE32F.9090604@bates.id.au> <42DCEF92.7080408@hyber.org> <42DF6BED.3000202@bates.id.au> <7a6679dcd096e0fd9a29686d8ad1b5cf@t-mobile.co.uk> <42E8BCAD.10803@bates.id.au> <42EAF10A.3030006@bates.id.au> Message-ID: <51C6B5E6-7A3A-46C9-BAC1-B0FCF78B38B9@acm.org> Tim, > Can someone who uses the test_server please describe how they have > their > development environment set up on their workstation? > I do use the test_server quite extensively for my development. The description below sound much worse than it is once you've set it all up ;-). Hang in there! > Where have you > installed erlang? > Regular 'make install' under /usr/local. > Where do you put your own code in relation to that? > I do _not_ put my code under the /usr/local/lib/erlang/lib. I keep it all under some ~/ directory that I use for projects. This caused me some trouble with the test_server initially (as I did not even want the test_server to be under /usr/local), but wanted the testserver to be "just another" application under ~/. You can put the test_server wherever you want. In that directory you'll need a full blown erlang install "just" for the purpose of the test_server install (i.e. do a ./configure && make there). Let's say you want the test_server under ~/foo/test_server. Install erlang under e.g. ~/foo/test_server/otp_src_10B-2 and untar the test_server src into ~/oo/test_server/otp_src_10B-2/lib/test_server. Then apply the change that the diff shows at the bottom of this message before you build the test_server as described below. Run the following script to "install" the test_server code to you project test directory. The argument to the script has to be you _absolute_ path (otherwise the build didn't work for me) to the test directory of your project. E.g. ./build_deploy /Users/reto/project/test build_deploy: #!/bin/bash cd ~/foo/test_server/otp_src_R10B-2 export ERL_TOP=`pwd` ./configure cd lib/test_server/ make release_tests TESTROOT=$1 This all has to be done only once to get your project to be in a position to use the test_server application. > What do you do each time you change your code during development? > I have a directory structure that includes project/src project/ebin project/test The project/test directory will contain a test_server directory that stems from the install you did further up. The actual test code (the stuff under source code control) for my project is checked in under project/test/project_test. This directory contains the test src (.erl files) as well as the beam files for simplicity. The project/test/project_test directory also contains two test_server control files: project.spec: {topcase, {dir, "../project_test"}}. % Test specification on top level project.cover: {include, [module_name_1, module_name_2]}. The .cover file lists all modules that should be included in the coverage analysis. To run tests, I invoke a Makefile from the project/test directory (should really do it from project/test/project_test to get rid of all the ..). Something like $ make build_tests when tests changed $ make run_tests when tests or product code changed build_tests: cd project_test; erlc -I ../test_server -W -o . *.erl; cd .. TEST_EBIN=../../ebin run_tests: cd test_server; erl -env TEST_EBIN ${TEST_EBIN} -s ts run all_tests verbose cover_details -s erlang halt; cd .. The TEST_EBIN directory is picked up by the test_server.erl patch at the bottom of this message. It's needed for the test_server to work with code that is not under a /usr/local/lib/erlang/lib sibling to the test_server standard place. So TEST_EBIN points at the project ebin, not the test code itself. The latter is found since it's in the current directory when the testserver is fired up (the test_server picks that up all right). Once you have all this in place, you can go trough cycles of - edit - compile project - make run_tests pretty quickly. The result is a browser window that pops up with the test results. A little heavyweight maybe, but on a reasonable laptop, I turn things around pretty quickly using the test_server. The coverage data is an integral part of the report - very sweet (nicer than JUnit and Emma since it's more tightly integrated). The test_server to me doesn't feel heavyweight. The install sucks though as you can see if you choose not to have it in the src erlang/ lib/test_server place and you choose not to have your projects under erlang/lib/project. cheers, - Reto ==== //depot/sdev/testserver/src/testserver/lib/test_server/src/ test_server.erl#2 (text) ==== 358a359,361 > % NOTE kramer@REDACTED 2004-Oct-12 -- testserver otherwise can > % only deal with applications/modules under the otp lib dir. > ok = code:add_pathsa(get_ebin_paths()), 1603a1607,1631 > > get_ebin_paths() -> > % colon separated path list > % e.g. erl -env TEST_EBIN 'a:b:c' ... > case os:getenv("TEST_EBIN") of > false -> > []; > Ebin -> > % FIXME kramer@REDACTED 2004-Sep-14 -- colon is UNIX sepcific. > % Note: use absolute pathnames throughout. > PathList = string:tokens(Ebin, ":"), > {ok,Cwd} = file:get_cwd(), > lists:foreach( > fun(P) -> > case filelib:is_dir(P) of > false -> > exit("One of the EBIN directories ("++ > P++") does not exist (cwd is "++ > Cwd++")"); > true -> > ok > end > end, PathList), > PathList > end. From erlang-list@REDACTED Tue Aug 2 11:29:41 2005 From: erlang-list@REDACTED (erlang-list@REDACTED) Date: Tue, 2 Aug 2005 11:29:41 +0200 (CEST) Subject: Directory structure for non-OTP projects In-Reply-To: <050C1486-2607-421B-9D6F-B82345261ADB@gmail.com> References: <42DCE32F.9090604@bates.id.au> <42DCEF92.7080408@hyber.org> <42DF6BED.3000202@bates.id.au> <7a6679dcd096e0fd9a29686d8ad1b5cf@t-mobile.co.uk> <42E8BCAD.10803@bates.id.au> <42EAF10A.3030006@bates.id.au> <050C1486-2607-421B-9D6F-B82345261ADB@gmail.com> Message-ID: <26516.212.155.207.253.1122974981.squirrel@212.155.207.253> Sean Hinde wrote: > Having said that, I think it would be quite > interesting to see how a lightweight unit test > framework would look for Erlang. It should be easy > enough for someone well versed in the whole junit > thing to put one together. I am working with some friends on this in my spare time. XP Dojo automatically compiles all erlang files in or below a given directory, then detects and runs unit tests and acceptance tests. You can run it as a continuous server, which detects new or modified files and automatically recompiles and reruns the tests. > If the test specs looked something like the ones used > to drive the test server then even better. Right now they are a lot simpler, but if there is an interest we could look at adding support for tests written for the OTP test_server. We'll make an announcement when we feel it's ready for public consumption. Regards, Dominic Williams http://www.xpdojo.net http://www.dominicwilliams.net ---- From mats.cronqvist@REDACTED Tue Aug 2 16:08:17 2005 From: mats.cronqvist@REDACTED (Mats Cronqvist) Date: Tue, 02 Aug 2005 16:08:17 +0200 Subject: looking for eperf and dtop In-Reply-To: <7b57b4f303fafb276dddba184fbbd240@acm.org> References: <7b57b4f303fafb276dddba184fbbd240@acm.org> Message-ID: <42EF7E51.2020705@ericsson.com> i've had major problems getting at Sourceforge through The Corporate Firewall, but i should be able to get the stuff out shortly (to jungerl). mats Reto Kramer wrote: > I'm looking for eperf and dtop, the two tools Mats Conqvist names in his > 2004 presentation on debugging "large scale Erlang applications". I've > tried OTP, jungerl, trapexit and google, but cannot find them. > > Can eperf and dtop be made available to the open source Erlang users (a > la pan in jungerl perhaps)? > > Thanks, > - Reto > From ke.han@REDACTED Tue Aug 2 16:56:30 2005 From: ke.han@REDACTED (ke.han) Date: Tue, 02 Aug 2005 22:56:30 +0800 Subject: looking for eperf and dtop In-Reply-To: <42EF7E51.2020705@ericsson.com> References: <7b57b4f303fafb276dddba184fbbd240@acm.org> <42EF7E51.2020705@ericsson.com> Message-ID: <42EF899E.5020107@redstarling.com> emerge 'em... please ;-) Mats Cronqvist wrote: > i've had major problems getting at Sourceforge through The Corporate > Firewall, but i should be able to get the stuff out shortly (to jungerl). > > mats > > Reto Kramer wrote: > >> I'm looking for eperf and dtop, the two tools Mats Conqvist names in >> his 2004 presentation on debugging "large scale Erlang applications". >> I've tried OTP, jungerl, trapexit and google, but cannot find them. >> >> Can eperf and dtop be made available to the open source Erlang users >> (a la pan in jungerl perhaps)? >> >> Thanks, >> - Reto >> From serge@REDACTED Tue Aug 2 23:15:10 2005 From: serge@REDACTED (Serge Aleynikov) Date: Tue, 02 Aug 2005 17:15:10 -0400 Subject: Job opening Message-ID: <42EFE25E.4000009@hq.idt.net> Folks, I have an R&D position available at IDT in USA, Newark, NJ for a Sr. Telecom Protocol Developer with extensive experience in SS7/ISUP/SIGTRAN/SCTP/TCP protocols, test tools (like INET Spectra), and concurrent programming under Linux OS using C/C++/Erlang. If you are interested or know someone interested, please email me the resume. Regards, -- Serge Aleynikov R&D Telecom, IDT Corp. Tel: (973) 438-3436 Fax: (973) 438-1464 serge@REDACTED From sean.hinde@REDACTED Wed Aug 3 00:09:30 2005 From: sean.hinde@REDACTED (Sean Hinde) Date: Tue, 2 Aug 2005 23:09:30 +0100 Subject: R10B-6 compiler bug Message-ID: <0B7DF8ED-840B-4262-81AA-09805742C904@gmail.com> Hi, Just came across this one: -module(compile_bug). -export([ test/1]). -record(a, {a,b,c}). test(As) -> case As of A when A#a.b == ""; A#a.b == undefined -> true; _ -> false end. 23> c(compile_bug). Function test/1 refers to undefined label 5 ./compile_bug.erl:none: internal error in beam_dead; crash reason: {{case_clause,{'EXIT',{undefined_label,5}}}, [{compile,'-select_passes/2-anonymous-2-',2}, {compile,'-internal_comp/4-anonymous-1-',2}, {compile,fold_comp,3}, {compile,internal_comp,4}, {compile,internal,3}]} error The error seems to occur in pass 'beam_bool' - skipping this pass avoids creating the error Another workaround is to use 'or' instead of ';' Sean From ingela@REDACTED Wed Aug 3 09:51:04 2005 From: ingela@REDACTED (Ingela Anderton) Date: Wed, 3 Aug 2005 09:51:04 +0200 Subject: looking for eperf and dtop Message-ID: <17136.30568.491891.644697@gargle.gargle.HOWL> I meant to point this out to everyone on the list, that might be interested. (the reply-to-all-keyboard-combination does however not seem to sit comfortable in my fingers ;)) -------------- next part -------------- An embedded message was scrubbed... From: Reto Kramer Subject: Re: looking for eperf and dtop Date: Tue, 2 Aug 2005 13:29:52 -0700 Size: 2814 URL: -------------- next part -------------- -- /Ingela - OTP team From bjorn@REDACTED Wed Aug 3 12:28:45 2005 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 03 Aug 2005 12:28:45 +0200 Subject: R10B-6 compiler bug In-Reply-To: <0B7DF8ED-840B-4262-81AA-09805742C904@gmail.com> References: <0B7DF8ED-840B-4262-81AA-09805742C904@gmail.com> Message-ID: Thanks! Corrected! (The correction will be included in R10B-7.) /Bj?rn Sean Hinde writes: > Hi, > > Just came across this one: > > -module(compile_bug). > -export([ test/1]). > > -record(a, {a,b,c}). > > test(As) -> > case As of > A when A#a.b == ""; A#a.b == undefined -> > true; > _ -> > false > end. > > 23> c(compile_bug). > Function test/1 refers to undefined label 5 > ./compile_bug.erl:none: internal error in beam_dead; > crash reason: {{case_clause,{'EXIT',{undefined_label,5}}}, > [{compile,'-select_passes/2-anonymous-2-',2}, > {compile,'-internal_comp/4-anonymous-1-',2}, > {compile,fold_comp,3}, > {compile,internal_comp,4}, > {compile,internal,3}]} > error > > The error seems to occur in pass 'beam_bool' - skipping this pass > avoids creating the error > > Another workaround is to use 'or' instead of ';' > > Sean > -- Bj?rn Gustavsson, Erlang/OTP, Ericsson AB From mpquique@REDACTED Wed Aug 3 13:28:34 2005 From: mpquique@REDACTED (Enrique Marcote =?iso-8859-1?q?Pe=F1a?=) Date: Wed, 3 Aug 2005 13:28:34 +0200 Subject: Bluetooth Message-ID: <200508031328.34498.mpquique@udc.es> Hello, We need to develop an erlang bluetooth library. Has some (open source) work already been done in that direction? Maybe the guys from BluePosition want to share :-) I'd also love to hear your comments and ideas for such a library. Since we plan to release it as an open source project, we'd like to do it the right way, so others can benefit. We'd like to know the recommended approach for this kind of developments. Thank you. Best regards, Quique From francesco@REDACTED Wed Aug 3 10:18:21 2005 From: francesco@REDACTED (Francesco Cesarini (Erlang Training & Consulting)) Date: Wed, 03 Aug 2005 09:18:21 +0100 Subject: SASL - duplicate alarms bug In-Reply-To: <42E90C3B.3060207@hq.idt.net> References: <42E90C3B.3060207@hq.idt.net> Message-ID: <42F07DCD.9070905@erlang-consulting.com> The SASL Alarm handler is a very simple handler, provided to allow users to get started quickly. Somewhere in the documentation (And in both our and Ericsson's OTP courses) users are encouraged to develop their own handler and replace it with a more complex one. Regards, Francesco -- http://www.erlang-consulting.com Serge Aleynikov wrote: > Is there a reason that the SASL's alarm handler doesn't check for > duplicate alarms before adding new ones to the list? > > If you do the following on the system with low disk space / free memory: > > 1. Start SASL > 2. Start OS_MON > 3. Stop OS_MON > 4. Start OS_MON > > you'll get duplicate alarms that are not easily clearled (you'd need to > call alarm_handler:clear_alarm() multiple times for the same AlarmID... > > 17> alarm_handler:get_alarms(). > [{system_memory_high_watermark,[]}, > {{disk_almost_full,"/mnt/cdrom"},[]}, > {{disk_almost_full,"/usr"},[]}, > {system_memory_high_watermark,[]}, > {{disk_almost_full,"/mnt/cdrom"},[]}, > {{disk_almost_full,"/usr"},[]}] > 18> alarm_handler:clear_alarm(system_memory_high_watermark). > [{{disk_almost_full,"/mnt/cdrom"},[]}, > {{disk_almost_full,"/usr"},[]}, > {system_memory_high_watermark,[]}, > {{disk_almost_full,"/mnt/cdrom"},[]}, > {{disk_almost_full,"/usr"},[]}] > > This looks like a bug to me. > > Serge > > From serge@REDACTED Wed Aug 3 14:34:24 2005 From: serge@REDACTED (Serge Aleynikov) Date: Wed, 03 Aug 2005 08:34:24 -0400 Subject: SASL - duplicate alarms bug In-Reply-To: <42F07DCD.9070905@erlang-consulting.com> References: <42E90C3B.3060207@hq.idt.net> <42F07DCD.9070905@erlang-consulting.com> Message-ID: <42F0B9D0.8020805@hq.idt.net> Would it be correct to assume then that barely anyone uses the SASL's alarm_hangler? If so, what's the reason for leaving it in the OTP, or otherwise, why don't make the basic functionality a bit more usable within the SASL framework? Serge Francesco Cesarini (Erlang Training & Consulting) wrote: > The SASL Alarm handler is a very simple handler, provided to allow users > to get started quickly. Somewhere in the documentation (And in both our > and Ericsson's OTP courses) users are encouraged to develop their own > handler and replace it with a more complex one. > > Regards, > Francesco > -- > http://www.erlang-consulting.com > > Serge Aleynikov wrote: > >> Is there a reason that the SASL's alarm handler doesn't check for >> duplicate alarms before adding new ones to the list? >> >> If you do the following on the system with low disk space / free memory: >> >> 1. Start SASL >> 2. Start OS_MON >> 3. Stop OS_MON >> 4. Start OS_MON >> >> you'll get duplicate alarms that are not easily clearled (you'd need >> to call alarm_handler:clear_alarm() multiple times for the same >> AlarmID... >> >> 17> alarm_handler:get_alarms(). >> [{system_memory_high_watermark,[]}, >> {{disk_almost_full,"/mnt/cdrom"},[]}, >> {{disk_almost_full,"/usr"},[]}, >> {system_memory_high_watermark,[]}, >> {{disk_almost_full,"/mnt/cdrom"},[]}, >> {{disk_almost_full,"/usr"},[]}] >> 18> alarm_handler:clear_alarm(system_memory_high_watermark). >> [{{disk_almost_full,"/mnt/cdrom"},[]}, >> {{disk_almost_full,"/usr"},[]}, >> {system_memory_high_watermark,[]}, >> {{disk_almost_full,"/mnt/cdrom"},[]}, >> {{disk_almost_full,"/usr"},[]}] >> >> This looks like a bug to me. >> >> Serge From sebastian@REDACTED Wed Aug 3 16:40:16 2005 From: sebastian@REDACTED (Sebastian Bello) Date: Wed, 3 Aug 2005 11:40:16 -0300 Subject: mnesia: inserting a large number of records References: <003701c58ec1$68b8eff0$dc00a8c0@INSWITCH244> <20050727082402.GB81477@feeble.motivity.ca> <0e7901c593b6$23478db0$dc00a8c0@INSWITCH244> <20050801181121.GB22823@blank.motivity.ca> Message-ID: <00d601c59839$44bd6d70$dc00a8c0@INSWITCH244> Hakan, Vance, I tried the approach you pointed out, with the following results: #records inserted Time (without table lock) Time (with table lock) 1000 0:36 0:20 2000 1:55 1:10 3000 4:20 2:45 4000 7:00 4:40 5000 11:00 7:15 6000 15:00 6:40 (this may be a mistake) 8000 24:00 11:30 10000 35:00 19:30 With a large number of records the table lock solution becomes more attractive. Despite this, the table lock locks all other interactions on the table, right? I'll have to evaluate if this is acceptable for my scenario. Thank you both, Sebastian- ----- Original Message ----- From: "Vance Shipley" To: "Hakan Mattsson" Cc: "Sebastian Bello" ; Sent: Monday, August 01, 2005 3:11 PM Subject: Re: mnesia: inserting a large number of records > On Mon, Aug 01, 2005 at 03:50:48PM +0200, Hakan Mattsson wrote: > } > } Vance, did you try table locks? How much did you gain > } with your solution? > > I did not. The first part of my solution was to seperate the > text file parsing out. That takes twenty seconds itself. > I should have tried locking the table and then inserting the > preprocessed data to see if that would have given acceptable > performance. Our needs took me in a different direction however. > > For our use though we really wanted a facility to change the > whole table quickly and easily. Each table is a complete related > set of data. We swap out the table for a new version and if there > is a problem we swap it back. We can maintain multiple versions > of the table in backup files and change between them at will. > Admittedly this is a different problem than Sebastian asked about. > > > -Vance > > > From chris@REDACTED Wed Aug 3 16:42:23 2005 From: chris@REDACTED (Christophe Romain) Date: Wed, 3 Aug 2005 16:42:23 +0200 Subject: Erlang REPOS 1.3 beta 1 In-Reply-To: <42EC819E.2030905@erlang-fr.org> References: <42EC819E.2030905@erlang-fr.org> Message-ID: Hello, I spent several hours with mickael to try to correct the following bug in REPOS without any succes: in MacOSX port, the mouse coordinate into the Wings3D window is inverted for the vertical axis. the bug is certainly into esdl. can anyone help please ? From hakan@REDACTED Wed Aug 3 16:54:02 2005 From: hakan@REDACTED (Hakan Mattsson) Date: Wed, 3 Aug 2005 16:54:02 +0200 (CEST) Subject: mnesia: inserting a large number of records In-Reply-To: <00d601c59839$44bd6d70$dc00a8c0@INSWITCH244> References: <003701c58ec1$68b8eff0$dc00a8c0@INSWITCH244> <20050727082402.GB81477@feeble.motivity.ca> <0e7901c593b6$23478db0$dc00a8c0@INSWITCH244> <20050801181121.GB22823@blank.motivity.ca> <00d601c59839$44bd6d70$dc00a8c0@INSWITCH244> Message-ID: On Wed, 3 Aug 2005, Sebastian Bello wrote: SB> Despite this, the table lock locks all other interactions on the table, Yes. You should avoid to perform file parsing and other time consuming stuff in the transaction. Another approach is to handle the concurrency issues explicitly in your application and use dirty access instead. Good luck. /H?kan From francesco@REDACTED Wed Aug 3 16:40:25 2005 From: francesco@REDACTED (Francesco Cesarini (Erlang Training & Consulting)) Date: Wed, 03 Aug 2005 15:40:25 +0100 Subject: SASL - duplicate alarms bug In-Reply-To: <42F0B9D0.8020805@hq.idt.net> References: <42E90C3B.3060207@hq.idt.net> <42F07DCD.9070905@erlang-consulting.com> <42F0B9D0.8020805@hq.idt.net> Message-ID: <42F0D759.8090301@erlang-consulting.com> There used to be an application called EVA, an Event and Alarm Handler, which is discontinued and not supported any more. I didn't like it as it was too tightly connected to SNMP. I assume others felt the same, as I rarely saw others use it. Francesco Serge Aleynikov wrote: > Would it be correct to assume then that barely anyone uses the SASL's > alarm_hangler? If so, what's the reason for leaving it in the OTP, or > otherwise, why don't make the basic functionality a bit more usable > within the SASL framework? > > Serge > > Francesco Cesarini (Erlang Training & Consulting) wrote: > >> The SASL Alarm handler is a very simple handler, provided to allow >> users to get started quickly. Somewhere in the documentation (And in >> both our and Ericsson's OTP courses) users are encouraged to develop >> their own handler and replace it with a more complex one. >> >> Regards, >> Francesco >> -- >> http://www.erlang-consulting.com >> >> Serge Aleynikov wrote: >> >>> Is there a reason that the SASL's alarm handler doesn't check for >>> duplicate alarms before adding new ones to the list? >>> >>> If you do the following on the system with low disk space / free memory: >>> >>> 1. Start SASL >>> 2. Start OS_MON >>> 3. Stop OS_MON >>> 4. Start OS_MON >>> >>> you'll get duplicate alarms that are not easily clearled (you'd need >>> to call alarm_handler:clear_alarm() multiple times for the same >>> AlarmID... >>> >>> 17> alarm_handler:get_alarms(). >>> [{system_memory_high_watermark,[]}, >>> {{disk_almost_full,"/mnt/cdrom"},[]}, >>> {{disk_almost_full,"/usr"},[]}, >>> {system_memory_high_watermark,[]}, >>> {{disk_almost_full,"/mnt/cdrom"},[]}, >>> {{disk_almost_full,"/usr"},[]}] >>> 18> alarm_handler:clear_alarm(system_memory_high_watermark). >>> [{{disk_almost_full,"/mnt/cdrom"},[]}, >>> {{disk_almost_full,"/usr"},[]}, >>> {system_memory_high_watermark,[]}, >>> {{disk_almost_full,"/mnt/cdrom"},[]}, >>> {{disk_almost_full,"/usr"},[]}] >>> >>> This looks like a bug to me. >>> >>> Serge > > > > From sebastian@REDACTED Wed Aug 3 18:21:59 2005 From: sebastian@REDACTED (Sebastian Bello) Date: Wed, 3 Aug 2005 13:21:59 -0300 Subject: Dumping a mnesia database in a standard format Message-ID: <014c01c59847$79ead420$dc00a8c0@INSWITCH244> Hi all, more mnesia questions. Does anybody know of a tool to dump a mnesia database to a file, but in a format suitable for loading it into a non-mnesia (relational) database? I know it shouldn't be hard to write such a tool, just wanna know is one already exists. Thanks, Sebastian- Prepaid Expertise - Programmable Switches Powered by Ericsson Licensed Technology Sebasti?n Bello - Engineer - Development Center - IN Switch Solutions Inc. Headquarters - Miami-U.S.A. Tel: 1305-3578076 Fax: 1305-7686260 Development Center - Montevideo - Uruguay Tel/Fax: 5982-7104457 IN SWITCH EMEA Phone: +33 0 6 0335 9427 - Fax: +33 0 4 93655773 / emea@REDACTED IN SWITCH ASIA Phone: +92 51 2800397/8- Fax: +92 51 2800399/ inswasia@REDACTED e-mail: sebastian@REDACTED -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image001.gif Type: image/gif Size: 1429 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: logoparafondo.gif Type: image/gif Size: 16886 bytes Desc: not available URL: From serge@REDACTED Wed Aug 3 18:44:51 2005 From: serge@REDACTED (Serge Aleynikov) Date: Wed, 03 Aug 2005 12:44:51 -0400 Subject: SASL - duplicate alarms bug In-Reply-To: <42F0D759.8090301@erlang-consulting.com> References: <42E90C3B.3060207@hq.idt.net> <42F07DCD.9070905@erlang-consulting.com> <42F0B9D0.8020805@hq.idt.net> <42F0D759.8090301@erlang-consulting.com> Message-ID: <42F0F483.9010808@hq.idt.net> Nevertheless, there is a leftover dependency - the OS_MON's mib references EVA's mib, and therefore I should say that if you want to take advantage of OS_MON's alarms & SNMP you need EVA until that dependency is removed. I ended up implementing functionality similar to the one in EVA where alarms can be mapped to SNMP traps, without EVA's overhead. I wonder how others use alarms without use of SNMP... Serge Francesco Cesarini (Erlang Training & Consulting) wrote: > There used to be an application called EVA, an Event and Alarm Handler, > which is discontinued and not supported any more. I didn't like it as it > was too tightly connected to SNMP. I assume others felt the same, as I > rarely saw others use it. > > Francesco > > > Serge Aleynikov wrote: > >> Would it be correct to assume then that barely anyone uses the SASL's >> alarm_hangler? If so, what's the reason for leaving it in the OTP, or >> otherwise, why don't make the basic functionality a bit more usable >> within the SASL framework? >> >> Serge >> >> Francesco Cesarini (Erlang Training & Consulting) wrote: >> >>> The SASL Alarm handler is a very simple handler, provided to allow >>> users to get started quickly. Somewhere in the documentation (And in >>> both our and Ericsson's OTP courses) users are encouraged to develop >>> their own handler and replace it with a more complex one. >>> >>> Regards, >>> Francesco >>> -- >>> http://www.erlang-consulting.com >>> >>> Serge Aleynikov wrote: >>> >>>> Is there a reason that the SASL's alarm handler doesn't check for >>>> duplicate alarms before adding new ones to the list? >>>> >>>> If you do the following on the system with low disk space / free >>>> memory: >>>> >>>> 1. Start SASL >>>> 2. Start OS_MON >>>> 3. Stop OS_MON >>>> 4. Start OS_MON >>>> >>>> you'll get duplicate alarms that are not easily clearled (you'd need >>>> to call alarm_handler:clear_alarm() multiple times for the same >>>> AlarmID... >>>> >>>> 17> alarm_handler:get_alarms(). >>>> [{system_memory_high_watermark,[]}, >>>> {{disk_almost_full,"/mnt/cdrom"},[]}, >>>> {{disk_almost_full,"/usr"},[]}, >>>> {system_memory_high_watermark,[]}, >>>> {{disk_almost_full,"/mnt/cdrom"},[]}, >>>> {{disk_almost_full,"/usr"},[]}] >>>> 18> alarm_handler:clear_alarm(system_memory_high_watermark). >>>> [{{disk_almost_full,"/mnt/cdrom"},[]}, >>>> {{disk_almost_full,"/usr"},[]}, >>>> {system_memory_high_watermark,[]}, >>>> {{disk_almost_full,"/mnt/cdrom"},[]}, >>>> {{disk_almost_full,"/usr"},[]}] >>>> >>>> This looks like a bug to me. >>>> >>>> Serge From serge@REDACTED Wed Aug 3 18:58:07 2005 From: serge@REDACTED (Serge Aleynikov) Date: Wed, 03 Aug 2005 12:58:07 -0400 Subject: SASL - duplicate alarms bug In-Reply-To: <42F0D759.8090301@erlang-consulting.com> References: <42E90C3B.3060207@hq.idt.net> <42F07DCD.9070905@erlang-consulting.com> <42F0B9D0.8020805@hq.idt.net> <42F0D759.8090301@erlang-consulting.com> Message-ID: <42F0F79F.40801@hq.idt.net> In case the OTP team feels like patching the SASL's alarm handler, here's a simple fix. Serge Francesco Cesarini (Erlang Training & Consulting) wrote: > There used to be an application called EVA, an Event and Alarm Handler, > which is discontinued and not supported any more. I didn't like it as it > was too tightly connected to SNMP. I assume others felt the same, as I > rarely saw others use it. > > Francesco > > > Serge Aleynikov wrote: > >> Would it be correct to assume then that barely anyone uses the SASL's >> alarm_hangler? If so, what's the reason for leaving it in the OTP, or >> otherwise, why don't make the basic functionality a bit more usable >> within the SASL framework? >> >> Serge >> >> Francesco Cesarini (Erlang Training & Consulting) wrote: >> >>> The SASL Alarm handler is a very simple handler, provided to allow >>> users to get started quickly. Somewhere in the documentation (And in >>> both our and Ericsson's OTP courses) users are encouraged to develop >>> their own handler and replace it with a more complex one. >>> >>> Regards, >>> Francesco >>> -- >>> http://www.erlang-consulting.com >>> >>> Serge Aleynikov wrote: >>> >>>> Is there a reason that the SASL's alarm handler doesn't check for >>>> duplicate alarms before adding new ones to the list? >>>> >>>> If you do the following on the system with low disk space / free >>>> memory: >>>> >>>> 1. Start SASL >>>> 2. Start OS_MON >>>> 3. Stop OS_MON >>>> 4. Start OS_MON >>>> >>>> you'll get duplicate alarms that are not easily clearled (you'd need >>>> to call alarm_handler:clear_alarm() multiple times for the same >>>> AlarmID... >>>> >>>> 17> alarm_handler:get_alarms(). >>>> [{system_memory_high_watermark,[]}, >>>> {{disk_almost_full,"/mnt/cdrom"},[]}, >>>> {{disk_almost_full,"/usr"},[]}, >>>> {system_memory_high_watermark,[]}, >>>> {{disk_almost_full,"/mnt/cdrom"},[]}, >>>> {{disk_almost_full,"/usr"},[]}] >>>> 18> alarm_handler:clear_alarm(system_memory_high_watermark). >>>> [{{disk_almost_full,"/mnt/cdrom"},[]}, >>>> {{disk_almost_full,"/usr"},[]}, >>>> {system_memory_high_watermark,[]}, >>>> {{disk_almost_full,"/mnt/cdrom"},[]}, >>>> {{disk_almost_full,"/usr"},[]}] >>>> >>>> This looks like a bug to me. >>>> >>>> Serge >> >> >> >> >> > > > -- Serge Aleynikov R&D Telecom, IDT Corp. Tel: (973) 438-3436 Fax: (973) 438-1464 serge@REDACTED -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: alarm_handler.erl.patch URL: From kramer@REDACTED Wed Aug 3 20:51:55 2005 From: kramer@REDACTED (Reto Kramer) Date: Wed, 3 Aug 2005 11:51:55 -0700 Subject: mailing list archives as mbox file(s) - on trapexit? Message-ID: <6DACEA5F-20E8-4FD1-B955-7399CA7455DC@acm.org> I'm old fashioned and like mailing list archives on my local mail client, so that I can search years of wisdom during my daily train rides. Many mailing lists make yearly or monthly mbox files available. Is there someone out there who could do that for the erlang-questions list? Perhaps in the process of spinning up trapexit, the files were used and are still around? Could they be linked onto trapexit somewhere? Thanks from a train rider, - Reto From sebastian@REDACTED Wed Aug 3 21:10:23 2005 From: sebastian@REDACTED (Sebastian Bello) Date: Wed, 3 Aug 2005 16:10:23 -0300 Subject: Simple text user interface question Message-ID: <02b701c5985f$013f06f0$dc00a8c0@INSWITCH244> Hi, I have to insert records in a database and would like to print the number inserted so far on a console. Is there an easy way (without using slang, etc) to print the number always on the same line, the new number overwriting the prior one (something like asking for a carriage return without a line feed)? Thanks, Sebastian- Prepaid Expertise - Programmable Switches Powered by Ericsson Licensed Technology Sebasti?n Bello - Engineer - Development Center - IN Switch Solutions Inc. Headquarters - Miami-U.S.A. Tel: 1305-3578076 Fax: 1305-7686260 Development Center - Montevideo - Uruguay Tel/Fax: 5982-7104457 IN SWITCH EMEA Phone: +33 0 6 0335 9427 - Fax: +33 0 4 93655773 / emea@REDACTED IN SWITCH ASIA Phone: +92 51 2800397/8- Fax: +92 51 2800399/ inswasia@REDACTED e-mail: sebastian@REDACTED -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image001.gif Type: image/gif Size: 1429 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: logoparafondo.gif Type: image/gif Size: 16886 bytes Desc: not available URL: From sebastian@REDACTED Wed Aug 3 22:03:16 2005 From: sebastian@REDACTED (Sebastian Bello) Date: Wed, 3 Aug 2005 17:03:16 -0300 Subject: mnesia query References: <033501c5887a$ea9ecaf0$3000a8c0@INSWITCH244> <035701c5888d$ed3cacb0$3000a8c0@INSWITCH244> <036501c58895$ac331260$3000a8c0@INSWITCH244> <002901c58ad3$2d2fff60$3000a8c0@INSWITCH244> <022801c58edf$5da6f080$dc00a8c0@INSWITCH244> Message-ID: <02df01c59866$639459c0$dc00a8c0@INSWITCH244> No ideas? Sebastian- ----- Original Message ----- From: "Sebastian Bello" To: Sent: Friday, July 22, 2005 2:04 PM Subject: Re: mnesia query > I've done some test with indexes and am a bit confused. > I've ran the same query using select, index_read and QLC and performance > seems to follow that same order(faster to slower). I noted that performance > depedends on the number of records associated to the value of the index > searched. There's surely something I'm missing here. My questions would be: > 1. shouldn't performance be better for index_read and QLC than select (since > an index is beeing used)? > 2. when using QLC, should indexes be used explicitly (or just write a normal > list comprehension query)? > 3. depending on 2, how can I use two indexes with QLC? > 4. just to be sure, should a search through two indexes be always faster > than using just one? > > I saw some old questions regarding this point, but didn't get a clear idea > about it. > Thanks, > Sebastian- > > ----- Original Message ----- > From: "Ulf Wiger" > To: "Sebastian Bello" ; > Sent: Sunday, July 17, 2005 11:19 AM > Subject: Re: mnesia query > > > > Den 2005-07-17 15:26:43 skrev Sebastian Bello : > > > > > But is it possible to use mnesia:index_match_object() with two indexes? > > > Sebastian- > > > > No. You specify exactly _one_ index that index_match_object() is to use. > > > > /Uffe > > > > > > > From pete-erlang-questions@REDACTED Thu Aug 4 00:15:12 2005 From: pete-erlang-questions@REDACTED (pete-erlang-questions@REDACTED) Date: Wed, 3 Aug 2005 18:15:12 -0400 Subject: Critique of solution to an exercise from the online course Message-ID: <20050803221512.GC30047@kazmier.com> [Disclaimer: I have no experience with functional programming, but I've been intrigued recently about Erlang (the poker server blog and the comparison of yaws to apache). I decided to investigate and printed some of the documentation which I read on vacation last week sitting by a pool. In other words, please be gentle.] I'm trying to learn Erlang and I'm doing some of the sample exercises from the online course (linked in the documentation section of the erlang.org site), but I was hoping someone might provide some feedback on my solution to one of the problems. Here is the question: 2) Write a function which starts N processes in a ring, and sends a message M times around all the processes in the ring. After the messages have been sent the processes should terminate gracefully. And here is my solution: -module(ring). -export([start/2, start/4, head/1, head/2, node/2]). start(NumProcesses, NumTokenPasses) -> HeadOfRing = spawn(ring, head, [NumTokenPasses]), start(NumProcesses - 1, NumTokenPasses, HeadOfRing, HeadOfRing). start(0, _NumTokenPasses, NextNode, HeadOfRing) -> %% After all of the processes have been spawned, send the head of %% the ring a message so that it can get a reference to its next %% node which was not known when it was spawned. HeadOfRing ! {next_node, NextNode}; start(NumProcesses, NumTokenPasses, NextNode, HeadOfRing) -> Pid = spawn(ring, node, [NumTokenPasses, NextNode]), start(NumProcesses - 1, NumTokenPasses, Pid, HeadOfRing). head(NumTokenPasses) -> receive {next_node, NextNode} -> %%io:format("~p HeadOfRing received START token~n", [self()]), head(NumTokenPasses, NextNode) end. head(0, _NextNode) -> %%io:format("~p HeadOfRing is exiting~n", [self()]), {done, head, self()}; head(NumTokenPasses, NextNode) -> %%io:format("~p HeadOfRing sending token~n", [self()]), NextNode ! token, receive token -> %%io:format("~p HeadOfRing received token~n", [self()]), head(NumTokenPasses - 1, NextNode) end. node(0, _NextNode) -> %%io:format("~p Node is exiting~n", [self()]), {done, self()}; node(NumTokenPasses, NextNode) -> receive token -> %%io:format("~p Node received token~n", [self()]), %%io:format("~p Node sending token~n", [self()]), NextNode ! token, node(NumTokenPasses - 1, NextNode) end. Aside from comments and suggestions, I'd also appreciate any ideas why my processes aren't exiting correctly. Things work for a while but then things fall apart on me. kaz@REDACTED:~/work/src/erlang$ erl Erlang (BEAM) emulator version 5.4.6 [source] [threads:0] Eshell V5.4.6 (abort with ^G) 1> ring:start(1000, 100). {next_node,<0.1031.0>} 2> length(processes()). 24 3> ring:start(1000, 10000). {next_node,<0.2033.0>} 4> length(processes()). 1024 5> Thanks for the help. Pete From md1matso@REDACTED Thu Aug 4 02:38:31 2005 From: md1matso@REDACTED (Mats-Ola Persson) Date: Thu, 4 Aug 2005 02:38:31 +0200 Subject: ex11, plotting and Cairo ... In-Reply-To: References: Message-ID: <590C5D9F-3931-4E31-BFE5-8456BFB7CE4D@mdstud.chalmers.se> 1 aug 2005 kl. 15.16 skrev Bjorn Gustavsson: > We have a spent far too much time to implement > windows, dialog boxes, menus, and even fonts on top of OpenGL. > Also, some > drivers on some platforms have bugs in basic OpenGL features > (generally in > features that games never use). > > Another drawback with SDL is that it is a game toolkit. On the Mac > platform, > a feature that Wings depends but generally not used in games are > broken, > forcing me to use an old version of SDL. Hi all, For the last couple of months I have, as part of my master thesis, made a prototype implementation of a binding to wxWidgets. Currently the project is really only a large collection of different hacks and very pre-alpha-ish. A few simple GUI apps have, however, been implemented, among others a re-implementation of etop. Screenshots can be found at http://www.mdstud.chalmers.se/~md1matso/ etop/ (running MacOSX) I will release the code soon hopefully. Probably, as my thesis comes to an end, perhaps earlier. The thesis *should* be completed sometime this month, I'm currently more than half through :) A quick word about the library: Unfortunately, the binding itself is VERY low-level and is more or less a translation of the C++ interface to Erlang. This is due to the fact that wxWidgets is very large. It would not be feasible to write all the wrappers and stuff by hand. Instead most of the code is generated directly from wxWidgets header files. I can say that Erlang's search for a nice GUI library does not end here, but hopefully one can use this library to build nice abstractions upon. Kenneth Lunding has asked me to present the project at the Erlang User Conference and if I can stand the heat, I will ;) /MO From vlad_dumitrescu@REDACTED Thu Aug 4 08:08:51 2005 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Thu, 4 Aug 2005 08:08:51 +0200 Subject: Simple text user interface question References: <02b701c5985f$013f06f0$dc00a8c0@INSWITCH244> Message-ID: >I have to insert records in a database and would like to print the number inserted so far on a console. Is >there an easy way (without using slang, etc) to print the number always on the same line, the new >number overwriting the prior one (something like asking for a carriage return without a line feed)? Hi, The short answer is "not in a portable way". The long answer is "you can hack something up, for your own machine and environment, but it's probably more work than it's worth". What's needed? Look up your terminal's capabilities, and use them from Erlang. I did once a small library that used ANSI codes to steer the cursor and put some colors on the screen. Worked nice, but of course the output will be jumbled-up on terminals with no ANSI support... regards, Vlad From hedeland@REDACTED Thu Aug 4 08:52:30 2005 From: hedeland@REDACTED (Per Hedeland) Date: Thu, 4 Aug 2005 08:52:30 +0200 (CEST) Subject: Simple text user interface question In-Reply-To: Message-ID: <200508040652.j746qUxB004869@tordmule.bluetail.com> "Vlad Dumitrescu" wrote: > >>I have to insert records in a database and would like to print the number >inserted so far on a console. Is >>there an easy way (without using slang, etc) to print the number always on >the same line, the new >>number overwriting the prior one (something like asking for a carriage >return without a line feed)? >The short answer is "not in a portable way". >The long answer is "you can hack something up, for your own machine and >environment, but it's probably more work than it's worth". Hm, well, for cursor positioning in general that may be true, and I'm sure there are *some* systems it would not work on, but for anything that faithfully displays the text it receives doing exactly the "something like" above works just fine - no ANSI support needed. I.e. try this with e.g. l(1,10): l(N,N) -> io:format("~n",[]), ok; l(M,N) -> io:format("\r~w ", [M]), receive after 1000 -> ok end, l(M+1,N). Will be a bit messy on a printing terminal, but should follow the spec there too...:-) --Per Hedeland From vlad.xx.dumitrescu@REDACTED Thu Aug 4 09:00:29 2005 From: vlad.xx.dumitrescu@REDACTED (Vlad Dumitrescu XX (LN/EAB)) Date: Thu, 4 Aug 2005 09:00:29 +0200 Subject: Simple text user interface question Message-ID: <11498CB7D3FCB54897058DE63BE3897C4BE5B4@esealmw105.eemea.ericsson.se> > Hm, well, for cursor positioning in general that may be true, and I'm > sure there are *some* systems it would not work on, but for anything > that faithfully displays the text it receives doing exactly the > "something like" above works just fine - no ANSI support needed. I.e. > try this with e.g. l(1,10): Good point! The trouble is that under Windows this works only in a text shell - not in werl.exe, and not in a shell opened in Emacs. /Vlad From bjorn@REDACTED Thu Aug 4 09:35:40 2005 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 04 Aug 2005 09:35:40 +0200 Subject: Erlang REPOS 1.3 beta 1 In-Reply-To: References: <42EC819E.2030905@erlang-fr.org> Message-ID: The bug is in SDL, not ESDL. The Wings distribution uses SDL-1.2.5, which is several releases old. /Bjorn Christophe Romain writes: > Hello, > > I spent several hours with mickael to try to correct the following bug > in REPOS without any succes: > in MacOSX port, the mouse coordinate into the Wings3D window is > inverted for the vertical axis. > the bug is certainly into esdl. > > can anyone help please ? > > -- Bj?rn Gustavsson, Erlang/OTP, Ericsson AB From hakan@REDACTED Thu Aug 4 09:59:22 2005 From: hakan@REDACTED (Hakan Mattsson) Date: Thu, 4 Aug 2005 09:59:22 +0200 (CEST) Subject: Dumping a mnesia database in a standard format In-Reply-To: <014c01c59847$79ead420$dc00a8c0@INSWITCH244> References: <014c01c59847$79ead420$dc00a8c0@INSWITCH244> Message-ID: On Wed, 3 Aug 2005, Sebastian Bello wrote: SB> more mnesia questions. Does anybody know of a tool to dump a SB> mnesia database to a file, but in a format suitable for loading it SB> into a non-mnesia (relational) database? I know it shouldn't be hard SB> to write such a tool, just wanna know is one already exists. Mnesia has no such support off the shelf. But you may write your own Mnesia backup callback module to handle any backup media or file format. For example you may use a simple text format with one record per row and the attributes separated with some unique character (e.g. tab). But you should probably limit your records to only contain data that are easily transformed to types that a RDBMS may represent. See http://erlang.se/doc/doc-5.4.8/lib/mnesia-4.2.2/doc/html/Mnesia_App_B.html#9 for details about the backup callback API. /H?kan From ulf@REDACTED Thu Aug 4 10:53:08 2005 From: ulf@REDACTED (Ulf Wiger) Date: Thu, 04 Aug 2005 10:53:08 +0200 Subject: Dumping a mnesia database in a standard format In-Reply-To: References: <014c01c59847$79ead420$dc00a8c0@INSWITCH244> Message-ID: Den 2005-08-04 09:59:22 skrev Hakan Mattsson : > On Wed, 3 Aug 2005, Sebastian Bello wrote: > > SB> more mnesia questions. Does anybody know of a tool to dump a > SB> mnesia database to a file, but in a format suitable for loading it > SB> into a non-mnesia (relational) database? I know it shouldn't be hard > SB> to write such a tool, just wanna know is one already exists. > > Mnesia has no such support off the shelf. > But you may write your own Mnesia backup > callback module to handle any backup media > or file format. > > For example you may use a simple text format > with one record per row and the attributes > separated with some unique character (e.g. tab). > But you should probably limit your records to > only contain data that are easily transformed > to types that a RDBMS may represent. Time to shamelessly plug one of my own contribs (again). One way to impose type limits on mnesia is to use rdbms (found in jungerl). It allows you to specify types for each attribute, and verifies that all records written conform to the specifications. It also has a generic data import module, into which you can plug in your own import formats (the one format supported is tab-delimited text with a header row, which is a fairly common format for e.g. mail merge). One could expand rdbms with an export tool as well, perhaps in a way that you can fairly easily specify import and export support at the same time for a new format. One could also imagine somehow extending the set of possible meta-data in rdbms to give better support for data export (i.e. specify how a data object should be represented externally.) /Uffe -- Ulf Wiger From serge@REDACTED Thu Aug 4 14:07:40 2005 From: serge@REDACTED (Serge Aleynikov) Date: Thu, 04 Aug 2005 08:07:40 -0400 Subject: emulator exit Message-ID: <42F2050C.3030201@hq.idt.net> I need to be able to set the exit code at completion of the emulator process, so that I can distinguish from the OS whether the emulator finished with reasons other than 'normal' or 'shutdown'. Is there a way to do that? erlang:halt(), init:stop(), etc. don't seem to have such an option. Thanks. Serge From sebastian@REDACTED Thu Aug 4 14:54:36 2005 From: sebastian@REDACTED (Sebastian Bello) Date: Thu, 4 Aug 2005 09:54:36 -0300 Subject: Simple text user interface question References: <11498CB7D3FCB54897058DE63BE3897C4BE5B4@esealmw105.eemea.ericsson.se> Message-ID: <002a01c598f3$ac0375f0$dc00a8c0@INSWITCH244> Vlad and Per, by the moment I'm not looking for a portable and elegant solution. I'm working on Windows and tried "\r" with werl.exe yesterday!! But the solution working in a text shell is enough. Thanks! One more question: I tried io:get_chars('Input key: ', 1) but it seems to wait for an ENTER and to cut the read characters to the specified length. I'm in fact looking for a way to read just N (in this case 1) keys from the keyboard, *without* waiting for an ENTER. Any ideas? Sebastian- ----- Original Message ----- From: "Vlad Dumitrescu XX (LN/EAB)" To: Sent: Thursday, August 04, 2005 4:00 AM Subject: RE: Simple text user interface question > > Hm, well, for cursor positioning in general that may be true, and I'm > > sure there are *some* systems it would not work on, but for anything > > that faithfully displays the text it receives doing exactly the > > "something like" above works just fine - no ANSI support needed. I.e. > > try this with e.g. l(1,10): > > Good point! The trouble is that under Windows this works only in a text shell - not in werl.exe, and not in a shell opened in Emacs. > > /Vlad > > From serge@REDACTED Thu Aug 4 15:42:41 2005 From: serge@REDACTED (Serge Aleynikov) Date: Thu, 04 Aug 2005 09:42:41 -0400 Subject: emulator exit In-Reply-To: <42F20E8F.2060103@mobilearts.se> References: <42F2050C.3030201@hq.idt.net> <42F20E8F.2060103@mobilearts.se> Message-ID: <42F21B51.5080902@hq.idt.net> Thanks, I seemed to have missed this one in the docs. Is the proper way of shutting down the emulator cleanly with an exit code the following? 1> F = fun(N) -> init:stop(), erlang:halt(N) end. #Fun 2> F(100). ~>echo $? 100 Is it guaranteed that the erlang:halt/1 call will be executed before the emulator exits as a result of the init:stop() call? Serge Rikard Johansson wrote: > > Actually there is a erlang:halt/1 which take the wanted exit code > (integer()) as argument. > > 1> erlang:halt(11). > [rikard@REDACTED rikard]$ echo $? > 11 > > Best regards, > > /Rikard > > Serge Aleynikov wrote: > >> I need to be able to set the exit code at completion of the emulator >> process, so that I can distinguish from the OS whether the emulator >> finished with reasons other than 'normal' or 'shutdown'. Is there a >> way to do that? >> >> erlang:halt(), init:stop(), etc. don't seem to have such an option. >> >> Thanks. >> >> Serge From ulf@REDACTED Thu Aug 4 22:53:07 2005 From: ulf@REDACTED (Ulf Wiger) Date: Thu, 04 Aug 2005 22:53:07 +0200 Subject: CUFP blurb lost in transmission? Message-ID: I've tried several times to post a registration call for the Commercial Users of Functional Programming workshop in Tallinn (the day before the Erlang workshop). It seems to get caught somewhere. Is there an aggressive spam filter weeding out dirty words like Scheme, Haskell, etc? http://www.galois.com/cufp/ Francesco Cesarini is one of the confirmed speakers, and I'm sure many of the discussions will be quite fun. Let's spice things up with some Erlang presence, shall we? If any mailing list administrator has a spam bucket from which the official message can be fetched, please, re-send it or whatever. Otherwise, all the necessary info can be had by following the link above. /Uffe (CUFP committee member) -- Ulf Wiger From kruegger@REDACTED Thu Aug 4 23:34:52 2005 From: kruegger@REDACTED (Stephen Han) Date: Thu, 4 Aug 2005 14:34:52 -0700 Subject: inet:getiflist() behaviour in Windows Message-ID: <86f1f53505080414342a0bf4@mail.gmail.com> Hi This is what I did in Linux (gentoo with kernel 2.6.10) 2> inet:getiflist(). {ok,["lo","eth0"]} And this what I did in Windows XP 5> inet:getiflist(). {ok,["240.802.170.641","100.0.0.721"]} Both of them running R10B-6. Is this work as designed or not? The function is public but documented. regards, From meena_selvam@REDACTED Fri Aug 5 01:20:22 2005 From: meena_selvam@REDACTED (MEENA SELVAM) Date: Thu, 4 Aug 2005 16:20:22 -0700 (PDT) Subject: where can i find more info on the apply BIF Message-ID: <20050804232023.91945.qmail@web30412.mail.mud.yahoo.com> where can i find more info on the apply BIF __________________________________ Do you Yahoo!? Yahoo! Mail - You care about security. So do we. http://promotions.yahoo.com/new_mail From meena_selvam@REDACTED Fri Aug 5 01:23:52 2005 From: meena_selvam@REDACTED (MEENA SELVAM) Date: Thu, 4 Aug 2005 16:23:52 -0700 (PDT) Subject: what happens if i apply a Fun on a empty list Message-ID: <20050804232353.25256.qmail@web30406.mail.mud.yahoo.com> Res = apply(Fun, []) What will be in Res? will it have the return value of function; or something is wrong with the above statement? meena __________________________________ Do you Yahoo!? Read only the mail you want - Yahoo! Mail SpamGuard. http://promotions.yahoo.com/new_mail From hakan.stenholm@REDACTED Fri Aug 5 01:55:30 2005 From: hakan.stenholm@REDACTED (=?ISO-8859-1?Q?H=E5kan_Stenholm?=) Date: Fri, 05 Aug 2005 01:55:30 +0200 Subject: what happens if i apply a Fun on a empty list In-Reply-To: <20050804232353.25256.qmail@web30406.mail.mud.yahoo.com> References: <20050804232353.25256.qmail@web30406.mail.mud.yahoo.com> Message-ID: <42F2AAF2.1080803@mbox304.swipnet.se> MEENA SELVAM wrote: >Res = apply(Fun, []) > >What will be in Res? will it have the return value of >function; > >or something is wrong with the above statement? > > > The above is ok and will contain the result of the call to "Fun()" call in Res, i.e. if the call is a call to a valid function things will look like below: %% call math:pi() 1> apply(fun math:pi/0, []). 3.14159 %% call lists:append([1,2,3],[4,5,6]) 2> apply(fun lists:append/2, [[1,2,3],[4,5,6]]). [1,2,3,4,5,6] If the call is to a non-existent function like in the example below ( lists:append() ), there will instead be a runtime execption. 3> apply(fun lists:append/2, []). =ERROR REPORT==== 5-Aug-2005::01:39:26 === Error in process <0.30.0> with exit value: {{badarity,{#Fun,[]}},[{erl_eval,do_apply,5},{shell,exprs,6},{shell,eval_loop,3}]} ** exited: {{badarity,{#Fun,[]}}, [{erl_eval,do_apply,5},{shell,exprs,6},{shell,eval_loop,3}]} ** Documentation about apply and funs is available in the "erlang" module documentation (http://erlang.se/doc/doc-5.4.8/lib/kernel-2.10.9/doc/html/erlang.html) and in the "Erlang Reference Manual" page chapter 6.17 (http://erlang.se/doc/doc-5.4.8/doc/reference_manual/expressions.html#6.17). There are also more info about funs in Programming Examples chapter 2 (http://erlang.se/doc/doc-5.4.8/doc/programming_examples/funs.html#2) >meena > > > >__________________________________ >Do you Yahoo!? >Read only the mail you want - Yahoo! Mail SpamGuard. >http://promotions.yahoo.com/new_mail > > > From ulf@REDACTED Fri Aug 5 02:04:38 2005 From: ulf@REDACTED (Ulf Wiger) Date: Fri, 05 Aug 2005 02:04:38 +0200 Subject: what happens if i apply a Fun on a empty list In-Reply-To: <20050804232353.25256.qmail@web30406.mail.mud.yahoo.com> References: <20050804232353.25256.qmail@web30406.mail.mud.yahoo.com> Message-ID: Den 2005-08-05 01:23:52 skrev MEENA SELVAM : > Res = apply(Fun, []) > > What will be in Res? will it have the return value of > function; > > or something is wrong with the above statement? > > meena Nothing like a little experimentation: Eshell V5.4.8 (abort with ^G) 1> apply(fun() -> foo end, []). foo 2> apply(fun(X) -> foo end, []). ** exited: {{badarity,{#Fun,[]}},[{erl_eval,expr,3}]} ** 3> What apply(Fun, []) means is "apply Fun()", i.e. with no arguments. If Fun is a function of arity 0, then it will work, otherwise not. /Uffe -- Ulf Wiger From ulf@REDACTED Fri Aug 5 02:10:14 2005 From: ulf@REDACTED (Ulf Wiger) Date: Fri, 05 Aug 2005 02:10:14 +0200 Subject: where can i find more info on the apply BIF In-Reply-To: <20050804232023.91945.qmail@web30412.mail.mud.yahoo.com> References: <20050804232023.91945.qmail@web30412.mail.mud.yahoo.com> Message-ID: Den 2005-08-05 01:20:22 skrev MEENA SELVAM : > where can i find more info on the apply BIF The BIFs are documented in erl -man erlang. The 'erlang' module contains the built-ins. It's a bit special: there is actually an erlang.erl file, but it doesn't contain nearly all of the code (most of the functions in the module erlang are implemented in C). The BIFs, and most of the basic operations supported in Erlang, can be called as erlang:BIF(...): 3> erlang:apply(erlang,send,[self(),hello]). hello 4> flush(). Shell got hello ok 5> erlang:'+'(3,4). 7 But as always, stick to the documented functions. ;-) /Uffe -- Ulf Wiger From meena_selvam@REDACTED Fri Aug 5 02:22:58 2005 From: meena_selvam@REDACTED (MEENA SELVAM) Date: Thu, 4 Aug 2005 17:22:58 -0700 (PDT) Subject: how do i repeat a func in a loop, while returning the func just before each iteration Message-ID: <20050805002258.99616.qmail@web30409.mail.mud.yahoo.com> In the below code, the return value of the entire function is some detail about sessions. Infact as part of this function call, the other function foo is called with different parameters each time.. some type of recursion is built in the function definition of nselect_cols. But leaving those details aside, I would like to know how I can repeat the function nselect_cols say 10 times, each time the PId parameter being changed to 1,2, 3,... upto 10. But I should be able to get the return value as before.(return value of snasSessionDetailTable is what function foo returns) snasSessionDetailTable(get_next, RowIndex, Cols) -> {atomic, Res} = reg:transaction( fun() -> case .... of {Op, [...] = Oid} -> .... ... nselect_cols(NCols, Oid, fun foo/2, {XId, SId, PId}, ?...., ?...), end_of_table -> end_of_table(Cols) end end), Res. When I try to write a seperate function as follows: do_for_all_ports(PId,NCols, Oid, XId, SId) when PId < 10 -> Res = nselect_cols(NCols, Oid, fun foo/2, {XId, SId, PId}, ?..., ?...), do_for_all_ports(PId+1,NCols, Oid, XId, SId). and call this instead, then the new code becomes: snasSessionDetailTable(get_next, RowIndex, Cols) -> {atomic, Res} = reg:transaction( fun() -> case .... of {Op, [...] = Oid} -> .... do_for_all_ports(1,NCols, Oid, XId, SId) end_of_table -> end_of_table(Cols) end end), Res. But the problem with this is, the function nselect_cols results in calling multiple calls to foo as before, when PId is 1; but before in the original code the output of these multiple calls to foo was the return value of the outer level SnasSessionDetailTable function.(expected behaviour). The moment I add the looping behaviour with the Pid parameter being incremented each time, the output of the calls to foo are no longer return values of the outer level SnasSessionDetailTable function. the return value becomes those corresponding to PId 10 only. How do i make it to return every time? PS: Just to add more info, the function foo has the format foo(colno,{XId, SId, PId}) and colno is nothing but NCols which is changed from 1 to some "n" due to recursion built within nselect_cols definition. meena __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From pete-erlang-questions@REDACTED Fri Aug 5 03:05:29 2005 From: pete-erlang-questions@REDACTED (pete-erlang-questions@REDACTED) Date: Thu, 4 Aug 2005 21:05:29 -0400 Subject: Critique of solution to an exercise from the online course In-Reply-To: <20050803221512.GC30047@kazmier.com> References: <20050803221512.GC30047@kazmier.com> Message-ID: <20050805010529.GA8555@kazmier.com> On Wed, Aug 03, 2005 at 06:15:12PM -0400, pete-erlang-questions@REDACTED wrote: > Aside from comments and suggestions, I'd also appreciate any ideas why > my processes aren't exiting correctly. Things work for a while but > then things fall apart on me. > > kaz@REDACTED:~/work/src/erlang$ erl > Erlang (BEAM) emulator version 5.4.6 [source] [threads:0] > > Eshell V5.4.6 (abort with ^G) > 1> ring:start(1000, 100). > {next_node,<0.1031.0>} > 2> length(processes()). > 24 > 3> ring:start(1000, 10000). > {next_node,<0.2033.0>} > 4> length(processes()). > 1024 > 5> I figured out why my processes were not "exiting". It just turned out that they hadn't finished running. Doh! I should have left the print statement when the head of the ring received the token back and exited. I'd still be interested in any feedback on the code as I'd like to make sure I'm doing things the "right way". Thanks, Pete From valentin@REDACTED Fri Aug 5 08:12:45 2005 From: valentin@REDACTED (Valentin Micic) Date: Fri, 5 Aug 2005 08:12:45 +0200 Subject: ONC/RPC Message-ID: <005601c59984$b2d7b120$0100a8c0@MONEYMAKER2> Hello, Anybody out there with a direct experience (positive or negative) in using user contribution rpc-1.1? So far I've been using C/C++ based RPC client that sources traffic requests from ERLANG run-time, but would really like to move the whole thing to ERLANG at some stage. Is there any reason why I should not do it? V. From gunilla@REDACTED Fri Aug 5 08:24:57 2005 From: gunilla@REDACTED (Gunilla Arendt) Date: Fri, 05 Aug 2005 08:24:57 +0200 Subject: Critique of solution to an exercise from the online course In-Reply-To: <20050803221512.GC30047@kazmier.com> References: <20050803221512.GC30047@kazmier.com> Message-ID: <42F30639.7080404@erix.ericsson.se> Hi Pete! The code looks fine to me! My only comment is that only start/2 (to be called from the shell) and head/1 and node/2 (used in spawn/3 calls) need to be exported, the other functions IMO are internal. If you would like to practice some more, you could consider that actually all processes in the ring have an almost identical behavior. That is, you don't have to distinguish between the head process and the rest of the processes, which means even less code is needed. (Hint: let each process start the next process in the ring.) Good luck! / Gunilla pete-erlang-questions@REDACTED wrote: > [Disclaimer: I have no experience with functional programming, but > I've been intrigued recently about Erlang (the poker server blog and > the comparison of yaws to apache). I decided to investigate and > printed some of the documentation which I read on vacation last week > sitting by a pool. In other words, please be gentle.] > > I'm trying to learn Erlang and I'm doing some of the sample exercises > from the online course (linked in the documentation section of the > erlang.org site), but I was hoping someone might provide some feedback > on my solution to one of the problems. > > Here is the question: > > 2) Write a function which starts N processes in a ring, and sends a > message M times around all the processes in the ring. After the > messages have been sent the processes should terminate gracefully. > > And here is my solution: > > -module(ring). > -export([start/2, start/4, head/1, head/2, node/2]). > > start(NumProcesses, NumTokenPasses) -> > HeadOfRing = spawn(ring, head, [NumTokenPasses]), > start(NumProcesses - 1, NumTokenPasses, HeadOfRing, HeadOfRing). > > start(0, _NumTokenPasses, NextNode, HeadOfRing) -> > %% After all of the processes have been spawned, send the head of > %% the ring a message so that it can get a reference to its next > %% node which was not known when it was spawned. > HeadOfRing ! {next_node, NextNode}; > > start(NumProcesses, NumTokenPasses, NextNode, HeadOfRing) -> > Pid = spawn(ring, node, [NumTokenPasses, NextNode]), > start(NumProcesses - 1, NumTokenPasses, Pid, HeadOfRing). > > head(NumTokenPasses) -> > receive > {next_node, NextNode} -> > %%io:format("~p HeadOfRing received START token~n", [self()]), > head(NumTokenPasses, NextNode) > end. > > head(0, _NextNode) -> > %%io:format("~p HeadOfRing is exiting~n", [self()]), > {done, head, self()}; > > head(NumTokenPasses, NextNode) -> > %%io:format("~p HeadOfRing sending token~n", [self()]), > NextNode ! token, > receive > token -> > %%io:format("~p HeadOfRing received token~n", [self()]), > head(NumTokenPasses - 1, NextNode) > end. > > node(0, _NextNode) -> > %%io:format("~p Node is exiting~n", [self()]), > {done, self()}; > > node(NumTokenPasses, NextNode) -> > receive > token -> > %%io:format("~p Node received token~n", [self()]), > %%io:format("~p Node sending token~n", [self()]), > NextNode ! token, > node(NumTokenPasses - 1, NextNode) > end. > > Aside from comments and suggestions, I'd also appreciate any ideas why > my processes aren't exiting correctly. Things work for a while but > then things fall apart on me. > > kaz@REDACTED:~/work/src/erlang$ erl > Erlang (BEAM) emulator version 5.4.6 [source] [threads:0] > > Eshell V5.4.6 (abort with ^G) > 1> ring:start(1000, 100). > {next_node,<0.1031.0>} > 2> length(processes()). > 24 > 3> ring:start(1000, 10000). > {next_node,<0.2033.0>} > 4> length(processes()). > 1024 > 5> > > > Thanks for the help. > > Pete > > -- _____Gunilla Arendt______________________________________________ OTP Development Gunilla.Arendt@REDACTED +46-8-7275730 ecn 851 5730 From ulf@REDACTED Fri Aug 5 09:39:49 2005 From: ulf@REDACTED (Ulf Wiger) Date: Fri, 05 Aug 2005 09:39:49 +0200 Subject: how do i repeat a func in a loop, while returning the func just before each iteration In-Reply-To: <20050805002258.99616.qmail@web30409.mail.mud.yahoo.com> References: <20050805002258.99616.qmail@web30409.mail.mud.yahoo.com> Message-ID: Den 2005-08-05 02:22:58 skrev MEENA SELVAM : > I would like to know how I can repeat the function > nselect_cols say 10 times, each time the PId parameter > being changed to 1,2, 3,... upto 10. But I should be > able to get the return value as before.(return value > of snasSessionDetailTable is what function foo > returns) There are some nice functions that operate on lists. You can use some of those. Just to get you thinking, I can suggest the following way to "loop" and collect values: Iters = lists:seq(1,10), % -> [1,2,3,4,5,6,7,8,9,10] [foo(...) || I <- Iters]. lists:foldl( fun(Iter, Acc) -> _NewAcc = case ... of ... -> ...; ... end end, InitialAcc, Iters). I wouldn't worry too much about creating a list rather than using a loop counter, but if your program is really that performance-critical, you can write your own iterator function in order to skip this step. It's a good idea to adhere to the pattern of map and fold. /Uffe -- Ulf Wiger From ulf.wiger@REDACTED Tue Aug 2 17:23:51 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Tue, 2 Aug 2005 17:23:51 +0200 Subject: registration for CUFP 2005 Message-ID: Erlangers, The day before the Erlang Workshop in Tallinn, you have a chance to attend the Commercial Users of Functional Programming (CUFP) workshop. Last year, there was no Erlang representation at the workshop, which was otherwise viewed as a success. This year, some Erlangers will attend, and you can add Francesco Cesarini to the list of confirmed speakers below. There will also be a discussion on stimulating a CUFP community. Perhaps the current Erlang Community initiative could serve as fuel to the fire? Regards, Ulf Wiger (CUFP committee member) - - - - - - - - - - - - - - - - - - - - - - - - - - IMPORTANT NOTE: Registration is now available at: http://www.cs.ioc.ee/tfp-icfp-gpce05 CUFP 2005 THE SECOND ACM SIGPLAN COMMERCIAL USERS OF FUNCTIONAL PROGRAMMING WORKSHOP http://www.galois.com/cufp/ Talinn, Estonia September 24th 2005 Co-located with ICFP http://www.brics.dk/~danvy/icfp05/ ---------------------------------------------------------------------- Important dates Early registration deadline July 29, 2005 Late registration deadline September 2, 2005 Workshop September 24, 2005 Registration is now available at: http://www.cs.ioc.ee/tfp-icfp-gpce05 ---------------------------------------------------------------------- The goal of CUFP is to build a community for users of functional programming languages and technology, be they using functional languages in their professional lives, in an open source project (other than implementation of functional languages), as a hobby, or any combination thereof. In short: anyone who uses functional programming as a /means/, but not an /end/. ---------------------------------------------------------------------- Schedule The meeting will last a full day, with a mix of invited presentations and discussion sessions. This year, we have the following confirmed speakers: * Atrijus Tang; talking about PUGS, a Perl6 implementation, written in Haskell; * Fabrice Le Fessant; talking about MLDonkey, a popular multi-platform, multi-network P2P client written in OCaml. * Michael Sperber; talking about uses of Scheme in the banking industry. * David Roundy; talking about darcs, a popular and flexible revision control system well-suited to highly distributed development, written in Haskell. * Jim Grundy; talking his experiences with functional programming at Intel's Strategic CAD Labs. * Robert Boone; talking about his experiences at FreeScale. * Jonathan Soebel; talking about lessons the FP community can learn from the OMG's Model Driven Architecture (MDA) and its related marketing efforts. We will also be having two working sessions, where lively debate and brainstorming will be the order of the day: * FP, Education, and Industry: industry folks complain that there aren't enough FP folks being produced by schools, and educators complain that students don't see any point in studying FP if there are no jobs to be had. How can we break this stalemate? Simon Thompson of Functional and Declarative Programming in Education (FDPE05) will be joining us, and we'll be debriefing at FDPE05. * Stimulating a CUFP Community: we'd like the buzz and excitement surrounding CUFP to persist beyond the workshops. What would such a community look like? How do we make it happen? The session will kick off with two separate but complimentary starting points: a proposed "Users of FP" community web site and a proposed "Haskell Consortium" web site. There will be no published proceedings, as the meeting is intended to be more a discussion forum than a technical interchange. A full report of last year's workshop appeared in the Functional Programming column of the December 2004 issue of SIGPLAN Notices, and we plan to do the same this year. From klacke@REDACTED Fri Aug 5 13:31:01 2005 From: klacke@REDACTED (Claes Wikstom) Date: Fri, 05 Aug 2005 13:31:01 +0200 Subject: ONC/RPC In-Reply-To: <005601c59984$b2d7b120$0100a8c0@MONEYMAKER2> References: <005601c59984$b2d7b120$0100a8c0@MONEYMAKER2> Message-ID: <42F34DF5.7060201@hyber.org> Valentin Micic wrote: > Hello, > > Anybody out there with a direct experience (positive or negative) in using > user contribution rpc-1.1? > So far I've been using C/C++ based RPC client that sources traffic requests > from ERLANG run-time, but would really like to move the whole thing to > ERLANG at some stage. Is there any reason why I should not do it? Nortel use the Erlang sun RPC code extensively in production code today. /klacke From joelr1@REDACTED Fri Aug 5 19:02:33 2005 From: joelr1@REDACTED (Joel Reymont) Date: Fri, 5 Aug 2005 19:02:33 +0200 Subject: Generic way to retrieve all records from a table Message-ID: <4ABA6DE2-1858-4B51-97B2-542715C73ADD@gmail.com> Folks, Is there a good generic way to retrieve all records from a Mnesia table given a table name? Thanks, Joel -- http://wagerlabs.com/uptick From erlang@REDACTED Fri Aug 5 19:16:53 2005 From: erlang@REDACTED (Peter-Henry Mander) Date: Fri, 05 Aug 2005 18:16:53 +0100 Subject: Memory usage with ETS Message-ID: <1123262213.15157.18.camel@hymir.newport-networks.com> Hi Gurus, I've carried out a little experiment. The program I've written originally used several ETS tables throughout it's processing lifetime, and memory consumption grew gradually as it progressed. I have found that periodically copying all the records over to a new table, deleting the original table then calling erlang:garbage_collect/0 has helped to stabilise memory consumption. Is this a suitable method? Are there any drawbacks or gotchas I should be wary of? The program performance is dominated by disk access since it processes call data records, so I doubt that copying a few tables with approximately 32,000 records each will have a huge impact. However will this method cause performance issues on other systems? For example, I've rewritten the timer module so that I can specify timer periods with microsecond granularity to enable issuing messages at rates of, say 333 cps (the timer approximates the period to the nearest millisecond and will achieve 333 cps on average). I've used ETS to store the timer sequence since inserting into lists gets very costly as the number and frequency of the timers increases. I haven't run the timer for very long but I suspect the ETS table will grow monotonically. How can I reduce the memory footprint without resorting to table copying which will disrupt the timer? Pete. -- "The Tao of Programming flows far away and returns on the wind of morning." From erlang@REDACTED Fri Aug 5 20:15:16 2005 From: erlang@REDACTED (Peter-Henry Mander) Date: Fri, 05 Aug 2005 19:15:16 +0100 Subject: Memory usage with ETS In-Reply-To: <1123262213.15157.18.camel@hymir.newport-networks.com> References: <1123262213.15157.18.camel@hymir.newport-networks.com> Message-ID: <1123265716.15157.23.camel@hymir.newport-networks.com> No! no, I'm wrong. It didn't work. ETS memory consumption still grows regardless. Grumble. Any helpful suggestions? (on Friday evening? Yeah right, I'm going home!) Pete. On Fri, 2005-08-05 at 18:16 +0100, Peter-Henry Mander wrote: > Hi Gurus, > > I've carried out a little experiment. The program I've written > originally used several ETS tables throughout it's processing lifetime, > and memory consumption grew gradually as it progressed. I have found > that periodically copying all the records over to a new table, deleting > the original table then calling erlang:garbage_collect/0 has helped to > stabilise memory consumption. > > Is this a suitable method? Are there any drawbacks or gotchas I should > be wary of? > > The program performance is dominated by disk access since it processes > call data records, so I doubt that copying a few tables with > approximately 32,000 records each will have a huge impact. However will > this method cause performance issues on other systems? > > For example, I've rewritten the timer module so that I can specify timer > periods with microsecond granularity to enable issuing messages at rates > of, say 333 cps (the timer approximates the period to the nearest > millisecond and will achieve 333 cps on average). I've used ETS to store > the timer sequence since inserting into lists gets very costly as the > number and frequency of the timers increases. I haven't run the timer > for very long but I suspect the ETS table will grow monotonically. How > can I reduce the memory footprint without resorting to table copying > which will disrupt the timer? > > Pete. > > From meena_selvam@REDACTED Fri Aug 5 21:09:40 2005 From: meena_selvam@REDACTED (MEENA SELVAM) Date: Fri, 5 Aug 2005 12:09:40 -0700 (PDT) Subject: convert a tuple or list to 4 byte integer value Message-ID: <20050805190940.47841.qmail@web30402.mail.mud.yahoo.com> I have an IPaddress tuple {47,80,18,222} or after conversion using tuple_to_list I have [47,80,18,222] But the snmp object type to hold this ip address is 'IpAddress' which is 4 bytes of integer. I tried, list_to_integer[47,80,18,222] which gives a badarg error, 1> list_to_integer([47,80,18,222]). ** exited: {badarg,[{erlang,list_to_integer,[[47,80,18,222]]}, {erl_eval,do_apply,5}, {shell,exprs,6}, {shell,eval_loop,3}]} ** =ERROR REPORT==== 5-Aug-2005::12:02:17 === Error in process <0.30.0> with exit value: {badarg,[{erlang,list_to_integer,[[47,80,18,222]]},{erl_eval,do_apply,5},{shell,exprs,6},{shell,eval_loop,3}]} But actually what I need is, not the ascii equivalent. I need to convert this to 4 bytes one with 47, one with 80 How can I do this? meena __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From serge@REDACTED Fri Aug 5 22:04:09 2005 From: serge@REDACTED (Serge Aleynikov) Date: Fri, 05 Aug 2005 16:04:09 -0400 Subject: convert a tuple or list to 4 byte integer value In-Reply-To: <20050805190940.47841.qmail@web30402.mail.mud.yahoo.com> References: <20050805190940.47841.qmail@web30402.mail.mud.yahoo.com> Message-ID: <42F3C639.3080309@hq.idt.net> Try this: 10> <> = <<47,80,18,222>>. <<47,80,18,222>> 11> I. 793776862 12> <>. <<47,80,18,222>> Serge MEENA SELVAM wrote: > I have an IPaddress tuple {47,80,18,222} or after > conversion using tuple_to_list I have [47,80,18,222] > > But the snmp object type to hold this ip address is > 'IpAddress' which is 4 bytes of integer. > > I tried, list_to_integer[47,80,18,222] which gives a > badarg error, > > 1> list_to_integer([47,80,18,222]). > ** exited: > {badarg,[{erlang,list_to_integer,[[47,80,18,222]]}, > {erl_eval,do_apply,5}, > {shell,exprs,6}, > {shell,eval_loop,3}]} ** > > =ERROR REPORT==== 5-Aug-2005::12:02:17 === > Error in process <0.30.0> with exit value: > {badarg,[{erlang,list_to_integer,[[47,80,18,222]]},{erl_eval,do_apply,5},{shell,exprs,6},{shell,eval_loop,3}]} > > > But actually what I need is, not the ascii equivalent. > I need to convert this to 4 bytes one with 47, one > with 80 > > How can I do this? > > meena From ulf@REDACTED Fri Aug 5 22:18:00 2005 From: ulf@REDACTED (Ulf Wiger) Date: Fri, 05 Aug 2005 22:18:00 +0200 Subject: Generic way to retrieve all records from a table In-Reply-To: <4ABA6DE2-1858-4B51-97B2-542715C73ADD@gmail.com> References: <4ABA6DE2-1858-4B51-97B2-542715C73ADD@gmail.com> Message-ID: Den 2005-08-05 19:02:33 skrev Joel Reymont : > Folks, > > Is there a good generic way to retrieve all records from a Mnesia table > given a table name? > > Thanks, Joel There are a few ways to do it, with slightly different characteristics depending on your needs. Raw performance will vary between the alternatives, depending on size of the table, locality, etc. As a general note, efficiently retrieving the whole table inside a transaction is non-trivial, since the transaction store needs to be checked and order possibly preserved. * * * match_object(Pattern) match_object(Tab, Pattern) dirty_match_object/[1,2] For Pattern, you can use table_info(Tab, wild_pattern). Note that the record name of a table doesn't need to be the same as the table name, but mnesia:match_object(Tab, mnesia:table_info(Tab, wild_pattern)) will always work. * * * mnesia:select(Tab, [{WildPattern, [], ['$_']}]) will do the same thing as match_object/2, but in a more unintuitive fashion. There's a point, though: mnesia:select(Tab, MatchSpec, N, Lock) will retrieve N objects at a time, then return with the result and a continuation. This can be quite useful in order to achieve better real-time characteristics and/or memory characteristics. * * * mnesia:foldl(Function, Acc, Table) works like lists:foldl/3 more or less, and will traverse the table one object at a time. This sort of traversal goes easy on the garbage collector, which doesn't particularly like rapid buildups of live data on the heap. To simply retrieve all objects from the table, mnesia:foldl(fun(X, Acc) -> [X|Acc] end, [], Table), (which is just to illustrate, as obviously, match_object/2 would be much better at this particular task.) * * * all_keys(Tab) and dirty_all_keys(Tab) have been around for a while. Personally, I'm much in favour of foldl() or select() then. There is of course also mnesia:dump_to_textfile(Tab), but I assume that's not what you're after? /Uffe -- Ulf Wiger From ulf@REDACTED Fri Aug 5 22:24:22 2005 From: ulf@REDACTED (Ulf Wiger) Date: Fri, 05 Aug 2005 22:24:22 +0200 Subject: Memory usage with ETS In-Reply-To: <1123262213.15157.18.camel@hymir.newport-networks.com> References: <1123262213.15157.18.camel@hymir.newport-networks.com> Message-ID: Den 2005-08-05 19:16:53 skrev Peter-Henry Mander : > For example, I've rewritten the timer module so that I can specify timer > periods with microsecond granularity to enable issuing messages at rates > of, say 333 cps (the timer approximates the period to the nearest > millisecond and will achieve 333 cps on average). I've used ETS to store > the timer sequence since inserting into lists gets very costly as the > number and frequency of the timers increases. I haven't run the timer > for very long but I suspect the ETS table will grow monotonically. How > can I reduce the memory footprint without resorting to table copying > which will disrupt the timer? Here's a suggestion: skip the timer module and use the timer BIFs instead. Actually, even starting a regular process per timer is much more efficient than using the timer module, and the BIFs erlang:send_after/3 and erlang:start_timer/3 are *much* more efficient and scale very well. /Uffe -- Ulf Wiger From meena_selvam@REDACTED Sun Aug 7 06:27:30 2005 From: meena_selvam@REDACTED (MEENA SELVAM) Date: Sat, 6 Aug 2005 21:27:30 -0700 (PDT) Subject: how to get [3,5] from [ ["3"], ["5"] ] Message-ID: <20050807042730.78034.qmail@web30405.mail.mud.yahoo.com> Hi, I need to extract the first element of every tuple, in a tuplelist in the format[a,b] what I have is: FirElem = fun(X)-> {C,_} = X, C end. lists:map(FirElem,[{["3"],["red"]},{["5"],["yellow"]}]). which gives [["3"],["5"]] But I require to make a list [3,5] for which I do not find any BIF or functions( to convert [["3"],["5"]]. Any suggestions? meena ____________________________________________________ Start your day with Yahoo! - make it your home page http://www.yahoo.com/r/hs From meena_selvam@REDACTED Sun Aug 7 08:20:07 2005 From: meena_selvam@REDACTED (MEENA SELVAM) Date: Sat, 6 Aug 2005 23:20:07 -0700 (PDT) Subject: how to get [3,5] from [ ["3"], ["5"] ] - use of io_lib:format In-Reply-To: <20050807042730.78034.qmail@web30405.mail.mud.yahoo.com> Message-ID: <20050807062007.65579.qmail@web30408.mail.mud.yahoo.com> Will this code work? FinalList = fun(X) -> io_lib:format("~7s',X) end. lists:map(FinalList, [["3"],["5"]]). my requirement is for a arbitrary number of elements rather than 3 and 5. PS: Right now, I do not have access to erlang compiler, so I am yet to try this out. my doubt is, io_lib:format writes on terminal, but does it return the character that is printed or some other return values. is there anything similar to sprintf in c, in formatting and moving the output of to a list? meena --- MEENA SELVAM wrote: > Hi, > I need to extract the first element of every tuple, > in > a tuplelist in the format[a,b] > > what I have is: > > FirElem = fun(X)-> > {C,_} = X, > C > end. > > lists:map(FirElem,[{["3"],["red"]},{["5"],["yellow"]}]). > > which gives [["3"],["5"]] > > But I require to make a list [3,5] for which I do > not > find any BIF or functions( to convert [["3"],["5"]]. > Any suggestions? > > meena > > > > ____________________________________________________ > Start your day with Yahoo! - make it your home page > http://www.yahoo.com/r/hs > > __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From meena_selvam@REDACTED Sun Aug 7 08:39:10 2005 From: meena_selvam@REDACTED (MEENA SELVAM) Date: Sat, 6 Aug 2005 23:39:10 -0700 (PDT) Subject: how to get [3,5] from [ ["3"], ["5"] ] - it works! i used string:to_integer In-Reply-To: <20050807062007.65579.qmail@web30408.mail.mud.yahoo.com> Message-ID: <20050807063910.21547.qmail@web30403.mail.mud.yahoo.com> FinalList = fun(X) -> {I} = string:to_integer(X), I end. lists:map(FinalList, [["3"],["5"]]). --- MEENA SELVAM wrote: > Will this code work? > > FinalList = fun(X) -> io_lib:format("~7s',X) > end. > > lists:map(FinalList, [["3"],["5"]]). > > my requirement is for a arbitrary number of elements > rather than 3 and 5. > > PS: Right now, I do not have access to erlang > compiler, so I am yet to try this out. > > my doubt is, io_lib:format writes on terminal, but > does it return the character that is printed or some > other return values. > > is there anything similar to sprintf in c, in > formatting and moving the output of to a list? > > meena > > --- MEENA SELVAM wrote: > > > Hi, > > I need to extract the first element of every > tuple, > > in > > a tuplelist in the format[a,b] > > > > what I have is: > > > > FirElem = fun(X)-> > > {C,_} = X, > > C > > end. > > > > > lists:map(FirElem,[{["3"],["red"]},{["5"],["yellow"]}]). > > > > which gives [["3"],["5"]] > > > > But I require to make a list [3,5] for which I do > > not > > find any BIF or functions( to convert > [["3"],["5"]]. > > Any suggestions? > > > > meena > > > > > > > > > ____________________________________________________ > > Start your day with Yahoo! - make it your home > page > > http://www.yahoo.com/r/hs > > > > > > > __________________________________________________ > Do You Yahoo!? > Tired of spam? Yahoo! Mail has the best spam > protection around > http://mail.yahoo.com > ____________________________________________________ Start your day with Yahoo! - make it your home page http://www.yahoo.com/r/hs From hedeland@REDACTED Sun Aug 7 19:25:44 2005 From: hedeland@REDACTED (Per Hedeland) Date: Sun, 7 Aug 2005 19:25:44 +0200 (CEST) Subject: how to get [3,5] from [ ["3"], ["5"] ] - it works! i used string:to_integer In-Reply-To: <20050807063910.21547.qmail@web30403.mail.mud.yahoo.com> Message-ID: <200508071725.j77HPiIc021206@tordmule.bluetail.com> MEENA SELVAM wrote: > >FinalList = fun(X) -> {I} = string:to_integer(X), > I > end. > > lists:map(FinalList, [["3"],["5"]]). You want the list_to_integer/1 BIF (documented in the erlang(3) man page): 1> F = fun([S]) -> list_to_integer(S) end. #Fun 2> lists:map(F, [["3"],["5"]]). [3,5] >> my doubt is, io_lib:format writes on terminal, but >> does it return the character that is printed or some >> other return values. >> >> is there anything similar to sprintf in c, in >> formatting and moving the output of to a list? io_lib:format() doesn't write on the terminal, and is indeed similar to sprintf() in C - but what you'd want for this (in the general case) would rather be the opposite, something similar to sscanf() in C, which is io_lib:fread(). Unfortunately the documentation for fread() in the io_lib(3) man page is wrong, claiming that it uses the same format codes as io:format(). Writing an integer with io:format() is done with the 'w' format code, but that doesn't work to read an integer with fread(), and the 'd' format code that is needed doesn't work with io:format(). Luckily you have the source. 5> io_lib:fread("~d", "42"). {ok,"*",[]} A somewhat surprising result, but due to the shell's "helpfulness" in using 'p' for printouts - it is actually correct: 6> io:format("~w~n", [v(-1)]). {ok,[42],[]} ok >> > I need to extract the first element of every >> tuple, >> > in >> > a tuplelist in the format[a,b] >> > >> > what I have is: >> > >> > FirElem = fun(X)-> >> > {C,_} = X, >> > C >> > end. >> > >> > >> >lists:map(FirElem,[{["3"],["red"]},{["5"],["yellow"]}]). 7> f(F). ok 8> F = fun({[S],_}) -> list_to_integer(S) end. #Fun 9> lists:map(F,[{["3"],["red"]},{["5"],["yellow"]}]). [3,5] --Per Hedeland From hedeland@REDACTED Sun Aug 7 19:36:32 2005 From: hedeland@REDACTED (Per Hedeland) Date: Sun, 7 Aug 2005 19:36:32 +0200 (CEST) Subject: inet:getiflist() behaviour in Windows In-Reply-To: <86f1f53505080414342a0bf4@mail.gmail.com> Message-ID: <200508071736.j77HaWrM021238@tordmule.bluetail.com> Stephen Han wrote: > >This is what I did in Linux (gentoo with kernel 2.6.10) > >2> inet:getiflist(). >{ok,["lo","eth0"]} As expected. >And this what I did in Windows XP > >5> inet:getiflist(). >{ok,["240.802.170.641","100.0.0.721"]} Totally useless. >Both of them running R10B-6. > >Is this work as designed or not? I don't know about "designed", but looking at e.g. the useless output of "netstat -r" on Windows, it's what I would expect. Windows gurus, do interfaces in Windows actually have names, that can be used for something (programmatically)? And if so, why are interfaces "named" by their IP address? --Per Hedeland From hedeland@REDACTED Sun Aug 7 20:02:32 2005 From: hedeland@REDACTED (Per Hedeland) Date: Sun, 7 Aug 2005 20:02:32 +0200 (CEST) Subject: Simple text user interface question In-Reply-To: <002a01c598f3$ac0375f0$dc00a8c0@INSWITCH244> Message-ID: <200508071802.j77I2Wp8021337@tordmule.bluetail.com> "Sebastian Bello" wrote: > >One more question: I tried io:get_chars('Input key: ', 1) but it seems to >wait for an ENTER and to cut the read characters to the specified length. >I'm in fact looking for a way to read just N (in this case 1) keys from the >keyboard, *without* waiting for an ENTER. Any ideas? Well, now you're getting into the really system-dependant stuff - dependant not on terminal type but on OS. And since you're running Windows, I won't presume to have any useful advice. On Unix, the default mode of the tty driver is to collect complete lines before delivering anything to the application - which is what the vast majority of applications want. On most Unices, you can get the behaviour you want by invoking Erlang as stty -icanon min 1 time 0; erl -oldshell You will have a *very* unfriendly shell though - this is probably more appropriate for cases where you don't want to have a shell at all. (Also, depending on your *Unix* shell, the tty may be in a "weird" mode after exiting Erlang.) However, it can be noted that the "ttsl" driver used by the standard shell (both on Unix and Windows, though the driver is different) already puts the tty in this "one character at a time" mode - it is necessary to be able to do general "command-line editing" (hm, from a quick look at the Windows version, it seems it doesn't actually do anything special for this...). But somewhere in the Erlang I/O chain, the "deliver only complete lines" behaviour is re-instated - again probably since that's what most applications want. You can hunt through the source to find where, and possibly find a way to turn it off... --Per Hedeland From mikael.karlsson@REDACTED Sun Aug 7 20:56:04 2005 From: mikael.karlsson@REDACTED (Mikael Karlsson) Date: Sun, 7 Aug 2005 20:56:04 +0200 Subject: how to get [3,5] from [ ["3"], ["5"] ] - it works! i used string:to_integer In-Reply-To: <200508071725.j77HPiIc021206@tordmule.bluetail.com> References: <200508071725.j77HPiIc021206@tordmule.bluetail.com> Message-ID: <200508072056.05049.mikael.karlsson@creado.com> Or with list comprehensions: 17> A. [{["3"],["red"]},{["5"],["yellow"]}] 18> [list_to_integer(X) || {[X],_} <- A]. [3,5] - Mikael s?ndag 07 augusti 2005 19:25 skrev Per Hedeland: .. > 8> F = fun({[S],_}) -> list_to_integer(S) end. > #Fun > 9> lists:map(F,[{["3"],["red"]},{["5"],["yellow"]}]). > [3,5] > > --Per Hedeland From erlang@REDACTED Mon Aug 8 09:00:55 2005 From: erlang@REDACTED (Peter-Henry Mander) Date: Mon, 08 Aug 2005 08:00:55 +0100 Subject: *** SPAM *** Re: Memory usage with ETS In-Reply-To: References: <1123262213.15157.18.camel@hymir.newport-networks.com> Message-ID: <1123484455.5908.23.camel@hymir.newport-networks.com> Hi Uffe, Thanks for the BIF suggestion. Unfortunately they're not an easy fit to the purpose I have in mind. I wish to have a fun execute repeatedly at regular intervals that can fall between millisecond ticks, so that I can simulate a firing rate at an arbitrary frequency. The ETS based micro_timer I wrote allows me to specify timer periods in microseconds. It is true that in reality the timer granularity is strictly 1000 microseconds, but I'm happy to accept a mean deviation from the desired rate (or jitter) of 500 microsecond. If I wanted stricter control I would need a C link-in driver (or write the whole project in C *shudder*) and twiddle the OS timer parameters to suit. The fact I can bundle an environment into a fun and let the initiating process die means that I reduce the process footprint drastically while it does nothing; it's gone! I'm aware of hibernate, which does a fine job of reducing the process memory footprint when idle (but is it as small as a fun?), I also wanted to reduce the number of messages bursting around the system. The fun storage in ETS is certainly not negligable, but I've had programs that consumed vast amounts of memory in many thousands of processes simply waiting (and hibernating) for a trigger message to come in, which was followed by a huge message storm which impacted performance. Admittedly my design was crap, I'm still learning. Pete. On Fri, 2005-08-05 at 22:24 +0200, Ulf Wiger wrote: > Den 2005-08-05 19:16:53 skrev Peter-Henry Mander > : > > > For example, I've rewritten the timer module so that I can specify timer > > periods with microsecond granularity to enable issuing messages at rates > > of, say 333 cps (the timer approximates the period to the nearest > > millisecond and will achieve 333 cps on average). I've used ETS to store > > the timer sequence since inserting into lists gets very costly as the > > number and frequency of the timers increases. I haven't run the timer > > for very long but I suspect the ETS table will grow monotonically. How > > can I reduce the memory footprint without resorting to table copying > > which will disrupt the timer? > > Here's a suggestion: skip the timer module and use the > timer BIFs instead. Actually, even starting a regular process > per timer is much more efficient than using the timer module, > and the BIFs erlang:send_after/3 and erlang:start_timer/3 > are *much* more efficient and scale very well. > > /Uffe From ulf@REDACTED Mon Aug 8 09:17:03 2005 From: ulf@REDACTED (Ulf Wiger) Date: Mon, 08 Aug 2005 09:17:03 +0200 Subject: Memory usage with ETS In-Reply-To: <1123262213.15157.18.camel@hymir.newport-networks.com> References: <1123262213.15157.18.camel@hymir.newport-networks.com> Message-ID: Den 2005-08-05 19:16:53 skrev Peter-Henry Mander : > I've carried out a little experiment. The program I've written > originally used several ETS tables throughout it's processing lifetime, > and memory consumption grew gradually as it progressed. BTW, I recall that this was a bug long ago (ETS didn't allocate memory in a fibonacci sequence like the processes did, and therefore fragmented memory; another variation was fix_alloc:ing objects that were stored in ETS, but in a way that long-lived objects could "partition" memory space, which led to fragmentation.(*)) I don't know if any such bug has re-appeared...? ETS tables dynamically expand, but they should also shrink dynamically (with a hysteresis.) Are you sure you don't have a memory leak in the sense that you have lingering objects that should have been deleted? (*) Apologies if my description of these bugs is ridicuously flawed -- in any event, there were problems with ETS and memory fragmentation a few years ago. > I'm aware of hibernate, which does a fine job of reducing the process > memory footprint when idle (but is it as small as a fun?), I also wanted > to reduce the number of messages bursting around the system. Hibernate in a process holding only a fun should be quite close to the memory footprint of the same fun in an ETS table. Note that if you create the process with a proc_lib function, you will get some stuff in the process dictionary that, while being useful for debugging, of course will increase the footprint. Hibernate doesn't empty the process dictionary. Regarding the number of messages, using spawn/hibernate is going to use less CPU power than the timer.erl module. That should be the important part (that, and memory, of course). /Uffe -- Ulf Wiger From erlang@REDACTED Mon Aug 8 10:00:55 2005 From: erlang@REDACTED (Peter-Henry Mander) Date: Mon, 08 Aug 2005 09:00:55 +0100 Subject: Memory usage with ETS In-Reply-To: References: <1123262213.15157.18.camel@hymir.newport-networks.com> Message-ID: <1123488055.5908.62.camel@hymir.newport-networks.com> Hi Uffe, On Mon, 2005-08-08 at 09:17 +0200, Ulf Wiger wrote: > ETS tables dynamically expand, but they should also shrink > dynamically (with a hysteresis.) Are you sure you don't have > a memory leak in the sense that you have lingering objects > that should have been deleted? It's not a bug in ETS, it's a flaw in my program. I found that I was using 'bag' instead of 'set' and the memory leak was due to multiple record instances not being retrieved and deleted properly. Like you said, I had 'lingering objects'. Why did I choose 'bag'? I wonder... When I used the 'set' table option the memory consuption was much improved, it didn't monotonically increase over time. > Hibernate in a process holding only a fun should be quite close to the > memory footprint of the same fun in an ETS table. Note that if you > create the process with a proc_lib function, you will get some stuff > in the process dictionary that, while being useful for debugging, > of course will increase the footprint. Hibernate doesn't empty the > process dictionary. I'm a good lad, I avoid using the process dictionary altogether. How can I ensure that the process context only contains the strict minimum before hibernating? Is there a way of purging the process dictionary? > Regarding the number of messages, using spawn/hibernate is going to > use less CPU power than the timer.erl module. That should be the > important part (that, and memory, of course). Alright, I'll try to write up a comparative test of the two methods, one using my micro_timer, and the other using timer BIFs and hibernate. The micro_timer works quite well, except I've observed some spurious delays over long time periods. Would garbage collection potentially cause these delays? I realise that insisting on implementing this in Erlang may be misguided. An old 'C' dog would turn his nose up at the idea of implementing time-critical software in a declarative language with periodic garbage collection. But I've had encouraging results so far, and I wish to iron out the remaining wrinkle. Pete. From erlang@REDACTED Mon Aug 8 09:31:25 2005 From: erlang@REDACTED (Peter-Henry Mander) Date: Mon, 08 Aug 2005 08:31:25 +0100 Subject: [Fwd: *** SPAM *** Re: *** SPAM *** Re: Memory usage with ETS] Message-ID: <1123486285.5908.32.camel@hymir.newport-networks.com> Hi Uffe, Sorry about the subject line pollution, it's a lame mockery of Monty Python. My ISP has the most annoying and brain dead spam policy I know of. I can't even opt-out of the spam labling scheme. I'll be switching ISP soon. Pete. -------- Forwarded Message -------- From: Peter-Henry Mander Reply-To: erlang@REDACTED To: Ulf Wiger Cc: Erlang Questions Subject: *** SPAM *** Re: *** SPAM *** Re: Memory usage with ETS Date: Mon, 08 Aug 2005 08:00:55 +0100 Hi Uffe, Thanks for the BIF suggestion. [...] From nm@REDACTED Mon Aug 8 15:42:50 2005 From: nm@REDACTED (Gaspar Chilingarov) Date: Mon, 08 Aug 2005 18:42:50 +0500 Subject: editing erlang programs in vim Message-ID: <42F7615A.30607@web.am> Sure, I know, that (semi)official editor for erlang programming is emacs, but, sigh, I'm too used to work in (g)vim to edit everything ;). Vim misses description files to allow comfortable indentation and compiler support and many another small useful faetures. Anyone interested can download archive with my config from here: http://nothing.am/erlang/erl.tar.bz2 every vim user should know where to unpack this directory structure :) Any comments and suggestions (especially unified diffs :) are welcome. -- Gaspar Chilingarov System Administrator t +37491 419763 (mob) t +37410 240399 (office) w www.web.am i 63174784 e nm@REDACTED From james.hague@REDACTED Mon Aug 8 16:30:12 2005 From: james.hague@REDACTED (James Hague) Date: Mon, 8 Aug 2005 09:30:12 -0500 Subject: editing erlang programs in vim In-Reply-To: <42F7615A.30607@web.am> References: <42F7615A.30607@web.am> Message-ID: Nifty! If I can find the time, I'll try it. I tossed out the Erlang syntax coloring that comes with vim and made my own. The big difference is that I do syntax coloring of function heads. For example, in this code: fib(N) when N < 2 -> 1; fib(N) -> fib(N-2) + fib(N-1). everything to the left of the "->" on each line is in it's own color. This makes code *much* easier to read, at least for me. Other differences are: * Coloring of lists, tuples, and binaries, which help make syntax errors more obvious. * Generally more robust handling than the default colorer (handles character constants correctly, etc.). * No coloring of BIFs and standard library functions, because I don't see the point. If anyone would like to try it, let me know. James From alex.arnon@REDACTED Mon Aug 8 16:51:42 2005 From: alex.arnon@REDACTED (Alex Arnon) Date: Mon, 8 Aug 2005 17:51:42 +0300 Subject: Distributed spawn-linking. Message-ID: <944da41d05080807511d315b26@mail.gmail.com> Hi All, A (newbie question): Consider a somewhat convoluted architecture: I have two processes, the Spawner and Overseer. The Spawner's role is to spawn processes, while the overseer would link to them and manage their operation (sending command messages and the like). My question is: if the Spawner does this: Overseer ! {new, spawn(SomeNode, Behaviour, Args)} and the Overseer then does: receive {new, Pid} -> link(Pid), Pid ! {i_see_you, self()} ... Is there any chance that the link would fail/message would get lost due to there not being a process yet? In other words, does spawn() wait for SomeNode to respond with an ACK before returning? From erlang@REDACTED Mon Aug 8 17:18:49 2005 From: erlang@REDACTED (Michael McDaniel) Date: Mon, 8 Aug 2005 08:18:49 -0700 Subject: Distributed spawn-linking. In-Reply-To: <944da41d05080807511d315b26@mail.gmail.com> References: <944da41d05080807511d315b26@mail.gmail.com> Message-ID: <20050808151849.GV20625@fangora.autosys.us> On Mon, Aug 08, 2005 at 05:51:42PM +0300, Alex Arnon wrote: > Hi All, > > A (newbie question): > Consider a somewhat convoluted architecture: I have two processes, the > Spawner and Overseer. The Spawner's role is to spawn processes, while > the overseer would link to them and manage their operation (sending > command messages and the like). My question is: > if the Spawner does this: > > Overseer ! {new, spawn(SomeNode, Behaviour, Args)} > > and the Overseer then does: > > receive > {new, Pid} -> > link(Pid), > Pid ! {i_see_you, self()} > ... > > Is there any chance that the link would fail/message would get lost > due to there not being a process yet? In other words, does spawn() > wait for SomeNode to respond with an ACK before returning? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ googling "message passing acknowledge" shows ... http://www.erlang.org/ml-archive/erlang-questions/200212/msg00284.html From camster@REDACTED Mon Aug 8 17:26:45 2005 From: camster@REDACTED (Richard Cameron) Date: Mon, 8 Aug 2005 16:26:45 +0100 Subject: Line numbers in stack traces Message-ID: <02ADE0BC-D2C1-4258-94B1-39E6210D0440@citeulike.org> I think this would ordinarily qualify as being a silly question, but it seems quite valid here: Is there any way to extract enough information from a standard erlang stack trace to be able to work out at which line the exception was thrown? To illustrate this with a convoluted example, we have: > -module(test). > > -export([crasher/0]). > > crasher() -> > {ok, _Value1} = function_which_mysteriously_fails(), > {ok, _Value2} = function_which_mysteriously_fails(). > > function_which_mysteriously_fails() -> > U = random:uniform(), > if > U > 0.5 -> > {ok, U}; > true -> > error > end. > when I run this on R10B-6 (along with a bit of bad luck on my side), I see this: > home:/tmp rcameron$ erl > Erlang (BEAM) emulator version 5.4.8 [source] [hipe] > > Eshell V5.4.8 (abort with ^G) > 1> test:crasher(). > ** exited: {{badmatch,error}, > [{test,crasher,0}, > {erl_eval,do_apply,5}, > {shell,exprs,6}, > {shell,eval_loop,3}]} ** > > =ERROR REPORT==== 8-Aug-2005::16:13:31 === > Error in process <0.30.0> with exit value: {{badmatch,error}, > [{test,crasher,0},{erl_eval,do_apply,5},{shell,exprs,6}, > {shell,eval_loop,3}]} > Now this is all very true, but it's not too helpful. At which line was the error? Will the runtime tell me where it crashed without me having to go and re-run the process with tracing, or with a bunch of io:format statements temporarily inserted into the code? I'm aware of jungerl's smart_exceptions, but this does seem the sort of thing which really ought to be in the core of the language. Python/ Tcl/Ruby/Perl will all give you a stack trace traces with line numbers, and C will give you a core file which will tell you the exact position of failure. Won't Erlang? Have I missed the command line option which does this, or is there some good reason why it's difficult for the virtual machine to report on this information (some obscure consequence of the way it compiles tail-recursive functions?) Richard. From alex.arnon@REDACTED Mon Aug 8 18:14:15 2005 From: alex.arnon@REDACTED (Alex Arnon) Date: Mon, 8 Aug 2005 19:14:15 +0300 Subject: Distributed spawn-linking. In-Reply-To: <20050808151849.GV20625@fangora.autosys.us> References: <944da41d05080807511d315b26@mail.gmail.com> <20050808151849.GV20625@fangora.autosys.us> Message-ID: <944da41d050808091418e3ec10@mail.gmail.com> On 8/8/05, Michael McDaniel wrote: > On Mon, Aug 08, 2005 at 05:51:42PM +0300, Alex Arnon wrote: > > Hi All, > > > > A (newbie question): > > Consider a somewhat convoluted architecture: I have two processes, the > > Spawner and Overseer. The Spawner's role is to spawn processes, while > > the overseer would link to them and manage their operation (sending > > command messages and the like). My question is: > > if the Spawner does this: > > > > Overseer ! {new, spawn(SomeNode, Behaviour, Args)} > > > > and the Overseer then does: > > > > receive > > {new, Pid} -> > > link(Pid), > > Pid ! {i_see_you, self()} > > ... > > > > Is there any chance that the link would fail/message would get lost > > due to there not being a process yet? In other words, does spawn() > > wait for SomeNode to respond with an ACK before returning? > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > googling "message passing acknowledge" shows ... > > http://www.erlang.org/ml-archive/erlang-questions/200212/msg00284.html > > > Thank you, but this does not answer my question, which is specifically about the behaviour of spawn(). I shall reword: - Is spawn(Node, ...) a synchronous operation? I.e. does the spawning process wait for the target node to acknowledge and assign the PID before returning? - If not, does Erlang handle the original example? And if it does, how? From paris@REDACTED Mon Aug 8 18:37:56 2005 From: paris@REDACTED (Javier =?iso-8859-1?Q?Par=EDs_Fern=E1ndez?=) Date: Mon, 8 Aug 2005 18:37:56 +0200 Subject: Distributed spawn-linking. In-Reply-To: <944da41d050808091418e3ec10@mail.gmail.com> References: <944da41d05080807511d315b26@mail.gmail.com> <20050808151849.GV20625@fangora.autosys.us> <944da41d050808091418e3ec10@mail.gmail.com> Message-ID: <20050808163756.GA17586@dc.fi.udc.es> Hi, On Mon, Aug 08, 2005 at 07:14:15PM +0300, Alex Arnon wrote: > Thank you, but this does not answer my question, which is specifically > about the behaviour of spawn(). I shall reword: > - Is spawn(Node, ...) a synchronous operation? I.e. does the spawning > process wait for the target node to acknowledge and assign the PID > before returning? > - If not, does Erlang handle the original example? And if it does, how? Well, as the spawn call returns the pid of the created process, it has to be syncrhonous. However, in your example, the new process could die before the overseer links with it. Regards. Javier From kruegger@REDACTED Mon Aug 8 19:03:26 2005 From: kruegger@REDACTED (Stephen Han) Date: Mon, 8 Aug 2005 10:03:26 -0700 Subject: inet:getiflist() behaviour in Windows In-Reply-To: <200508071736.j77HaWrM021238@tordmule.bluetail.com> References: <86f1f53505080414342a0bf4@mail.gmail.com> <200508071736.j77HaWrM021238@tordmule.bluetail.com> Message-ID: <86f1f535050808100356c86435@mail.gmail.com> In my Windows XP, the netstat -r shows that "0x1" as loopback interface and "0x2" as ethernet. However, if I do inet:ifget("0x1", [addr, flags]), returns {error, einval}. Maybe the way of unix implementation and the windows are different. I have a feeling that I should not use the undocumented function even if it is exported publically. regards On 8/7/05, Per Hedeland wrote: > Stephen Han wrote: > > > >This is what I did in Linux (gentoo with kernel 2.6.10) > > > >2> inet:getiflist(). > >{ok,["lo","eth0"]} > > As expected. > > >And this what I did in Windows XP > > > >5> inet:getiflist(). > >{ok,["240.802.170.641","100.0.0.721"]} > > Totally useless. > > >Both of them running R10B-6. > > > >Is this work as designed or not? > > I don't know about "designed", but looking at e.g. the useless output of > "netstat -r" on Windows, it's what I would expect. > > Windows gurus, do interfaces in Windows actually have names, that can be > used for something (programmatically)? And if so, why are interfaces > "named" by their IP address? > > --Per Hedeland > From chandrashekhar.mullaparthi@REDACTED Mon Aug 8 19:35:20 2005 From: chandrashekhar.mullaparthi@REDACTED (Chandrashekhar Mullaparthi) Date: Mon, 8 Aug 2005 18:35:20 +0100 Subject: Distributed spawn-linking. In-Reply-To: <20050808163756.GA17586@dc.fi.udc.es> References: <944da41d05080807511d315b26@mail.gmail.com> <20050808151849.GV20625@fangora.autosys.us> <944da41d050808091418e3ec10@mail.gmail.com> <20050808163756.GA17586@dc.fi.udc.es> Message-ID: On 8 Aug 2005, at 17:37, Javier Par?s Fern?ndez wrote: > Hi, > > On Mon, Aug 08, 2005 at 07:14:15PM +0300, Alex Arnon wrote: >> Thank you, but this does not answer my question, which is specifically >> about the behaviour of spawn(). I shall reword: >> - Is spawn(Node, ...) a synchronous operation? I.e. does the spawning >> process wait for the target node to acknowledge and assign the PID >> before returning? >> - If not, does Erlang handle the original example? And if it does, >> how? > > Well, as the spawn call returns the pid of the created process, it has > to be syncrhonous. I don't think so. This is what the manpage says. spawn(Node, Module, Function, ArgumentList) Works like spawn/3, with the exception that the process is spawned at Node. If Node does not exist, a useless Pid is returned. Failure: badarg if Node, Module, or Function are not atoms, or ArgumentList is not a list. spawn_link(Node, Module, Function, ArgumentList) Works like spawn_link/3, except that the process is spawned at Node. If an attempt is made to spawn a process on a node which does not exist, a useless Pid is returned, and an EXIT signal will be received. And if you look in kernel/src/erlang.erl you'll see exactly how a spawn on a remote node is implemented. In short, you can't rely on the output of spawn/4 or spawn_link/4 to "guarantee" that a process has been spawned on the remote node. You'll need some application level protocol to establish this. cheers Chandru From david.nospam.hopwood@REDACTED Mon Aug 8 21:21:10 2005 From: david.nospam.hopwood@REDACTED (David Hopwood) Date: Mon, 08 Aug 2005 20:21:10 +0100 Subject: inet:getiflist() behaviour in Windows In-Reply-To: <200508071736.j77HaWrM021238@tordmule.bluetail.com> References: <200508071736.j77HaWrM021238@tordmule.bluetail.com> Message-ID: <42F7B0A6.2020706@blueyonder.co.uk> Per Hedeland wrote: > Windows gurus, do interfaces in Windows actually have names, that can be > used for something (programmatically)? Sort of, almost. There are names for "Network connections" -- see the NetConnectionID property of Win32_NetworkAdapter: But note that: - the NetConnectionID property was only added in XP, and hardly anything uses it. - a network connection is not quite the same thing as an interface, for example the loopback interface is not a network connection. - the user can arbitrarily rename network connections, i.e. they are user-oriented names rather than stable identifiers. The usual method of enumerating interfaces is the SIO_GET_INTERFACE_LIST ioctl, which doesn't involve names. -- David Hopwood From hedeland@REDACTED Mon Aug 8 21:36:49 2005 From: hedeland@REDACTED (Per Hedeland) Date: Mon, 8 Aug 2005 21:36:49 +0200 (CEST) Subject: Distributed spawn-linking. In-Reply-To: Message-ID: <200508081936.j78Janeg025688@tordmule.bluetail.com> Chandrashekhar Mullaparthi wrote: > >On 8 Aug 2005, at 17:37, Javier Par?s Fern?ndez wrote: > >> Hi, >> >> On Mon, Aug 08, 2005 at 07:14:15PM +0300, Alex Arnon wrote: >>> Thank you, but this does not answer my question, which is specifically >>> about the behaviour of spawn(). I shall reword: >>> - Is spawn(Node, ...) a synchronous operation? I.e. does the spawning >>> process wait for the target node to acknowledge and assign the PID >>> before returning? >>> - If not, does Erlang handle the original example? And if it does, >>> how? >> >> Well, as the spawn call returns the pid of the created process, it has >> to be syncrhonous. [ snip ] >And if you look in kernel/src/erlang.erl you'll see exactly how a spawn >on a remote node is implemented. In short, you can't rely on the output >of spawn/4 or spawn_link/4 to "guarantee" that a process has been >spawned on the remote node. You'll need some application level protocol >to establish this. But that wasn't the question either. If "doesn't exist yet" and "synchronous operation" plus elaboration isn't clear enough, maybe this rephrasing of (my understanding of) the question helps: Assuming that a process actually *is* spawned on the remote node, can you be sure that spawn/4 doesn't return its pid before the process really exists? And the answer is "yes", which can be verified via your pointer to the source (including following the gen_server call to net_kernel). Possible reasons for a "no" answer could be: There exists an optimization to assign/create the pid on the local node before actually doing the remote spawn. (Of course this would require some pretty complex implementation to allow all nodes to create unique pids on behalf of all other nodes, so it probably wouldn't be an optimization after all - plus it would be a pretty useless optimization if it were one, since you don't have much use for the pid until the process exists - if you're in a real hurry, you could always spawn a local process to do the remote spawn...) or The pid is assigned/created by the remote node, but for some unknown reason it doesn't do it via a normal local spawn, instead using some undocumented/internal mechanism that delivers a pid first (which is sent back to the originating node immediately) and does the actual spawn afterwards. Well, it *could* be implemented like that...:-) Either way, and beside (my understanding of) the question, both the "useless pid" returned on some errors, and the case of the process dying before it is sent a message, will result in an EXIT signal due to the link/1 being done by the communicating process (though of course the delivery of that EXIT signal is *not* necessarily synchronous). --Per Hedeland From serge@REDACTED Mon Aug 8 23:09:18 2005 From: serge@REDACTED (Serge Aleynikov) Date: Mon, 08 Aug 2005 17:09:18 -0400 Subject: mnesia replication Message-ID: <42F7C9FE.5070904@hq.idt.net> Folks, I have a master mnesia database (disc_copy) and N replicas on different nodes (ram_copies). Is it possible to postpone mnesia replication from the master node to replicas, make data changes to the master, perform some data validation and cleanup, and then force the replicated nodes to resynch? Is this a good approach in terms of avoiding extensive locking overhead in trying to load multiple tables with preserving referential integrity of data accross several tables? Thanks, Serge From nm@REDACTED Mon Aug 8 23:49:50 2005 From: nm@REDACTED (Gaspar Chilingarov) Date: Tue, 9 Aug 2005 02:49:50 +0500 (AMST) Subject: test_server understanding and hacking :) Message-ID: <59298.217.113.1.123.1123537790.squirrel@webmail.web.am> Hi all :) I'm making an attempt to strip down test_server just to several modules, still leaving all cool functionality in place -- maily I do need any cross-node, cross-platphors testing, one thing which I wish to have -- is a simple tool for an unit testing -- like junit or even simplier. I've stuck in the following place - test_server_line module provides very useful functionality to know, which line of test failed. But I need someone to explain me, what kind of magic is put there :) I need something like test_server:get_loc(), but for now I'm failing to understand how it is related to test_server_line at all, which kind of parse transform is done in test_server_line and if tested process stores test_server_loc in process dictionary, how do I get it's value, when process exits for some reason. For my project for this moment I should say that complete test_server environment is too heavyweight, but sometime I will switch to it -- when project will be large enougth. For now it's OK to have simple tool, which can just separate tests from source and provide me info -- which modules fail or misbehave at which points. Thanks in advance :) -- Gaspar Chilingarov System Administrator t +37491 419763 w www.web.am e nm@REDACTED From nm@REDACTED Tue Aug 9 01:15:23 2005 From: nm@REDACTED (Gaspar Chilingarov) Date: Tue, 9 Aug 2005 04:15:23 +0500 (AMST) Subject: simple_tests server Message-ID: <60942.217.113.1.123.1123542923.squirrel@webmail.web.am> Hi all ;) Finnaly I ended up with very simplified version of test_server, which is almost equal in syntax with original test_server, but are much more lightweight and easy to use. I've put simple test module into attach -- -module(adder). -compile(export_all). add(3,Y) -> 2*3 + Y; add(X,Y) -> X + Y. -- test suite looks almost the same as for test_server -- -module(adder_SUITE). -include("test_server.hrl"). -export([all/1, test1/1, test2/1]). all(doc) -> "example test from adder module"; all(suite) -> [ test1, test2 ]. test1(doc) -> "Test simple adding"; test1(Config) when is_list(Config) -> ?line 7 = adder:add(2,5), ?line 9 = adder:add(7,2). test2(doc) -> "Test special case"; test2(Config) when is_list(Config) -> ?line 7 = adder:add(4, 3), ?line 7 = adder:add(3, 4), ok. -- first test should pass and second one is failing. if you run this command in unix shell erl -s simple_tests run adder_SUITE -s init stop | grep '^\(FAIL\|PASS\):' with output like this PASS: "Test simple adding" FAIL: "Test special case" (at {adder_SUITE,21}) reason {{badmatch,10}, it will grep passed and failed tests in adder module - which is almost enougth for developing simple standalone applications. Now, which functions should would you recommend to port test_server here? Which functions are useful and commonly used in testing and which ones are rare? Thanks in advance :) -- Gaspar Chilingarov System Administrator t +37491 419763 w www.web.am e nm@REDACTED -------------- next part -------------- A non-text attachment was scrubbed... Name: simple_tests.tbz Type: application/octet-stream Size: 1562 bytes Desc: not available URL: From alex.arnon@REDACTED Tue Aug 9 10:04:21 2005 From: alex.arnon@REDACTED (Alex Arnon) Date: Tue, 9 Aug 2005 11:04:21 +0300 Subject: Distributed spawn-linking. In-Reply-To: <200508081936.j78Janeg025688@tordmule.bluetail.com> References: <200508081936.j78Janeg025688@tordmule.bluetail.com> Message-ID: <944da41d05080901047808b229@mail.gmail.com> On 8/8/05, Per Hedeland wrote: > Chandrashekhar Mullaparthi > wrote: > > > >On 8 Aug 2005, at 17:37, Javier Par?s Fern?ndez wrote: > > > >> Hi, > >> > >> On Mon, Aug 08, 2005 at 07:14:15PM +0300, Alex Arnon wrote: > >>> Thank you, but this does not answer my question, which is specifically > >>> about the behaviour of spawn(). I shall reword: > >>> - Is spawn(Node, ...) a synchronous operation? I.e. does the spawning > >>> process wait for the target node to acknowledge and assign the PID > >>> before returning? > >>> - If not, does Erlang handle the original example? And if it does, > >>> how? > >> > >> Well, as the spawn call returns the pid of the created process, it has > >> to be syncrhonous. > > [ snip ] > > >And if you look in kernel/src/erlang.erl you'll see exactly how a spawn > >on a remote node is implemented. In short, you can't rely on the output > >of spawn/4 or spawn_link/4 to "guarantee" that a process has been > >spawned on the remote node. You'll need some application level protocol > >to establish this. > > But that wasn't the question either. If "doesn't exist yet" and > "synchronous operation" plus elaboration isn't clear enough, maybe this > rephrasing of (my understanding of) the question helps: Assuming that a > process actually *is* spawned on the remote node, can you be sure that > spawn/4 doesn't return its pid before the process really exists? And the > answer is "yes", which can be verified via your pointer to the source > (including following the gen_server call to net_kernel). > > Possible reasons for a "no" answer could be: > > There exists an optimization to assign/create the pid on the local node > before actually doing the remote spawn. (Of course this would require > some pretty complex implementation to allow all nodes to create unique > pids on behalf of all other nodes, so it probably wouldn't be an > optimization after all - plus it would be a pretty useless optimization > if it were one, since you don't have much use for the pid until the > process exists - if you're in a real hurry, you could always spawn a > local process to do the remote spawn...) > > or > > The pid is assigned/created by the remote node, but for some unknown > reason it doesn't do it via a normal local spawn, instead using some > undocumented/internal mechanism that delivers a pid first (which is sent > back to the originating node immediately) and does the actual spawn > afterwards. > > Well, it *could* be implemented like that...:-) > > Either way, and beside (my understanding of) the question, both the > "useless pid" returned on some errors, and the case of the process dying > before it is sent a message, will result in an EXIT signal due to the > link/1 being done by the communicating process (though of course the > delivery of that EXIT signal is *not* necessarily synchronous). > > --Per Hedeland > Thank you all for your answers. This answers my question :) One last query - is this behaviour that I can rely on in the future (as far as the documentation binds us)? From bjorn@REDACTED Tue Aug 9 10:00:02 2005 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 09 Aug 2005 10:00:02 +0200 Subject: Line numbers in stack traces In-Reply-To: <02ADE0BC-D2C1-4258-94B1-39E6210D0440@citeulike.org> References: <02ADE0BC-D2C1-4258-94B1-39E6210D0440@citeulike.org> Message-ID: Richard Cameron writes: > > Have I missed the command line option which does this, or is there > some good reason why it's difficult for the virtual machine to report > on this information (some obscure consequence of the way it compiles > tail-recursive functions?) No, there is no command line option. Yes. There is a good reason. The virtual machine has no information about line numbers. It would be possible for the virtual machine to give you information about the exact address where the error occurred, but it would be hard to use that information. /Bjorn -- Bj?rn Gustavsson, Erlang/OTP, Ericsson AB From chandrashekhar.mullaparthi@REDACTED Tue Aug 9 11:10:06 2005 From: chandrashekhar.mullaparthi@REDACTED (Chandrashekhar Mullaparthi) Date: Tue, 9 Aug 2005 10:10:06 +0100 Subject: mnesia replication In-Reply-To: <42F7C9FE.5070904@hq.idt.net> References: <42F7C9FE.5070904@hq.idt.net> Message-ID: Hi, On 8 Aug 2005, at 22:09, Serge Aleynikov wrote: > Folks, > > I have a master mnesia database (disc_copy) and N replicas on > different nodes (ram_copies). Is it possible to postpone mnesia > replication from the master node to replicas, make data changes to the > master, perform some data validation and cleanup, and then force the > replicated nodes to resynch? I don't know of any way you can do this using mnesia. > Is this a good approach in terms of avoiding extensive locking > overhead in trying to load multiple tables with preserving referential > integrity of data accross several tables? Have you considered using sticky locks? They are quite useful if you are only ever going to write to mnesia on one node at a time. cheers Chandru From david.nospam.hopwood@REDACTED Tue Aug 9 14:19:21 2005 From: david.nospam.hopwood@REDACTED (David Hopwood) Date: Tue, 09 Aug 2005 13:19:21 +0100 Subject: Line numbers in stack traces In-Reply-To: References: <02ADE0BC-D2C1-4258-94B1-39E6210D0440@citeulike.org> Message-ID: <42F89F49.4050102@blueyonder.co.uk> Bjorn Gustavsson wrote: > Richard Cameron writes: > >>Have I missed the command line option which does this, or is there >>some good reason why it's difficult for the virtual machine to report >>on this information (some obscure consequence of the way it compiles >>tail-recursive functions?) > > No, there is no command line option. > > Yes. There is a good reason. The virtual machine has no information about > line numbers. Isn't that a design limitation of the virtual machine code format? I think language VMs should be designed to allow this at least in a debugging mode. -- David Hopwood From ke.han@REDACTED Tue Aug 9 17:04:28 2005 From: ke.han@REDACTED (ke.han) Date: Tue, 09 Aug 2005 23:04:28 +0800 Subject: Line numbers in stack traces In-Reply-To: References: <02ADE0BC-D2C1-4258-94B1-39E6210D0440@citeulike.org> Message-ID: <42F8C5FC.3080702@redstarling.com> Bjorn Gustavsson wrote: > Richard Cameron writes: > >>Have I missed the command line option which does this, or is there >>some good reason why it's difficult for the virtual machine to report >>on this information (some obscure consequence of the way it compiles >>tail-recursive functions?) > > > No, there is no command line option. > > Yes. There is a good reason. The virtual machine has no information about > line numbers. It would be possible for the virtual machine to give you information > about the exact address where the error occurred, but it would be hard > to use that information. > > /Bjorn I would have to list this as my #1 complaint about erlang. Far above any other gripes. I realize the tracing facility is robust. But it is certainly not convenient. Especially for someone new to erlang. I don't understand why the debug compile can't provide this info by default. Can someone explain what it would take to put this into a very near future release? thanks, ke han From serge@REDACTED Tue Aug 9 22:28:45 2005 From: serge@REDACTED (Serge Aleynikov) Date: Tue, 09 Aug 2005 16:28:45 -0400 Subject: mnesia replication In-Reply-To: References: <42F7C9FE.5070904@hq.idt.net> Message-ID: <42F911FD.9010107@hq.idt.net> Chandrashekhar Mullaparthi wrote: >> Is this a good approach in terms of avoiding extensive locking >> overhead in trying to load multiple tables with preserving referential >> integrity of data accross several tables? > > Have you considered using sticky locks? They are quite useful if you are > only ever going to write to mnesia on one node at a time. > I am experimenting with several writing methods including table-level locks, sticky locks, and backup-restore technique (suggested by Vance in one of the former emails), but haven't come to a conclusion yet which technique provides better performance in case of the following mnesia configuration and size of the database of about 700M: Master -------------- RamCopy1 DiskCopy ------+ ... | | ... | +------- RamCopyN Standby DiskCopy All writes happen either at the Master or at Standby (if Master is down) node. What I need to ensure is that: 1. RamCopy nodes can be added or removed as servers get added or removed to/from the network. 2. It should be possible to delete table copies of RamCopyK node from the mnesia schema on Master/Standby nodes, while the RamCopyK host is off-line. 3. Inavailability of both Master and Stadby nodes should not impact the accessibility of data on any RamCopy. 4. If at startup a RamCopy node detects no Master/Standby nodes, it should be able to load the database image from disk. 5. The should be no replication of data between RamCopy nodes, only from Master/Slave to RamCopy nodes. To address the issues above, While the following configuration mnesia:create_schema([ a@REDACTED, b@REDACTED, r@REDACTED, ..., r@REDACTED]) mnesia:create_table(some_table, [{disc_copies, [a@REDACTED, b@REDACTED]}, {ram_copies, [r@REDACTED, ..., r@REDACTED]}) solves #3; mnesia:add_table_copy/3 and mnesia:del_table_copy/2 takes case of #1; mnesia:wait_for_tables/2 and mnesia:force_load_table/1 takes care of #4, I am not sure how to deal with #2 and #5... Serge From meena_selvam@REDACTED Tue Aug 9 22:30:49 2005 From: meena_selvam@REDACTED (MEENA SELVAM) Date: Tue, 9 Aug 2005 13:30:49 -0700 (PDT) Subject: can i alter a parameter within a function Message-ID: <20050809203050.47766.qmail@web30402.mail.mud.yahoo.com> If I have a function which takes a parameter A as in the call f1("found") is it OK if I change the value of the parameter A within the function as below? f1(A) when A /= "not_found" -> VId =1, if s_key(VId) /= "not_found" -> VId = VId +1, f1(A), true-> A = "not_found", Vid -1 end ____________________________________________________ Start your day with Yahoo! - make it your home page http://www.yahoo.com/r/hs From hakan.stenholm@REDACTED Tue Aug 9 23:24:22 2005 From: hakan.stenholm@REDACTED (=?ISO-8859-1?Q?H=E5kan_Stenholm?=) Date: Tue, 09 Aug 2005 23:24:22 +0200 Subject: can i alter a parameter within a function In-Reply-To: <20050809203050.47766.qmail@web30402.mail.mud.yahoo.com> References: <20050809203050.47766.qmail@web30402.mail.mud.yahoo.com> Message-ID: <42F91F06.8040704@mbox304.swipnet.se> MEENA SELVAM wrote: >If I have a function which takes a parameter A as in >the call f1("found") is it OK if I change the value of >the parameter A within the function as below? > >f1(A) when A /= "not_found" -> > VId =1, > if s_key(VId) /= "not_found" -> > VId = VId +1, > f1(A), > true-> > A = "not_found", > Vid -1 > end > > No, you can't reassign the the value of a variable in the current function clause scoop. The example code will result in a pattern mismatch (and and a runtime exception) if the true branch is ever selected. The initial guard ensures that A /= "not_found", so the pattern match (which will be done as A has already been set to a value) will always fail. You'll need to introduce a new variable to hold any new value you want to use in a function clause. --if-- and --case-- statements are usually used like this: function(...) -> ... %% Res is set / bound to the last value of the evaluated branch. %% Res could be [A,B,C], {A,B}, A or any other valid %% pattern matching pattern, but is usually a single variable or a tuple if several %% variables are to be set by the branching statement (if, case, ...) Res = if ... -> ... true -> ... end, %% do something with the new variable/s from Res ... ps: atoms are faster than strings - i.e. the code will run faster if you use 'not_found' and 'found' instead, a single integer compare is done instead of a string compare. > > > > > >____________________________________________________ >Start your day with Yahoo! - make it your home page >http://www.yahoo.com/r/hs > > > > From ulf@REDACTED Wed Aug 10 00:59:33 2005 From: ulf@REDACTED (Ulf Wiger) Date: Wed, 10 Aug 2005 00:59:33 +0200 Subject: can i alter a parameter within a function In-Reply-To: <20050809203050.47766.qmail@web30402.mail.mud.yahoo.com> References: <20050809203050.47766.qmail@web30402.mail.mud.yahoo.com> Message-ID: Den 2005-08-09 22:30:49 skrev MEENA SELVAM : > > If I have a function which takes a parameter A as in > the call f1("found") is it OK if I change the value of > the parameter A within the function as below? > > f1(A) when A /= "not_found" -> > VId =1, > if s_key(VId) /= "not_found" -> > VId = VId +1, > f1(A), > true-> > A = "not_found", > Vid -1 > end No, you cannot alter the value of a variable once it has been bound. If you compile and run the code above, you will (after fixing the mis-spelled Vid on the 8th line) notice that it exits with a 'badmatch'. A is bound to a value when the function is called, and will retain that value until it's no longer referenced. Besides, on the 7th line, changing A (even if you could) would have no effect, since it is not referenced after that. Remember that all variables in Erlang have local scope. See chapter "6.3 Variables" in the Erlang Reference Manual (http://erlang.se/doc/doc-5.4.8/doc/reference_manual/expressions.html#6.3) /Uffe -- Ulf Wiger From bfulg@REDACTED Wed Aug 10 01:40:13 2005 From: bfulg@REDACTED (Brent Fulgham) Date: Tue, 9 Aug 2005 16:40:13 -0700 (PDT) Subject: editing erlang programs in vim In-Reply-To: Message-ID: <20050809234013.26395.qmail@web81204.mail.yahoo.com> --- James Hague wrote: > Nifty! If I can find the time, I'll try it. > > I tossed out the Erlang syntax coloring that comes > with vim and made my own. The big difference is > that I do syntax coloring of function > heads. For example, in this code: > > fib(N) when N < 2 -> 1; > fib(N) -> fib(N-2) + fib(N-1). > > everything to the left of the "->" on each line is > in it's own color. This makes code *much* easier to > read, at least for me. I would! In fact, the two of you should try to merge these syntax modes and forward them on to Bram. He's not an Erlang user (AFAIK) and would probably appreciate being provided a mode that is useful to real Erlang users. -Brent From ok@REDACTED Wed Aug 10 03:09:45 2005 From: ok@REDACTED (Richard A. O'Keefe) Date: Wed, 10 Aug 2005 13:09:45 +1200 (NZST) Subject: Line numbers in stack traces Message-ID: <200508100109.j7A19jUb341967@atlas.otago.ac.nz> Informed that The [Erlang] virtual machine has no information about line numbers. David Hopwood asked Isn't that a design limitation of the virtual machine code format? I think language VMs should be designed to allow this at least in a debugging mode. There are a number of assumptions hidden here: (1) all VM code comes from source code (2) all source code is hand-written (3) therefore all VM code *has* line numbers which it is simply incompetent of the VM not to retain. (4) the relationship between source lines and VM code is easy to maintain. Since Erlang/OTP provides several ways to generate and manipulate source code, (1) and (2) are false. Even in C, macros place serious limits on the utility of line numbers: a single "function call" in a line may expand to hundreds of tokens which cannot be stepped into, and the line where the error *is* may be in a completely different file from the reported line. Erlang macros are regrettably similar to C macros. Then we mustn't forget things like YECC and code generators like ASN.1 (see 'asn1') and CORBA interfaces (see 'ic'). While this is not yet a major consideration for Erlang, consider the fact that compilers for functional programming languages tend to do *major* restructuring, starting with in-line expansion, simplification, reordering, and progressing to things like deforestation (which is certainly applicable to Erlang). The practical consequence of this is that a few bytes of code (BEAM or other VM or HiPE-generated native code) may contain bits of many different functions, so that line number information would overwhelm actual useful code. I'd rather see a QuickCheck for Erlang; is there one? From david.nospam.hopwood@REDACTED Wed Aug 10 04:47:47 2005 From: david.nospam.hopwood@REDACTED (David Hopwood) Date: Wed, 10 Aug 2005 03:47:47 +0100 Subject: Line numbers in stack traces In-Reply-To: <200508100109.j7A19jUb341967@atlas.otago.ac.nz> References: <200508100109.j7A19jUb341967@atlas.otago.ac.nz> Message-ID: <42F96AD3.7060700@blueyonder.co.uk> Richard A. O'Keefe wrote: > Informed that > The [Erlang] virtual machine has no information about line numbers. > > David Hopwood asked > > Isn't that a design limitation of the virtual machine code format? > I think language VMs should be designed to allow this at least in a > debugging mode. > > There are a number of assumptions hidden here: > (1) all VM code comes from source code > (2) all source code is hand-written I wasn't assuming either of these. I said that the VM format should be *designed to allow this*. I.e. where source line numbers exist (not necessarily Erlang source; the concept of line numbers applies to any textual source language), the VM format should provide a way of encoding them, at least in a debugging mode. And line numbers are still useful if the source is machine-generated, to the writer of the generator program. > (3) therefore all VM code *has* line numbers > which it is simply incompetent of the VM not to retain. I didn't say that it was an incompetent decision, either. It is a design limitation, not shared by many other VM designs (e.g. typical Java and Smalltalk VMs). > (4) the relationship between source lines and VM code is easy to maintain. It's not trivial, but it's not rocket science either. > Since Erlang/OTP provides several ways to generate and manipulate source > code, (1) and (2) are false. Even in C, macros place serious limits on > the utility of line numbers: a single "function call" in a line may > expand to hundreds of tokens which cannot be stepped into, True, but there is only so much code on a line, even if it expands to "hundreds of tokens". The size of the expansion isn't actually very important; what matters is whether a line number identifies the point at which the exception occurred in a way that is usefully more precise than the current stack traces. Stepping into the code isn't what we were talking about; line numbers in stack traces do not replace a debugger. > and the line where the error *is* may be in a completely different file > from the reported line. Erlang macros are regrettably similar to C macros. This is true, but it doesn't seriously interfere with the utility of line numbers, especially for programmers who make little or no use of macros. In any case, if the particular line that is reported contains a macro application, then it is obvious that the problem might be with the macro definition. I don't see why that would be surprising or difficult to deal with. > Then we mustn't forget things like YECC and code generators like ASN.1 > (see 'asn1') and CORBA interfaces (see 'ic'). JVM classfiles have a way of specifying line numbers in multiple levels of source language, e.g. both the input and the output of a code generator. > While this is not yet a major consideration for Erlang, consider the > fact that compilers for functional programming languages tend to do > *major* restructuring, starting with in-line expansion, simplification, > reordering, and progressing to things like deforestation (which is > certainly applicable to Erlang). The practical consequence of this is > that a few bytes of code (BEAM or other VM or HiPE-generated native > code) may contain bits of many different functions, so that line number > information would overwhelm actual useful code. That's one reason why you might only want to support this in a debugging mode. I am skeptical that the size of this information would be larger than the actual code except in contrived pathological cases, though. -- David Hopwood From ok@REDACTED Wed Aug 10 07:16:09 2005 From: ok@REDACTED (Richard A. O'Keefe) Date: Wed, 10 Aug 2005 17:16:09 +1200 (NZST) Subject: Line numbers in stack traces Message-ID: <200508100516.j7A5G9R6412823@atlas.otago.ac.nz> David Hopwood continues: > There are a number of assumptions hidden here: > (1) all VM code comes from source code > (2) all source code is hand-written I wasn't assuming either of these. Not deliberately, perhaps, but these are extremely common assumptions amongst programmers in general. It is *important* to remember that programs are DATA. I said that the VM format should be *designed to allow this*. But that is to assume that this is more important than other things (like compact code). For example, I just compiled a C program with (129k) and without (68k) debugging information. The debugging information pretty much doubled the size of the file. Doubtless you will retort that this cost comes from *having* debugging information, not from *being able to have* debugging information. But there is a cost: a considerably more complicated object code format is required to support the debugging info. I.e. where source line numbers exist (not necessarily Erlang source; the concept of line numbers applies to any textual source language), This isn't actually true, and I have used just such a language. Interlisp-D on the Xerox D-machines. There *was* a textual form in files, and there *was* a "textual" editor. And while debugging support on the D-machines was excellent, I can't for the life of me think of any reason why anyone would ever have wanted to know a line number. Line numbers were totally under the control of the pretty-printer. Oh yeah, another such language I use a lot: Smalltalk. When you edit code, what you see is text. But (a) you can flip between text as you typed it, pretty-printed text, pretty-printed text with colouring, or a non-traditional syntax, and (b) the code doesn't *have* line numbers, even though it eventually ends up in a file. This is not a barrier to debugging, in fact although I have debugged more Smalltalk code than I like to admit getting wrong, it only just occurred to me that there was no way of finding out about line numbers. Smalltalk doesn't have macros, which helps a lot when debugging it. the VM format should provide a way of encoding them, at least in a debugging mode. You are confusing a *source position* (which makes sense even if, as in Interlisp-D and Smalltalk, the code is technically held in a data base) with *line numbers*. And line numbers are still useful if the source is machine-generated, to the writer of the generator program. I was assuming the fairly common situation in which the person debugging the code is NOT the person who wrote the generator. Note that if a programming language is intended for use with tail recursion optimisation, as Prolog and Scheme and Erlang are, then a debugger *must* discard most dynamic line number information or else choke on its own stack. (Prolog debuggers commonly choose the choke-on-your-own-stack option.) > (3) therefore all VM code *has* line numbers > which it is simply incompetent of the VM not to retain. I didn't say that it was an incompetent decision, either. It is a design limitation, not shared by many other VM designs (e.g. typical Java and Smalltalk VMs). The only Smalltalk VMs I am familiar with are the ones described in the Blue Book (which just happens to be on my desk right beside my terminal at the moment), the closely related one in Squeak, and a couple of new ones described in the Squeak mailing list. (Oh, and the one used in a CIT thesis in the 80s.) NONE of them have any provision for line number information. I don't know what Ambrai Smalltalk's VM looks like, but I can't find anything in its CompiledCode class that refers to line numbers. Basically, Smalltalk debuggers rely on finding 'call' instructions in the byte code and matching them up to message sends in the source. (In Smalltalk-80, Squeak, and Ambrai, stack traces do NOT include line numbers.) This points the way to an Erlang debugger which doesn't have and doesn't need line number information: all it needs is "which clause of which function in which module?" Given that, when you want to display the right position in a debugger window, you pick up the function from the window, find the clause, compile it, and match the VM instruction position to the position in the clause. If the compiler recorded the source position of the first token of each clause in each function, then knowing which clause of which function you were in would get you very close in terms of line numbers. Like well-written Smalltalk, well-written Erlang is supposed to have lots of *small* clauses, no? Of course, function inlining would make that problematic. > (4) the relationship between source lines and VM code is easy to maintain. It's not trivial, but it's not rocket science either. It's sufficiently difficult that people have earned PhDs for doing it. I think there are much better things to spend the time and money on. True, but there is only so much code on a line, even if it expands to "hundreds of tokens". I have had to debug C code where one line, looking like a function call, expanded via a cascade of macros, to the equivalent of several hundred *lines*. The size of the expansion isn't actually very important; what matters is whether a line number identifies the point at which the exception occurred in a way that is usefully more precise than the current stack traces. But those are the *same* question. The expansion is not only very large, it is inaccessible. In debugging other people's C code I have several times been reduced to cc -E ... foobar.c | cb >foobar-i.c cc -g ... foobar-i.c mv foobar-i.o foobar.o in order to get something "usefully more precise". (Oddly enough, the program that gave me the most trouble in this regard was written by a full Professor of Software Engineering...) Stepping into the code isn't what we were talking about; line numbers in stack traces do not replace a debugger. Nobody ever said they did. > and the line where the error *is* may be in a completely different file > from the reported line. Erlang macros are regrettably similar to C macros. This is true, but it doesn't seriously interfere with the utility of line numbers, This has not been my experience. especially for programmers who make little or no use of macros. In any case, if the particular line that is reported contains a macro application, then it is obvious that the problem might be with the macro definition. I don't see why that would be surprising or difficult to deal with. Because it isn't "obvious" *where* the problem is within the cascade of macro applications. JVM classfiles have a way of specifying line numbers in multiple levels of source language, e.g. both the input and the output of a code generator. Good for them. (Although the relevant word here is 'enhancements'.) However, the fact that there is an interface is no guarantee that there is anything at the other end of it. See the Location interface, where we learn The availability of a line number for a location will depend on the level of debugging information from the target VM. We also learn if we read further that there is no way of passing this information through Java *source* code, which is a pity. There is one important difference between Erlang and Java: the level of support. There is so much money and manpower behind Java that Sun can afford to do things (and so much muscle behind C# that Sun cannot afford NOT to do things) that are not necessarily a good use of resources for enhancing Erlang. [Modern functional compilers can restructure the code in truly major ways.] That's one reason why you might only want to support this in a debugging mode. Note, above all, that A DEBUGGING MODE NEED NOT USE THE VM. For example, the Quintus Prolog debugger was *not* based in any way on the WAM: debugged code was interpreted from abstract syntax trees, rather like Lisp. (For that matter, in order to get source information, later versions of QP even used a special version of 'read'.) So in order to support line number information (should that prove to be usefully more precise than {module,function,arity,clause}) in a debugging mode, it is NOT necessary to have any support for line numbers in the VM. (As noted above, QP was able to provide source positions in debugging mode without having any support for it in the WAM.) I am skeptical that the size of this information would be larger than the actual code except in contrived pathological cases, though. It is large, because the information required basically amounts to undoing the transformations. Inlining is just the beginning. My earlier mention of TRO doesn't seem to have sunk in. Iterative code in Erlang relies on turning the dynamically last call in a function into a jump. When an error (badmatch, badarith, badarg, &c) is reported, the line number of the actual error report doesn't tell you very much. Quite often it's inside some system function. *Your* function call which contains the error has very often disappeared completely from the stack. The important question is not "is adding line numbers a good way to improve Erlang stack traces" but "what is the best use of Erlang development resources to help people get their Erlang programs right?" As I think I've said, I'd rather have QuickCheck. From ok@REDACTED Wed Aug 10 07:42:39 2005 From: ok@REDACTED (Richard A. O'Keefe) Date: Wed, 10 Aug 2005 17:42:39 +1200 (NZST) Subject: Line numbers in stack traces Message-ID: <200508100542.j7A5gdo2391299@atlas.otago.ac.nz> I pointed out that macros make source line numbers much less useful, lamenting that Erlang has such things. David Hopwood wrote This is true, but it doesn't seriously interfere with the utility of line numbers, especially for programmers who make little or no use of macros. I just extracted all the non-white-space non-comment non-'end' lines from the *.[ehy]rl files in an Erlang distribution, and found that one line in 94 is a -define. This is a *higher* proportion of -defines in Erlang/OTP than I have #defines in my C code! From tpatro@REDACTED Wed Aug 10 07:58:37 2005 From: tpatro@REDACTED (Tamas Patrovics) Date: Wed, 10 Aug 2005 07:58:37 +0200 Subject: ESense 1.8 released In-Reply-To: References: Message-ID: Changes https://sourceforge.net/project/shownotes.php?group_id=139206&release_id=348134 Files https://sourceforge.net/projects/esense/ Homepage http://esense.sourceforge.net/ From mikael.karlsson@REDACTED Wed Aug 10 08:22:59 2005 From: mikael.karlsson@REDACTED (Mikael Karlsson) Date: Wed, 10 Aug 2005 08:22:59 +0200 Subject: pretty printing of records Message-ID: <200508100823.00075.mikael.karlsson@creado.com> I have noticed the nice erlang shell commands rr() and rp() to display records with attribute names and all. Is there a way to do something similar directly from a program, using io:format("..",[Record]) for instance? Mikael From Lennart.Ohman@REDACTED Wed Aug 10 10:04:23 2005 From: Lennart.Ohman@REDACTED (=?iso-8859-1?Q?Lennart_=D6hman?=) Date: Wed, 10 Aug 2005 10:04:23 +0200 Subject: SV: pretty printing of records Message-ID: Hi, the main "problem" is of course that record-field names are not available in run-time, unless *you* store them some place. The nice rr functionality in the shell then of course reads a record definition and stores it "somewhere", available to the shell process. And then formats any tuple suspected of being that record accordingly instead of plain tuple format. What you want to do is pretty simple to accomplish in your own program. But you must have run-time access to field-names and their respective location. This can of course be done by using standard record constructs such as record_info(fields,RecordType) (which in compile time will expand to the list of all fields in their correct order). I would make a function which returns a string looking like a record (#myrecord{field1=foo,field2=bar}) and then call io:format("~s",[record2string(Record,record_info(fields,myrecord))]) Since the record_info construct will expand to a list in compile time. It might be of interest, if .beam sizes is of importance and their will be a lot of calls to record2string/2, to make a more clever record2string function which instead has all record-field lists expanded once and for all, taking just the record-type as argument. Best Regards, Lennart ------------------------------------------------------------- Lennart Ohman phone : +46-8-587 623 27 Sj?land & Thyselius Telecom AB cellular: +46-70-552 6735 Sehlstedtsgatan 6 fax : +46-8-667 8230 SE-115 28 STOCKHOLM, SWEDEN email : lennart.ohman@REDACTED ________________________________ Fr?n: owner-erlang-questions@REDACTED genom Mikael Karlsson Skickat: on 2005-08-10 08:22 Till: erlang-questions@REDACTED ?mne: pretty printing of records I have noticed the nice erlang shell commands rr() and rp() to display records with attribute names and all. Is there a way to do something similar directly from a program, using io:format("..",[Record]) for instance? Mikael -------------- next part -------------- An HTML attachment was scrubbed... URL: From vlad.xx.dumitrescu@REDACTED Wed Aug 10 10:37:12 2005 From: vlad.xx.dumitrescu@REDACTED (Vlad Dumitrescu XX (LN/EAB)) Date: Wed, 10 Aug 2005 10:37:12 +0200 Subject: pretty printing of records Message-ID: <11498CB7D3FCB54897058DE63BE3897C4BE5B8@esealmw105.eemea.ericsson.se> Hi, Using record_info is a compile-time option - you can only do it in a module where the record is defined. Which is fine most of the time. For the mode advanced use, there is a contribution in jungerl (lib/msc/src/rec_info.erl) that will use the tricks from shell.erl to take a record and a module where it is defined and return a list of {key, value}s. This works dynamically, retrieving the record definition from the module's beam or the source. Of course, you still need to know of a module where this record is used. It's not at all optimized, but might be useful. One issue is that retrieving record info from a source file requires compiling it... best regards, Vlad -------------- next part -------------- An HTML attachment was scrubbed... URL: From camster@REDACTED Wed Aug 10 12:33:27 2005 From: camster@REDACTED (Richard Cameron) Date: Wed, 10 Aug 2005 11:33:27 +0100 Subject: Line numbers in stack traces In-Reply-To: <200508100516.j7A5G9R6412823@atlas.otago.ac.nz> References: <200508100516.j7A5G9R6412823@atlas.otago.ac.nz> Message-ID: On 10 Aug 2005, at 06:16, Richard A. O'Keefe wrote: > You are confusing a *source position* (which makes sense even if, > as in > Interlisp-D and Smalltalk, the code is technically held in a data > base) > with *line numbers*. OK. This is perhaps straying away from the point though. Whether I get a line number, or some other way of working out where my program died, that's got to be good news. I've just spent a good five minutes tracking down a badmatch inside a gen_server handle_call/3 function. There's a clause for each message the server handles, so saying the error is in handle_call/3 is effectively sending me off to look for a needle in a haystack - especially when the virtual machine probably knows (or could know) more information about where it went wrong and is only giving me cryptic clues so I can work it out for myself. > Note that if a programming language is intended for use with tail > recursion optimisation, as Prolog and Scheme and Erlang are, then > a debugger *must* discard most dynamic line number information or > else choke on its own stack. (Prolog debuggers commonly choose the > choke-on-your-own-stack option.) Fine. I admit that optimising away tail-recursive function calls complicates matters somewhat, but I don't think it makes it impossible. "Programs are data" as you point out before, and Lisp is an example of a language with far more complex macro substitution than Erlang. If you imagine the compiler repeatedly transforming the S-expressions of your raw source code down into simpler and simpler forms which eventually converge into something which can be translated down into bytecode or machine instructions, then there *is* an inherent concept of source position which can be inferred from the address of the crash - you simply unravel the compilation process back to find out which expression in the user's code caused the problem. If you partially unravel the compilation process you get to see intermediate results of macro substitution. Whether this gives a line number directly is irrelevant. In your Lisp environment where all code is pretty printed you can simply ask the pretty printer which line it's chosen to print that expression on today. Of course, if I can a location of the error more detailed than just a line number, I'd take that too. > to line numbers. Basically, Smalltalk debuggers rely on finding > 'call' > instructions in the byte code and matching them up to message sends in > the source. (In Smalltalk-80, Squeak, and Ambrai, stack traces do NOT > include line numbers.) So we're talking about an implementation issue here? Instead of, say, bloating up your bytecode by adding a (filename, linenumber) tuple to each instruction, can't we build up a mapping table (the one I talk about above) at compile time which maps the bytecode address back up into the original source code? From what I recall, this is how the debug information is stored in a C executable. Does this address your concerns about bloating the size of the bytecode in a world where the VM can handle debugging information, but the user has chosen to disable it? In that case, we'd just eliminate the source<->bytecode mapping structure and the overhead of "potentially" having debug information would be pretty much zero? > If the compiler recorded the source position of the first token > of each clause in each function, then knowing which clause of which > function you were in would get you very close in terms of line > numbers. Yes. I think that's what I'm suggesting. Actually, if you're going for broke, why not record the position of each expression in the function in our separate (optional) mapping table. > Like well-written Smalltalk, well-written Erlang is supposed to have > lots of *small* clauses, no? handle_call/3 is probably the worst case I've seen at the moment. Lots of little function clauses which make up one big function. Unfortunately the stack trace doesn't tell you which *clause* it failed in... only the function name and arity. That's decidedly annoying. > It's sufficiently difficult that people have earned PhDs for doing it. > I think there are much better things to spend the time and money on. Well... if it's a choice between spending my time and money trying to interpret somewhat vague stack traces, then I could see the attraction of investing some of my time sorting this out. > In any case, if the particular line that is reported contains a > macro application, then it is obvious that the problem might be > with the macro definition. I don't see why that would be > surprising or difficult to deal with. > > Because it isn't "obvious" *where* the problem is within the > cascade of > macro applications. But this problem has been satisfactorily dealt with in Lisp, which has far more powerful and confusing macro support than Erlang. > There is one important difference between Erlang and Java: > the level of support. > There is so much money and manpower behind Java that Sun can afford > to do things (and so much muscle behind C# that Sun cannot afford NOT > to do things) that are not necessarily a good use of resources for > enhancing Erlang. Well, I really don't think that expecting the stack trace to tell you precisely where the error occurred is something that Sun/Microsoft implement in their VMs purely for beauty parade purposes such that IT consultant produce ticks in the appropriate boxes. It's highly useful, and it's really winding me up that I can't see this information at the moment. My initial impressions of Erlang are that I'm far more efficient writing "control" applications in it than I am in Python/Ruby/Tcl etc, and that it seems to encourage me to think in way where I produce fewer bugs. I'm generally much more confident that, once the code compiles, it'll work first time than I am in pretty much any other language. However, the really horrible part comes when I really do have to start interpreting stack traces. I feel like I'm playing a guessing game, and I'm just wasting my time. It's possible I'm just not yet experienced enough in Erlang to think in ways which don't require me to know where the code has crashed, or to perhaps just grumpily accept the fact that the runtime doesn't tell me that. But, for now, I'd have to rank it as the most significant disadvantage of the language. > So in order to support line number information (should that prove > to be > usefully more precise than {module,function,arity,clause}) in a > debugging > mode, it is NOT necessary to have any support for line numbers in > the VM. > (As noted above, QP was able to provide source positions in > debugging mode > without having any support for it in the WAM.) I think this is exactly what I'm talking about. I just can't see why you don't want it. > It is large, because the information required basically amounts to > undoing > the transformations. Inlining is just the beginning. Doesn't this just result in a more complex source<->bytecode mapping table? > My earlier mention of TRO doesn't seem to have sunk in. > Iterative code in Erlang relies on turning the dynamically last > call in a function into a jump. > > When an error (badmatch, badarith, badarg, &c) is reported, the line > number of the actual error report doesn't tell you very much. Quite > often it's inside some system function. *Your* function call which > contains the error has very often disappeared completely from the > stack. So your function call disappears from the reported stack trace too. I don't see how that makes the availability of more detailed code position information relatively less useful. I can (just about) live with functions disappearing from the stack like that... and I really don't want to complicate things by throwing yet another idea in, but how about creating a ring-buffer in the virtual machine to keep track of the top n items of the "logical" stack. So, instead of simply producing a jump instruction at a tail- recursive call, why don't we write the stack frame which would have been generated if we didn't have this optimisation into the buffer? That might go some way into solving the other (but less annoying) erlang stack trace problem of it omitting function calls which have been optimised away - you'd generate the top n levels of the stack trace from the ring buffer, and then glue on whatever else is sitting below on the real stack? > The important question is not "is adding line numbers a good way to > improve Erlang stack traces" but "what is the best use of Erlang > development resources to help people get their Erlang programs right?" > > As I think I've said, I'd rather have QuickCheck. Oh, I don't think so. Programs crash, and all I want to know is where they've crashed. This information is (almost) in the virtual machine already, and it really annoys me to have to play a guessing game every time. Richard. From richardc@REDACTED Wed Aug 10 12:32:52 2005 From: richardc@REDACTED (Richard Carlsson) Date: Wed, 10 Aug 2005 12:32:52 +0200 Subject: Line numbers in stack traces In-Reply-To: <200508100109.j7A19jUb341967@atlas.otago.ac.nz> References: <200508100109.j7A19jUb341967@atlas.otago.ac.nz> Message-ID: <42F9D7D4.9000405@csd.uu.se> Richard A. O'Keefe wrote: > I'd rather see a QuickCheck for Erlang; is there one? Yes, there is: http://www.cs.chalmers.se/~rjmh/ErlangQC/ /Richard From vlad.xx.dumitrescu@REDACTED Wed Aug 10 12:53:16 2005 From: vlad.xx.dumitrescu@REDACTED (Vlad Dumitrescu XX (LN/EAB)) Date: Wed, 10 Aug 2005 12:53:16 +0200 Subject: Line numbers in stack traces Message-ID: <11498CB7D3FCB54897058DE63BE3897C4BE5BA@esealmw105.eemea.ericsson.se> > -----Original Message----- > From: owner-erlang-questions@REDACTED > [mailto:owner-erlang-questions@REDACTED]On Behalf Of Richard Cameron > Programs crash, and all I want to know is where > they've crashed. This information is (almost) in the virtual machine > already, and it really annoys me to have to play a guessing game > every time. Hi, I would also like to see better support for this. If you have a bug to hunt *now*, a way to find out which clause in handle_call is at fault, you can start the gen_server with a {debug, [trace]} option and you will get on the console a listing of all messages that the process received. The last one is usually the one thet triggered the exception. regards, Vlad From ulf.wiger@REDACTED Wed Aug 10 13:48:12 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Wed, 10 Aug 2005 13:48:12 +0200 Subject: pretty printing of records Message-ID: My suggestion back in May 24 was the following: http://www.erlang.org/ml-archive/erlang-questions/200505/msg00201.html (My hack didn't work with remote shells. They do something really weird with pids and I/O redirection.) /Uffe > -----Original Message----- > From: owner-erlang-questions@REDACTED > [mailto:owner-erlang-questions@REDACTED]On Behalf Of Mikael Karlsson > Sent: den 10 augusti 2005 08:23 > To: erlang-questions@REDACTED > Subject: pretty printing of records > > > I have noticed the nice erlang shell commands rr() and rp() > to display records with attribute names and all. > Is there a way to do something similar directly from a > program, using io:format("..",[Record]) for instance? > > Mikael > > From olivier@REDACTED Wed Aug 10 14:44:55 2005 From: olivier@REDACTED (olivier) Date: Wed, 10 Aug 2005 14:44:55 +0200 Subject: pretty printing of records In-Reply-To: References: Message-ID: <42F9F6C7.3000002@dolphian.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello, Speaking of pretty-printing, I'd like to submit a feature request for the "tv" module of erlang: I recently patched tv_io_lib.erl to "view binaries as strings", as I store binaries in Mnesia that are printable. That could be an addition to "view lists as lists/strings", what do you think ? Cheers, - -- Olivier Girondel Project Leader Dolphian -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org iD8DBQFC+fbGpqVXaJzJYNIRArLEAKCEMZkxsSyo367FqLkPECWhpPxOowCffAQS Nv4beW/kRdlw29QIzwIrcPc= =az71 -----END PGP SIGNATURE----- From erlang@REDACTED Wed Aug 10 14:55:51 2005 From: erlang@REDACTED (Inswitch Solutions) Date: Wed, 10 Aug 2005 09:55:51 -0300 Subject: Mnesia vs MySQL Message-ID: <1fbd01c59daa$d969d500$4a00a8c0@Inswitch251> Hi, MySql database has been improved a lot and we are evaluating it using ODBC Erlang application. As far as I know MySql has all mnesia features (replicas, distribution, ..), plus GUI administration and SQL. What points in favour does Mnesia database have over MySQL? Perfomarnce issues? thanks, Eduardo Prepaid Expertise - Programmable Switches Powered by Ericsson Licensed Technology Eng. Eduardo Figoli - Development Center - IN Switch Solutions Inc. Headquarters - Miami-U.S.A. Tel: 1305-3578076 Fax: 1305-7686260 Development Center - Montevideo - Uruguay Tel/Fax: 5982-7104457 e-mail: eduardo@REDACTED -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image001.gif Type: image/gif Size: 1429 bytes Desc: not available URL: From ulf.wiger@REDACTED Wed Aug 10 15:07:41 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Wed, 10 Aug 2005 15:07:41 +0200 Subject: Mnesia vs MySQL Message-ID: Mnesia is different from MySQL in several ways. Whether or not the differences are in Mnesia's favour certainly depends on what you need to do: - No semantic gap for erlang programmers. Mnesia operates directly on Erlang terms and uses Erlang semantics for accesses - Low latency. E.g. dirty_read from a mnesia table takes only a few microseconds. There is no way you can read a MySQL object as quickly. This assumes that your application is written in erlang, of course. - In-service upgrade. Mnesia can be upgraded without service interruption. - Small memory footprint (not that I know how much MySQL uses) There are certainly other differences. I'll let someone else continue. /Uffe -----Original Message----- From: owner-erlang-questions@REDACTED [mailto:owner-erlang-questions@REDACTED]On Behalf Of Inswitch Solutions Sent: den 10 augusti 2005 14:56 To: erlang-questions@REDACTED Subject: Mnesia vs MySQL Hi, MySql database has been improved a lot and we are evaluating it using ODBC Erlang application. As far as I know MySql has all mnesia features (replicas, distribution, ..), plus GUI administration and SQL. What points in favour does Mnesia database have over MySQL? Perfomarnce issues? thanks, Eduardo Prepaid Expertise - Programmable Switches Powered by Ericsson Licensed Technology Eng. Eduardo Figoli - Development Center - IN Switch Solutions Inc. Headquarters - Miami-U.S.A. Tel: 1305-3578076 Fax: 1305-7686260 Development Center - Montevideo - Uruguay Tel/Fax: 5982-7104457 e-mail: eduardo@REDACTED -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image001.gif Type: image/gif Size: 1429 bytes Desc: image001.gif URL: From erlang@REDACTED Wed Aug 10 15:11:03 2005 From: erlang@REDACTED (Inswitch Solutions) Date: Wed, 10 Aug 2005 10:11:03 -0300 Subject: pretty printing of records References: <42F9F6C7.3000002@dolphian.com> Message-ID: <1fee01c59dac$f95acb60$4a00a8c0@Inswitch251> Surely not the best way but I print records like this: %% function to expose each record info getFields(myRecord) -> record_info(fields, myRecord); ... %% the record output in "field......value" format makeResponse([], [], StrResp) -> StrResp; makeResponse([F|Fields], [V|TValues], StrResp) -> Fld = io_lib:format("~p......................", [F]), Str = io_lib:format("~20s: ~p\r\n", [Fld, V]), makeResponse(Fields, TValues, StrResp++Str). Hope it helps you, Eduardo ----- Original Message ----- From: "olivier" To: "Ulf Wiger (AL/EAB)" Cc: "Mikael Karlsson" ; Sent: Wednesday, August 10, 2005 9:44 AM Subject: Re: pretty printing of records > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > > Hello, > > Speaking of pretty-printing, I'd like to submit a feature request > for the "tv" module of erlang: > > I recently patched tv_io_lib.erl to "view binaries as strings", as > I store binaries in Mnesia that are printable. That could be an > addition to "view lists as lists/strings", what do you think ? > > Cheers, > > - -- > Olivier Girondel > Project Leader > Dolphian > -----BEGIN PGP SIGNATURE----- > Version: GnuPG v1.4.1 (GNU/Linux) > Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org > > iD8DBQFC+fbGpqVXaJzJYNIRArLEAKCEMZkxsSyo367FqLkPECWhpPxOowCffAQS > Nv4beW/kRdlw29QIzwIrcPc= > =az71 > -----END PGP SIGNATURE----- > From chandrashekhar.mullaparthi@REDACTED Wed Aug 10 16:14:14 2005 From: chandrashekhar.mullaparthi@REDACTED (Chandrashekhar Mullaparthi) Date: Wed, 10 Aug 2005 15:14:14 +0100 Subject: mnesia replication In-Reply-To: <42F911FD.9010107@hq.idt.net> References: <42F7C9FE.5070904@hq.idt.net> <42F911FD.9010107@hq.idt.net> Message-ID: On 9 Aug 2005, at 21:28, Serge Aleynikov wrote: > Chandrashekhar Mullaparthi wrote: >>> Is this a good approach in terms of avoiding extensive locking >>> overhead in trying to load multiple tables with preserving >>> referential integrity of data accross several tables? >> Have you considered using sticky locks? They are quite useful if you >> are only ever going to write to mnesia on one node at a time. > > I am experimenting with several writing methods including table-level > locks, sticky locks, and backup-restore technique (suggested by Vance > in one of the former emails), but haven't come to a conclusion yet > which technique provides better performance in case of the following > mnesia configuration and size of the database of about 700M: > > Master -------------- RamCopy1 > DiskCopy ------+ ... > | | ... > | +------- RamCopyN > Standby > DiskCopy > > All writes happen either at the Master or at Standby (if Master is > down) node. > > What I need to ensure is that: > > 2. It should be possible to delete table copies of RamCopyK node from > the mnesia schema on Master/Standby nodes, while the RamCopyK host is > off-line. You can do this using mnesia:del_table_copy/3 mnesia:del_table_copy(schema, r@REDACTED). Once you do this you are not supposed to bring back the node r@REDACTED with it's old database. The results are "undefined" according to the documentation. > > 5. The should be no replication of data between RamCopy nodes, only > from Master/Slave to RamCopy nodes. AFAIK, this is not possible with mnesia. But as long as you are not going to perform updates on the RAM copy nodes, there will not be any replication traffic between these nodes - it will always be from master/slave to the ram copy nodes. > I am not sure how to deal with #2 and #5... hope this helps. Chandru From ulf.wiger@REDACTED Wed Aug 10 16:23:17 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Wed, 10 Aug 2005 16:23:17 +0200 Subject: push_element/2 - efficient sliding window Message-ID: Inspired by Joel Reymont's trials trying to make an on-line trading platform in erlang, and by the recent discussions about trace data, I thought I'd try to invent a new BIF (never tried that before...) Since I have no authority to introduce BIFs in Erlang, getting this accepted could be done by: (a) the OTP team finding it a good idea and just doing it (b) enough users finding it useful to generate popular demand. erlang:push_element(Tuple, Value) pushes value into position 1 of Tuple, shifting the existing values one step to the right. This can be used as a fixed-size sliding window which costs the same as setelement/3 to update. Eshell V5.4.8 (abort with ^G) 1> erlang:push_element({a,b,c},3). {3,a,b} 2> erlang:push_element(v(1),3). {3,3,a} 3> erlang:push_element({a,b},3). {3,a} 4> erlang:push_element({a},3). {3} 5> erlang:push_element({},3). =ERROR REPORT==== 10-Aug-2005::16:10:49 === Error in process <0.30.0> with exit value: {badarg,[{erlang,push_element,[{},3]},{erl_eval,do_apply,5},{shell,exprs,6},{shell,eval_loop,3}]} ** exited: {badarg,[{erlang,push_element,[{},3]}, {erl_eval,do_apply,5}, {shell,exprs,6}, {shell,eval_loop,3}]} ** 6> T = erlang:make_tuple(200,a). {a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a|...} 7> timer:tc(erlang,push_element,[T,1]). {8,{1,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a|...}} My heavy-handed attempt at writing this in C (copy-paste setelement_3 and tweaking it some): BIF_RETTYPE push_element_2(BIF_ALIST_2) { Eterm* ptr; Eterm* hp; Eterm* resp; Uint size; if (is_not_tuple(BIF_ARG_1)) { error: BIF_ERROR(BIF_P, BADARG); } ptr = tuple_val(BIF_ARG_1); size = arityval(*ptr) + 1; /* include arity */ if (size < 2) { goto error; } hp = HAlloc(BIF_P, size); /* copy the tuple */ resp = hp; *hp++ = *ptr++; *hp++ = BIF_ARG_2; size = size-2; while (size--) { /* XXX use memcpy? */ *hp++ = *ptr++; } BIF_RET(make_tuple(resp)); } You then have to go into erts/emulator/beam/bif.tab and add the new BIF. In order to test it, make clean, and then 'make opt' (rebuild the optimized beam). /Uffe From thomasl_erlang@REDACTED Wed Aug 10 16:40:25 2005 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Wed, 10 Aug 2005 07:40:25 -0700 (PDT) Subject: Line numbers in stack traces In-Reply-To: <02ADE0BC-D2C1-4258-94B1-39E6210D0440@citeulike.org> Message-ID: <20050810144025.24569.qmail@web34414.mail.mud.yahoo.com> --- Richard Cameron wrote: > Is there any way to extract enough information from > a standard erlang > stack trace to be able to work out at which line the > exception was > thrown? I wrote a parse transform that took care of this, smart_exceptions in jungerl. Alas, using it in R10 is a hassle since the compiler warns about generated code (and can't be told to shut up). And using it has triggered an evil compiler bug, so perhaps it's not practical anymore. (The compiler bug probably is fixed by now; I don't recall.) The key idea is that exceptions are generated only at certain known points in the code. So the transform works like this: at every* point where an exception can be thrown, code is inserted to throw a more informative exception which indicates the module, line, reason, involved data and whatnot. * Every point I could think of; I missed handling exceptions thrown when you try to build a binary. A simple example: f(a, X) -> g(X). would become something like this: f(a,X) -> g(X); f(T1,T2) -> exit({?MODULE, ?LINE, function_clause, [T1,T2]}). BIFs were handled by catching exceptions and rethrowing a more informative one. And so on. Look at the generated code for details. (The beam compiler gets rid of redundant code too.) Having "smart exceptions" has been quite useful for practical work, but I would prefer an official/supported solution. That could use the same technique as above, which is not a huge effort. (It would be possible to do better too.) As someone mentioned, adding debugging support increases object code size (and compile time in this case). Personally, I have found it well worth the cost. Best, Thomas ____________________________________________________ Start your day with Yahoo! - make it your home page http://www.yahoo.com/r/hs From joelr1@REDACTED Wed Aug 10 16:45:32 2005 From: joelr1@REDACTED (Joel Reymont) Date: Wed, 10 Aug 2005 16:45:32 +0200 Subject: push_element/2 - efficient sliding window In-Reply-To: References: Message-ID: <96491556-1B65-46E3-B46F-69B4B71C84AC@gmail.com> Go Uffe! Now I just need another BIF to slide a tuple of a fixed size over a large tuple. Then I would be happy :-). Say you have a tuple of 1,000,000 items and I want to move a window of 100 items through it, shifting it from 1 to 100 then from 2 to 101 and so on. For extra credit it should not copy data but return a "reference" which would indeed make it a "window". Joel On Aug 10, 2005, at 4:23 PM, Ulf Wiger (AL/EAB) wrote: > erlang:push_element(Tuple, Value) pushes value into position 1 of > Tuple, shifting the existing values one step to the right. This can > be used as a fixed-size sliding window which costs the same as > setelement/3 to update. -- http://wagerlabs.com/uptick From ulf.wiger@REDACTED Wed Aug 10 16:49:38 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Wed, 10 Aug 2005 16:49:38 +0200 Subject: push_element/2 - efficient sliding window Message-ID: Hmmm, I think I'll let someone else take care of that one. (: I think tuples of 1,000,000 items are a bit ... impractical in Erlang today. /Uffe > -----Original Message----- > From: owner-erlang-questions@REDACTED > [mailto:owner-erlang-questions@REDACTED]On Behalf Of Joel Reymont > Sent: den 10 augusti 2005 16:46 > To: Erlang Users' List > Subject: Re: push_element/2 - efficient sliding window > > > Go Uffe! > > Now I just need another BIF to slide a tuple of a fixed size over a > large tuple. Then I would be happy :-). Say you have a tuple of > 1,000,000 items and I want to move a window of 100 items through it, > shifting it from 1 to 100 then from 2 to 101 and so on. > > For extra credit it should not copy data but return a "reference" > which would indeed make it a "window". > > Joel > > On Aug 10, 2005, at 4:23 PM, Ulf Wiger (AL/EAB) wrote: > > > erlang:push_element(Tuple, Value) pushes value into position 1 of > > Tuple, shifting the existing values one step to the right. > This can > > be used as a fixed-size sliding window which costs the same as > > setelement/3 to update. > > -- > http://wagerlabs.com/uptick > > > > From joelr1@REDACTED Wed Aug 10 17:12:26 2005 From: joelr1@REDACTED (Joel Reymont) Date: Wed, 10 Aug 2005 17:12:26 +0200 Subject: push_element/2 - efficient sliding window In-Reply-To: References: Message-ID: There goes my trading system :-(. On Aug 10, 2005, at 4:49 PM, Ulf Wiger (AL/EAB) wrote: > > Hmmm, I think I'll let someone else take care of that one. (: > > I think tuples of 1,000,000 items are a bit ... impractical in > Erlang today. -- http://wagerlabs.com/uptick From ke.han@REDACTED Wed Aug 10 17:48:23 2005 From: ke.han@REDACTED (ke.han) Date: Wed, 10 Aug 2005 23:48:23 +0800 Subject: install/config esense Message-ID: <42FA21C7.2070906@redstarling.com> I have decided to give emacs a try again. Mainly due to what's in esense. I have successfully installed a Windows version of Emacs (with Windows keymappings in place; this helps lots) and also have the erlang mode working. However, I don't find any directions for config of esense mode in emacs. I assume its as easy as adding some lines to the .emacs file similar to how erlang mode was installed. Is this correct? I also assume that there is some reference I need to the esense index that I generate. Can someone show me what I need to add to my .emacs file to make my .erl/.hrl files automatically use esense? Would be nice if the esense README included some instructions similar to http://erlang.se/doc/doc-5.4.8/lib/tools-2.4.4/doc/html/erlang_mode_chapter.html thanks, ke han From serge@REDACTED Wed Aug 10 18:06:03 2005 From: serge@REDACTED (Serge Aleynikov) Date: Wed, 10 Aug 2005 12:06:03 -0400 Subject: mnesia replication In-Reply-To: References: <42F7C9FE.5070904@hq.idt.net> <42F911FD.9010107@hq.idt.net> Message-ID: <42FA25EB.2090509@hq.idt.net> mnesia:del_table_copy/2, seems to have a restriction that the node from which the replica is to be deleted should *not* have schema stored on disk: ~/tmp>erl -sname a ~/tmp>erl -sname b -mnesia extra_db_nodes \[a@REDACTED\] (a@REDACTED)1> mnesia:create_schema([a@REDACTED, b@REDACTED]). ok (a@REDACTED)2> mnesia:start(). ok (b@REDACTED)1> mnesia:start(). ok (a@REDACTED)3> mnesia:create_table(test, [{disc_copies, [a@REDACTED]},{ram_copies, [b@REDACTED]}]). {atomic,ok} (b@REDACTED)2> q(). ok (a@REDACTED)4> mnesia:del_table_copy(test, b@REDACTED). {aborted,{not_active,"All replicas on diskfull nodes are not active yet", test, [b@REDACTED]}} ------------ What's the advantage/disadvantage of creating the disk-based schema on each node vs. keeping it on a subset of nodes? In the configuration below does it make sense to keep the schema on disk only on the Master/Standby nodes? ------------ On a separate note, I tried to emulate a disk crash on node b@REDACTED with a disk-copy of the schema by wiping out the content of mnesia directory, and attempting to recover that mnesia node. Upon startup of mnesia on b@REDACTED it crashed with a core dump: ** FATAL ** Failed to merge schema: Incompatible schema storage types (local). on b@REDACTED storage ram_copies, on a@REDACTED storage disc_copies What I did next was I manually copied the "schema.DAT" file from a@REDACTED, and started mnesia. ~/tmp>mkdir Mnesia.b\@devlinuxpro/ ~/tmp>cp Mnesia.a\@devlinuxpro/schema.DAT Mnesia.b\@devlinuxpro/ ~/tmp>erl -sname b -mnesia extra_db_nodes \[a@REDACTED\] (b@REDACTED)1> mnesia:start(). ok Then mnesia:del_table_copy/2 worked alright from node a@REDACTED: (a@REDACTED)6> mnesia:del_table_copy(test, b@REDACTED). {atomic,ok} (b@REDACTED)2> mnesia:info(). ... opt_disc. Directory "/home/serge/tmp/Mnesia.b@REDACTED" is used. use fallback at restart = false running db nodes = [a@REDACTED,b@REDACTED] stopped db nodes = [] master node tables = [] remote = [test] ram_copies = [] disc_copies = [schema] disc_only_copies = [] [{a@REDACTED,disc_copies}] = [test] [{a@REDACTED,disc_copies},{b@REDACTED,disc_copies}] = [schema] ... I am not sure if this is the right way to get rid of a faulty replica of a table in case of a disk-hosted schema, but this approach seems to work. Serge Chandrashekhar Mullaparthi wrote: > > On 9 Aug 2005, at 21:28, Serge Aleynikov wrote: > >> Chandrashekhar Mullaparthi wrote: >> >>>> Is this a good approach in terms of avoiding extensive locking >>>> overhead in trying to load multiple tables with preserving >>>> referential integrity of data accross several tables? >>> >>> Have you considered using sticky locks? They are quite useful if you >>> are only ever going to write to mnesia on one node at a time. >> >> >> I am experimenting with several writing methods including table-level >> locks, sticky locks, and backup-restore technique (suggested by Vance >> in one of the former emails), but haven't come to a conclusion yet >> which technique provides better performance in case of the following >> mnesia configuration and size of the database of about 700M: >> >> Master -------------- RamCopy1 >> DiskCopy ------+ ... >> | | ... >> | +------- RamCopyN >> Standby >> DiskCopy >> >> All writes happen either at the Master or at Standby (if Master is >> down) node. >> >> What I need to ensure is that: >> >> 2. It should be possible to delete table copies of RamCopyK node from >> the mnesia schema on Master/Standby nodes, while the RamCopyK host is >> off-line. > > You can do this using mnesia:del_table_copy/3 > > mnesia:del_table_copy(schema, r@REDACTED). > > Once you do this you are not supposed to bring back the node r@REDACTED > with it's old database. The results are "undefined" according to the > documentation. > >> >> 5. The should be no replication of data between RamCopy nodes, only >> from Master/Slave to RamCopy nodes. > > > AFAIK, this is not possible with mnesia. But as long as you are not > going to perform updates on the RAM copy nodes, there will not be any > replication traffic between these nodes - it will always be from > master/slave to the ram copy nodes. > >> I am not sure how to deal with #2 and #5... > > > hope this helps. > Chandru -- Serge Aleynikov R&D Telecom, IDT Corp. Tel: (973) 438-3436 Fax: (973) 438-1464 serge@REDACTED From nicolas@REDACTED Wed Aug 10 18:48:05 2005 From: nicolas@REDACTED (Nicolas Niclausse) Date: Wed, 10 Aug 2005 18:48:05 +0200 Subject: inet:getiflist() behaviour in Windows In-Reply-To: <86f1f53505080414342a0bf4@mail.gmail.com> References: <86f1f53505080414342a0bf4@mail.gmail.com> Message-ID: <42FA2FC5.7030905@niclux.org> Stephen Han ecrivait le 04.08.2005 23:34: > Hi > > This is what I did in Linux (gentoo with kernel 2.6.10) > > 2> inet:getiflist(). > {ok,["lo","eth0"]} this function doesn't seem to handle alias interfaces (at least on linux) Eshell V5.4.8 (abort with ^G) >inet:getiflist(). {ok,["lo",[],[2],[],"eth1",[]]} I have 4 interfaces: eth0, eth0:0, eth0:1 and eth1 -- Nicolas From chandrashekhar.mullaparthi@REDACTED Wed Aug 10 18:56:58 2005 From: chandrashekhar.mullaparthi@REDACTED (Chandrashekhar Mullaparthi) Date: Wed, 10 Aug 2005 17:56:58 +0100 Subject: mnesia replication In-Reply-To: <42FA25EB.2090509@hq.idt.net> References: <42F7C9FE.5070904@hq.idt.net> <42F911FD.9010107@hq.idt.net> <42FA25EB.2090509@hq.idt.net> Message-ID: <94428fb04eee1b60b47305f114c64446@t-mobile.co.uk> On 10 Aug 2005, at 17:06, Serge Aleynikov wrote: > mnesia:del_table_copy/2, seems to have a restriction that the node > from which the replica is to be deleted should *not* have schema > stored on disk: > > ~/tmp>erl -sname a > ~/tmp>erl -sname b -mnesia extra_db_nodes \[a@REDACTED\] > > (a@REDACTED)1> mnesia:create_schema([a@REDACTED, b@REDACTED]). > ok > (a@REDACTED)2> mnesia:start(). > ok > > (b@REDACTED)1> mnesia:start(). > ok > > (a@REDACTED)3> mnesia:create_table(test, > [{disc_copies, [a@REDACTED]},{ram_copies, [b@REDACTED]}]). > {atomic,ok} > > (b@REDACTED)2> q(). > ok > > (a@REDACTED)4> mnesia:del_table_copy(test, b@REDACTED). > {aborted,{not_active,"All replicas on diskfull nodes are not active > yet", > test, > [b@REDACTED]}} What I suggested (and I thought that's what you asked for) was a way to remove the whole RAM copy node out of the schema. If that is what you want, the first argument to the mnesia:del_table_copy/2 function must be the name schema and not 'test'. In the above example, you are trying to delete a table from a node where mnesia is not running. It will obviously not work. > ------------ > > What's the advantage/disadvantage of creating the disk-based schema on > each node vs. keeping it on a subset of nodes? In your case, there isn't much of an advantage if you are always going to start your RAM copy nodes with the extra_db_nodes sepcified. > > In the configuration below does it make sense to keep the schema on > disk only on the Master/Standby nodes? Consider the situation when both your master/standby nodes are down. When your ram-copy node comes up, it will not be able to fetch a schema from anywhere and most likely refuse to start - assuming you wait for certain tables to be available. Even if you don't wait for tables, your function calls to mnesia will crash because the tables you are referring to will not be known to mnesia. If this is ok for your application then you can get away with keeping the schema on disk only on master/standby nodes. > > ------------ > On a separate note, I tried to emulate a disk crash on node > b@REDACTED with a disk-copy of the schema by wiping out the content > of mnesia directory, and attempting to recover that mnesia node. Upon > startup of mnesia on b@REDACTED it crashed with a core dump: > > ** FATAL ** Failed to merge schema: Incompatible schema storage types > (local). on b@REDACTED storage ram_copies, on a@REDACTED storage > disc_copies > > What I did next was I manually copied the "schema.DAT" file from > a@REDACTED, and started mnesia. > > ~/tmp>mkdir Mnesia.b\@devlinuxpro/ > ~/tmp>cp Mnesia.a\@devlinuxpro/schema.DAT Mnesia.b\@devlinuxpro/ > > ~/tmp>erl -sname b -mnesia extra_db_nodes \[a@REDACTED\] > (b@REDACTED)1> mnesia:start(). > ok > > Then mnesia:del_table_copy/2 worked alright from node a@REDACTED: > > (a@REDACTED)6> mnesia:del_table_copy(test, b@REDACTED). > {atomic,ok} > > (b@REDACTED)2> mnesia:info(). > ... > opt_disc. Directory "/home/serge/tmp/Mnesia.b@REDACTED" is used. > use fallback at restart = false > running db nodes = [a@REDACTED,b@REDACTED] > stopped db nodes = [] > master node tables = [] > remote = [test] > ram_copies = [] > disc_copies = [schema] > disc_only_copies = [] > [{a@REDACTED,disc_copies}] = [test] > [{a@REDACTED,disc_copies},{b@REDACTED,disc_copies}] = [schema] > ... > > I am not sure if this is the right way to get rid of a faulty replica > of a table in case of a disk-hosted schema, but this approach seems to > work. I think the right way of recovery is this. 1. Delete b@REDACTED from the mnesia schema using the mnesia:del_table_copy/2 command on a@REDACTED 2. Bring up b@REDACTED with the extra_db_nodes parameter 3. Do an mnesia:add_table_copy(test, b@REDACTED, ram_copies). Chandru > > Chandrashekhar Mullaparthi wrote: >> On 9 Aug 2005, at 21:28, Serge Aleynikov wrote: >>> Chandrashekhar Mullaparthi wrote: >>> >>>>> Is this a good approach in terms of avoiding extensive locking >>>>> overhead in trying to load multiple tables with preserving >>>>> referential integrity of data accross several tables? >>>> >>>> Have you considered using sticky locks? They are quite useful if >>>> you are only ever going to write to mnesia on one node at a time. >>> >>> >>> I am experimenting with several writing methods including >>> table-level locks, sticky locks, and backup-restore technique >>> (suggested by Vance in one of the former emails), but haven't come >>> to a conclusion yet which technique provides better performance in >>> case of the following mnesia configuration and size of the database >>> of about 700M: >>> >>> Master -------------- RamCopy1 >>> DiskCopy ------+ ... >>> | | ... >>> | +------- RamCopyN >>> Standby >>> DiskCopy >>> >>> All writes happen either at the Master or at Standby (if Master is >>> down) node. >>> >>> What I need to ensure is that: >>> >>> 2. It should be possible to delete table copies of RamCopyK node >>> from the mnesia schema on Master/Standby nodes, while the RamCopyK >>> host is off-line. >> You can do this using mnesia:del_table_copy/3 >> mnesia:del_table_copy(schema, r@REDACTED). >> Once you do this you are not supposed to bring back the node >> r@REDACTED with it's old database. The results are "undefined" >> according to the documentation. >>> >>> 5. The should be no replication of data between RamCopy nodes, only >>> from Master/Slave to RamCopy nodes. >> AFAIK, this is not possible with mnesia. But as long as you are not >> going to perform updates on the RAM copy nodes, there will not be any >> replication traffic between these nodes - it will always be from >> master/slave to the ram copy nodes. >>> I am not sure how to deal with #2 and #5... >> hope this helps. >> Chandru > > -- > Serge Aleynikov > R&D Telecom, IDT Corp. > Tel: (973) 438-3436 > Fax: (973) 438-1464 > serge@REDACTED > From serge@REDACTED Wed Aug 10 19:04:46 2005 From: serge@REDACTED (Serge Aleynikov) Date: Wed, 10 Aug 2005 13:04:46 -0400 Subject: mnesia replication In-Reply-To: <94428fb04eee1b60b47305f114c64446@t-mobile.co.uk> References: <42F7C9FE.5070904@hq.idt.net> <42F911FD.9010107@hq.idt.net> <42FA25EB.2090509@hq.idt.net> <94428fb04eee1b60b47305f114c64446@t-mobile.co.uk> Message-ID: <42FA33AE.1040509@hq.idt.net> Thanks for your recommendations! Chandrashekhar Mullaparthi wrote: > On 10 Aug 2005, at 17:06, Serge Aleynikov wrote: > >> mnesia:del_table_copy/2, seems to have a restriction that the node >> from which the replica is to be deleted should *not* have schema >> stored on disk: >> >> ~/tmp>erl -sname a >> ~/tmp>erl -sname b -mnesia extra_db_nodes \[a@REDACTED\] >> >> (a@REDACTED)1> mnesia:create_schema([a@REDACTED, b@REDACTED]). >> ok >> (a@REDACTED)2> mnesia:start(). >> ok >> >> (b@REDACTED)1> mnesia:start(). >> ok >> >> (a@REDACTED)3> mnesia:create_table(test, >> [{disc_copies, [a@REDACTED]},{ram_copies, [b@REDACTED]}]). >> {atomic,ok} >> >> (b@REDACTED)2> q(). >> ok >> >> (a@REDACTED)4> mnesia:del_table_copy(test, b@REDACTED). >> {aborted,{not_active,"All replicas on diskfull nodes are not active yet", >> test, >> [b@REDACTED]}} > > > What I suggested (and I thought that's what you asked for) was a way to > remove the whole RAM copy node out of the schema. If that is what you > want, the first argument to the mnesia:del_table_copy/2 function must be > the name schema and not 'test'. In the above example, you are trying to > delete a table from a node where mnesia is not running. It will > obviously not work. > >> ------------ >> >> What's the advantage/disadvantage of creating the disk-based schema on >> each node vs. keeping it on a subset of nodes? > > > In your case, there isn't much of an advantage if you are always going > to start your RAM copy nodes with the extra_db_nodes sepcified. > >> >> In the configuration below does it make sense to keep the schema on >> disk only on the Master/Standby nodes? > > > Consider the situation when both your master/standby nodes are down. > When your ram-copy node comes up, it will not be able to fetch a schema > from anywhere and most likely refuse to start - assuming you wait for > certain tables to be available. Even if you don't wait for tables, your > function calls to mnesia will crash because the tables you are referring > to will not be known to mnesia. If this is ok for your application then > you can get away with keeping the schema on disk only on master/standby > nodes. > >> >> ------------ >> On a separate note, I tried to emulate a disk crash on node >> b@REDACTED with a disk-copy of the schema by wiping out the content >> of mnesia directory, and attempting to recover that mnesia node. Upon >> startup of mnesia on b@REDACTED it crashed with a core dump: >> >> ** FATAL ** Failed to merge schema: Incompatible schema storage types >> (local). on b@REDACTED storage ram_copies, on a@REDACTED storage >> disc_copies >> >> What I did next was I manually copied the "schema.DAT" file from >> a@REDACTED, and started mnesia. >> >> ~/tmp>mkdir Mnesia.b\@devlinuxpro/ >> ~/tmp>cp Mnesia.a\@devlinuxpro/schema.DAT Mnesia.b\@devlinuxpro/ >> >> ~/tmp>erl -sname b -mnesia extra_db_nodes \[a@REDACTED\] >> (b@REDACTED)1> mnesia:start(). >> ok >> >> Then mnesia:del_table_copy/2 worked alright from node a@REDACTED: >> >> (a@REDACTED)6> mnesia:del_table_copy(test, b@REDACTED). >> {atomic,ok} >> >> (b@REDACTED)2> mnesia:info(). >> ... >> opt_disc. Directory "/home/serge/tmp/Mnesia.b@REDACTED" is used. >> use fallback at restart = false >> running db nodes = [a@REDACTED,b@REDACTED] >> stopped db nodes = [] >> master node tables = [] >> remote = [test] >> ram_copies = [] >> disc_copies = [schema] >> disc_only_copies = [] >> [{a@REDACTED,disc_copies}] = [test] >> [{a@REDACTED,disc_copies},{b@REDACTED,disc_copies}] = [schema] >> ... >> >> I am not sure if this is the right way to get rid of a faulty replica >> of a table in case of a disk-hosted schema, but this approach seems to >> work. > > > I think the right way of recovery is this. > > 1. Delete b@REDACTED from the mnesia schema using the > mnesia:del_table_copy/2 command on a@REDACTED > 2. Bring up b@REDACTED with the extra_db_nodes parameter > 3. Do an mnesia:add_table_copy(test, b@REDACTED, ram_copies). > > Chandru > >> >> Chandrashekhar Mullaparthi wrote: >> >>> On 9 Aug 2005, at 21:28, Serge Aleynikov wrote: >>> >>>> Chandrashekhar Mullaparthi wrote: >>>> >>>>>> Is this a good approach in terms of avoiding extensive locking >>>>>> overhead in trying to load multiple tables with preserving >>>>>> referential integrity of data accross several tables? >>>>> >>>>> >>>>> Have you considered using sticky locks? They are quite useful if >>>>> you are only ever going to write to mnesia on one node at a time. >>>> >>>> >>>> >>>> I am experimenting with several writing methods including >>>> table-level locks, sticky locks, and backup-restore technique >>>> (suggested by Vance in one of the former emails), but haven't come >>>> to a conclusion yet which technique provides better performance in >>>> case of the following mnesia configuration and size of the database >>>> of about 700M: >>>> >>>> Master -------------- RamCopy1 >>>> DiskCopy ------+ ... >>>> | | ... >>>> | +------- RamCopyN >>>> Standby >>>> DiskCopy >>>> >>>> All writes happen either at the Master or at Standby (if Master is >>>> down) node. >>>> >>>> What I need to ensure is that: >>>> >>>> 2. It should be possible to delete table copies of RamCopyK node >>>> from the mnesia schema on Master/Standby nodes, while the RamCopyK >>>> host is off-line. >>> >>> You can do this using mnesia:del_table_copy/3 >>> mnesia:del_table_copy(schema, r@REDACTED). >>> Once you do this you are not supposed to bring back the node >>> r@REDACTED with it's old database. The results are "undefined" >>> according to the documentation. >>> >>>> >>>> 5. The should be no replication of data between RamCopy nodes, only >>>> from Master/Slave to RamCopy nodes. >>> >>> AFAIK, this is not possible with mnesia. But as long as you are not >>> going to perform updates on the RAM copy nodes, there will not be any >>> replication traffic between these nodes - it will always be from >>> master/slave to the ram copy nodes. >>> >>>> I am not sure how to deal with #2 and #5... >>> >>> hope this helps. >>> Chandru >> >> >> -- >> Serge Aleynikov >> R&D Telecom, IDT Corp. >> Tel: (973) 438-3436 >> Fax: (973) 438-1464 >> serge@REDACTED >> > > -- Serge Aleynikov R&D Telecom, IDT Corp. Tel: (973) 438-3436 Fax: (973) 438-1464 serge@REDACTED From erlang@REDACTED Wed Aug 10 19:15:18 2005 From: erlang@REDACTED (Michael McDaniel) Date: Wed, 10 Aug 2005 10:15:18 -0700 Subject: Mnesia vs MySQL In-Reply-To: References: Message-ID: <20050810171518.GR20625@fangora.autosys.us> I use MySQL (via ODBC) right now for an erlang application. I have thought of using Mnesia as the immediate data sink, and then have it flush out to MySQL. The reason for this would be so that I can replicate the incoming data across other nodes without having to use MySQL replication. MySQL would still be used for the permanent data store so that other (non-erlang) applications can easily access the data. ~Michael On Wed, Aug 10, 2005 at 03:07:41PM +0200, Ulf Wiger (AL/EAB) wrote: > > Mnesia is different from MySQL in several ways. Whether or not the > differences are in Mnesia's favour certainly depends on what you need > to do: > > - No semantic gap for erlang programmers. Mnesia operates directly on > Erlang terms > > and uses Erlang semantics for accesses > > - Low latency. E.g. dirty_read from a mnesia table takes only a few > microseconds. There is no way you > > can read a MySQL object as quickly. This assumes that your > application is written in erlang, of course. > > - In-service upgrade. Mnesia can be upgraded without service > interruption. > > - Small memory footprint (not that I know how much MySQL uses) > > There are certainly other differences. I'll let someone else continue. > > /Uffe > > -----Original Message----- > From: owner-erlang-questions@REDACTED > [mailto:owner-erlang-questions@REDACTED]On Behalf Of Inswitch > Solutions > Sent: den 10 augusti 2005 14:56 > To: erlang-questions@REDACTED > Subject: Mnesia vs MySQL > > Hi, > > > > MySql database has been improved a lot and we are evaluating it using > ODBC Erlang application. > > As far as I know MySql has all mnesia features (replicas, > distribution, ..), plus GUI administration and SQL. > > > > What points in favour does Mnesia database have over MySQL? > Perfomarnce issues? > > > > > > thanks, Eduardo > > > > > > [cid:562555912@REDACTED] > > Prepaid Expertise - Programmable Switches > Powered by Ericsson Licensed Technology > Eng. Eduardo Figoli - Development Center - IN Switch Solutions Inc. > Headquarters - Miami-U.S.A. Tel: 1305-3578076 Fax: 1305-7686260 > Development Center - Montevideo - Uruguay Tel/Fax: 5982-7104457 > e-mail: [1]eduardo@REDACTED > > > References > > 1. mailto:eduardo@REDACTED From mfs@REDACTED Wed Aug 10 19:33:45 2005 From: mfs@REDACTED (Mark Scandariato) Date: Wed, 10 Aug 2005 13:33:45 -0400 (EDT) Subject: inet:getiflist() behaviour in Windows Message-ID: <13578657.1123695225537.JavaMail.root@mswamui-cedar.atl.sa.earthlink.net> This is from winxp sp2 (bleh) with one interface, where the correct IP address is 157.198.238.176: Erlang (BEAM) emulator version 5.4.8 [threads:0] Eshell V5.4.8 (abort with ^G) 1> {ok, L} = inet:getiflist(). {ok,["671.832.891.751","100.0.0.721"]} 2> [lists:reverse(I) || I <- L]. ["157.198.238.176","127.0.0.001"] 3> YMMV. -----Original Message----- From: Nicolas Niclausse Sent: Aug 10, 2005 12:48 PM To: erlang-questions@REDACTED Subject: Re: inet:getiflist() behaviour in Windows Stephen Han ecrivait le 04.08.2005 23:34: > Hi > > This is what I did in Linux (gentoo with kernel 2.6.10) > > 2> inet:getiflist(). > {ok,["lo","eth0"]} this function doesn't seem to handle alias interfaces (at least on linux) Eshell V5.4.8 (abort with ^G) >inet:getiflist(). {ok,["lo",[],[2],[],"eth1",[]]} I have 4 interfaces: eth0, eth0:0, eth0:1 and eth1 -- Nicolas From tty@REDACTED Wed Aug 10 19:48:35 2005 From: tty@REDACTED (tty@REDACTED) Date: Wed, 10 Aug 2005 13:48:35 -0400 Subject: OTP/TCP server recommendation Message-ID: Hello, I am writing an OTP application which requires starting a TCP based server for incoming requests. I want this TCP server to be under a supervisor (for restarts etc). What is the 'best practice' for this scenario ? At this moment I have a 'portal' module which looks something like this : =============================================== start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []), gen_server:cast(?MODULE, server). init(_Args) -> {ok, #state{}}. handle_cast(server, _State) -> server(), {noreply, #state{server = ?SERVER, port = ?PORT}}. server() -> {ok, LSock} = gen_tcp:listen(5600, [binary, {packet, 0}]), server(LSock). server(Socket) -> {ok, Sock} = gen_tcp:accept(Socket), receive {tcp, Sock, Data} -> % do stuff with Data end, gen_tcp:send(Sock, list_to_binary("all is well\n")), gen_tcp:close(Sock), server(Socket). =============================================== Although the above works I find it somewhat ugly. Thanks in advance. Tee From anders.nygren@REDACTED Wed Aug 10 19:59:14 2005 From: anders.nygren@REDACTED (Anders Nygren) Date: Wed, 10 Aug 2005 12:59:14 -0500 Subject: length of an iolist Message-ID: Hi http://www.erlang.org/ml-archive/erlang-questions/200503/msg00091.html Bj?rn Gustavsson mentioned two possible new BIFS iolist_size(IOList) iolist_to_binary(IOList) Any news on their possible arrival in the, (hopefully near), future? /Anders Nygren From tpatro@REDACTED Wed Aug 10 20:31:07 2005 From: tpatro@REDACTED (Tamas Patrovics) Date: Wed, 10 Aug 2005 20:31:07 +0200 Subject: install/config esense In-Reply-To: <42FA21C7.2070906@redstarling.com> References: <42FA21C7.2070906@redstarling.com> Message-ID: On 8/10/05, ke.han wrote: > However, I don't find any directions for config of esense mode in emacs. > I assume its as easy as adding some lines to the .emacs file similar to > how erlang mode was installed. Is this correct? Emacs packages usually have instructions for installation at the beginning of the ELisp file. If you take a look at esense.el you can find some instructions contributed by Mats Cronqvist there. > Would be nice if the esense README included some instructions similar to > http://erlang.se/doc/doc-5.4.8/lib/tools-2.4.4/doc/html/erlang_mode_chapter.html Yes, it would be nice. If anyone feels like writing more detailed installation instructions just send me the text and I'll add it to the distribution. /Tamas From james.hague@REDACTED Wed Aug 10 20:34:59 2005 From: james.hague@REDACTED (James Hague) Date: Wed, 10 Aug 2005 13:34:59 -0500 Subject: Line numbers in stack traces In-Reply-To: <20050810144025.24569.qmail@web34414.mail.mud.yahoo.com> References: <02ADE0BC-D2C1-4258-94B1-39E6210D0440@citeulike.org> <20050810144025.24569.qmail@web34414.mail.mud.yahoo.com> Message-ID: Mildly related rant: Heck file:consult doesn't even give you the line number in case of an error (which is maddening!). James From david.nospam.hopwood@REDACTED Thu Aug 11 00:29:15 2005 From: david.nospam.hopwood@REDACTED (David Hopwood) Date: Wed, 10 Aug 2005 23:29:15 +0100 Subject: Line numbers in stack traces In-Reply-To: <200508100542.j7A5gdo2391299@atlas.otago.ac.nz> References: <200508100542.j7A5gdo2391299@atlas.otago.ac.nz> Message-ID: <42FA7FBB.6050601@blueyonder.co.uk> Richard A. O'Keefe wrote: > I pointed out that macros make source line numbers much less > useful, lamenting that Erlang has such things. > > David Hopwood wrote > This is true, but it doesn't seriously interfere with the utility of line > numbers, especially for programmers who make little or no use of macros. > > I just extracted all the non-white-space non-comment non-'end' lines from > the *.[ehy]rl files in an Erlang distribution, and found that > > one line in 94 is a -define. > > This is a *higher* proportion of -defines in Erlang/OTP than > I have #defines in my C code! What proportion have a definition that is longer than one line or that uses another macro? (A rough estimate based on a sample will do. I'm genuinely interested, not just trying to make a point.) -- David Hopwood From ok@REDACTED Thu Aug 11 03:31:49 2005 From: ok@REDACTED (Richard A. O'Keefe) Date: Thu, 11 Aug 2005 13:31:49 +1200 (NZST) Subject: Line numbers in stack traces Message-ID: <200508110131.j7B1VngB419861@atlas.otago.ac.nz> Richard Cameron wrote: I've just spent a good five minutes tracking down a badmatch inside a gen_server handle_call/3 function. There's a clause for each message the server handles, so saying the error is in handle_call/3 is effectively sending me off to look for a needle in a haystack This is a case where the lightweight approach I've repeatedly suggested, namely reporting {Module,Function_Name,Arity,Clause_Number}, ^^^^^^^^^^^^^ would probably give you 90% of what line numbers might have, at a fraction of the implementation effort. I don't know what BEAM looks like. Is there any documentation of it, other than the source code of the emulator (and of course the compiler sources, all roughly 20kSLOC of them)? genop.tab tells me there are instructions call_last -- maybe call_only? call_ext_last return and poking around in beam_*.erl files tells me that code after these instructions is unreachable. So in the absence of inlining, it would suffice to plant an extra {clause_number,N} instruction after each of these. Then, to find out the module, function, and arity, given an instruction address, do whatever is done now, and to find out the clause number, just parse instructions forward until the next {clause_number,N} instruction. A key phrase there is "in the absence of inlining". But the Erlang compiler *does* support inlining, both explicit, via -compile({inline, [{Name,Arity},...]}). and implicit. This means that ... f(...) -> % clause N ... g(...) ...; ... either has to include code to push "I'm really in g" at the beginning of the expansion of g and pop it at the end AND refrain from merging code in g with code before or after the call to g, which is one of the main reasons for inlining, OR the location reported will be clause N of f instead of clause whatever of g, OR the compiler must refrain from inlining in debugging mode. The simplest thing to do would seem to be - if a module (or a function) is compiled in debugging mode, then function calls in that module (or in the body of that function) will not be expanded inline - if a module is not compiled in debugging mode, people must know to expect that "exception in {M,F,A,C}" *really* means "exception in {M,F,A,C} or some function called therein", which, thanks to tail recursion optimisation, it does anyway. especially when the virtual machine probably knows (or could know) more information about where it went wrong and is only giving me cryptic clues so I can work it out for myself. I thought the point of this thread was that the virtual machine almost certainly DOESN'T have any more information than it gives you. "Programs are data" as you point out before, and Lisp is an example of a language with far more complex macro substitution than Erlang. Yes, and I have spent enough time inside Lisp debuggers to know what a NIGHTMARE macros are for debugging Lisp. (Especially the really nasty thing where you have fix a macro but the debugger is stepping you through, but not showing you, the OLD expansion...) It was precisely my bad experiences with trying to debug macro-heavy Lisp code that led to my opposition to macros in Quintus Prolog and and my distress that Erlang has succumbed to C envy. If you imagine the compiler repeatedly transforming the S-expressions of your raw source code down into simpler and simpler forms which eventually converge into something which can be translated down into bytecode or machine instructions, then there *is* an inherent concept of source position which can be inferred from the address of the crash It is precisely because I have written complex macro-generating macros (an OOP library obsoleted by CLOS, an SGML-hacking library, some old long-discarded AI stuff) that I know that this is quite untrue. In macroised code, each byte of the result owes its existence to the *interaction* of many lines; you cannot point to ANY of them and say "that is my source". - you simply unravel the compilation process back to find out which expression in the user's code caused the problem. Hysterical laughter. In a stateful language like Lisp, the translation may have depended on such a way that it is no longer *possible* to redo (let alone undo) the compilation process. Guess what? Erlang is stateful enough for this to be a problem. (module = global variable.) Don't forget, an Erlang compile-time transformation can do ANYTHING it wants to, including picking a transformation according to the current price of Microsoft stock. So we're talking about an implementation issue here? Instead of, say, bloating up your bytecode by adding a (filename, linenumber) tuple to each instruction, can't we build up a mapping table (the one I talk about above) at compile time which maps the bytecode address back up into the original source code? Basically a mapping table *does* add a (filename,linenumber) tuple to each instruction, albeit with some compression. From what I recall, this is how the debug information is stored in a C executable. And as I pointed out with numbers, this GREATLY INCREASES the size of the C executable. Does this address your concerns about bloating the size of the bytecode in a world where the VM can handle debugging information, but the user has chosen to disable it? How could it? I've read the DWARF manual cover to cover; I can still remember when the code reorganiser for a certain C compiler (shifting procedures around to improve paging) managed to break C++ because C++ relied on the mapping tables for exception handling, and the code reorganiser forgot to update them. In short, you're not telling me anything I wasn't already well aware of, so how code it address my concerns? My primary concern is the *human* time required to implement something like this, and the loss of other good things we might have had if that time were spent in more productive ways. People seem to think it is a simple thing to get right. I have learned over the years *not* to trust C compiler line number information; the debuggers will skip backwards and forwards in very strange ways, and too often fail to stop at all at a line which is plainly there. If I cannot rely on C compilers with large amounts of money and time behind them, how easy is it going to be for Erlang? We are talking about a serious increase in the complexity of BEAM files. We are talking about nearly every part of the compiler being affected in trivial to enormously complex ways. And for what looks to me to be very minor benefit. {Module,Name,Arity,Clause} could give us _most_ of the benefit of line number information for MUCH less cost. > If the compiler recorded the source position of the first token > of each clause in each function, then knowing which clause of which > function you were in would get you very close in terms of line > numbers. Yes. I think that's what I'm suggesting. No, it's very different. I am talking about locating *only* the beginnings of *clauses*. Actually, if you're going for broke, why not record the position of each expression in the function in our separate (optional) mapping table. My whole point is that we SHOULDN'T go for broke; that clause level information is cheap to obtain and store, cheap enough that we might as well always do it, while the position of each "expression" isn't even *defined* when you have, as Erlang does have, macros and inlining. > Because it isn't "obvious" *where* the problem is within the > cascade of > macro applications. But this problem has been satisfactorily dealt with in Lisp, which has far more powerful and confusing macro support than Erlang. No, it has *not* been satisfactorily dealt with in Lisp, not at all. Very far from it, in fact. My initial impressions of Erlang are that I'm far more efficient writing "control" applications in it than I am in Python/Ruby/Tcl etc, and that it seems to encourage me to think in way where I produce fewer bugs. I'm generally much more confident that, once the code compiles, it'll work first time than I am in pretty much any other language. However, the really horrible part comes when I really do have to start interpreting stack traces. I feel like I'm playing a guessing game, and I'm just wasting my time. Well yes, interpreting stack traces IS a waste of time for ANY programming language. I am very pleased to learn that there is a prototype version of QuickCheck for Erlang: http://www.cs.chalmers.se/~rjmh/ErlangQC/ Now if someone will just tell me where the actual source code http://www.cs.chalmers.se/~rjmh/ErlangQC/qc.erl went to (because I get a 404 when I try to download it), I'll be a happy camper. There's a wonderful binary search tool that I'd like to see adapted to Erlang as well. > So in order to support line number information (should that prove > to be > usefully more precise than {module,function,arity,clause}) in a > debugging > mode, it is NOT necessary to have any support for line numbers in > the VM. > (As noted above, QP was able to provide source positions in > debugging mode > without having any support for it in the WAM.) I think this is exactly what I'm talking about. I just can't see why you don't want it. I didn't say I don't want it, I said I don't want it ***IN THE VM***. This is what debugging interpreters are for. (In Interlisp-D, for example, debugging was based on interpreting trees, not byte codes, although compiled code was byte codes. The only VM support required was the ability to trap function entry.) So your function call disappears from the reported stack trace too. I don't see how that makes the availability of more detailed code position information relatively less useful. Surely it is obvious? What good does a "precise" position give you if that position isn't *THERE* in the stack trace? I can (just about) live with functions disappearing from the stack like that... and I really don't want to complicate things by throwing yet another idea in, but how about creating a ring-buffer in the virtual machine to keep track of the top n items of the "logical" stack. How about NOT doing that? THIS is my point: DO NOT MESS AROUND WITH THE VM! Doing that has effects all OVER the place, costs that are grossly out of proportion to the benefits. All you really need is a source to source transformation: ... f(--args--) when --guard-- -> --body--; ... rewrites to ... f(--args--) when --guard-- -> tracer!{self(), --module--,f,--arity--,--clause number--}, X = (--body--), tracer!{self(),pop}, X; ... and now, without ANY changes to the VM or compiler AT ALL, you have your "logical" stack, So, instead of simply producing a jump instruction at a tail- recursive call, why don't we write the stack frame which would have been generated if we didn't have this optimisation into the buffer? You cannot be serious. Heck, why don't we just go all the way and run Erlang interpreted by a Tcl program interpreted by a Tcl interpreter written in interpreted BASIC? Then if that's still too fast we could throw in a few delay loops. Oh, I don't think so. Programs crash, and all I want to know is where they've crashed. This information is (almost) in the virtual machine already, and it really annoys me to have to play a guessing game every time. No, it *ISN'T* in the virtual machine already, or even close to it. Providing that information in the VM would cost a lot of development time and would interfere with a lot of other things it would be nice to have. There is already a serious conflict between accurate (complete) stack traces and usable performance (=TRO) which has been resolved in favour of usable performance. Me, I find that knowing *where* something crashed isn't terribly useful; what I want to know is where the *error* is, and that's usually somewhere else. Just yesterday, for example, I had a program crash. It turned out that the thing I needed to know was not where the program crashed, but what data it was looking at. The bug was in another program entirely! (The one that generated the bad data.) In Erlang terms, I would normally find more benefit in having the *arguments* of the functions in the stack trace than in having the line numbers. With the arguments of the top function, since they cannot possibly have changed, and since function headers and guards cannot have side effects and cannot depend on anything that could be changed by a side effect, it is possible to "replay" clause selection and discover which clause the crash was in (and, more importantly, why that clause was selected). So arguments can give you positions, but positions cannot give you arguments. Of course keeping arguments creates a conflict between accurate debugging information and usable performance (garbage collection). TANSTAAFL. From ok@REDACTED Thu Aug 11 03:56:27 2005 From: ok@REDACTED (Richard A. O'Keefe) Date: Thu, 11 Aug 2005 13:56:27 +1200 (NZST) Subject: Line numbers in stack traces Message-ID: <200508110156.j7B1uRPU411025@atlas.otago.ac.nz> I wrote: > one line in 94 is a -define. > This is a *higher* proportion of -defines in Erlang/OTP than > I have #defines in my C code! David Hopwood asked: What proportion have a definition that is longer than one line 12% are multiline. (my C code ranges from 5 to 20% multline #defines.) or that uses another macro? 11% use another macro, determined by checking for a "?". From mfs@REDACTED Thu Aug 11 04:33:21 2005 From: mfs@REDACTED (Mark Scandariato) Date: Wed, 10 Aug 2005 22:33:21 -0400 Subject: Line numbers in stack traces In-Reply-To: <200508110131.j7B1VngB419861@atlas.otago.ac.nz> References: <200508110131.j7B1VngB419861@atlas.otago.ac.nz> Message-ID: On Aug 10, 2005, at 9:31 PM, Richard A. O'Keefe wrote: > Well yes, interpreting stack traces IS a waste of time for ANY > programming > language. I am very pleased to learn that there is a prototype > version of > QuickCheck for Erlang: > http://www.cs.chalmers.se/~rjmh/ErlangQC/ > Now if someone will just tell me where the actual source code > http://www.cs.chalmers.se/~rjmh/ErlangQC/qc.erl > went to (because I get a 404 when I try to download it), > I'll be a happy camper. There's a wonderful binary search tool > that I'd like to see adapted to Erlang as well. Seems to have wandered into the jungerl. From ke.han@REDACTED Thu Aug 11 07:07:23 2005 From: ke.han@REDACTED (ke.han) Date: Thu, 11 Aug 2005 13:07:23 +0800 Subject: Line numbers in stack traces In-Reply-To: <200508110131.j7B1VngB419861@atlas.otago.ac.nz> References: <200508110131.j7B1VngB419861@atlas.otago.ac.nz> Message-ID: <42FADD0B.6090804@redstarling.com> Richard A. O'Keefe wrote: > > This is a case where the lightweight approach I've repeatedly suggested, > namely reporting > > {Module,Function_Name,Arity,Clause_Number}, > ^^^^^^^^^^^^^ > > would probably give you 90% of what line numbers might have, at a fraction > of the implementation effort. > ... > (The one that generated the bad data.) In Erlang terms, I would normally > find more benefit in having the *arguments* of the functions in the stack > trace than in having the line numbers. With the arguments of the top > function, since they cannot possibly have changed, and since function > headers and guards cannot have side effects and cannot depend on anything > that could be changed by a side effect, it is possible to "replay" clause > selection and discover which clause the crash was in (and, more importantly, > why that clause was selected). So arguments can give you positions, but > positions cannot give you arguments. > > Of course keeping arguments creates a conflict between accurate debugging > information and usable performance (garbage collection). TANSTAAFL. > > The above ideas sound dead on!!! So when can we see a prototype? ;-) How about linking this to Smalltalk style walkback windows and debugger? ;-) ok, thats asking a bit much for a first step...I'll be happy with better info on the console and adding links into the emacs mode to quickly get to the code (similar to compile errors, but with clause finding instead of line number finding, of course). This has been a fruitful discussion. How can these ideas get implemented and not drop the ball on this one? thanks ke han From mikael.karlsson@REDACTED Thu Aug 11 08:44:57 2005 From: mikael.karlsson@REDACTED (Mikael Karlsson) Date: Thu, 11 Aug 2005 08:44:57 +0200 Subject: pretty printing of records In-Reply-To: <200508100823.00075.mikael.karlsson@creado.com> References: <200508100823.00075.mikael.karlsson@creado.com> Message-ID: <200508110844.57467.mikael.karlsson@creado.com> Thanks for all suggestions, looks as there are a number of solutions. What I forgot to mention was that a precondition was that my records are defined in a number of .hrl files, some quite large, generated by the asn1 compiler, so "hand coding" of record_info for every record was not an option. I also do not know before reception which of all possible messages (records) I will receive. What was nice with the shell commands was that I just could do: rr("../include/*.hrl). A=receive_any_message_defined_as_a_record_in_hrl_with_records_in_it(). rp(A). What I wan't to achieve is a good lookin log formatting for messages directly from my program and not from the shell, so if one could add a function call for the shell command rr("..") too, to Ulf Wigers solution: http://www.erlang.org/ml-archive/erlang-questions/200505/msg00201.html then everything would be in place I think. Or maybe the jungerl the solution in (lib/msc/src/rec_info.erl) suggested by Vlad could work if I include all .hrl files in the module calling rec_info:to_list/2. I do not know how the compiler works here though, will it include all record definitions from the source code in the beam file, or will it strip of the ones not used in the code? Seems it that it can take a list of source (.hrl ?) files as well so that means it would work. Thanks Mikael From vlad.xx.dumitrescu@REDACTED Thu Aug 11 08:51:31 2005 From: vlad.xx.dumitrescu@REDACTED (Vlad Dumitrescu XX (LN/EAB)) Date: Thu, 11 Aug 2005 08:51:31 +0200 Subject: pretty printing of records Message-ID: <11498CB7D3FCB54897058DE63BE3897C4BE5BD@esealmw105.eemea.ericsson.se> Hi, > -----Original Message----- > From: Mikael Karlsson > Or maybe the jungerl the solution in > (lib/msc/src/rec_info.erl) suggested > by Vlad could work if I include all .hrl files in the module calling > rec_info:to_list/2. No, it is enough that you know of a module that includes the record definitions. If not all are in one module, it is easy to work with a list of modules to search through. > Seems it that it can take a list of source (.hrl ?) files as > well so that means it would work. No, it is also the module's source code, which is compiled on the fly and the record info retrieved from the parsed result. Right now, this isn't cached in any way, so it's grossly inefficient. regards, Vlad From ulf.wiger@REDACTED Thu Aug 11 11:56:27 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Thu, 11 Aug 2005 11:56:27 +0200 Subject: push_element/2 - efficient sliding window Message-ID: With an evening's hindsight, I've modified my hack to the following: Erlang (BEAM) emulator version 5.4.8 [source] [hipe] Eshell V5.4.8 (abort with ^G) 1> erlang:lshift_element({a,b,c,d},1). {b,c,d,1} 2> erlang:rshift_element({a,b,c,d},1). {1,a,b,c} This might be useful for: - A trace collector which keeps a fixed number of elements in a history window. This could be used to provide better error messages when a process crashes (e.g. having a message trace enabled on selected processes, and reporting the last N messages if one of them crashes.) For this to be useful, the history window must be very efficient. - A limited undo buffer. It's easy enough to do unlimited undo in Erlang: just save old state variables in a list, and pop the previous state variable to undo. Keeping only e.g. 20 previous states is more cumbersome and expensive. This could be fairly easily done using the above BIFs: undoable_action(Action, S, UndoBuf) -> S1 = Action(S), {S1, erlang:lshift_element(UndoBuf, S)}. undo(UndoBuf) -> {element(1, UndoBuf), erlang:rshift_element(UndoBuf, undefined)}. If undo(Buf) returns {undefined, _Buf1}, there is no previous State. BTW, timing a loop of 1000 shifts on a 200-tuple, these BIFs cost about 2-3 microsecs each. /Uffe > -----Original Message----- > From: owner-erlang-questions@REDACTED > [mailto:owner-erlang-questions@REDACTED]On Behalf Of Ulf Wiger > (AL/EAB) > Sent: den 10 augusti 2005 16:23 > To: erlang-questions@REDACTED > Subject: push_element/2 - efficient sliding window > > > > Inspired by Joel Reymont's trials trying to make an on-line > trading platform in erlang, and by the recent discussions > about trace data, I thought I'd try to invent a new BIF > (never tried that before...) > > Since I have no authority to introduce BIFs in Erlang, > getting this accepted could be done by: > (a) the OTP team finding it a good idea and just doing it > (b) enough users finding it useful to generate popular demand. > > > erlang:push_element(Tuple, Value) pushes value into position > 1 of Tuple, shifting the existing values one step to the > right. This can be used as a fixed-size sliding window which > costs the same as setelement/3 to update. > > Eshell V5.4.8 (abort with ^G) > 1> erlang:push_element({a,b,c},3). > {3,a,b} > 2> erlang:push_element(v(1),3). > {3,3,a} > 3> erlang:push_element({a,b},3). > {3,a} > 4> erlang:push_element({a},3). > {3} > 5> erlang:push_element({},3). > > =ERROR REPORT==== 10-Aug-2005::16:10:49 === > Error in process <0.30.0> with exit value: > {badarg,[{erlang,push_element,[{},3]},{erl_eval,do_apply,5},{s > hell,exprs,6},{shell,eval_loop,3}]} > > ** exited: {badarg,[{erlang,push_element,[{},3]}, > {erl_eval,do_apply,5}, > {shell,exprs,6}, > {shell,eval_loop,3}]} ** > 6> T = erlang:make_tuple(200,a). > {a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a|...} > 7> timer:tc(erlang,push_element,[T,1]). > {8,{1,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a|...}} > > > My heavy-handed attempt at writing this in C (copy-paste > setelement_3 and tweaking it some): > > BIF_RETTYPE push_element_2(BIF_ALIST_2) > { > Eterm* ptr; > Eterm* hp; > Eterm* resp; > Uint size; > > if (is_not_tuple(BIF_ARG_1)) { > error: > BIF_ERROR(BIF_P, BADARG); > } > ptr = tuple_val(BIF_ARG_1); > size = arityval(*ptr) + 1; /* include arity */ > if (size < 2) { > goto error; > } > > hp = HAlloc(BIF_P, size); > > /* copy the tuple */ > resp = hp; > *hp++ = *ptr++; > *hp++ = BIF_ARG_2; > size = size-2; > while (size--) { /* XXX use memcpy? */ > *hp++ = *ptr++; > } > BIF_RET(make_tuple(resp)); > } > > > You then have to go into erts/emulator/beam/bif.tab and add > the new BIF. > In order to test it, make clean, and then 'make opt' (rebuild > the optimized beam). > > > /Uffe > From maruthavanan_s@REDACTED Thu Aug 11 12:32:38 2005 From: maruthavanan_s@REDACTED (maruthavanan s) Date: Thu, 11 Aug 2005 10:32:38 +0000 Subject: Expand memory in erlang Message-ID: An HTML attachment was scrubbed... URL: From erlang@REDACTED Thu Aug 11 13:31:22 2005 From: erlang@REDACTED (Peter-Henry Mander) Date: Thu, 11 Aug 2005 12:31:22 +0100 Subject: We cannot easily see that we are boxed into a corner Message-ID: <1123759882.12107.12.camel@hymir.newport-networks.com> Hi Gurus, I've wondered why most of us in the software trade are reluctant to try new methods of producing software, e.g. Erlang. Here's an article, a bit long but still intriguing to me. http://www.dreamsongs.com/MobSoftware.html Quote: "We are loathe through either our natures or our upbringing to admit that the programming tasks we are called upon to do are too hard with available tools or that better tools would improve our lives. We cannot easily see that we are boxed into a corner by the assumptions of our ancestors?as correct as those assumptions were or seemed to be at the time." Just though someone here might find it interesting too. Pete. -- "The Tao of Programming flows far away and returns on the wind of morning." From tim@REDACTED Thu Aug 11 15:02:03 2005 From: tim@REDACTED (Tim Bates) Date: Thu, 11 Aug 2005 22:32:03 +0930 Subject: Improving my code Message-ID: <42FB4C4B.8070504@bates.id.au> Hi folks, In the interests of improving my code (I understand the functional paradigm but am not yet fluent in it) would someone kindly suggest how can I improve upon the current snippets? update_history takes a list of {Name, Max, [Values]} tuples. It finds the element(s) of the list with matching Name, and adds Value to the front of the list. It then makes sure the Values list has no more than Max values in it. Other elements of the list are unchanged. eg update_history([{foo, 2, [1,2]}, {bar, 5, [2,3]}], foo, 0) -> [{foo, 2, [0,1]}, {bar, 5, [2,3]}]. update_history(History, Name, Value) -> update_history(History, Name, Value, []). update_history([], _Name, _Value, Acc) -> Acc; update_history([{Name, Max, Values}|Rest], Name, Value, Acc) -> NewVs = trunclist([Value] ++ Values, Max), update_history(Rest, Name, Value, Acc ++ [{Name, Num, NewVs}]); update_history([H|Rest], Name, Value, Acc) -> update_history(Rest, Name, Value, Acc ++ [H]). trunclist(List, Num) -> trunclist(List, Num, []). trunclist(_List, 0, Acc) -> Acc; trunclist([], _N, Acc) -> Acc; trunclist([L|Rest], N, Acc) -> trunclist(Rest, N - 1, Acc ++ [L]). Thanks, Tim. -- Tim Bates tim@REDACTED From vlad.xx.dumitrescu@REDACTED Thu Aug 11 15:16:19 2005 From: vlad.xx.dumitrescu@REDACTED (Vlad Dumitrescu XX (LN/EAB)) Date: Thu, 11 Aug 2005 15:16:19 +0200 Subject: Improving my code Message-ID: <11498CB7D3FCB54897058DE63BE3897C4BE5C2@esealmw105.eemea.ericsson.se> Hi, > In the interests of improving my code (I understand the functional > paradigm but am not yet fluent in it) would someone kindly > suggest how can I improve upon the current snippets? They look good, really. There are just a few observations to make: > update_history([], _Name, _Value, Acc) -> > Acc; *** lists:reverse(Acc); > update_history([{Name, Max, Values}|Rest], Name, Value, Acc) -> > NewVs = trunclist([Value] ++ Values, Max), *** NewVs = trunclist([Value | Values], Max), > update_history(Rest, Name, Value, Acc ++ [{Name, Num, NewVs}]); *** update_history(Rest, Name, Value, [{Name, Num, NewVs} | Acc]); > update_history([H|Rest], Name, Value, Acc) -> > update_history(Rest, Name, Value, Acc ++ [H]). *** update_history(Rest, Name, Value, [H | Acc]). This idiom of constructing a reversed list and "straighten it up" before returning is worth remembering - the application to trunclist is left as an exercise :-) best regards, Vlad From matthias@REDACTED Thu Aug 11 22:52:19 2005 From: matthias@REDACTED (Matthias Lang) Date: Thu, 11 Aug 2005 22:52:19 +0200 Subject: someone wants to know about Erlang for some sort of large database system Message-ID: <17147.47747.513443.631784@antilipe.corelatus.se> Could someone more enthusiastic and patient than I write an answer for this guy? I've gotten too old and cranky to deal with this sort of stuff. (Besides, I know very little about mnesia and oracle and I don't know the guy, I assume he's mailing me because he saw my name on some website.) Matthias -------------- next part -------------- An embedded message was scrubbed... From: Brian Doyle Subject: Choice of languages and data base structure Date: Thu, 11 Aug 2005 11:11:54 -0700 Size: 8113 URL: From ok@REDACTED Fri Aug 12 04:44:34 2005 From: ok@REDACTED (Richard A. O'Keefe) Date: Fri, 12 Aug 2005 14:44:34 +1200 (NZST) Subject: push_element/2 - efficient sliding window Message-ID: <200508120244.j7C2iYh5429802@atlas.otago.ac.nz> Suppose you want to maintain a sliding window of 20 elements, with new elements coming in from the left. initial_window(X) -> {X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X}. add_to_window(X, {A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T}) -> {X,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S}. Do we really need built-in support for this? From ok@REDACTED Fri Aug 12 04:55:55 2005 From: ok@REDACTED (Richard A. O'Keefe) Date: Fri, 12 Aug 2005 14:55:55 +1200 (NZST) Subject: Improving my code Message-ID: <200508120255.j7C2ttKm431956@atlas.otago.ac.nz> update_history(History, Name, Value) -> update_history(History, Name, Value, []). update_history([], _Name, _Value, Acc) -> Acc; update_history([{Name, Max, Values}|Rest], Name, Value, Acc) -> NewVs = trunclist([Value] ++ Values, Max), update_history(Rest, Name, Value, Acc ++ [{Name, Num, NewVs}]); Whenever you see a "++" in your code, you should flinch. You should feel as comfortable about it as you would a smouldering ember on a new carpet. To process a list of N elements this way will ALWAYS cost you O(N**2) time. You really don't need to do that. update_history([H|Rest], Name, Value, Acc) -> update_history(Rest, Name, Value, Acc ++ [H]). Your trunclist function has the same problem. Tail recursion is good, but NOT at the price of turning an O(N) operation into an O(N**2) one. A simple O(N) version is: update_history([{Name,Max,Values}|Rest], Name, Value) -> [{Name,Max,[Value | take(Max-1, Values)], Max)}|Rest]; update_history([Item|Rest], Name, Value) -> [Item | update_history(Rest, Name, Value)]; update_history([], _, _) -> []. take(N, [X|Xs]) when N > 0 -> [X | take(N-1,Xs)]; take(_, _) -> []. From meena_selvam@REDACTED Fri Aug 12 08:04:32 2005 From: meena_selvam@REDACTED (MEENA SELVAM) Date: Thu, 11 Aug 2005 23:04:32 -0700 (PDT) Subject: doubt regarding nested if blocks Message-ID: <20050812060432.36941.qmail@web30407.mail.mud.yahoo.com> In the following code sample, if the commented line(line 7) is uncommented, compilation is successful, but with the comment it crashes during compilation, (which i have included at the end) how can i get around the crash without introducing dummy statement? why does it crash at all? case Cookie of not_found -> "no_vlan"; _ -> {_,_,_,Dcookie,Pcookie} = Cookie, if Dcookie == undefined -> % dummy=1, if Pcookie == undefined -> [CE] = [], skip = 1; true-> [CE] = lookup_x(Pcookie , false) end; true-> [CE] = lookup_x(Dcookie , false) end, if skip /= 1 -> case ?CACHE_SNAS_INFO(CE) of Dev = #device{} -> Dev#device.vlan; undefined -> "no vlan" end; true -> "no_vlan" end end. crash reason: {{case_clause,{'EXIT',{function_clause, [{v3_life, call_op, [{k_internal,[],match_fail,1}]}, {v3_life,expr,3}, {v3_life,body,3}, {v3_life,body,3}, {v3_life,match,4}, {v3_life,val_clause,4}, {lists,map,2}, {v3_life,type_clause,4}]}}}, [{compile,'-select_passes/2-anonymous-2-',2}, {compile,'-internal_comp/4-anonymous-1-',2}, {compile,fold_comp,3}, {compile,internal_comp,4}, {compile,internal,3}]} ____________________________________________________ Start your day with Yahoo! - make it your home page http://www.yahoo.com/r/hs From bengt.kleberg@REDACTED Fri Aug 12 08:41:04 2005 From: bengt.kleberg@REDACTED (Bengt Kleberg) Date: Fri, 12 Aug 2005 08:41:04 +0200 Subject: doubt regarding nested if blocks In-Reply-To: <20050812060432.36941.qmail@web30407.mail.mud.yahoo.com> References: <20050812060432.36941.qmail@web30407.mail.mud.yahoo.com> Message-ID: <42FC4480.6030700@ericsson.com> On 2005-08-12 08:04, MEENA SELVAM wrote: > In the following code sample, if the commented > line(line 7) is uncommented, compilation is > successful, but with the comment it crashes during > compilation, (which i have included at the end) > > how can i get around the crash without introducing > dummy statement? why does it crash at all? > > case Cookie of > not_found -> > "no_vlan"; > _ -> > {_,_,_,Dcookie,Pcookie} = Cookie, > if Dcookie == undefined -> > % dummy=1, > if Pcookie == undefined -> > [CE] = [], > skip = 1; > true-> > [CE] = lookup_x(Pcookie , > false) > end; > true-> > [CE] = lookup_x(Dcookie , false) > end, > if skip /= 1 -> > case ?CACHE_SNAS_INFO(CE) of > Dev = #device{} -> > > Dev#device.vlan; > undefined -> > "no vlan" > end; > true -> "no_vlan" > end > end. i can not reproduce your crash. i added a module, function head and a macro definition. i then compiled the function. it compiled (with lots of warnings and errors). by adding dummy functions and a record i got a clean compile. erlc does not have a versin(?), but erl says: Erlang (THREADS,HIPE) (BEAM) emulator version 5.4.7 btw: are you matching the atom 'skip' with the integer 1 to cause a run time crash? > skip = 1; would it not be clearer to call erlang:throw(), or similarfunction, instead? and please consider rewriteing > if skip /= 1 -> would it not be clearer as if false -> also consider rewriteing > case ?CACHE_SNAS_INFO(CE) of > Dev = #device{} -> > Dev#device.vlan; as case ?CACHE_SNAS_INFO(CE) of #device{vlan=Vlan} -> Vlan; bengt From ulf@REDACTED Fri Aug 12 09:31:14 2005 From: ulf@REDACTED (Ulf Wiger) Date: Fri, 12 Aug 2005 09:31:14 +0200 Subject: push_element/2 - efficient sliding window In-Reply-To: <200508120244.j7C2iYh5429802@atlas.otago.ac.nz> References: <200508120244.j7C2iYh5429802@atlas.otago.ac.nz> Message-ID: Den 2005-08-12 04:44:34 skrev Richard A. O'Keefe : > Suppose you want to maintain a sliding window of 20 elements, > with new elements coming in from the left. > > initial_window(X) -> > {X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X}. > > add_to_window(X, {A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T}) -> > {X,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S}. > > Do we really need built-in support for this? It's about as justified as erlang:make_tuple/2 and erlang:append_element/2. Those two can be implemented in exactly the same manner as you describe, but only if it is practical to hard- code the size of the tuple. If that isn't true, then there is no generic way to do it in Erlang that doesn't add significant overhead. The cheapest way I've found so far to do a "left shift" of a tuple is: add_to_window(X, {List, _Tup}) -> List1 = tl(List) ++ [X], {List1, list_to_tuple(List1)}. This is about three times as expensive as the BIF, and also requires you to lug the window along as a list, along with the tuple representation. Not that this adds tremendous memory overhead. Doing away with the list, you can do: add_to_window(X, Tup) -> L = tuple_to_list(Tup), L1 = tl(L) ++ [X], list_to_tuple(L1). This adds an element to the end of the tuple. Adding it to the beginning without knowing the size of the tuple is more expensive. Why? Because we have built-in support for append and tuple_to_list/list_to_tuple (all of these can easily be implemented in Erlang). That's what makes the program above reasonably fast. rshift_tuple(X, Tup) -> L = tuple_to_list(Tup), [_|R] = lists:reverse(R), list_to_tuple([X|lists:reverse(R)]). Since a shift BIF would cost about the same as tuple_to_list/1, lists:reverse/1, list_to_tuple/1 and append/2 above (they are all BIFs), the efficiency gain of adding the BIF would be about 4x in the generic case. Actually erlang:make_tuple/2 was my suggestion. This was after having written my own make_tuple/2 in Erlang a number of times, roughly in the manner you suggest: make_tuple(10, X) -> {X, X, X, X, X, X, X, X, X, X}; make_tuple(20, X) -> {X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X}; make_tuple(N, X) when is_integer(N) -> list_to_tuple(lists:duplicate(N, X)). I see no reason why we should grace the list type with optimized versions of append, subtract, keymember, member, keysearch and reverse, but not offer similar optimizations for tuples. I think tuples could be used to great advantage in many cases where we use ETS today, if only a few steps were taken to ease their use a little bit. Another thing I'd like to see for tuples is a syntax addition: tag_search([{Tag | _} = T|_], Tag) -> {value, T}; ... That is, describing the "tail" of a tuple in a manner similar to that of lists. This form is actually used in some places in the documentation! Most likely because it's very convenient. It could also be used to improve backwards compatibility, since new elements in a tuple are usually added last to preserve order. I have not given much thought to the implementation issues of this last item. Perhaps it's difficult...? /Uffe -- Ulf Wiger From vlad.xx.dumitrescu@REDACTED Fri Aug 12 09:47:08 2005 From: vlad.xx.dumitrescu@REDACTED (Vlad Dumitrescu XX (LN/EAB)) Date: Fri, 12 Aug 2005 09:47:08 +0200 Subject: push_element/2 - efficient sliding window Message-ID: <11498CB7D3FCB54897058DE63BE3897C4BE5C3@esealmw105.eemea.ericsson.se> > -----Original Message----- > From: owner-erlang-questions@REDACTED > [mailto:owner-erlang-questions@REDACTED]On Behalf Of Ulf Wiger > Another thing I'd like to see for tuples is a syntax > addition: > > tag_search([{Tag | _} = T|_], Tag) -> > {value, T}; > ... > > That is, describing the "tail" of a tuple in a manner > similar to that of lists. This form is actually used > in some places in the documentation! Most likely because > it's very convenient. It could also be used to improve > backwards compatibility, since new elements in a tuple > are usually added last to preserve order. Dou you think it should also work as a constructor? Tuple2 = { Elem | Tuple1} Elegance would require it, but it would be quite inefficient to use tuples in this way (where in fact lists are needed) because one needs to copy the tuple contents, whereas adding to the head of a list is constant time. regards, Vlad From vlad.xx.dumitrescu@REDACTED Fri Aug 12 10:29:01 2005 From: vlad.xx.dumitrescu@REDACTED (Vlad Dumitrescu XX (LN/EAB)) Date: Fri, 12 Aug 2005 10:29:01 +0200 Subject: Syntax tools Message-ID: <11498CB7D3FCB54897058DE63BE3897C4BE5C4@esealmw105.eemea.ericsson.se> Hi, I would like to use syntax_tools to prettyprint source code, but with a slightly modified layout - for example, I'd like to have a newline after function clause arrows. At first I thought this would be done with prettyprinter hooks, but they are only called for annotations. My question is: is there a way to customize the behaviour like this in a friendly way, or do I have to take the axe and hack away? On a related issue: erl_syntax_lib:strip_comments/1 doesn't strip top-level comments... best regards, Vlad -------------- next part -------------- An HTML attachment was scrubbed... URL: From Reddy_P@REDACTED Fri Aug 12 10:25:13 2005 From: Reddy_P@REDACTED (Primanathan Reddy [ MTN - Innovation Centre ]) Date: Fri, 12 Aug 2005 10:25:13 +0200 Subject: tcp_inet question Message-ID: <5B289289AAC81D4397719C168EA40B19015BFA1F@MTNMAIL.mtn.co.za> Hello I am using Erlang R9-C2 running on solaris I got the following error report: =ERROR REPORT==== 11-Aug-2005::15:10:33 === #Port<0.554>: tcp_inet: Input driver gone away without deselecting! 1749- fatal: {invalid_name,"0\" REQ"} 1749- fatal: {invalid_name,"0\" REQ"} 1749- fatal: {invalid_name,"0\" REQ"} 1749- fatal: {invalid_name,"0\" REQ"} 1749- fatal: {invalid_name,"0\" REQ"} 1749- fatal: {invalid_name,"0\" REQ"} 1749- fatal: {invalid_name,"0\" REQ"} =ERROR REPORT==== 11-Aug-2005::19:19:24 === #Port<0.33>: tcp_inet: Input driver gone away without deselecting! =ERROR REPORT==== 11-Aug-2005::19:37:32 === #Port<0.295>: tcp_inet: Input driver gone away without deselecting! Can anyone help me with what the above error means Regards Primanathan Reddy Pharos Consulting (PTY) LTD +27832129774 NOTE: This e-mail message is subject to the MTN Group disclaimer see http://www.mtn.co.za/disclaimer -------------- next part -------------- An HTML attachment was scrubbed... URL: From ulf.wiger@REDACTED Fri Aug 12 11:05:48 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Fri, 12 Aug 2005 11:05:48 +0200 Subject: push_element/2 - efficient sliding window Message-ID: Vlad Dumitrescu wrote: > > Ulf Wiger wrote: > > tag_search([{Tag | _} = T|_], Tag) -> > > {value, T}; > > ... > > > > That is, describing the "tail" of a tuple in a manner > > similar to that of lists. This form is actually used > > in some places in the documentation! Most likely because > > it's very convenient. It could also be used to improve > > backwards compatibility, since new elements in a tuple > > are usually added last to preserve order. > > Dou you think it should also work as a constructor? > Tuple2 = { Elem | Tuple1} > > Elegance would require it, but it would be quite inefficient > to use tuples in this way (where in fact lists are needed) > because one needs to copy the tuple contents, whereas adding > to the head of a list is constant time. I'd be perfectly happy to have it as syntactic sugar for tag_search([T|_], Tag) when element(1, T) == Tag -> {value, T}; In this particular example, it's only a marginal improvement, but in other cases, it could be a significant boon: (Just grabbing some code from stdlib -- erl_lint.erl: pattern({record_field,Line,_,_}=M, _Vt, _Old, _Bvt, St0) -> case expand_package(M, St0) of {error, St1} -> {[],[],add_error(Line, illegal_expr, St1)}; {_, St1} -> {[],[],St1} end; Imagine wanting to add an "annotations" element to tuples in the parse tree (or perhaps column numbers). It's a silly idea, since it would require a total rewrite of compiler and linter, and a load of other modules as well. What if we could rewrite the above code as: pattern({record_field,Line|_}=M, _Vt, _Old, _Bvt, St0) -> case expand_package(M, St0) of {error, St1} -> {[],[],add_error(Line, illegal_expr, St1)}; {_, St1} -> {[],[],St1} end; But this function didn't modify the tuple, so it's an easy case. pattern({op,_Line,'++',{cons,Li,{char,_L2,_C},T},R}, Vt, Old, Bvt, St) -> pattern({op,Li,'++',T,R}, Vt, Old, Bvt, St); %Char unimportant here would at first become: pattern({op,_Line,'++',{cons,Li,{char,_L2,_C|_},T|_},R|Rest}, Vt, Old, Bvt, St) -> pattern({op,Li,'++',T,R|Rest}, Vt, Old, Bvt, St); %Char unimportant here Then, yes, it would have to work as a constructor too, but with the meaning of: pattern(P, Vt, Old, Bvt, St) when element(1,P) == op, element(2,P) == '++', element(1,element(3,P))==cons, element(1,element(3,element(3,P)))==char -> Cons = element(3, P), Li = element(2, Cons), T = element(3, Cons), P1 = setelement(2, setelement(4, P, T), Li), pattern(P1, Vt, Old, Bvt, St); %Char unimportant here That is, not modifying the lenght of the tuple, but rather as syntactic sugar for what would otherwise be a cascade of setelement/3 calls. (which may also serve to illustrate why nobody in his right mind writes code like this today.) /Uffe From vlad.xx.dumitrescu@REDACTED Fri Aug 12 11:23:10 2005 From: vlad.xx.dumitrescu@REDACTED (Vlad Dumitrescu XX (LN/EAB)) Date: Fri, 12 Aug 2005 11:23:10 +0200 Subject: push_element/2 - efficient sliding window Message-ID: <11498CB7D3FCB54897058DE63BE3897C4BE5C5@esealmw105.eemea.ericsson.se> Mmm, yes, it is an interesting idea. But I'm not sure if it would qualify under the rule of "least astonishment" if {H|T} behaves differently than [H|T]. Perhaps it would be better to introduce Richard O'Keefe's abstract patterns instead (I might be wrong that they could solve this issue). regards, Vlad From richardc@REDACTED Fri Aug 12 12:01:14 2005 From: richardc@REDACTED (Richard Carlsson) Date: Fri, 12 Aug 2005 12:01:14 +0200 Subject: Syntax tools In-Reply-To: <11498CB7D3FCB54897058DE63BE3897C4BE5C4@esealmw105.eemea.ericsson.se> References: <11498CB7D3FCB54897058DE63BE3897C4BE5C4@esealmw105.eemea.ericsson.se> Message-ID: <42FC736A.2090707@csd.uu.se> Vlad Dumitrescu XX (LN/EAB) wrote: > > I would like to use syntax_tools to prettyprint source code, but with a > slightly modified layout - for example, I'd like to have a newline after > function clause arrows. I made the layout so that it tries to be as compact as possible, so it will not break lines if there is enough room horizontally. Of course, this might not suit everyone, but it suited me at the time. > At first I thought this would be done with prettyprinter hooks, but they > are only called for annotations. Yes. In hindsight, maybe I should have added more hooks after all. Perhaps I can still change it and remain backwards compatible. > My question is: is there a way to customize the behaviour like this in a > friendly way, or do I have to take the axe and hack away? If you add annotations to the nodes you want to handle, as a prepass, you should be able to trigger the hooks and do the formatting your way. > On a related issue: erl_syntax_lib:strip_comments/1 doesn't strip > top-level comments... Thanks, I'll look at it. /Richard From Reddy_P@REDACTED Fri Aug 12 12:29:39 2005 From: Reddy_P@REDACTED (Primanathan Reddy [ MTN - Innovation Centre ]) Date: Fri, 12 Aug 2005 12:29:39 +0200 Subject: tcp_inet question Message-ID: <5B289289AAC81D4397719C168EA40B19015BFB06@MTNMAIL.mtn.co.za> OK Traced the 1749- fatal error to the xml parser. Non DTD compliant data was being sent to the parser. This still leaves me with the tcp_inet error! Can anyone assist with where this error comes from? =ERROR REPORT==== 11-Aug-2005::19:19:24 === #Port<0.33>: tcp_inet: Input driver gone away without deselecting! =ERROR REPORT==== 11-Aug-2005::19:37:32 === #Port<0.295>: tcp_inet: Input driver gone away without deselecting! Thanks in advance Regards Primanathan Reddy Pharos Consulting (PTY) LTD +27832129774 NOTE: This e-mail message is subject to the MTN Group disclaimer see http://www.mtn.co.za/disclaimer -------------- next part -------------- An HTML attachment was scrubbed... URL: From ermine@REDACTED Fri Aug 12 16:47:57 2005 From: ermine@REDACTED (Anastasia Gornostaeva) Date: Fri, 12 Aug 2005 18:47:57 +0400 Subject: inets or yaws: transfer-encoding Message-ID: <20050812144757.GA17448@ermine.home> Hello. I need to process http requests from some mobile phones, they uses chunked data in POST method. In http headers they send Transer-encoding: chunked, not "content-length" or "connection: close". Yaws does not implement such request.I attempt to hack yaws sources, but i get http_error from gen_tcp:read function on first line of POST body. Is inets capable to process chunked data at server side? Are here any sane reasons to avoid receivind chunked data by server? ermine From ingela@REDACTED Fri Aug 12 17:17:02 2005 From: ingela@REDACTED (Ingela Anderton) Date: Fri, 12 Aug 2005 17:17:02 +0200 Subject: inets or yaws: transfer-encoding References: <20050812144757.GA17448@ermine.home> Message-ID: <17148.48494.91775.250403@gargle.gargle.HOWL> Anastasia Gornostaeva wrote: > Is inets capable to process chunked data at server side? Inets has that capability. > Are here any sane reasons to avoid receivind chunked data by server? I do not know of one, but chunked encoding is a HTTP/1.1 feature and not all servers support HTTP/1.1. (Note I do not claim to know anything about yaws or why there seems to be a problem there.) -- /Ingela - OTP team From mfs@REDACTED Fri Aug 12 17:32:40 2005 From: mfs@REDACTED (Mark Scandariato) Date: Fri, 12 Aug 2005 11:32:40 -0400 (GMT-04:00) Subject: length of an iolist Message-ID: <2024047.1123860760462.JavaMail.root@mswamui-bichon.atl.sa.earthlink.net> How would iolist_to_binary differ from list_to_binary? Here are two versions of iolist_size I put together - an erlang version and a bif. -module(tst). -export([i_size/1]). i_size(L) -> i_size(L, 0). i_size([], S) -> S; i_size([H|T], S) when is_binary(H) -> i_size(T, S+size(H)); i_size([H|T], S) when H >= 0, H =< 255 -> i_size(T, S+1); i_size([H|T], S) when is_list(H) -> i_size(T, S) + i_size(H); i_size(_, _) -> erlang:error(badarg). This is a cut, paste, hack of list_to_binary_1 (inspired by Ulf Wiger's erlang:push_element/1): BIF_RETTYPE iolist_size_1(BIF_ALIST_1) { Eterm bin; int i; if (is_nil(BIF_ARG_1)) { BIF_RET(SMALL_ZERO); } if (is_not_list(BIF_ARG_1)) { error: BIF_ERROR(BIF_P, BADARG); } if ((i = io_list_len(BIF_ARG_1)) < 0) { goto error; } BIF_RET(make_small_or_big(i, BIF_P)); } Here's how they perform on an iMac G5 (1.6GHz, Mac OS X 10.4.2) with R10B-6 (L is a list of nested lists and binaries, not terribly deep - maybe 3 levels of nesting): 111> erlang:garbage_collect(), timer:tc(tst, i_size, [L]). {23318,51000} 112> erlang:garbage_collect(), timer:tc(erlang, iolist_size, [L]). {359,51000} Mark. From mfs@REDACTED Fri Aug 12 17:43:53 2005 From: mfs@REDACTED (Mark Scandariato) Date: Fri, 12 Aug 2005 11:43:53 -0400 (GMT-04:00) Subject: length of an iolist Message-ID: <28220869.1123861433755.JavaMail.root@mswamui-bichon.atl.sa.earthlink.net> Cut & paste indeed! I just noticed the superfluous "Eterm bin;" in the bif. (Doh!) -----Original Message----- From: Mark Scandariato Sent: Aug 12, 2005 11:32 AM To: erlang-questions@REDACTED Subject: Re: length of an iolist How would iolist_to_binary differ from list_to_binary? Here are two versions of iolist_size I put together - an erlang version and a bif. -module(tst). -export([i_size/1]). i_size(L) -> i_size(L, 0). i_size([], S) -> S; i_size([H|T], S) when is_binary(H) -> i_size(T, S+size(H)); i_size([H|T], S) when H >= 0, H =< 255 -> i_size(T, S+1); i_size([H|T], S) when is_list(H) -> i_size(T, S) + i_size(H); i_size(_, _) -> erlang:error(badarg). This is a cut, paste, hack of list_to_binary_1 (inspired by Ulf Wiger's erlang:push_element/1): BIF_RETTYPE iolist_size_1(BIF_ALIST_1) { Eterm bin; int i; if (is_nil(BIF_ARG_1)) { BIF_RET(SMALL_ZERO); } if (is_not_list(BIF_ARG_1)) { error: BIF_ERROR(BIF_P, BADARG); } if ((i = io_list_len(BIF_ARG_1)) < 0) { goto error; } BIF_RET(make_small_or_big(i, BIF_P)); } Here's how they perform on an iMac G5 (1.6GHz, Mac OS X 10.4.2) with R10B-6 (L is a list of nested lists and binaries, not terribly deep - maybe 3 levels of nesting): 111> erlang:garbage_collect(), timer:tc(tst, i_size, [L]). {23318,51000} 112> erlang:garbage_collect(), timer:tc(erlang, iolist_size, [L]). {359,51000} Mark. From serge@REDACTED Fri Aug 12 23:21:30 2005 From: serge@REDACTED (Serge Aleynikov) Date: Fri, 12 Aug 2005 17:21:30 -0400 Subject: application startup Message-ID: <42FD12DA.8050805@hq.idt.net> Folks, I have the following config, and I noticed that os_mon and mnesia applications get started at startup when I use a boot script: >erlc -pa ../ebin -o ../ebin drpdb.rel >cd ../ebin >erl -boot drpdb -sname drpdb -config ../priv/drpdb I was under impression that if an application is listed in the *.rel file, it should be loaded but not started. In order for it to be started it must be included in the {applications, ...} tuple of the *.app file. However, what I am observing is that all apps that are listed in the *.rel file are started automatically. Am I doing something wrong? ====== drpdb.rel ======== {release, {"drpdb","1.0"}, {erts, "5.4.8"}, [{kernel,"2.10.9"}, {stdlib,"1.13.8"}, {sasl, "2.0.1"}, {drpdb, "1.0"}, {os_mon, "1.7.4"}, {mnesia, "4.2.2"} ]}. ====== drpdb.app ======== {application, drpdb, [ {description, "Master Database Server"}, {vsn, "1.0"}, {id, "drpdb"}, {modules, [ drpdb_app, drpdb_sup, drpdb ] }, {registered, [ drpdb_sup, drpdb ] }, {applications, [ kernel, sasl ] }, {mod, {drpdb_app, []}}, {env, []} ] }. -- Serge Aleynikov R&D Telecom, IDT Corp. Tel: (973) 438-3436 Fax: (973) 438-1464 serge@REDACTED From sean.hinde@REDACTED Fri Aug 12 23:46:05 2005 From: sean.hinde@REDACTED (Sean Hinde) Date: Fri, 12 Aug 2005 22:46:05 +0100 Subject: application startup In-Reply-To: <42FD12DA.8050805@hq.idt.net> References: <42FD12DA.8050805@hq.idt.net> Message-ID: On 12 Aug 2005, at 22:21, Serge Aleynikov wrote: > > I was under impression that if an application is listed in the > *.rel file, it should be loaded but not started. In order for it > to be started it must be included in the {applications, ...} tuple > of the *.app file. However, what I am observing is that all apps > that are listed in the *.rel file are started automatically. Am I > doing something wrong? > > ====== drpdb.rel ======== > {release, {"drpdb","1.0"}, {erts, "5.4.8"}, > [{kernel,"2.10.9"}, > {stdlib,"1.13.8"}, > {sasl, "2.0.1"}, > {drpdb, "1.0"}, > {os_mon, "1.7.4"}, > {mnesia, "4.2.2"} > ]}. > > > ====== drpdb.app ======== > {application, drpdb, > [ > {description, "Master Database Server"}, > {vsn, "1.0"}, > {id, "drpdb"}, > {modules, > [ > drpdb_app, > drpdb_sup, > drpdb > ] > }, > {registered, [ drpdb_sup, drpdb ] }, > {applications, [ kernel, sasl ] }, > {mod, {drpdb_app, []}}, ^^^^^^^^^^^^^^^^^^^^^^^ > {env, []} > ] > }. The mod entry in the .app file is the thing which causes the application to start. Sean From ulf@REDACTED Fri Aug 12 23:59:35 2005 From: ulf@REDACTED (Ulf Wiger) Date: Fri, 12 Aug 2005 23:59:35 +0200 Subject: application startup In-Reply-To: <42FD12DA.8050805@hq.idt.net> References: <42FD12DA.8050805@hq.idt.net> Message-ID: All applications in the .rel file are started automatically if they - have a 'mod' attribute - are not included in another application The 'builder' contrib builds two start scripts: one where all applications are started as expected, and one where only kernel and stdlib are started, but all applications are loaded, and the code path set to include all code. The latter script is useful if you e.g. want to initialize mnesia and other stuff, and the way it's generated is by simply modifying the start script after it's been built. /Uffe Den 2005-08-12 23:21:30 skrev Serge Aleynikov : > Folks, > > I have the following config, and I noticed that os_mon and mnesia > applications get started at startup when I use a boot script: > > >erlc -pa ../ebin -o ../ebin drpdb.rel > >cd ../ebin > >erl -boot drpdb -sname drpdb -config ../priv/drpdb > > I was under impression that if an application is listed in the *.rel > file, it should be loaded but not started. In order for it to be > started it must be included in the {applications, ...} tuple of the > *.app file. However, what I am observing is that all apps that are > listed in the *.rel file are started automatically. Am I doing > something wrong? > > ====== drpdb.rel ======== > {release, {"drpdb","1.0"}, {erts, "5.4.8"}, > [{kernel,"2.10.9"}, > {stdlib,"1.13.8"}, > {sasl, "2.0.1"}, > {drpdb, "1.0"}, > {os_mon, "1.7.4"}, > {mnesia, "4.2.2"} > ]}. > > > ====== drpdb.app ======== > {application, drpdb, > [ > {description, "Master Database Server"}, > {vsn, "1.0"}, > {id, "drpdb"}, > {modules, > [ > drpdb_app, > drpdb_sup, > drpdb > ] > }, > {registered, [ drpdb_sup, drpdb ] }, > {applications, [ kernel, sasl ] }, > {mod, {drpdb_app, []}}, > {env, []} > ] > }. > -- Ulf Wiger From orbitz@REDACTED Sat Aug 13 06:23:05 2005 From: orbitz@REDACTED (orbitz@REDACTED) Date: Sat, 13 Aug 2005 00:23:05 -0400 Subject: Throw or return a tuple Message-ID: <73b6898c58d0154fbb8dbc1a7f2552aa@ezabel.com> I find myself often confused about which to do, should I throw an exception when an error happens in a function or always go with returning {ok, Value} or {error, Whatever}. Some people seem try to tell me that I should use {error, Value} and "get out of your OO mindset with exceptions". But I think that is bull. I don't see why exceptions should be purely considered OO and erlang has exceptions, why shouldn't I use them? That seems like the talk of people afraid of change or something similar. The most convincing argument for me to use exceptions is because I want to be able to do: foo(bar()) rather than {ok, V} = ...yadda. What do people generally prefer? Are we moving towards more exceptions? OTP seems to use exceptions for somethings and an error tuple for others. Thanks From ulf@REDACTED Sat Aug 13 09:25:50 2005 From: ulf@REDACTED (Ulf Wiger) Date: Sat, 13 Aug 2005 09:25:50 +0200 Subject: Throw or return a tuple In-Reply-To: <73b6898c58d0154fbb8dbc1a7f2552aa@ezabel.com> References: <73b6898c58d0154fbb8dbc1a7f2552aa@ezabel.com> Message-ID: Den 2005-08-13 06:23:05 skrev : > I find myself often confused about which to do, should I throw an > exception when an error happens in a function or always go with > returning {ok, Value} or {error, Whatever}. This has been discussed now and then on the list. I think the cleanest way to program is to have functions that either return a good value or throw an exception (amendments to the rule will follow). Traditionally, there have been some problems with debugging this style of programming, but the problems are being addressed, e.g. with the new 'try' construct. Coupled with this is the 'let it crash' philosophy (http://www.google.com/search?&q=%22let+it+crash%22+erlang) A place where it's appropriate to wrap return values is for example: dict:read(Key) -> Value | exit() dict:search(Key) -> {found, Value} | not_found > Some people seem try to tell me that I should use {error, Value} and > "get out of your OO mindset with exceptions". But I think that is bull. I agree. One problem with always wrapping return values is that you get a lot of code like this: case foo(...) of {ok, Result} -> ..., case bar(...) of ... end; {error, Reason} -> {error, Reason} end. That is, the most common situation is that you can't handle the error return value where it first occurs, and just pass it on to the caller. Throwing exceptions is a much better way to accomplish this. /Uffe -- Ulf Wiger From bjorn@REDACTED Sat Aug 13 10:19:47 2005 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 13 Aug 2005 10:19:47 +0200 Subject: Throw or return a tuple In-Reply-To: References: <73b6898c58d0154fbb8dbc1a7f2552aa@ezabel.com> Message-ID: I agree, and I think that a good rule of thumb is to use exceptions for errors that are truly exceptional. For instance, when opening a file, I don't find it exceptional that a file does not exist, so I think that the file module is right in that it returns an error tuple. Within a particular application, file operations may in fact be exceptional, so that it makes sense to have exception-throwing wrappers for the file operations. Another example, any API that would force you to catch exceptions just to be able to successfully end a loop is WRONG. (E.g. if the queue module would throw an execption when trying to remove an element from an empty queue, or if end of file would cause an exception when reading from a file.) /Bj?rn "Ulf Wiger" writes: > Den 2005-08-13 06:23:05 skrev : > > > I find myself often confused about which to do, should I throw an > > exception when an error happens in a function or always go with > > returning {ok, Value} or {error, Whatever}. > > This has been discussed now and then on the list. > I think the cleanest way to program is to have functions > that either return a good value or throw an exception > (amendments to the rule will follow). > > Traditionally, there have been some problems with > debugging this style of programming, but the problems > are being addressed, e.g. with the new 'try' construct. > > Coupled with this is the 'let it crash' philosophy > (http://www.google.com/search?&q=%22let+it+crash%22+erlang) > > A place where it's appropriate to wrap return values is > for example: > > dict:read(Key) -> Value | exit() > dict:search(Key) -> {found, Value} | not_found > > > Some people seem try to tell me that I should use {error, Value} and > > "get out of your OO mindset with exceptions". But I think that is > > bull. > > I agree. > > > One problem with always wrapping return values is that > you get a lot of code like this: > > case foo(...) of > {ok, Result} -> > ..., > case bar(...) of > ... > end; > {error, Reason} -> > {error, Reason} > end. > > That is, the most common situation is that you can't > handle the error return value where it first occurs, > and just pass it on to the caller. Throwing exceptions > is a much better way to accomplish this. > > /Uffe > -- > Ulf Wiger > -- Bj?rn Gustavsson, Erlang/OTP, Ericsson AB From ulf@REDACTED Sat Aug 13 11:59:58 2005 From: ulf@REDACTED (Ulf Wiger) Date: Sat, 13 Aug 2005 11:59:58 +0200 Subject: Throw or return a tuple In-Reply-To: References: <73b6898c58d0154fbb8dbc1a7f2552aa@ezabel.com> Message-ID: Den 2005-08-13 10:19:47 skrev Bjorn Gustavsson : > Another example, any API that would force you to catch exceptions > just to be able to successfully end a loop is WRONG. (E.g. if > the queue module would throw an execption when trying to remove an > element from an empty queue, or if end of file would cause an exception > when reading from a file.) I think another good rule is to think through what the user is supposed to do in case a function can't do its job. A good example is timer:send_after/3. I've always wondered what would be appropriate to do when it returns {error, Reason}. If I can't start a timer, most likely it's due to an error in the way I'm calling the function, or because system resources are exhausted. Either way, it seems fairly difficult to continue. This would have been a good place to throw an exception rather than to try to return a "user-friendly" value. /Uffe -- Ulf Wiger From serge@REDACTED Sat Aug 13 15:17:44 2005 From: serge@REDACTED (Serge Aleynikov) Date: Sat, 13 Aug 2005 09:17:44 -0400 Subject: application startup In-Reply-To: References: <42FD12DA.8050805@hq.idt.net> Message-ID: <42FDF2F8.2050702@hq.idt.net> Ulf Wiger wrote: > > All applications in the .rel file are started > automatically if they > - have a 'mod' attribute I looked at $ERL_ROOT/lib/* and sampled several standard apps - they all have a 'mod' attribute, so I infer that by default any app listed in the application's *.rel file will get started automatically by default. > - are not included in another application I.e. not being included in the application's 'applications' attributes in the *.app file, or there's another place to include an application? > The 'builder' contrib builds two start scripts: > one where all applications are started as expected, > and one where only kernel and stdlib are started, > but all applications are loaded, and the code path > set to include all code. The latter script is useful > if you e.g. want to initialize mnesia and other stuff, > and the way it's generated is by simply modifying the > start script after it's been built. Thanks, I downloaded the 'builder' contrib. Will experiment with it. Serge > Den 2005-08-12 23:21:30 skrev Serge Aleynikov : > >> Folks, >> >> I have the following config, and I noticed that os_mon and mnesia >> applications get started at startup when I use a boot script: >> >> >erlc -pa ../ebin -o ../ebin drpdb.rel >> >cd ../ebin >> >erl -boot drpdb -sname drpdb -config ../priv/drpdb >> >> I was under impression that if an application is listed in the *.rel >> file, it should be loaded but not started. In order for it to be >> started it must be included in the {applications, ...} tuple of the >> *.app file. However, what I am observing is that all apps that are >> listed in the *.rel file are started automatically. Am I doing >> something wrong? >> >> ====== drpdb.rel ======== >> {release, {"drpdb","1.0"}, {erts, "5.4.8"}, >> [{kernel,"2.10.9"}, >> {stdlib,"1.13.8"}, >> {sasl, "2.0.1"}, >> {drpdb, "1.0"}, >> {os_mon, "1.7.4"}, >> {mnesia, "4.2.2"} >> ]}. >> >> >> ====== drpdb.app ======== >> {application, drpdb, >> [ >> {description, "Master Database Server"}, >> {vsn, "1.0"}, >> {id, "drpdb"}, >> {modules, >> [ >> drpdb_app, >> drpdb_sup, >> drpdb >> ] >> }, >> {registered, [ drpdb_sup, drpdb ] }, >> {applications, [ kernel, sasl ] }, >> {mod, {drpdb_app, []}}, >> {env, []} >> ] >> }. >> > > > -- Serge Aleynikov R&D Telecom, IDT Corp. Tel: (973) 438-3436 Fax: (973) 438-1464 serge@REDACTED From serge@REDACTED Sat Aug 13 16:41:11 2005 From: serge@REDACTED (Serge Aleynikov) Date: Sat, 13 Aug 2005 10:41:11 -0400 Subject: application startup In-Reply-To: <42FDF2F8.2050702@hq.idt.net> References: <42FD12DA.8050805@hq.idt.net> <42FDF2F8.2050702@hq.idt.net> Message-ID: <42FE0687.4060708@hq.idt.net> Ulf, I seemed to have rushed to ask the question before searching the mailing list. 'included_applications' attribute does the trick. So if I understand this correctly, in this case only sasl and drpdb will be started automatically (besides kernel and stdlib), and not mnesia and os_mon: {release, {"drpdb","1.0"}, {erts, "5.4.8"}, [{kernel,"2.10.9"}, {stdlib,"1.13.8"}, {sasl, "2.0.1"}, {drpdb, "1.0"}, {os_mon, "1.7.4"}, {mnesia, "4.2.2"} ]}. {application, drpdb, [ ... {included_applications, [ mnesia, os_mon ] }, {applications, [ kernel, sasl ] }, {mod, {drpdb_app, []}}, {env, []} ] }. Also I found your post where you modified the application_controller to customize start_phases: http://forums.trapexit.org:81/phpBB/viewtopic.php?t=4574&highlight=build+applications+start Is that available for download? Thanks. Serge Serge Aleynikov wrote: > Ulf Wiger wrote: > >> >> All applications in the .rel file are started >> automatically if they >> - have a 'mod' attribute > > > I looked at $ERL_ROOT/lib/* and sampled several standard apps - they all > have a 'mod' attribute, so I infer that by default any app listed in the > application's *.rel file will get started automatically by default. > >> - are not included in another application > > > I.e. not being included in the application's 'applications' attributes > in the *.app file, or there's another place to include an > application? > >> The 'builder' contrib builds two start scripts: >> one where all applications are started as expected, >> and one where only kernel and stdlib are started, >> but all applications are loaded, and the code path >> set to include all code. The latter script is useful >> if you e.g. want to initialize mnesia and other stuff, >> and the way it's generated is by simply modifying the >> start script after it's been built. > > > Thanks, I downloaded the 'builder' contrib. Will experiment with it. > > Serge > >> Den 2005-08-12 23:21:30 skrev Serge Aleynikov : >> Folks, >>> >>> I have the following config, and I noticed that os_mon and mnesia >>> applications get started at startup when I use a boot script: >>> >>> >erlc -pa ../ebin -o ../ebin drpdb.rel >>> >cd ../ebin >>> >erl -boot drpdb -sname drpdb -config ../priv/drpdb >>> >>> I was under impression that if an application is listed in the *.rel >>> file, it should be loaded but not started. In order for it to be >>> started it must be included in the {applications, ...} tuple of the >>> *.app file. However, what I am observing is that all apps that are >>> listed in the *.rel file are started automatically. Am I doing >>> something wrong? >>> >>> ====== drpdb.rel ======== >>> {release, {"drpdb","1.0"}, {erts, "5.4.8"}, >>> [{kernel,"2.10.9"}, >>> {stdlib,"1.13.8"}, >>> {sasl, "2.0.1"}, >>> {drpdb, "1.0"}, >>> {os_mon, "1.7.4"}, >>> {mnesia, "4.2.2"} >>> ]}. >>> >>> >>> ====== drpdb.app ======== >>> {application, drpdb, >>> [ >>> {description, "Master Database Server"}, >>> {vsn, "1.0"}, >>> {id, "drpdb"}, >>> {modules, >>> [ >>> drpdb_app, >>> drpdb_sup, >>> drpdb >>> ] >>> }, >>> {registered, [ drpdb_sup, drpdb ] }, >>> {applications, [ kernel, sasl ] }, >>> {mod, {drpdb_app, []}}, >>> {env, []} >>> ] >>> }. >>> >> >> >> > -- Serge Aleynikov R&D Telecom, IDT Corp. Tel: (973) 438-3436 Fax: (973) 438-1464 serge@REDACTED From ulf@REDACTED Sat Aug 13 18:23:51 2005 From: ulf@REDACTED (Ulf Wiger) Date: Sat, 13 Aug 2005 18:23:51 +0200 Subject: application startup In-Reply-To: <42FE0687.4060708@hq.idt.net> References: <42FD12DA.8050805@hq.idt.net> <42FDF2F8.2050702@hq.idt.net> <42FE0687.4060708@hq.idt.net> Message-ID: Den 2005-08-13 16:41:11 skrev Serge Aleynikov : > Also I found your post where you modified the application_controller to > customize start_phases: > > http://forums.trapexit.org:81/phpBB/viewtopic.php?t=4574&highlight=build+applications+start > Is that available for download? I still have it. I hope you also noted that applying the patch was very difficult? ;-) I can send it to you when I log in at work next time (it's not going to be right now.) /Uffe -- Ulf Wiger From ulf@REDACTED Sat Aug 13 18:26:14 2005 From: ulf@REDACTED (Ulf Wiger) Date: Sat, 13 Aug 2005 18:26:14 +0200 Subject: application startup In-Reply-To: <42FE0687.4060708@hq.idt.net> References: <42FD12DA.8050805@hq.idt.net> <42FDF2F8.2050702@hq.idt.net> <42FE0687.4060708@hq.idt.net> Message-ID: Den 2005-08-13 16:41:11 skrev Serge Aleynikov : > So if I understand this correctly, in this case only sasl and drpdb will > be started automatically (besides kernel and stdlib), and not mnesia and > os_mon: > {release, {"drpdb","1.0"}, {erts, "5.4.8"}, > [{kernel,"2.10.9"}, > {stdlib,"1.13.8"}, > {sasl, "2.0.1"}, > {drpdb, "1.0"}, > {os_mon, "1.7.4"}, > {mnesia, "4.2.2"} > ]}. > {application, drpdb, > [ > ... > {included_applications, [ mnesia, os_mon ] }, > {applications, [ kernel, sasl ] }, > {mod, {drpdb_app, []}}, > {env, []} > ] > }. This is correct. In fact, in the AXD 301, we've done something like this with the O&M applications (inets, snmp), where we include them in an application that we've made. It also has a special supervisor that starts them. The point of this was to have all the O&M apps move in parallel during takeover. /Uffe -- Ulf Wiger From orbitz@REDACTED Sat Aug 13 19:28:35 2005 From: orbitz@REDACTED (orbitz@REDACTED) Date: Sat, 13 Aug 2005 13:28:35 -0400 Subject: Parallel Programming Message-ID: <22b2737a7a50867914c9d717b428f16f@ezabel.com> Obviously Erlang is not made to do computationally intensive work such as computing primes or what not. However I was thinking that Erlang obviously makes an excellent framework for doing that kind of work. I was thinking one could use erlang to communicate between nodes and then use a port to a fortran program or what not. Obviously I doubt I'm the first person to think of this, so has anyone else attempted this or have any suggestions as it if it is a good idea or not? Thanks From serge@REDACTED Sat Aug 13 20:50:06 2005 From: serge@REDACTED (Serge Aleynikov) Date: Sat, 13 Aug 2005 14:50:06 -0400 Subject: Parallel Programming In-Reply-To: <22b2737a7a50867914c9d717b428f16f@ezabel.com> References: <22b2737a7a50867914c9d717b428f16f@ezabel.com> Message-ID: <42FE40DE.6080806@hq.idt.net> We've done exactily this approach in one of the projects where a large computational task was multiplexed between several nodes running C ports doing mathematical optimization. Erlang was used only for splitting work load, distribution and gathering results. I am sure other libraries (like MPI) could have been used, but it took very little effort to do parallelization in Erlang/OTP, and C-based code was only focused on solving the actual optimization problem. This approach also helped to use different resources concurrently for solving mathematical, distributed and integrational problems, with very little overlap of responsibilities, which allowed to implement the solution impressively quickly. Regards, Serge orbitz@REDACTED wrote: > Obviously Erlang is not made to do computationally intensive work such > as computing primes or what not. However I was thinking that Erlang > obviously makes an excellent framework for doing that kind of work. > I was thinking one could use erlang to communicate between nodes and > then use a port to a fortran program or what not. > Obviously I doubt I'm the first person to think of this, so has anyone > else attempted this or have any suggestions as it if it is a good idea > or not? > > Thanks From orbitz@REDACTED Sat Aug 13 21:18:33 2005 From: orbitz@REDACTED (orbitz@REDACTED) Date: Sat, 13 Aug 2005 15:18:33 -0400 Subject: Parallel Programming In-Reply-To: <42FE40DE.6080806@hq.idt.net> References: <22b2737a7a50867914c9d717b428f16f@ezabel.com> <42FE40DE.6080806@hq.idt.net> Message-ID: <272e16ea457114c657de16f1d6e4c836@ezabel.com> Interesting. I am taking an independent study on Parallel Programming shortly and I would like to use erlang to create some sort of useful framework. I think I could use erlang to split up the data and then reconstruct it and handle communication, like you just described. On Aug 13, 2005, at 2:50 PM, Serge Aleynikov wrote: > We've done exactily this approach in one of the projects where a large > computational task was multiplexed between several nodes running C > ports doing mathematical optimization. Erlang was used only for > splitting work load, distribution and gathering results. > > I am sure other libraries (like MPI) could have been used, but it took > very little effort to do parallelization in Erlang/OTP, and C-based > code was only focused on solving the actual optimization problem. > This approach also helped to use different resources concurrently for > solving mathematical, distributed and integrational problems, with > very little overlap of responsibilities, which allowed to implement > the solution impressively quickly. > > Regards, > > Serge > > orbitz@REDACTED wrote: >> Obviously Erlang is not made to do computationally intensive work >> such as computing primes or what not. However I was thinking that >> Erlang obviously makes an excellent framework for doing that kind of >> work. >> I was thinking one could use erlang to communicate between nodes and >> then use a port to a fortran program or what not. >> Obviously I doubt I'm the first person to think of this, so has >> anyone else attempted this or have any suggestions as it if it is a >> good idea or not? >> Thanks > From serge@REDACTED Sat Aug 13 22:09:37 2005 From: serge@REDACTED (Serge Aleynikov) Date: Sat, 13 Aug 2005 16:09:37 -0400 Subject: Parallel Programming In-Reply-To: <272e16ea457114c657de16f1d6e4c836@ezabel.com> References: <22b2737a7a50867914c9d717b428f16f@ezabel.com> <42FE40DE.6080806@hq.idt.net> <272e16ea457114c657de16f1d6e4c836@ezabel.com> Message-ID: <42FE5381.10308@hq.idt.net> Good luck. I am sure you'll find doing distributed part of the project in Erlang quite enjoyable! Serge orbitz@REDACTED wrote: > Interesting. I am taking an independent study on Parallel Programming > shortly and I would like to use erlang to create some sort of useful > framework. I think I could use erlang to split up the data and then > reconstruct it and handle communication, like you just described. > > > On Aug 13, 2005, at 2:50 PM, Serge Aleynikov wrote: > >> We've done exactily this approach in one of the projects where a large >> computational task was multiplexed between several nodes running C >> ports doing mathematical optimization. Erlang was used only for >> splitting work load, distribution and gathering results. >> >> I am sure other libraries (like MPI) could have been used, but it took >> very little effort to do parallelization in Erlang/OTP, and C-based >> code was only focused on solving the actual optimization problem. >> This approach also helped to use different resources concurrently for >> solving mathematical, distributed and integrational problems, with >> very little overlap of responsibilities, which allowed to implement >> the solution impressively quickly. >> >> Regards, >> >> Serge >> >> orbitz@REDACTED wrote: >> >>> Obviously Erlang is not made to do computationally intensive work >>> such as computing primes or what not. However I was thinking that >>> Erlang obviously makes an excellent framework for doing that kind of >>> work. >>> I was thinking one could use erlang to communicate between nodes and >>> then use a port to a fortran program or what not. >>> Obviously I doubt I'm the first person to think of this, so has >>> anyone else attempted this or have any suggestions as it if it is a >>> good idea or not? >>> Thanks From orbitz@REDACTED Sat Aug 13 22:58:47 2005 From: orbitz@REDACTED (orbitz@REDACTED) Date: Sat, 13 Aug 2005 16:58:47 -0400 Subject: Throw or return a tuple In-Reply-To: References: <73b6898c58d0154fbb8dbc1a7f2552aa@ezabel.com> Message-ID: <8533d67154720091972bd9e4aba59afb@ezabel.com> The try/catch syntax seems to be a lot ebtter than case catch. Does it still have some common limitations that one should watch out for? On Aug 13, 2005, at 3:25 AM, Ulf Wiger wrote: > Den 2005-08-13 06:23:05 skrev : > >> I find myself often confused about which to do, should I throw an >> exception when an error happens in a function or always go with >> returning {ok, Value} or {error, Whatever}. > > This has been discussed now and then on the list. > I think the cleanest way to program is to have functions > that either return a good value or throw an exception > (amendments to the rule will follow). > > Traditionally, there have been some problems with > debugging this style of programming, but the problems > are being addressed, e.g. with the new 'try' construct. > > Coupled with this is the 'let it crash' philosophy > (http://www.google.com/search?&q=%22let+it+crash%22+erlang) > > A place where it's appropriate to wrap return values is > for example: > > dict:read(Key) -> Value | exit() > dict:search(Key) -> {found, Value} | not_found > >> Some people seem try to tell me that I should use {error, Value} and >> "get out of your OO mindset with exceptions". But I think that is >> bull. > > I agree. > > > One problem with always wrapping return values is that > you get a lot of code like this: > > case foo(...) of > {ok, Result} -> > ..., > case bar(...) of > ... > end; > {error, Reason} -> > {error, Reason} > end. > > That is, the most common situation is that you can't > handle the error return value where it first occurs, > and just pass it on to the caller. Throwing exceptions > is a much better way to accomplish this. > > /Uffe > -- > Ulf Wiger > From ulf@REDACTED Sat Aug 13 23:15:55 2005 From: ulf@REDACTED (Ulf Wiger) Date: Sat, 13 Aug 2005 23:15:55 +0200 Subject: Throw or return a tuple In-Reply-To: <8533d67154720091972bd9e4aba59afb@ezabel.com> References: <73b6898c58d0154fbb8dbc1a7f2552aa@ezabel.com> <8533d67154720091972bd9e4aba59afb@ezabel.com> Message-ID: Den 2005-08-13 22:58:47 skrev : > The try/catch syntax seems to be a lot ebtter than case catch. Does it > still have some common limitations that one should watch out for? Well, one thing to consider if you decide to use "assertion-style" programming with pattern-matching, is that it can sometimes be difficult to know where in a function a crash occured: copy_file(F1, F2) -> {ok, Fd1} = file:open(F1, read), {ok, Fd2} = file:open(F2, write), copy_chunks(Fd1, Fd2). If the above function exits with e.g. a {badmatch, {error, eaccess}}, it can be difficult to know which operation caused the problem. There are ways to get around this. Either refactor, and make (in this case) a helper function for open(), or find innovative ways to wrap your statements: copy_file(F1, F2) -> {_, {ok, Fd1}} = {F1, file:open(F1, read)}, {_, {ok, Fd2}} = {F2, file:open(F2, write)}, copy_chunks(Fd1, Fd2). would instead give you an error message like this one: ** exited: {{badmatch,{"foo.txt",{error,enoent}}}, [{f,copy,2}, {erl_eval,do_apply,5}, {shell,exprs,6}, {shell,eval_loop,3}]} ** /Uffe -- Ulf Wiger From klacke@REDACTED Sat Aug 13 23:23:24 2005 From: klacke@REDACTED (Claes Wikstrom) Date: Sat, 13 Aug 2005 23:23:24 +0200 Subject: inets or yaws: transfer-encoding In-Reply-To: <17148.48494.91775.250403@gargle.gargle.HOWL> References: <20050812144757.GA17448@ermine.home> <17148.48494.91775.250403@gargle.gargle.HOWL> Message-ID: <42FE64CC.1080605@hyber.org> Ingela Anderton wrote: > Anastasia Gornostaeva wrote: > >>Is inets capable to process chunked data at server side? > > Inets has that capability. And so has yaws ... ofcource, otherwise pretty much nothing would work. /klacke From nm@REDACTED Sun Aug 14 00:38:49 2005 From: nm@REDACTED (Gaspar Chilingarov) Date: Sun, 14 Aug 2005 03:38:49 +0500 (AMST) Subject: Vim and Erlang syntax files Message-ID: <58128.217.113.1.123.1123972729.squirrel@webmail.web.am> Hi all! I've done some work on merging default Vim syntax files with syntax files sent by James Hague and extended them with several additons - now it can detect and highlight differently clause head, clause argument list and clause's guard You should add in your colorscheme description file 3 new groups - FunHead FunGuard and FunArgs Guard BIFs also separated to different syntax group. You can try colorscheme northsky, included in file to see how it looks ;) For now file is uploaded to http://nothing.am/erlang/erl.tar.bz2 In case if you cannot download this file, just drop me the mail. -- Gaspar Chilingarov System Administrator t +37491 419763 w www.web.am e nm@REDACTED From serge@REDACTED Sun Aug 14 03:46:13 2005 From: serge@REDACTED (Serge Aleynikov) Date: Sat, 13 Aug 2005 21:46:13 -0400 Subject: Throw or return a tuple In-Reply-To: <8533d67154720091972bd9e4aba59afb@ezabel.com> References: <73b6898c58d0154fbb8dbc1a7f2552aa@ezabel.com> <8533d67154720091972bd9e4aba59afb@ezabel.com> Message-ID: <42FEA265.3060204@hq.idt.net> AFAIK the debugger in the latest Erlang release still doesn't like the try/catch syntax. Does any one know when this is going to be fixed? Serge orbitz@REDACTED wrote: > The try/catch syntax seems to be a lot ebtter than case catch. Does it > still have some common limitations that one should watch out for? > > > On Aug 13, 2005, at 3:25 AM, Ulf Wiger wrote: > >> Den 2005-08-13 06:23:05 skrev : >> >>> I find myself often confused about which to do, should I throw an >>> exception when an error happens in a function or always go with >>> returning {ok, Value} or {error, Whatever}. >> >> >> This has been discussed now and then on the list. >> I think the cleanest way to program is to have functions >> that either return a good value or throw an exception >> (amendments to the rule will follow). >> >> Traditionally, there have been some problems with >> debugging this style of programming, but the problems >> are being addressed, e.g. with the new 'try' construct. >> >> Coupled with this is the 'let it crash' philosophy >> (http://www.google.com/search?&q=%22let+it+crash%22+erlang) >> >> A place where it's appropriate to wrap return values is >> for example: >> >> dict:read(Key) -> Value | exit() >> dict:search(Key) -> {found, Value} | not_found >> >>> Some people seem try to tell me that I should use {error, Value} and >>> "get out of your OO mindset with exceptions". But I think that is bull. >> >> >> I agree. >> >> >> One problem with always wrapping return values is that >> you get a lot of code like this: >> >> case foo(...) of >> {ok, Result} -> >> ..., >> case bar(...) of >> ... >> end; >> {error, Reason} -> >> {error, Reason} >> end. >> >> That is, the most common situation is that you can't >> handle the error return value where it first occurs, >> and just pass it on to the caller. Throwing exceptions >> is a much better way to accomplish this. >> >> /Uffe >> -- >> Ulf Wiger From ok@REDACTED Mon Aug 15 05:52:57 2005 From: ok@REDACTED (Richard A. O'Keefe) Date: Mon, 15 Aug 2005 15:52:57 +1200 (NZST) Subject: push_element/2 - efficient sliding window Message-ID: <200508150352.j7F3qvUu431807@atlas.otago.ac.nz> With reference to (fixed size) sliding windows, I asked whether we really needed built-in support. "Ulf Wiger" replied: It's about as justified as erlang:make_tuple/2 and erlang:append_element/2. I guess that's a NO, then. (:-) It is far from clear why make_tuple/2 should ever have been a built-in. make_tuple(Size, Initial) -> tabulate(Size, fun (_) -> Initial end). tabulate(Size, F) -> % the built-in I'd prefer list_to_tuple(lists:map(F, lists:seq(1, Size))). For what kind of application is constructing a tuple with all elements equal a large help? Is this really something that is so common that it *pays* to cut its overhead? erlang:append_element(Tuple, Element) -> list_to_tuple(tuple_to_list(Tuple) ++ [Element]). Again, making this a built-in operation saves a constant factor in time, but it is *still* an O(N) operation and therefore best avoided. Here is *one* operation which could handle them both: set_or_extend(Index, Tuple, New_Element, Fill) when tuple(Tuple), integer(Index), 1 =< Index, Index =< size(Tuple) -> setelement(Index, Tuple, New_Element); set_or_extend(Index, Tuple, New_Element, Fill) when tuple(Tuple), integer(Index), Index > size(Tuple) -> list_to_tuple(tuple_to_list(Tuple) ++ lists:map(fun (N) -> if N < Index -> Fill ; N = Index -> New_Element end end, lists:seq(size(Tuple)+1, Index))). That is, if the index is outside the existing range, the tuple is extended with the Fill element, and then the resulting tuple has the element at Index replaced by New_Element. make_tuple(S, E) -> set_or_extend(S, {}, E, E). append_element(T, E) -> set_or_extend(size(S)+1, T, E, E). Am I seriously proposing set_or_extend/4? Well, this is half fun and full earnest. This operation would be quite a bit more useful to me (as in, I would have occasion to use it) than make_tuple/2 or append_element/2 (which I have not yet had occasion to use). My real point is simply that hacking oodles of special cases is not the best way to design built-in functions; there are generalisations which should be exploted. In the same way, the proposed 'push' operation (which is, contrary to the usual sense of 'push' in computing, also a truncate; such clashes are the snake's warning rattle that something bad is about to happen) is a quirky special case. There must be some good generalisations waiting to be thought of. I should also point out that I am not saying that a good candidate for built-in status is a good candidate for everyday use; "wrapper" functions for common special cases may also be a good idea. Let's push this one a little further. Can we find ONE operation which covers make_tuple/2, append_element/2, the proposed push_element, and a whole lot of other things, which could reasonably go in C? Yep. tuple_stuff(Tuple, Amount, Fill, Rotation, Drop, Take) Tuple a tuple Amount a non-negative integer Fill any term Rotation an integer in the range -N..+N, where N = size(Tuple) + Amount Drop an integer in the range -N..+N Take an integer in the range -M..+M where M = N - |Drop| Step 1: extend Tuple on the right with Amount copies of Fill e.g. tuple_stuff({a,b,c}, 2, d, ...) starts with {a,b,c,d,d}. Step 2: rotation Tuple by Rotation. If Rotation >= 0, take the last Rotation elements and move them to the front; if Rotation =< 0, take the first |Rotation| elements and move them to the back. Step 3: if Drop >= 0, discard the first |Drop| elements; if Drop =< 0, discard the last |Drop| elements. Step 4: if Take >= 0, take the first |Take| elements; if Take =< 0, take the last |Take| elements. Now, make_tuple(Size, Element) -> tuple_stuff({}, Size, Element, 0, 0, Size). append_element(Tuple, Element) -> tuple_stuff(Tuple, 1, Element, 0, 0, size(Tuple)+1). prepend_element(Tuple, Element) -> tuple_stuff(Tuple, 1, Element, 1, 0, size(Tuple)+1). add_element_at_left_of_window(Element, Tuple) -> tuple_stuff(Tuple, 1, Element, 1, -1, size(Tuple)). add_element_at_right_of_window(Tuple, Element) -> tuple_stuff(Tuple, 1, Element, 0, 1, size(Tuple)). There has to be a better name than tuple_stuff/6, but I hope you get my point. ONE built-in goes into erlang:, lots of special-purpose wrappers go in a new tuples: modules, and further special cases can be added without penalty. The cheapest way I've found so far to do a "left shift" of a tuple is: The obvious question has to be this: if you want a sliding window, is a tuple the right tool for the job? The equally obvious answer is "NO WAY!" Why? Because even with a BIF, it's O(N) time and O(N) space turn-over to add an element (and remove another), whereas with the right kind of tree it can be done in O(lgN) time and O(lgN) space. (Proof: think of it as a priority queue. At every step we remove the element with the smallest timestamp and add a new element with a greater timestamp than any existing element.) Using a tuple only makes sense for SMALL fixed windows. Since a shift BIF would cost about the same as The tuple_stuff/6 operation described above handles shifts and rotates. I see no reason why we should grace the list type with optimized versions of append, subtract, keymember, member, keysearch and reverse, but not offer similar optimizations for tuples. I see no reason why the list type should be graced with optimised versions of append, subtract, member, keymember, keysort, and reverse. At least, in an ideal world. Just last week I responded to a question from someone in a Prolog mailing list. It turned out that the crude unordered list representation of sets was looking pretty good in the Prolog system he was using, and more sophisticated approaches weren't paying off. Why? Because he was using a SLOW Prolog, where memberchk/2 was coded in C. In a commercial Prolog, where memberchk/2 *wasn't* special-cased like that, not only did the more sophisticated approaches pay off after all, but even the code based on memberchk/2 was faster! The only reason for having BIF support for list operations is a compiler that doesn't generate fast code for plain Erlang versions. With time, one may be permitted to HiPE that the need for such things will be reduced. I think tuples could be used to great advantage in many cases where we use ETS today, if only a few steps were taken to ease their use a little bit. I think that's a good idea, *BUT* hacking one special case at a time may not be the best way to do that. Another thing I'd like to see for tuples is a syntax addition: tag_search([{Tag | _} = T|_], Tag) -> {value, T}; Agreed. From chandrashekhar.mullaparthi@REDACTED Mon Aug 15 08:45:14 2005 From: chandrashekhar.mullaparthi@REDACTED (Chandrashekhar Mullaparthi) Date: Mon, 15 Aug 2005 07:45:14 +0100 Subject: OTP/TCP server recommendation In-Reply-To: References: Message-ID: <395a1297988db0850e5106ffe75a75bf@t-mobile.co.uk> I think Sean Hinde wrote a small article about this which is available at trapexit.org cheers Chandru On 10 Aug 2005, at 18:48, tty@REDACTED wrote: > Hello, > > I am writing an OTP application which requires starting a TCP based > server for incoming requests. I want this TCP server to be under a > supervisor (for restarts etc). > What is the 'best practice' for this scenario ? > > At this moment I have a 'portal' module which looks something like > this : > > > > Thanks in advance. > > Tee > From bengt.kleberg@REDACTED Mon Aug 15 08:46:49 2005 From: bengt.kleberg@REDACTED (Bengt Kleberg) Date: Mon, 15 Aug 2005 08:46:49 +0200 Subject: Throw or return a tuple In-Reply-To: <73b6898c58d0154fbb8dbc1a7f2552aa@ezabel.com> References: <73b6898c58d0154fbb8dbc1a7f2552aa@ezabel.com> Message-ID: <43003A59.1080701@ericsson.com> On 2005-08-13 06:23, orbitz@REDACTED wrote: > I find myself often confused about which to do, should I throw an > exception when an error happens in a function or always go with > returning {ok, Value} or {error, Whatever}. there is a nice write-up on this subjecy included in the ''Erlang standard library packages''. i have included it below. bengt -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: CONVENTIONS URL: From gunilla@REDACTED Mon Aug 15 09:00:21 2005 From: gunilla@REDACTED (Gunilla Arendt) Date: Mon, 15 Aug 2005 09:00:21 +0200 Subject: application startup In-Reply-To: <42FE0687.4060708@hq.idt.net> References: <42FD12DA.8050805@hq.idt.net> <42FDF2F8.2050702@hq.idt.net> <42FE0687.4060708@hq.idt.net> Message-ID: <43003D85.10207@erix.ericsson.se> It is possible to specify that an application should only be loaded, not started, when creating the .rel file (see also rel(3)): {release, {"drpdb","1.0"}, {erts, "5.4.8"}, [{kernel,"2.10.9"}, {stdlib,"1.13.8"}, {sasl, "2.0.1"}, {drpdb, "1.0"}, {os_mon, "1.7.4", load}, {mnesia, "4.2.2", load} ]}. (At least when using systools:make_script/1,2 to generate the boot script, I don't know about 'builder'). IMO, this is a much better way to do it. Unless, of course, you really want os_mon and mnesia to be included applications, started by a supervisor in drpdb. / Gunilla Serge Aleynikov wrote: > Ulf, > > I seemed to have rushed to ask the question before searching the mailing > list. 'included_applications' attribute does the trick. > > So if I understand this correctly, in this case only sasl and drpdb will > be started automatically (besides kernel and stdlib), and not mnesia and > os_mon: > > {release, {"drpdb","1.0"}, {erts, "5.4.8"}, > [{kernel,"2.10.9"}, > {stdlib,"1.13.8"}, > {sasl, "2.0.1"}, > {drpdb, "1.0"}, > {os_mon, "1.7.4"}, > {mnesia, "4.2.2"} > ]}. > > {application, drpdb, > [ > ... > {included_applications, [ mnesia, os_mon ] }, > {applications, [ kernel, sasl ] }, > {mod, {drpdb_app, []}}, > {env, []} > ] > }. > > Also I found your post where you modified the application_controller to > customize start_phases: > > http://forums.trapexit.org:81/phpBB/viewtopic.php?t=4574&highlight=build+applications+start > > > Is that available for download? > > Thanks. > > Serge > > Serge Aleynikov wrote: > >> Ulf Wiger wrote: >> >>> >>> All applications in the .rel file are started >>> automatically if they >>> - have a 'mod' attribute >> >> >> >> I looked at $ERL_ROOT/lib/* and sampled several standard apps - they >> all have a 'mod' attribute, so I infer that by default any app listed >> in the application's *.rel file will get started automatically by >> default. >> >>> - are not included in another application >> >> >> >> I.e. not being included in the application's 'applications' attributes >> in the *.app file, or there's another place to include an >> application? >> >>> The 'builder' contrib builds two start scripts: >>> one where all applications are started as expected, >>> and one where only kernel and stdlib are started, >>> but all applications are loaded, and the code path >>> set to include all code. The latter script is useful >>> if you e.g. want to initialize mnesia and other stuff, >>> and the way it's generated is by simply modifying the >>> start script after it's been built. >> >> >> >> Thanks, I downloaded the 'builder' contrib. Will experiment with it. >> >> Serge >> >>> Den 2005-08-12 23:21:30 skrev Serge Aleynikov : >>> > Folks, > >>>> >>>> I have the following config, and I noticed that os_mon and mnesia >>>> applications get started at startup when I use a boot script: >>>> >>>> >erlc -pa ../ebin -o ../ebin drpdb.rel >>>> >cd ../ebin >>>> >erl -boot drpdb -sname drpdb -config ../priv/drpdb >>>> >>>> I was under impression that if an application is listed in the >>>> *.rel file, it should be loaded but not started. In order for it >>>> to be started it must be included in the {applications, ...} tuple >>>> of the *.app file. However, what I am observing is that all apps >>>> that are listed in the *.rel file are started automatically. Am I >>>> doing something wrong? >>>> >>>> ====== drpdb.rel ======== >>>> {release, {"drpdb","1.0"}, {erts, "5.4.8"}, >>>> [{kernel,"2.10.9"}, >>>> {stdlib,"1.13.8"}, >>>> {sasl, "2.0.1"}, >>>> {drpdb, "1.0"}, >>>> {os_mon, "1.7.4"}, >>>> {mnesia, "4.2.2"} >>>> ]}. >>>> >>>> >>>> ====== drpdb.app ======== >>>> {application, drpdb, >>>> [ >>>> {description, "Master Database Server"}, >>>> {vsn, "1.0"}, >>>> {id, "drpdb"}, >>>> {modules, >>>> [ >>>> drpdb_app, >>>> drpdb_sup, >>>> drpdb >>>> ] >>>> }, >>>> {registered, [ drpdb_sup, drpdb ] }, >>>> {applications, [ kernel, sasl ] }, >>>> {mod, {drpdb_app, []}}, >>>> {env, []} >>>> ] >>>> }. >>>> >>> >>> >>> >> > -- _____Gunilla Arendt______________________________________________ OTP Development Gunilla.Arendt@REDACTED +46-8-7275730 ecn 851 5730 From ingela@REDACTED Mon Aug 15 09:44:33 2005 From: ingela@REDACTED (Ingela Anderton) Date: Mon, 15 Aug 2005 09:44:33 +0200 Subject: Throw or return a tuple References: <73b6898c58d0154fbb8dbc1a7f2552aa@ezabel.com> Message-ID: <17152.18401.995457.337371@gargle.gargle.HOWL> orbitz@REDACTED wrote: > What do people generally prefer? Are we moving towards more exceptions? > OTP seems to use exceptions for somethings and an error tuple for > others. The OTP applications might not always use the best practise way of new erts features for backward compatibility reasons. Many OTP applications are patched backwards onto old erts-releases without having to maintain separate development branches for that application, hence utilization of new erts features, however nice they might be, are not always the obvious choice for all OTP-application. -- /Ingela - OTP team From bjorn@REDACTED Mon Aug 15 09:45:22 2005 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 15 Aug 2005 09:45:22 +0200 Subject: Throw or return a tuple In-Reply-To: <42FEA265.3060204@hq.idt.net> References: <73b6898c58d0154fbb8dbc1a7f2552aa@ezabel.com> <8533d67154720091972bd9e4aba59afb@ezabel.com> <42FEA265.3060204@hq.idt.net> Message-ID: Serge Aleynikov writes: > AFAIK the debugger in the latest Erlang release still doesn't like the > try/catch syntax. > > Does any one know when this is going to be fixed? > No. We don't know yet. We have started, but it turned out to be harder than we initially thought because a lot of exception handling code needed to rewritten and cleaned up. Sorry for that. /Bjorn -- Bj?rn Gustavsson, Erlang/OTP, Ericsson AB From bjorn@REDACTED Mon Aug 15 09:52:52 2005 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 15 Aug 2005 09:52:52 +0200 Subject: push_element/2 - efficient sliding window In-Reply-To: <200508150352.j7F3qvUu431807@atlas.otago.ac.nz> References: <200508150352.j7F3qvUu431807@atlas.otago.ac.nz> Message-ID: "Richard A. O'Keefe" writes: > With reference to (fixed size) sliding windows, > I asked whether we really needed built-in support. > > "Ulf Wiger" replied: > It's about as justified as erlang:make_tuple/2 > and erlang:append_element/2. > > I guess that's a NO, then. (:-) > I agree. In retrospect, we should not have added those two BIFs. They are very rarely used. Maybe we should take them out and replace them with Erlang functions in the erlang module. > > Yep. > > tuple_stuff(Tuple, Amount, Fill, Rotation, Drop, Take) > Tuple a tuple > Amount a non-negative integer > Fill any term > Rotation an integer in the range -N..+N, > where N = size(Tuple) + Amount > Drop an integer in the range -N..+N > Take an integer in the range -M..+M > where M = N - |Drop| > > Step 1: extend Tuple on the right with Amount copies of Fill > e.g. tuple_stuff({a,b,c}, 2, d, ...) starts with {a,b,c,d,d}. > > Step 2: rotation Tuple by Rotation. If Rotation >= 0, take the > last Rotation elements and move them to the front; if Rotation =< 0, > take the first |Rotation| elements and move them to the back. > > Step 3: if Drop >= 0, discard the first |Drop| elements; > if Drop =< 0, discard the last |Drop| elements. > > Step 4: if Take >= 0, take the first |Take| elements; > if Take =< 0, take the last |Take| elements. > Given a better name, we could consider adding this BIF. /Bjorn -- Bj?rn Gustavsson, Erlang/OTP, Ericsson AB From ulf.wiger@REDACTED Mon Aug 15 09:59:03 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Mon, 15 Aug 2005 09:59:03 +0200 Subject: push_element/2 - efficient sliding window Message-ID: Richard A. O'Keefe wrote: > > With reference to (fixed size) sliding windows, > I asked whether we really needed built-in support. > > "Ulf Wiger" replied: > It's about as justified as erlang:make_tuple/2 > and erlang:append_element/2. ... > > erlang:append_element(Tuple, Element) -> > list_to_tuple(tuple_to_list(Tuple) ++ [Element]). > > Again, making this a built-in operation saves a constant factor in > time, but it is *still* an O(N) operation and therefore best avoided. Based on the current implementation of (large) tuples, it's an O(N) operation. I think large tuples should be represented differently than they are today, and then append_element/2 could be made cheaper (not that that in itself would be the justification for changing the representation - reducing the cost of setelement/3 is a much better reason.) > Here is *one* operation which could handle them both: > > set_or_extend(Index, Tuple, New_Element, Fill) > when tuple(Tuple), integer(Index), 1 =< Index, Index =< > size(Tuple) > -> setelement(Index, Tuple, New_Element); > set_or_extend(Index, Tuple, New_Element, Fill) > when tuple(Tuple), integer(Index), Index > size(Tuple) > -> list_to_tuple(tuple_to_list(Tuple) ++ > lists:map(fun (N) -> if N < Index -> Fill > ; N = Index -> New_Element > end end, > lists:seq(size(Tuple)+1, Index))). > > That is, if the index is outside the existing range, the tuple is > extended with the Fill element, and then the resulting tuple has > the element at Index replaced by New_Element. Personally, I would prefer the BIF not to make assumptions about whether or not an index out of range is a programming error or an implicit wish to extend the tuple. Having setelement/3 and extend_tuple/3 as separate BIFs allows the programmer to easily write set_or_extend/4 as a combination of the two, using a trivial wrapper. > My real point is simply that hacking oodles of special cases > is not the best way to design built-in functions; there are > generalisations which should be exploted. Agreed. > In the same way, the proposed 'push' operation (which is, > contrary to the usual sense of 'push' in computing, also a > truncate; such clashes are the snake's warning rattle that > something bad is about to happen) is a quirky special case. In part as a response to the snake's warning rattle, I made a subsequent post where push_element/2 had been renamed as rshift_element/2, and complemented with lshift_element/2. I don't claim to have found ideal names yet, or even the ideal functions, but at least it's better than push_element/2. > There must be some good generalisations waiting to be > thought of. Indeed, and a good enough reason to set the ball rolling with some provocatively named custom BIFs. ;-) > Let's push this one a little further. > Can we find ONE operation which covers make_tuple/2, append_element/2, > the proposed push_element, and a whole lot of other things, > which could > reasonably go in C? > > Yep. ... > There has to be a better name than tuple_stuff/6, but I hope you get > my point. ONE built-in goes into erlang:, lots of special-purpose > wrappers go in a new tuples: modules, and further special cases can > be added without penalty. I have no problem with that (except perhaps trying to write this function myself in C...) > The obvious question has to be this: > if you want a sliding window, is a tuple the right tool > for the job? > The equally obvious answer is "NO WAY!" Why? Because even > with a BIF, > it's O(N) time and O(N) space turn-over to add an element (and remove > another), whereas with the right kind of tree it can be done in O(lgN) > time and O(lgN) space. (Proof: think of it as a priority queue. At > every step we remove the element with the smallest timestamp and add a > new element with a greater timestamp than any existing element.) > Using a tuple only makes sense for SMALL fixed windows. Not necessarily. While discussing this with Joel, (1) a fairly common size of the sliding window for a trading system would be 200, and many of the algorithms require random access to the elements of the window. Now, random access in a tuple is O(1) and *really* cheap. It becomes a question of which one is the most frequent operation: slide or read? If one can make it cheap enough to slide a tuple, it certainly wins hands-down on read. I made a comparison between using the lines module (which mimics an array using a tuple tree) and creating a sliding window using a list and list_to_tuple()). It was cheaper to slide the tuple tree, but no so much that it justified the overhead imposed by read(). > I see no reason why we should grace the list type with > optimized versions of append, subtract, keymember, member, > keysearch and reverse, but not offer similar optimizations > for tuples. > > I see no reason why the list type should be graced with > optimised versions > of append, subtract, member, keymember, keysort, and reverse. > At least, in an ideal world. Yes, well, many of the BIFs would go away in that ideal world. The reason for those BIFs is that their use is common enough that optimizing them tends to lead to significant cost savings in real applications. > The only reason for having BIF support for list operations is > a compiler that doesn't generate fast code for plain Erlang > versions. With time, one may be permitted to HiPE that the > need for such things will be reduced. Personally, I couldn't care less whether a function is made fast through compiler trickery or by making it a BIF. What does concern me is that some functions need to be made fast, or people will be tempted to write un-intuitive code. Tuples are great semantically, but people refrain from using them sometimes because some things are difficult or expensive to do. Is it a law of nature that large tuples should be expensive to update? Another example is the lack of GC for atoms, which causes people to bend over backwards trying to solve problems that should be easy. Perhaps rather than the lack of atom GC, the real problem is that you can't register processes, ports or ETS tables by anything that's not an atom. > I think tuples could be used to great advantage > in many cases where we use ETS today, if only a few steps > were taken to ease their use a little bit. > > I think that's a good idea, *BUT* hacking one special case at a time > may not be the best way to do that. You're absolutely right. of course. However, hacking one special case in order to get a discussion started may well be worth the effort. > Another thing I'd like to see for tuples is a syntax > addition: > > tag_search([{Tag | _} = T|_], Tag) -> > {value, T}; > > Agreed. Well, (: /Uffe From vlad_dumitrescu@REDACTED Mon Aug 15 11:11:56 2005 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Mon, 15 Aug 2005 11:11:56 +0200 Subject: [Erlide-devel] Module Wizard References: <6a2eaa91050814054150e37a72@mail.gmail.com> <6a2eaa9105081501426c1792ed@mail.gmail.com> Message-ID: Hej! No, I don't have any links to JDT documentation, but it's all in the jdt.core plugin. There are interfaces like IJavaElement and its descendants there, and the implementations in jdt.core.internal. In the beginning, I have copied most of the stuff to the core.erlang package, and renamed anything called "*Java*" to "*Erlang*" or "*Erl*", because I thought it would be a nice way to use all the experience they have. There are many things one would like to have from there (like WorkingCopies), but it becomes very difficult to understand why and how, and also since most of that is internal, updates and bug fixes aren't for free... Also, I think it's better to have something we understand even if it's a more naive implementation. The problem I see is that the Java model has to keep track of much more things (classpaths, for example) that aren't as relevant for Erlang, because modules can be built independently. Of course, with the addition of more sofisticated tools (like integrating xref), keeping track of the code path and any changes made to it becomes important. What I'd like to have is a simple model that we can get running for the simpler functionality, but that can be extended without much hassle. Another important issue is to decide where to put the interfaces between the Java side and the Erlang side. It would be nice if the Java side could be just a UI, and the ground work would be implemented in Erlang. But some things need be lightweight because they are called often and interactively (like syntax highlighting), so the performance penalty may be too large. Well, I hope this gives some things to think about. regards, Vlad From vlad_dumitrescu@REDACTED Mon Aug 15 11:15:53 2005 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Mon, 15 Aug 2005 11:15:53 +0200 Subject: [Erlide-devel] Module Wizard Message-ID: Oops, sorry, I forwarded to the wrong list... regards, Vlad From serge@REDACTED Mon Aug 15 14:44:33 2005 From: serge@REDACTED (Serge Aleynikov) Date: Mon, 15 Aug 2005 08:44:33 -0400 Subject: Throw or return a tuple In-Reply-To: References: <73b6898c58d0154fbb8dbc1a7f2552aa@ezabel.com> <8533d67154720091972bd9e4aba59afb@ezabel.com> <42FEA265.3060204@hq.idt.net> Message-ID: <43008E31.9090103@hq.idt.net> Frankly, this is the primary reason I am reluctant to use try/catch. I found that every time I used this construct, and needed to debug code, I ended up with rewriting the code using a case with a catch. Will have to wait for better days... :-( Serge Bjorn Gustavsson wrote: > Serge Aleynikov writes: > > >>AFAIK the debugger in the latest Erlang release still doesn't like the >>try/catch syntax. >> >>Does any one know when this is going to be fixed? >> > > > No. We don't know yet. We have started, but it turned out to be harder > than we initially thought because a lot of exception handling code needed > to rewritten and cleaned up. Sorry for that. > > /Bjorn > From vlad.xx.dumitrescu@REDACTED Mon Aug 15 16:07:03 2005 From: vlad.xx.dumitrescu@REDACTED (Vlad Dumitrescu XX (LN/EAB)) Date: Mon, 15 Aug 2005 16:07:03 +0200 Subject: UBF format Message-ID: <11498CB7D3FCB54897058DE63BE3897C4BE5CB@esealmw105.eemea.ericsson.se> Hi, I have a silly question. In the UBF-A specification, it is said that Structs Structures are written: { Obj1 Obj2 ... Objn } In the code, the elements can be separated by commas. Is the comma optional indeed, or did I miss something? Is the recommended use with or without commas? best regards, Vlad From serge@REDACTED Mon Aug 15 16:51:16 2005 From: serge@REDACTED (Serge Aleynikov) Date: Mon, 15 Aug 2005 10:51:16 -0400 Subject: application startup In-Reply-To: <43003D85.10207@erix.ericsson.se> References: <42FD12DA.8050805@hq.idt.net> <42FDF2F8.2050702@hq.idt.net> <42FE0687.4060708@hq.idt.net> <43003D85.10207@erix.ericsson.se> Message-ID: <4300ABE4.7000801@hq.idt.net> Very nice! While I couldn't find this reference in the HTML docs, you're right that in man pages it is described very clearly in black & white (at least on my terminal window ;-) ). Serge Gunilla Arendt wrote: > It is possible to specify that an application should only be loaded, not > started, when creating the .rel file (see also rel(3)): > > {release, {"drpdb","1.0"}, {erts, "5.4.8"}, > [{kernel,"2.10.9"}, > {stdlib,"1.13.8"}, > {sasl, "2.0.1"}, > {drpdb, "1.0"}, > {os_mon, "1.7.4", load}, > {mnesia, "4.2.2", load} > ]}. > > (At least when using systools:make_script/1,2 to generate the boot > script, I don't know about 'builder'). > > IMO, this is a much better way to do it. Unless, of course, you really > want os_mon and mnesia to be included applications, started by a > supervisor in drpdb. > > / Gunilla > > > > Serge Aleynikov wrote: > >> Ulf, >> >> I seemed to have rushed to ask the question before searching the >> mailing list. 'included_applications' attribute does the trick. >> >> So if I understand this correctly, in this case only sasl and drpdb >> will be started automatically (besides kernel and stdlib), and not >> mnesia and os_mon: >> >> {release, {"drpdb","1.0"}, {erts, "5.4.8"}, >> [{kernel,"2.10.9"}, >> {stdlib,"1.13.8"}, >> {sasl, "2.0.1"}, >> {drpdb, "1.0"}, >> {os_mon, "1.7.4"}, >> {mnesia, "4.2.2"} >> ]}. >> >> {application, drpdb, >> [ >> ... >> {included_applications, [ mnesia, os_mon ] }, >> {applications, [ kernel, sasl ] }, >> {mod, {drpdb_app, []}}, >> {env, []} >> ] >> }. >> >> Also I found your post where you modified the application_controller >> to customize start_phases: >> >> http://forums.trapexit.org:81/phpBB/viewtopic.php?t=4574&highlight=build+applications+start >> >> >> Is that available for download? >> >> Thanks. >> >> Serge >> >> Serge Aleynikov wrote: >> >>> Ulf Wiger wrote: >>> >>>> >>>> All applications in the .rel file are started >>>> automatically if they >>>> - have a 'mod' attribute >>> >>> >>> >>> >>> I looked at $ERL_ROOT/lib/* and sampled several standard apps - they >>> all have a 'mod' attribute, so I infer that by default any app listed >>> in the application's *.rel file will get started automatically by >>> default. >>> >>>> - are not included in another application >>> >>> >>> >>> >>> I.e. not being included in the application's 'applications' >>> attributes in the *.app file, or there's another place to include an >>> application? >>> >>>> The 'builder' contrib builds two start scripts: >>>> one where all applications are started as expected, >>>> and one where only kernel and stdlib are started, >>>> but all applications are loaded, and the code path >>>> set to include all code. The latter script is useful >>>> if you e.g. want to initialize mnesia and other stuff, >>>> and the way it's generated is by simply modifying the >>>> start script after it's been built. >>> >>> >>> >>> >>> Thanks, I downloaded the 'builder' contrib. Will experiment with it. >>> >>> Serge >>> >>>> Den 2005-08-12 23:21:30 skrev Serge Aleynikov : >>>> >> Folks, >> >>>>> >>>>> I have the following config, and I noticed that os_mon and mnesia >>>>> applications get started at startup when I use a boot script: >>>>> >>>>> >erlc -pa ../ebin -o ../ebin drpdb.rel >>>>> >cd ../ebin >>>>> >erl -boot drpdb -sname drpdb -config ../priv/drpdb >>>>> >>>>> I was under impression that if an application is listed in the >>>>> *.rel file, it should be loaded but not started. In order for it >>>>> to be started it must be included in the {applications, ...} tuple >>>>> of the *.app file. However, what I am observing is that all apps >>>>> that are listed in the *.rel file are started automatically. Am I >>>>> doing something wrong? >>>>> >>>>> ====== drpdb.rel ======== >>>>> {release, {"drpdb","1.0"}, {erts, "5.4.8"}, >>>>> [{kernel,"2.10.9"}, >>>>> {stdlib,"1.13.8"}, >>>>> {sasl, "2.0.1"}, >>>>> {drpdb, "1.0"}, >>>>> {os_mon, "1.7.4"}, >>>>> {mnesia, "4.2.2"} >>>>> ]}. >>>>> >>>>> >>>>> ====== drpdb.app ======== >>>>> {application, drpdb, >>>>> [ >>>>> {description, "Master Database Server"}, >>>>> {vsn, "1.0"}, >>>>> {id, "drpdb"}, >>>>> {modules, >>>>> [ >>>>> drpdb_app, >>>>> drpdb_sup, >>>>> drpdb >>>>> ] >>>>> }, >>>>> {registered, [ drpdb_sup, drpdb ] }, >>>>> {applications, [ kernel, sasl ] }, >>>>> {mod, {drpdb_app, []}}, >>>>> {env, []} >>>>> ] >>>>> }. >>>>> >>>> >>>> >>>> >>> >> > > -- Serge Aleynikov R&D Telecom, IDT Corp. Tel: (973) 438-3436 Fax: (973) 438-1464 serge@REDACTED From mats.cronqvist@REDACTED Mon Aug 15 17:17:35 2005 From: mats.cronqvist@REDACTED (Mats Cronqvist) Date: Mon, 15 Aug 2005 17:17:35 +0200 Subject: Throw or return a tuple In-Reply-To: <73b6898c58d0154fbb8dbc1a7f2552aa@ezabel.com> References: <73b6898c58d0154fbb8dbc1a7f2552aa@ezabel.com> Message-ID: <4300B20F.9070503@ericsson.com> throw an exception. personally, i believe that returning {ok,R}/{error,R} is ALWAYS wrong. e.g. file:open/2; as it is now, it will return {error,R} if there is some system resource missing (truly exceptional), or if you pass it bad data (e.g. a file that does not exist). in either case it should throw. i wonder where the {error,R} idiom came from... but there definitely seems to be a move away from it. mats orbitz@REDACTED wrote: > I find myself often confused about which to do, should I throw an > exception when an error happens in a function or always go with > returning {ok, Value} or {error, Whatever}. > > Some people seem try to tell me that I should use {error, Value} and > "get out of your OO mindset with exceptions". But I think that is > bull. I don't see why exceptions should be purely considered OO and > erlang has exceptions, why shouldn't I use them? That seems like the > talk of people afraid of change or something similar. The most > convincing argument for me to use exceptions is because I want to be > able to do: > > foo(bar()) rather than {ok, V} = ...yadda. > > What do people generally prefer? Are we moving towards more exceptions? > OTP seems to use exceptions for somethings and an error tuple for others. > > Thanks > From fritchie@REDACTED Mon Aug 15 20:29:43 2005 From: fritchie@REDACTED (Scott Lystig Fritchie) Date: Mon, 15 Aug 2005 13:29:43 -0500 Subject: length of an iolist In-Reply-To: Message of "Fri, 12 Aug 2005 11:43:53 EDT." <28220869.1123861433755.JavaMail.root@mswamui-bichon.atl.sa.earthlink.net> Message-ID: <200508151829.j7FIThB0043898@snookles.snookles.com> >>>>> "ms" == Mark Scandariato writes: ms> Here are two versions of iolist_size I put together - an erlang ms> version and a bif. I believe you need a clause to handle the case where your "io list" is actually a single binary. Easy enough to add. -Scott --- Scott Lystig Fritchie Professional Governing: Is It Faked? From joelr1@REDACTED Mon Aug 15 20:56:34 2005 From: joelr1@REDACTED (Joel Reymont) Date: Mon, 15 Aug 2005 20:56:34 +0200 Subject: Determining if process is alive on a different node Message-ID: Folks, I have a pid but I don't know if it's a local one. How would I determine if the process is alive? I'm storing pids in a Mnesia table in a multi-node environment and the node that hosted the process might have died. Rather than tracking node crashes I was wondering if there was an idiomatic way of figuring out if a process is alive. My understanding is that I can only use is_process_alive for local processes. Thanks, Joel -- http://wagerlabs.com/uptick From joelr1@REDACTED Mon Aug 15 21:04:46 2005 From: joelr1@REDACTED (Joel Reymont) Date: Mon, 15 Aug 2005 21:04:46 +0200 Subject: Determining if process is alive on a different node In-Reply-To: References: Message-ID: <2F2BC135-E645-493B-8CFB-53C3309B7062@gmail.com> It seems that a link with an unlink should do the trick but a receive is needed between the two since link will send EXIT with reason noproc if the process does not exist. What is a good timeout for the receive? Thanks, Joel On Aug 15, 2005, at 8:56 PM, Joel Reymont wrote: > Folks, > > I have a pid but I don't know if it's a local one. How would I > determine if the process is alive? From serge@REDACTED Mon Aug 15 21:06:00 2005 From: serge@REDACTED (Serge Aleynikov) Date: Mon, 15 Aug 2005 15:06:00 -0400 Subject: Determining if process is alive on a different node In-Reply-To: References: Message-ID: <4300E798.9050005@hq.idt.net> node(Pid) returns the node that owns the Pid. Node = node(), case node(Pid) of Node -> local; _ -> remote end. Joel Reymont wrote: > Folks, > > I have a pid but I don't know if it's a local one. How would I > determine if the process is alive? > > I'm storing pids in a Mnesia table in a multi-node environment and the > node that hosted the process might have died. Rather than tracking node > crashes I was wondering if there was an idiomatic way of figuring out > if a process is alive. > > My understanding is that I can only use is_process_alive for local > processes. > > Thanks, Joel > > -- > http://wagerlabs.com/uptick > > > > -- Serge Aleynikov R&D Telecom, IDT Corp. Tel: (973) 438-3436 Fax: (973) 438-1464 serge@REDACTED From joelr1@REDACTED Mon Aug 15 21:21:59 2005 From: joelr1@REDACTED (Joel Reymont) Date: Mon, 15 Aug 2005 21:21:59 +0200 Subject: Determining if process is alive on a different node In-Reply-To: <4300E798.9050005@hq.idt.net> References: <4300E798.9050005@hq.idt.net> Message-ID: Serge's use of use of node(Pid) made me thing that the following would work: rcp:call(node(pid), erlang, is_process_alive, [Pid]). Any drawbacks? Thanks, Joel On Aug 15, 2005, at 9:06 PM, Serge Aleynikov wrote: > node(Pid) returns the node that owns the Pid. > > Node = node(), > case node(Pid) of > Node -> local; > _ -> remote > end. From mfs@REDACTED Mon Aug 15 21:22:33 2005 From: mfs@REDACTED (Mark Scandariato) Date: Mon, 15 Aug 2005 15:22:33 -0400 (EDT) Subject: length of an iolist Message-ID: <1234443.1124133753952.JavaMail.root@mswamui-bichon.atl.sa.earthlink.net> I originally had one, but I took it out since "iolist" is supposed to be a list. Mark. -----Original Message----- From: Scott Lystig Fritchie Sent: Aug 15, 2005 2:29 PM To: Mark Scandariato Cc: erlang-questions@REDACTED Subject: Re: length of an iolist >>>>> "ms" == Mark Scandariato writes: ms> Here are two versions of iolist_size I put together - an erlang ms> version and a bif. I believe you need a clause to handle the case where your "io list" is actually a single binary. Easy enough to add. -Scott --- Scott Lystig Fritchie Professional Governing: Is It Faked? From rpettit@REDACTED Mon Aug 15 21:52:15 2005 From: rpettit@REDACTED (Rick Pettit) Date: Mon, 15 Aug 2005 14:52:15 -0500 Subject: Determining if process is alive on a different node In-Reply-To: References: <4300E798.9050005@hq.idt.net> Message-ID: <20050815195214.GA13432@vailsys.com> On Mon, Aug 15, 2005 at 09:21:59PM +0200, Joel Reymont wrote: > Serge's use of use of node(Pid) made me thing that the following > would work: > > rcp:call(node(pid), erlang, is_process_alive, [Pid]). > > Any drawbacks? > > Thanks, Joel Wouldn't wrapping the operation in a erlang:monitor/2, erlang:demonitor/1 with a receive following the operation (to catch the potential 'DOWN' message) be safer? do_it(Pid) -> MonitorRef = erlang:monitor(process, Pid), ...perform operation to obtain Result here... erlang:demonitor(MonitorRef), receive {'DOWN', MonitorRef, process, Pid, Info} -> {error, Info} after 0 -> {ok, Result} end. I should add that the call to erlang:monitor/2 will fail with 'badarg' on "old" nodes where remote process monitoring is not implemented, at least according to the manpage. Without wrapping the operation this way it would seem as though there is always a race between when you check to see if the process is alive and when you conduct your operation with the process. -Rick > On Aug 15, 2005, at 9:06 PM, Serge Aleynikov wrote: > > >node(Pid) returns the node that owns the Pid. > > > >Node = node(), > >case node(Pid) of > >Node -> local; > >_ -> remote > >end. > From serge@REDACTED Mon Aug 15 21:51:55 2005 From: serge@REDACTED (Serge Aleynikov) Date: Mon, 15 Aug 2005 15:51:55 -0400 Subject: Determining if process is alive on a different node In-Reply-To: References: <4300E798.9050005@hq.idt.net> Message-ID: <4300F25B.50302@hq.idt.net> Joel, Sorry, after rereading your message I realized I responded too quickly. :-( Yes the rpc:call(node(Pid), erlang, is_process_alive, [Pid]) would be the logical way to do it, but is it reliable? What if the node(Pid) node got bounced since the time we captured the Pid. The Pid value might've been reassigned to another process, as in the example below: (a@REDACTED)18> register(test, self()). true (b@REDACTED)1> net_adm:ping(a@REDACTED). pong (b@REDACTED)2> {test, a@REDACTED} ! self(). <0.36.0> (a@REDACTED)2> receive M -> M end. <4771.36.0> (b@REDACTED)3> ^C BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded (v)ersion (k)ill (D)b-tables (d)istribution a ~/tmp>erl -sname b Erlang (BEAM) emulator version 5.4.8 [source] [hipe] [threads:0] Eshell V5.4.8 (abort with ^G) (b@REDACTED)1> net_adm:ping(a@REDACTED). pong (a@REDACTED)5> rpc:call(b@REDACTED, erlang, is_process_alive, [pid(4771,36,0)]). true -------------- This last statement is not true, since it is not the same process on node b that originated the first message. The Pid that was originally recorded was reassigned to another process after the node was bounced. I believe it is more reliable to use erlang:monitor/2 calls at a time the Pid is captured, and watch for {'DOWN', ...} messages. Regards, Serge Joel Reymont wrote: > Serge's use of use of node(Pid) made me thing that the following would > work: > > rcp:call(node(pid), erlang, is_process_alive, [Pid]). > > Any drawbacks? > > Thanks, Joel > > On Aug 15, 2005, at 9:06 PM, Serge Aleynikov wrote: > >> node(Pid) returns the node that owns the Pid. >> >> Node = node(), >> case node(Pid) of >> Node -> local; >> _ -> remote >> end. > > > -- Serge Aleynikov R&D Telecom, IDT Corp. Tel: (973) 438-3436 Fax: (973) 438-1464 serge@REDACTED From serge@REDACTED Mon Aug 15 22:05:31 2005 From: serge@REDACTED (Serge Aleynikov) Date: Mon, 15 Aug 2005 16:05:31 -0400 Subject: mnesia:clear_table Message-ID: <4300F58B.8020205@hq.idt.net> Hi, I am wondering why the mnesia:clear_table/1 function is encapsulated in a transaction of its own. It prevents this function to be included in another transaction. I need to clear the table and populated it within a single transaction. Is there a way to do that other than iterating though all records in the table? F() -> mnesia:write_lock_table(Tab), % Delete records Keys = mnesia:all_keys(Tab), [mnesia:delete(Tab, Key) || Key <- Keys], % Insert records [mnesia:write(Tab, R) || R <- Data] end, mnesia:transaction(F). Thanks, -- Serge Aleynikov R&D Telecom, IDT Corp. Tel: (973) 438-3436 Fax: (973) 438-1464 serge@REDACTED From fritchie@REDACTED Mon Aug 15 22:20:09 2005 From: fritchie@REDACTED (Scott Lystig Fritchie) Date: Mon, 15 Aug 2005 15:20:09 -0500 Subject: length of an iolist In-Reply-To: Message of "Mon, 15 Aug 2005 15:22:33 EDT." <1234443.1124133753952.JavaMail.root@mswamui-bichon.atl.sa.earthlink.net> Message-ID: <200508152020.j7FKK9wk044813@snookles.snookles.com> >>>>> "ms" == Mark Scandariato writes: ms> I originally had one, but I took it out since "iolist" is supposed ms> to be a list. I suspect that the name "i/o list"/"iolist"/whatever was coined before the binary data type was added to Erlang ... so nowadays a proper iolist may be either: * a (possibly deep) list of: - integers representing byte values and/or - binaries * a single binary Looking in some old R9 documentation for gen_tcp:send/2: send(Socket, Packet) -> ok | {error, Reason} Types: Socket = socket() Packet = list() | binary() Reason = atom() Now that binaries are part of the language, it seems silly not to include a single binary as a valid packet to send. Ditto for a function like file:write/2: write(IoDevice, Bytes) Writes Bytes (possibly a deep list of characters, or a binary) to the file described by IoDevice. [...] Though neither definition really says that your (deep) list of characters may also include binaries of arbitrary size. Hm, in my R9 docs, "iolist" (and various spelling variations) do not appear in .../kernel-2.9/doc/html/index.html index. Does it appear in the R10 docs? -Scott --- Scott Lystig Fritchie Professional Governing: Is It Faked? From mfs@REDACTED Mon Aug 15 22:47:57 2005 From: mfs@REDACTED (Mark Scandariato) Date: Mon, 15 Aug 2005 16:47:57 -0400 (EDT) Subject: length of an iolist Message-ID: <22931627.1124138877415.JavaMail.root@mswamui-bichon.atl.sa.earthlink.net> >From the current docs (.../erl5.4.8/lib/kernel-2.10.9/doc/html/erlang.html): "Some BIFs, such as list_to_binary_1, take I/O lists as documents (written as iolist() in type descriptions). An I/O list is a deep list of binaries, integers in the range 0 through 255, and other I/O lists. In an I/O list, a binary is allowed as the tail of a list." ... "list_to_binary(DeepList) Types: DeepList = iolist() Returns a binary which is made from the integers and binaries in List. List may be deep and may contain any combination of integers and binaries. Example: list_to_binary([Bin1,1,[2,3,Bin2],4|Bin3]) Failure: badarg if List is not a list, or if it or any sublist contains anything else than binaries or integers in the range [0, 255]." Mark. PS: I agree that a single binary would be a reasonable thing to pass to such a function - but the docs appear to differ. -----Original Message----- From: Scott Lystig Fritchie Sent: Aug 15, 2005 4:20 PM To: Mark Scandariato Cc: erlang-questions@REDACTED Subject: Re: length of an iolist >>>>> "ms" == Mark Scandariato writes: ms> I originally had one, but I took it out since "iolist" is supposed ms> to be a list. I suspect that the name "i/o list"/"iolist"/whatever was coined before the binary data type was added to Erlang ... so nowadays a proper iolist may be either: * a (possibly deep) list of: - integers representing byte values and/or - binaries * a single binary Looking in some old R9 documentation for gen_tcp:send/2: send(Socket, Packet) -> ok | {error, Reason} Types: Socket = socket() Packet = list() | binary() Reason = atom() Now that binaries are part of the language, it seems silly not to include a single binary as a valid packet to send. Ditto for a function like file:write/2: write(IoDevice, Bytes) Writes Bytes (possibly a deep list of characters, or a binary) to the file described by IoDevice. [...] Though neither definition really says that your (deep) list of characters may also include binaries of arbitrary size. Hm, in my R9 docs, "iolist" (and various spelling variations) do not appear in .../kernel-2.9/doc/html/index.html index. Does it appear in the R10 docs? -Scott --- Scott Lystig Fritchie Professional Governing: Is It Faked? From klacke@REDACTED Mon Aug 15 23:37:42 2005 From: klacke@REDACTED (Claes Wikstrom) Date: Mon, 15 Aug 2005 23:37:42 +0200 Subject: Determining if process is alive on a different node In-Reply-To: <4300F25B.50302@hq.idt.net> References: <4300E798.9050005@hq.idt.net> <4300F25B.50302@hq.idt.net> Message-ID: <43010B26.3080700@hyber.org> Serge Aleynikov wrote: > (b@REDACTED)3> ^C > BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded > (v)ersion (k)ill (D)b-tables (d)istribution > a > ~/tmp>erl -sname b > Erlang (BEAM) emulator version 5.4.8 [source] [hipe] [threads:0] > Eshell V5.4.8 (abort with ^G) > (b@REDACTED)1> net_adm:ping(a@REDACTED). > pong > > (a@REDACTED)5> rpc:call(b@REDACTED, erlang, is_process_alive, > [pid(4771,36,0)]). > true > > -------------- > This last statement is not true, since it is not the same process on > node b that originated the first message. The Pid that was originally > recorded was reassigned to another process after the node was bounced. I'm not sure and haven't checked the current source. But in the stoneage when I first wrote the code for distributed erlang there was a small counter in each Pid which was somehow incremented when a node was started. Thus the node incarnation is checked and Pids from old dead nodes albeit with the right name are discarded and an error message is printed. The error above is the use of: pid(4771,36,0) You should collect the pid from the remote node, bind it to variable, restart the remote node and see that the old Pid is not useable. I checked, and if I try to use a Pid from a dead node, message is just discarded. /klacke From klacke@REDACTED Mon Aug 15 23:39:21 2005 From: klacke@REDACTED (Claes Wikstrom) Date: Mon, 15 Aug 2005 23:39:21 +0200 Subject: mnesia:clear_table In-Reply-To: <4300F58B.8020205@hq.idt.net> References: <4300F58B.8020205@hq.idt.net> Message-ID: <43010B89.3080301@hyber.org> Serge Aleynikov wrote: > Hi, > > I am wondering why the mnesia:clear_table/1 function is encapsulated in > a transaction of its own. It prevents this function to be included in > another transaction. > Transactions can be nested arbitrarily deep. Nesting doesn't come for free, but it works. /klacke From david.nospam.hopwood@REDACTED Mon Aug 15 23:56:13 2005 From: david.nospam.hopwood@REDACTED (David Hopwood) Date: Mon, 15 Aug 2005 22:56:13 +0100 Subject: What is a deep list, exactly? (was: length of an iolist) In-Reply-To: <22931627.1124138877415.JavaMail.root@mswamui-bichon.atl.sa.earthlink.net> References: <22931627.1124138877415.JavaMail.root@mswamui-bichon.atl.sa.earthlink.net> Message-ID: <43010F7D.6040802@blueyonder.co.uk> Mark Scandariato wrote: >>From the current docs (.../erl5.4.8/lib/kernel-2.10.9/doc/html/erlang.html): > > "Some BIFs, such as list_to_binary_1, take I/O lists as documents (written as iolist() > in type descriptions). An I/O list is a deep list of binaries, integers in the range > 0 through 255, and other I/O lists. In an I/O list, a binary is allowed as the tail > of a list." > [...] > PS: I agree that a single binary would be a reasonable thing to pass to such a > function - but the docs appear to differ. If I understand correctly, a deep list (in general, not specific to Erlang) is isomorphic to a binary tree where each node is labelled with either the element type or Nil. In Haskell-ish notation: deeplist t ::= t | Nil | Cons (deeplist t) (deeplist t) where in this case t = binary | char. ('|' means type union, not cons.) seems to confirm that this is the definition Scheme people use. In that case, a single binary would be an iolist (as would a single char). But this seems not to be the definition intended for Erlang, although it's not exactly clear from the above docs. Reading the docs literally it would be something like: iolist ::= Nil | Cons (char | binary | iolist) (binary | iolist) Is that right? If so it seems, well, ugly. -- David Hopwood From joelr1@REDACTED Tue Aug 16 00:04:12 2005 From: joelr1@REDACTED (Joel Reymont) Date: Tue, 16 Aug 2005 00:04:12 +0200 Subject: Determining if process is alive on a different node In-Reply-To: <4300F25B.50302@hq.idt.net> References: <4300E798.9050005@hq.idt.net> <4300F25B.50302@hq.idt.net> Message-ID: I have a setup with multiple game servers. If a game server dies players should be able to reconnect to a different game server. All game servers share a database. Even if I monitor every process on every node all nodes could potentially crash and I'll still need to verify the processes when I restart the cluster. If Klacke is right about Erlang tracking node incarnations then I do not have a problem and can just rpc:call(... is_process_alive ). On Aug 15, 2005, at 9:51 PM, Serge Aleynikov wrote: > What if the node(Pid) node got bounced since the time we captured > the Pid. The Pid value might've been reassigned to another > process, as in the example below: From gordonguthrie@REDACTED Tue Aug 16 01:14:03 2005 From: gordonguthrie@REDACTED (Gordon Guthrie) Date: Tue, 16 Aug 2005 00:14:03 +0100 Subject: Running slave:start_link on a localhost Message-ID: <1124147643.430121bbaedd7@backawinner.gg> Folks I am trying to get tsunami to run with the test controller, the test machines and the target machine on a localhost and I am unable to get it to work... By working through the code I have created a simple test in the erlang shell which I think ought to work, but doesnt... First up I have set up ssh so that when I run "ssh tsunami_host" it logs me straight into the localhost as if it was a remote machine. tsunami_host has an entry in /etc/hosts as per: 127.0.0.1 tsunami_host Then I run an erlang shell with the command "erl -sname tsunami_controller". At the erlang shell prompt I run "slave:start_link(tsunami_host, tsunami0, "-rsh ssh)." and get the message "Connection refused {error,timeout}" I am somewhat at a loss at this stage... Gordon ------------------------------------------------- This mail sent through IMP: http://horde.org/imp/ From harveyd@REDACTED Tue Aug 16 01:53:56 2005 From: harveyd@REDACTED (Dale Harvey) Date: Tue, 16 Aug 2005 00:53:56 +0100 Subject: Yaws / Post arguments Message-ID: Hey Im having problems building post arguments to send with the the http modules I was hoping to be able to chuck a record like so Bleh = #Record{define="stuff"}, http:request(post,{"http://blehbleh", [] , "text/plain",Bleh}. [] , []). and have the erlang client sort the headers out nicely, but httpc_manager keeps shouting at me for that. So ive been trying to just make the format the post arguments myself, My first guess was a list of key value tuples, since thats how they come out of parse_post http:request(post,{"http://blehbleh", [] , "text/plain", [{"key1",Val1},{"key2",Val2}] }. [] , []). but that gives a similiar error, ive tried most combinations of tuples, lists all with the same error. I couldnt find any records in the yaw_api pertaining to this, and no docs suggesting how to arrange the post arguments right now http:request(post,{"http://blehbleh", [] , "text/plain", "key1" }. [] , []). gives me [("key1",undefined}] from yaws_api:parse_post but no luck on adding a value, or extra vars Cheers Dale From serge@REDACTED Tue Aug 16 02:57:35 2005 From: serge@REDACTED (Serge Aleynikov) Date: Mon, 15 Aug 2005 20:57:35 -0400 Subject: Determining if process is alive on a different node In-Reply-To: <43010B26.3080700@hyber.org> References: <4300E798.9050005@hq.idt.net> <4300F25B.50302@hq.idt.net> <43010B26.3080700@hyber.org> Message-ID: <430139FF.2080107@hq.idt.net> Thanks, I'll keep this in mind. Claes Wikstrom wrote: > Serge Aleynikov wrote: > >> (b@REDACTED)3> ^C >> BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded >> (v)ersion (k)ill (D)b-tables (d)istribution >> a >> ~/tmp>erl -sname b >> Erlang (BEAM) emulator version 5.4.8 [source] [hipe] [threads:0] >> Eshell V5.4.8 (abort with ^G) >> (b@REDACTED)1> net_adm:ping(a@REDACTED). >> pong >> >> (a@REDACTED)5> rpc:call(b@REDACTED, erlang, is_process_alive, >> [pid(4771,36,0)]). >> true >> >> -------------- >> This last statement is not true, since it is not the same process on >> node b that originated the first message. The Pid that was originally >> recorded was reassigned to another process after the node was bounced. > > > > I'm not sure and haven't checked the current source. But in the stoneage > when I first wrote the code for distributed erlang there was a small > counter in each Pid which was somehow incremented when a node was > started. > > Thus the node incarnation is checked and Pids from old dead nodes > albeit with the right name are discarded and an error message > is printed. > > The error above is the use of: > > pid(4771,36,0) > > You should collect the pid from the remote node, bind it to variable, > restart the remote node and see that the old Pid is not useable. > I checked, and if I try to use a Pid from a dead node, message is > just discarded. > > > /klacke > From serge@REDACTED Tue Aug 16 03:10:08 2005 From: serge@REDACTED (Serge Aleynikov) Date: Mon, 15 Aug 2005 21:10:08 -0400 Subject: mnesia:clear_table In-Reply-To: <43010B89.3080301@hyber.org> References: <4300F58B.8020205@hq.idt.net> <43010B89.3080301@hyber.org> Message-ID: <43013CF0.40702@hq.idt.net> Indeed when I do: F = fun() -> mnesia:clear_table(Tab) end, mnesia:transaction(F). It works. That means that nested transactions are supported, however this code returns an error: p>erl -sname t Erlang (BEAM) emulator version 5.4.8 [source] [hipe] [threads:0] Eshell V5.4.8 (abort with ^G) (t@REDACTED)1> mnesia:create_schema([node()]). ok (t@REDACTED)2> mnesia:start(). ok (t@REDACTED)3> mnesia:create_table(test, [{ram_copies, [node()]}]). {atomic,ok} (t@REDACTED)4> mnesia:create_table(test1, [{ram_copies, [node()]}]). {atomic,ok} (t@REDACTED)5> F = fun() -> mnesia:clear_table(test), mnesia:clear_table(test1) end. #Fun (t@REDACTED)6> mnesia:transaction(F). {atomic,{aborted,nested_transaction}} Am I doing something unconventional, or there is a limit on the depth of nested transactions? Serge Claes Wikstrom wrote: > Serge Aleynikov wrote: > >> Hi, >> >> I am wondering why the mnesia:clear_table/1 function is encapsulated >> in a transaction of its own. It prevents this function to be included >> in another transaction. >> > > Transactions can be nested arbitrarily deep. Nesting doesn't > come for free, but it works. > > > /klacke > -- Serge Aleynikov R&D Telecom, IDT Corp. Tel: (973) 438-3436 Fax: (973) 438-1464 serge@REDACTED From ulf.wiger@REDACTED Tue Aug 16 08:48:16 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Tue, 16 Aug 2005 08:48:16 +0200 Subject: Determining if process is alive on a different node Message-ID: Klacke is right, as this simple example shows: %% on one node, register a process: Eshell V5.4.7 (abort with ^G) (n2@REDACTED)1> register(remote, self()). true %% on the other node, find the process, check that it's alive: Eshell V5.4.7 (abort with ^G) (n1@REDACTED)1> Pid = rpc:call(n2@REDACTED, erlang, whereis, [remote]). <4950.44.0> (n1@REDACTED)2> rpc:call(n2@REDACTED, erlang, is_process_alive, [Pid]). true %% now killing n2@REDACTED (n1@REDACTED)3> rpc:call(n2@REDACTED, erlang, is_process_alive, [Pid]). {badrpc,nodedown} %% restarting n2@REDACTED (n1@REDACTED)4> rpc:call(n2@REDACTED, erlang, is_process_alive, [Pid]). false /Uffe > -----Original Message----- > From: owner-erlang-questions@REDACTED > [mailto:owner-erlang-questions@REDACTED]On Behalf Of Joel Reymont > Sent: den 16 augusti 2005 00:04 > To: Erlang Users' List > Subject: Re: Determining if process is alive on a different node > > > I have a setup with multiple game servers. If a game server dies > players should be able to reconnect to a different game server. All > game servers share a database. > > Even if I monitor every process on every node all nodes could > potentially crash and I'll still need to verify the processes when I > restart the cluster. > > If Klacke is right about Erlang tracking node incarnations then I do > not have a problem and can just rpc:call(... is_process_alive ). > > On Aug 15, 2005, at 9:51 PM, Serge Aleynikov wrote: > > > What if the node(Pid) node got bounced since the time we captured > > the Pid. The Pid value might've been reassigned to another > > process, as in the example below: > From ulf.wiger@REDACTED Tue Aug 16 09:15:11 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Tue, 16 Aug 2005 09:15:11 +0200 Subject: mnesia:clear_table Message-ID: mnesia:clear_table/1 calls mnesia_schema:clear_table/1, which in its turn does the following: clear_table(Tab) -> schema_transaction(fun() -> do_clear_table(Tab) end). Schema transactions don't support nesting... or you could possibly have a schema transaction at the top and nest regular transactions in it(*), but as mnesia_schema:do_clear_table/1 is not exported, you'll have a hard time doing even that. (*) There may be serious issues with this - I can't say. If you really, really want to do this, and don't want to hack mnesia so as to export do_clear_table/1, you can emulate it easily enough. This is how it's implemented: do_clear_table(schema) -> mnesia:abort({bad_type, schema}); do_clear_table(Tab) -> TidTs = get_tid_ts_and_lock(schema, write), get_tid_ts_and_lock(Tab, write), insert_schema_ops(TidTs, make_clear_table(Tab)). make_clear_table(Tab) -> ensure_writable(schema), Cs = val({Tab, cstruct}), ensure_active(Cs), ensure_writable(Tab), [{op, clear_table, cs2list(Cs)}]. The functions that are not exported from mnesia_schema are: - do_clear_table/1 - make_clear_table/1 - ensure_writable/1 ensure_writable/1 looks like this: ensure_writable(Tab) -> case val({Tab, where_to_write}) of [] -> mnesia:abort({read_only, Tab}); _ -> ok end. So, you can copy the code for ensure_writable/1 and make_clear_table/1. Then, your code becomes: my_do_clear_table(schema) -> mnesia:abort({bad_type, schema}); my_do_clear_table(Tab) -> TidTs = mnesia_schema:get_tid_ts_and_lock(schema, write), mnesia_schema:get_tid_ts_and_lock(Tab, write), mnesia_schema:insert_schema_ops(TidTs, my_make_clear_table(Tab)). my_make_clear_table(Tab) -> my_ensure_writable(schema), Cs = mnesia_lib:val({Tab, cstruct}), mnesia_schema:ensure_active(Cs), my_ensure_writable(Tab), [{op, clear_table, mnesia_schema:cs2list(Cs)}]. my_ensure_writable(Tab) -> case mnesia_lib:val({Tab, where_to_write}) of [] -> mnesia:abort({read_only, Tab}); _ -> ok end. Then you can combine this with other ops inside a top-level schema_transaction (important!) (n2@REDACTED)6> mnesia:create_table(test, [{ram_copies, [node()]}]). {atomic,ok} (n2@REDACTED)7> mnesia:create_table(test1, [{ram_copies,[node()]}]). {atomic,ok} (n2@REDACTED)8> mnesia:dirty_write({test,a,1}). ok (n2@REDACTED)9> mnesia:dirty_write({test1,a,1}). ok (n2@REDACTED)11> mnesia_schema:schema_transaction(fun() -> cleart:my_do_clear_table(test), cleart:my_do_clear_table(test1), mnesia:write({test,b,1}), mnesia:write({test1,b,1}) end). {atomic,ok} (n2@REDACTED)12> ets:tab2list(test). [{test,b,1}] (n2@REDACTED)13> mnesia_schema:schema_transaction(fun() -> cleart:my_do_clear_table(test), cleart:my_do_clear_table(test1), mnesia:transaction(fun() -> mnesia:write({test,b,1}), mnesia:write({test1,b,1}) end) end). {atomic,{atomic,ok}} (n2@REDACTED)14> ets:tab2list(test). [{test,b,1}] mnesia_schema:schema_transaction( fun() -> my_clear_table(Tab), mnesia:transaction(fun() -> ... end)). (: /Uffe > -----Original Message----- > From: owner-erlang-questions@REDACTED > [mailto:owner-erlang-questions@REDACTED]On Behalf Of Serge Aleynikov > Sent: den 16 augusti 2005 03:10 > To: Claes Wikstrom > Cc: Erlang Questions > Subject: Re: mnesia:clear_table > > > Indeed when I do: > > F = fun() -> > mnesia:clear_table(Tab) > end, > mnesia:transaction(F). > > It works. That means that nested transactions are supported, however > this code returns an error: > > p>erl -sname t > Erlang (BEAM) emulator version 5.4.8 [source] [hipe] [threads:0] > Eshell V5.4.8 (abort with ^G) > (t@REDACTED)1> mnesia:create_schema([node()]). > ok > (t@REDACTED)2> mnesia:start(). > ok > (t@REDACTED)3> mnesia:create_table(test, [{ram_copies, [node()]}]). > {atomic,ok} > (t@REDACTED)4> mnesia:create_table(test1, [{ram_copies, > [node()]}]). > > {atomic,ok} > (t@REDACTED)5> F = fun() -> mnesia:clear_table(test), > mnesia:clear_table(test1) end. > #Fun > (t@REDACTED)6> mnesia:transaction(F). > > {atomic,{aborted,nested_transaction}} > > Am I doing something unconventional, or there is a limit on > the depth of > nested transactions? > > Serge > > Claes Wikstrom wrote: > > Serge Aleynikov wrote: > > > >> Hi, > >> > >> I am wondering why the mnesia:clear_table/1 function is > encapsulated > >> in a transaction of its own. It prevents this function to > be included > >> in another transaction. > >> > > > > Transactions can be nested arbitrarily deep. Nesting doesn't > > come for free, but it works. > > > > > > /klacke > > > > -- > Serge Aleynikov > R&D Telecom, IDT Corp. > Tel: (973) 438-3436 > Fax: (973) 438-1464 > serge@REDACTED > -------------- next part -------------- A non-text attachment was scrubbed... Name: cleart.erl Type: application/octet-stream Size: 982 bytes Desc: cleart.erl URL: From ingela@REDACTED Tue Aug 16 09:23:15 2005 From: ingela@REDACTED (Ingela Anderton) Date: Tue, 16 Aug 2005 09:23:15 +0200 Subject: Yaws / Post arguments References: Message-ID: <17153.37987.635687.598473@gargle.gargle.HOWL> Dale Harvey wrote: > Hey > > Im having problems building post arguments to send with the the http modules > > I was hoping to be able to chuck a record like so > > Bleh = #Record{define="stuff"}, > http:request(post,{"http://blehbleh", [] , "text/plain",Bleh}. [] , []). > > and have the erlang client sort the headers out nicely, but > httpc_manager keeps shouting at me for that. The inets HTTP-Client API states that a request could be: request() - {url(), headers()} | {url(), headers(), content_type(), body()} where body is: body() = string() | binary() So in your case that would be: Bleh = #Record{define="stuff"}, http:request(post,{"http://blehbleh", [] , "text/plain", term_to_binary(Bleh)}, [] , []). ^^^ note not "." but "," > So ive been trying to just make the format the post arguments myself, > My first guess was a list of key value tuples, since thats how they > come out of parse_post > > http:request(post,{"http://blehbleh", [] , "text/plain", > [{"key1",Val1},{"key2",Val2}] }. [] , []). As noted above: On the client side the post body should be of type string() or binary(). > but that gives a similiar error, ive tried most combinations of > tuples, lists all with the same error. I couldnt find any records in > the yaw_api pertaining to this, and no docs suggesting how to arrange > the post arguments > > right now > > http:request(post,{"http://blehbleh", [] , "text/plain", "key1" }. [] , []). > > gives me [("key1",undefined}] from yaws_api:parse_post > > but no luck on adding a value, or extra vars How yaws works I will leave to Clacke to explain ;) -- /Ingela - OTP team From hedeland@REDACTED Tue Aug 16 09:42:38 2005 From: hedeland@REDACTED (Per Hedeland) Date: Tue, 16 Aug 2005 09:42:38 +0200 (CEST) Subject: Determining if process is alive on a different node In-Reply-To: Message-ID: <200508160742.j7G7gcG8059560@tordmule.bluetail.com> "Ulf Wiger (AL/EAB)" wrote: > >Klacke is right, as this simple example shows: Well, the mechanism does cover that "simple example" (and that's basically what it was designed to do), but for anyone that really needs to rely on old Pids never matching new processes, it's probably a good idea to make sure what guarantees are actually provided - e.g. when the remote host does a full reboot, or the Pids are "very" old. In the old days the "creation number" was only two bits, with state maintained by epmd - and looking at current epmd source, it seems that *it* does the same today (actually only 1..3 is used). But maybe there is more magic on the Erlang node side these days, I haven't checked. --Per Hedeland From mats.cronqvist@REDACTED Tue Aug 16 11:14:10 2005 From: mats.cronqvist@REDACTED (Mats Cronqvist) Date: Tue, 16 Aug 2005 11:14:10 +0200 Subject: Throw or return a tuple In-Reply-To: <73b6898c58d0154fbb8dbc1a7f2552aa@ezabel.com> References: <73b6898c58d0154fbb8dbc1a7f2552aa@ezabel.com> Message-ID: <4301AE62.6060506@ericsson.com> throw an exception. personally, i believe that returning {ok,R}/{error,R} is ALWAYS wrong. e.g. file:open/2; as it is now, it will return {error,R} if there is some system resource missing (truly exceptional), or if you pass it bad data (e.g. a file that does not exist). in either case it should throw. i wonder where the {error,R} idiom came from... but there definitely seems to be a move away from it. mats orbitz@REDACTED wrote: > I find myself often confused about which to do, should I throw an > exception when an error happens in a function or always go with > returning {ok, Value} or {error, Whatever}. > > Some people seem try to tell me that I should use {error, Value} and > "get out of your OO mindset with exceptions". But I think that is > bull. I don't see why exceptions should be purely considered OO and > erlang has exceptions, why shouldn't I use them? That seems like the > talk of people afraid of change or something similar. The most > convincing argument for me to use exceptions is because I want to be > able to do: > > foo(bar()) rather than {ok, V} = ...yadda. > > What do people generally prefer? Are we moving towards more exceptions? > OTP seems to use exceptions for somethings and an error tuple for others. > > Thanks > From joelr1@REDACTED Tue Aug 16 11:24:26 2005 From: joelr1@REDACTED (Joel Reymont) Date: Tue, 16 Aug 2005 11:24:26 +0200 Subject: Sharing virtual memory: several Mnesia nodes on the same machine Message-ID: <7ED0CFB6-61D7-4BBE-8CD6-CADC470944DB@gmail.com> Folks, If I have several nodes on the same machine using the _same_ Mnesia database, is the memory shared using mmap or some such mechanism? Thanks, Joel -- http://wagerlabs.com/uptick From ulf.wiger@REDACTED Tue Aug 16 11:34:35 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Tue, 16 Aug 2005 11:34:35 +0200 Subject: Sharing virtual memory: several Mnesia nodes on the same machine Message-ID: No. The nodes run as separate Unix (or windows) processes, using no shared memory, communicating over TCP. The main reason for running several nodes on one machine has been to simulate a real network. /Uffe > -----Original Message----- > From: owner-erlang-questions@REDACTED > [mailto:owner-erlang-questions@REDACTED]On Behalf Of Joel Reymont > Sent: den 16 augusti 2005 11:24 > To: Erlang Users' List > Subject: Sharing virtual memory: several Mnesia nodes on the same > machine > > > Folks, > > If I have several nodes on the same machine using the _same_ Mnesia > database, is the memory shared using mmap or some such mechanism? > > Thanks, Joel > > -- > http://wagerlabs.com/uptick > > > > From ulf.wiger@REDACTED Tue Aug 16 11:40:22 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Tue, 16 Aug 2005 11:40:22 +0200 Subject: Determining if process is alive on a different node Message-ID: Agreed. There should really be a housekeeping process that removes dead pids from the tables. This process could monitor the other node, and remove all pids that belong to that node if it dies. Per Hedeland wrote: > > Well, the mechanism does cover that "simple example" (and > that's basically what it was designed to do), but for > anyone that really needs to rely on old Pids never > matching new processes, it's probably a good idea to > make sure what guarantees are actually provided - > e.g. when the remote host does a full reboot, or the > Pids are "very" old. Agreed. There should really be some housekeeping process that removes dead pids from the table(s) if the other node goes down. If this is done by a background process, there is a race condition to consider. If the other node restarts quickly, the creation number will make sure that there is no mixup; if the other node does a full reboot, there is ample time to remove the pids (at least assuming that you are running Erlang on normal machines) To be really sure, you can turn change the dist_auto_connect option in the kernel application. If this is set to 'never', nodes will not automatically re-connect, and you have full control over the time between a node dying and it reconnecting. /Uffe > -----Original Message----- > From: Per Hedeland [mailto:hedeland@REDACTED] > Sent: den 16 augusti 2005 09:43 > To: erlang-questions@REDACTED; joelr1@REDACTED; Ulf Wiger (AL/EAB) > Subject: RE: Determining if process is alive on a different node > > > "Ulf Wiger (AL/EAB)" wrote: > > > >Klacke is right, as this simple example shows: > > Well, the mechanism does cover that "simple example" (and that's > basically what it was designed to do), but for anyone that > really needs > to rely on old Pids never matching new processes, it's probably a good > idea to make sure what guarantees are actually provided - > e.g. when the > remote host does a full reboot, or the Pids are "very" old. > > In the old days the "creation number" was only two bits, with state > maintained by epmd - and looking at current epmd source, it seems that > *it* does the same today (actually only 1..3 is used). But maybe there > is more magic on the Erlang node side these days, I haven't checked. > > --Per Hedeland > From rprice@REDACTED Tue Aug 16 11:41:18 2005 From: rprice@REDACTED (Roger Price) Date: Tue, 16 Aug 2005 11:41:18 +0200 (CEST) Subject: Trying to install the Erlang documentation Message-ID: I downloaded otp_src_R10B-5.tar.gz , unzipped and untarred it, entered directory otp_src_R10B-5 and read the README. I followed the instructions to install Erlang/OTP and then read "How to install the Erlang/OTP documentation". This calls for me to cd /lib/erlang gunzip -c otp_html_R10B-0.tar.gz | tar xf - I guess is the default /usr/local, but /usr/local/lib/erlang contains no file otp_html_R10B-0.tar.gz. Do I have to download otp_html_R10B-0.tar.gz and place it into /usr/local/lib/erlang, or should this happen some other way? Should I understand that "otp_html_R10B-0.tar.gz" means "otp_doc_html_R10B-5.tar.gz"? Any help would be much appreciated, Roger From mats.cronqvist@REDACTED Tue Aug 16 11:50:52 2005 From: mats.cronqvist@REDACTED (Mats Cronqvist) Date: Tue, 16 Aug 2005 11:50:52 +0200 Subject: Trying to install the Erlang documentation In-Reply-To: References: Message-ID: <4301B6FC.2070007@ericsson.com> i do this; cd $OTP_ROOT/lib/erlang ; tar -xzf /wherever/otp_doc_man_X.tar.gz > > Do I have to download otp_html_R10B-0.tar.gz and place it into > /usr/local/lib/erlang, or should this happen some other way? you have to download it, and put it wherever. > Should I understand that "otp_html_R10B-0.tar.gz" means > "otp_doc_html_R10B-5.tar.gz"? yes. > Any help would be much appreciated, note that installing the wrong version of the docs is bad (since the application dirs have version numbers). mats From rprice@REDACTED Tue Aug 16 12:28:04 2005 From: rprice@REDACTED (Roger Price) Date: Tue, 16 Aug 2005 12:28:04 +0200 (CEST) Subject: Throw or return a tuple In-Reply-To: <4301AE62.6060506@ericsson.com> Message-ID: On Tue, 16 Aug 2005, Mats Cronqvist wrote: > throw an exception. > personally, i believe that returning {ok,R}/{error,R} is ALWAYS wrong. > e.g. file:open/2; as it is now, it will return {error,R} if there is > some system resource missing (truly exceptional), or if you pass it bad > data (e.g. a file that does not exist). in either case it should throw. > i wonder where the {error,R} idiom came from... but there definitely > seems to be a move away from it. I seems to me that there is place for both {error,Reason}, or better, {refused,R}, and exceptions. Perhaps the criteria is that {error,R} is for situations that may occur in the normal course of business which prevent the function from completing, and exceptions are for things that are not expected in normal business. Examples: File permissions do not allow access - {refused,R} File system is on fire/has been stolen/power off - exception (Don't laugh, I've had these things happen) Roger From serge@REDACTED Tue Aug 16 13:48:26 2005 From: serge@REDACTED (Serge Aleynikov) Date: Tue, 16 Aug 2005 07:48:26 -0400 Subject: mnesia:clear_table In-Reply-To: References: Message-ID: <4301D28A.3070106@hq.idt.net> How much nicer would it be if do_clear_table were exported! :-) If schema transaction don't support nesting, I am not sure your answer clarifies why the following code should work if schema transaction don't support nesting: mnesia:transaction( fun() -> mnesia:clear_table(test), end). Indeed what led me to the original confusion was that my simple prototype with clearing/loading a single table inside a transaction worked, but when I extended that into multiple tables, it failed miserably for the reason you indicated below. So, is it expected that only a single schema trancation can be encapsulated in another transaction, and is it safe to use the transaction above? Serge Ulf Wiger (AL/EAB) wrote: > > mnesia:clear_table/1 calls mnesia_schema:clear_table/1, > which in its turn does the following: > > clear_table(Tab) -> > schema_transaction(fun() -> do_clear_table(Tab) end). > > > Schema transactions don't support nesting... or you could > possibly have a schema transaction at the top and nest > regular transactions in it(*), but as mnesia_schema:do_clear_table/1 > is not exported, you'll have a hard time doing even that. > > > (*) There may be serious issues with this - I can't say. > > > If you really, really want to do this, and don't want to > hack mnesia so as to export do_clear_table/1, you can > emulate it easily enough. This is how it's implemented: > > do_clear_table(schema) -> > mnesia:abort({bad_type, schema}); > do_clear_table(Tab) -> > TidTs = get_tid_ts_and_lock(schema, write), > get_tid_ts_and_lock(Tab, write), > insert_schema_ops(TidTs, make_clear_table(Tab)). > > make_clear_table(Tab) -> > ensure_writable(schema), > Cs = val({Tab, cstruct}), > ensure_active(Cs), > ensure_writable(Tab), > [{op, clear_table, cs2list(Cs)}]. > > The functions that are not exported from mnesia_schema are: > - do_clear_table/1 > - make_clear_table/1 > - ensure_writable/1 > > ensure_writable/1 looks like this: > > ensure_writable(Tab) -> > case val({Tab, where_to_write}) of > [] -> mnesia:abort({read_only, Tab}); > _ -> ok > end. > > > So, you can copy the code for ensure_writable/1 and > make_clear_table/1. Then, your code becomes: > > my_do_clear_table(schema) -> > mnesia:abort({bad_type, schema}); > my_do_clear_table(Tab) -> > TidTs = mnesia_schema:get_tid_ts_and_lock(schema, write), > mnesia_schema:get_tid_ts_and_lock(Tab, write), > mnesia_schema:insert_schema_ops(TidTs, my_make_clear_table(Tab)). > > my_make_clear_table(Tab) -> > my_ensure_writable(schema), > Cs = mnesia_lib:val({Tab, cstruct}), > mnesia_schema:ensure_active(Cs), > my_ensure_writable(Tab), > [{op, clear_table, mnesia_schema:cs2list(Cs)}]. > > my_ensure_writable(Tab) -> > case mnesia_lib:val({Tab, where_to_write}) of > [] -> mnesia:abort({read_only, Tab}); > _ -> ok > end. > > > Then you can combine this with other ops inside a > top-level schema_transaction (important!) > > > (n2@REDACTED)6> mnesia:create_table(test, [{ram_copies, [node()]}]). > {atomic,ok} > (n2@REDACTED)7> mnesia:create_table(test1, [{ram_copies,[node()]}]). > {atomic,ok} > (n2@REDACTED)8> mnesia:dirty_write({test,a,1}). > ok > (n2@REDACTED)9> mnesia:dirty_write({test1,a,1}). > ok > (n2@REDACTED)11> mnesia_schema:schema_transaction(fun() -> cleart:my_do_clear_table(test), cleart:my_do_clear_table(test1), mnesia:write({test,b,1}), mnesia:write({test1,b,1}) end). > {atomic,ok} > (n2@REDACTED)12> ets:tab2list(test). > [{test,b,1}] > (n2@REDACTED)13> mnesia_schema:schema_transaction(fun() -> cleart:my_do_clear_table(test), cleart:my_do_clear_table(test1), mnesia:transaction(fun() -> mnesia:write({test,b,1}), mnesia:write({test1,b,1}) end) end). > {atomic,{atomic,ok}} > (n2@REDACTED)14> ets:tab2list(test). [{test,b,1}] > > > > mnesia_schema:schema_transaction( > fun() -> > my_clear_table(Tab), > mnesia:transaction(fun() -> > ... > end)). > > (: > > /Uffe > > >>-----Original Message----- >>From: owner-erlang-questions@REDACTED >>[mailto:owner-erlang-questions@REDACTED]On Behalf Of Serge Aleynikov >>Sent: den 16 augusti 2005 03:10 >>To: Claes Wikstrom >>Cc: Erlang Questions >>Subject: Re: mnesia:clear_table >> >> >>Indeed when I do: >> >>F = fun() -> >> mnesia:clear_table(Tab) >> end, >>mnesia:transaction(F). >> >>It works. That means that nested transactions are supported, however >>this code returns an error: >> >>p>erl -sname t >>Erlang (BEAM) emulator version 5.4.8 [source] [hipe] [threads:0] >>Eshell V5.4.8 (abort with ^G) >>(t@REDACTED)1> mnesia:create_schema([node()]). >>ok >>(t@REDACTED)2> mnesia:start(). >>ok >>(t@REDACTED)3> mnesia:create_table(test, [{ram_copies, [node()]}]). >>{atomic,ok} >>(t@REDACTED)4> mnesia:create_table(test1, [{ram_copies, >>[node()]}]). >> >>{atomic,ok} >>(t@REDACTED)5> F = fun() -> mnesia:clear_table(test), >>mnesia:clear_table(test1) end. >>#Fun >>(t@REDACTED)6> mnesia:transaction(F). >> >>{atomic,{aborted,nested_transaction}} >> >>Am I doing something unconventional, or there is a limit on >>the depth of >>nested transactions? >> >>Serge >> >>Claes Wikstrom wrote: >> >>>Serge Aleynikov wrote: >>> >>> >>>>Hi, >>>> >>>>I am wondering why the mnesia:clear_table/1 function is >> >>encapsulated >> >>>>in a transaction of its own. It prevents this function to >> >>be included >> >>>>in another transaction. >>>> >>> >>>Transactions can be nested arbitrarily deep. Nesting doesn't >>>come for free, but it works. >>> >>> >>>/klacke From ulf.wiger@REDACTED Tue Aug 16 14:01:53 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Tue, 16 Aug 2005 14:01:53 +0200 Subject: mnesia:clear_table Message-ID: Serge Aleynikov wrote: > > If schema transaction don't support nesting, I am not sure > your answer clarifies why the following code should work > if schema transaction don't support nesting: > > mnesia:transaction( > fun() -> > mnesia:clear_table(test), > end). But it doesn't work: 4> mnesia:create_table(test,[{ram_copies,[node()]}]). {atomic,ok} 5> mnesia:transaction(fun() -> mnesia:clear_table(test) end). {atomic,{aborted,nested_transaction}} Granted, the return value is a bit funny. (: /Uffe From serge@REDACTED Tue Aug 16 14:14:04 2005 From: serge@REDACTED (Serge Aleynikov) Date: Tue, 16 Aug 2005 08:14:04 -0400 Subject: mnesia:clear_table In-Reply-To: References: Message-ID: <4301D88C.7050508@hq.idt.net> Ulf, I'm sorry - it was my oversight - I looked back at the test I did and saw: (t@REDACTED)5> F = fun() -> mnesia:clear_table(test), mnesia:write({test, 1, 1}) end. #Fun (t@REDACTED)6> mnesia:transaction(F). {atomic,ok} Clearly the return of mnesia:write() masked the failure of the mnesia:clear_table. Thinking in line with the other thread on exceptions vs. return of {error, Reason}, looks like this type of error would be a good candidate for raising an exception. Serge Ulf Wiger (AL/EAB) wrote: > Serge Aleynikov wrote: > >>If schema transaction don't support nesting, I am not sure >>your answer clarifies why the following code should work >>if schema transaction don't support nesting: >> >>mnesia:transaction( >> fun() -> >> mnesia:clear_table(test), >> end). > > > > But it doesn't work: > > 4> mnesia:create_table(test,[{ram_copies,[node()]}]). > {atomic,ok} > 5> mnesia:transaction(fun() -> mnesia:clear_table(test) end). > {atomic,{aborted,nested_transaction}} > > Granted, the return value is a bit funny. (: > > > /Uffe From hakan@REDACTED Tue Aug 16 14:54:37 2005 From: hakan@REDACTED (Hakan Mattsson) Date: Tue, 16 Aug 2005 14:54:37 +0200 (CEST) Subject: mnesia:clear_table In-Reply-To: <4301D28A.3070106@hq.idt.net> References: <4301D28A.3070106@hq.idt.net> Message-ID: A long time ago I added some severe restrictions on schema transactions in Mnesia in order to get a truly relieble system. Of course it is possible to relax some restrictions that feels too annoying and do like Uffe suggests. But if such a solution should be included in Mnesia, it would have to be more general and also handle reads within the transaction in a consistent manner. Uffes solution does only handle writes. /H?kan On Tue, 16 Aug 2005, Serge Aleynikov wrote: SA> How much nicer would it be if do_clear_table were exported! :-) SA> SA> If schema transaction don't support nesting, I am not sure your answer SA> clarifies why the following code should work if schema transaction don't SA> support nesting: SA> SA> mnesia:transaction( SA> fun() -> SA> mnesia:clear_table(test), SA> end). SA> SA> Indeed what led me to the original confusion was that my simple prototype SA> with clearing/loading a single table inside a transaction worked, but when I SA> extended that into multiple tables, it failed miserably for the reason you SA> indicated below. SA> SA> So, is it expected that only a single schema trancation can be encapsulated SA> in another transaction, and is it safe to use the transaction above? SA> SA> Serge SA> SA> Ulf Wiger (AL/EAB) wrote: SA> > SA> > mnesia:clear_table/1 calls mnesia_schema:clear_table/1, SA> > which in its turn does the following: SA> > SA> > clear_table(Tab) -> SA> > schema_transaction(fun() -> do_clear_table(Tab) end). SA> > SA> > SA> > Schema transactions don't support nesting... or you could possibly have a SA> > schema transaction at the top and nest SA> > regular transactions in it(*), but as mnesia_schema:do_clear_table/1 SA> > is not exported, you'll have a hard time doing even that. SA> > SA> > SA> > (*) There may be serious issues with this - I can't say. SA> > SA> > SA> > If you really, really want to do this, and don't want to hack mnesia so as SA> > to export do_clear_table/1, you can emulate it easily enough. This is how SA> > it's implemented: SA> > SA> > do_clear_table(schema) -> SA> > mnesia:abort({bad_type, schema}); SA> > do_clear_table(Tab) -> SA> > TidTs = get_tid_ts_and_lock(schema, write), SA> > get_tid_ts_and_lock(Tab, write), SA> > insert_schema_ops(TidTs, make_clear_table(Tab)). SA> > SA> > make_clear_table(Tab) -> SA> > ensure_writable(schema), SA> > Cs = val({Tab, cstruct}), SA> > ensure_active(Cs), SA> > ensure_writable(Tab), SA> > [{op, clear_table, cs2list(Cs)}]. SA> > SA> > The functions that are not exported from mnesia_schema are: SA> > - do_clear_table/1 SA> > - make_clear_table/1 SA> > - ensure_writable/1 SA> > SA> > ensure_writable/1 looks like this: SA> > SA> > ensure_writable(Tab) -> SA> > case val({Tab, where_to_write}) of SA> > [] -> mnesia:abort({read_only, Tab}); SA> > _ -> ok SA> > end. SA> > SA> > SA> > So, you can copy the code for ensure_writable/1 and make_clear_table/1. SA> > Then, your code becomes: SA> > SA> > my_do_clear_table(schema) -> SA> > mnesia:abort({bad_type, schema}); SA> > my_do_clear_table(Tab) -> SA> > TidTs = mnesia_schema:get_tid_ts_and_lock(schema, write), SA> > mnesia_schema:get_tid_ts_and_lock(Tab, write), SA> > mnesia_schema:insert_schema_ops(TidTs, my_make_clear_table(Tab)). SA> > SA> > my_make_clear_table(Tab) -> SA> > my_ensure_writable(schema), SA> > Cs = mnesia_lib:val({Tab, cstruct}), SA> > mnesia_schema:ensure_active(Cs), SA> > my_ensure_writable(Tab), SA> > [{op, clear_table, mnesia_schema:cs2list(Cs)}]. SA> > SA> > my_ensure_writable(Tab) -> SA> > case mnesia_lib:val({Tab, where_to_write}) of SA> > [] -> mnesia:abort({read_only, Tab}); SA> > _ -> ok SA> > end. SA> > SA> > SA> > Then you can combine this with other ops inside a top-level SA> > schema_transaction (important!) SA> > SA> > SA> > (n2@REDACTED)6> mnesia:create_table(test, [{ram_copies, [node()]}]). SA> > {atomic,ok} SA> > (n2@REDACTED)7> mnesia:create_table(test1, [{ram_copies,[node()]}]). SA> > {atomic,ok} SA> > (n2@REDACTED)8> mnesia:dirty_write({test,a,1}). SA> > ok SA> > (n2@REDACTED)9> mnesia:dirty_write({test1,a,1}). SA> > ok SA> > (n2@REDACTED)11> mnesia_schema:schema_transaction(fun() -> SA> > cleart:my_do_clear_table(test), cleart:my_do_clear_table(test1), SA> > mnesia:write({test,b,1}), mnesia:write({test1,b,1}) end). SA> > {atomic,ok} SA> > (n2@REDACTED)12> ets:tab2list(test). SA> > [{test,b,1}] SA> > (n2@REDACTED)13> mnesia_schema:schema_transaction(fun() -> SA> > cleart:my_do_clear_table(test), cleart:my_do_clear_table(test1), SA> > mnesia:transaction(fun() -> mnesia:write({test,b,1}), SA> > mnesia:write({test1,b,1}) end) end). SA> > {atomic,{atomic,ok}} SA> > (n2@REDACTED)14> ets:tab2list(test). SA> > [{test,b,1}] SA> > SA> > SA> > mnesia_schema:schema_transaction( SA> > fun() -> SA> > my_clear_table(Tab), SA> > mnesia:transaction(fun() -> ... SA> > end)). SA> > SA> > (: SA> > SA> > /Uffe SA> > SA> > SA> > > -----Original Message----- SA> > > From: owner-erlang-questions@REDACTED SA> > > [mailto:owner-erlang-questions@REDACTED]On Behalf Of Serge Aleynikov SA> > > Sent: den 16 augusti 2005 03:10 SA> > > To: Claes Wikstrom SA> > > Cc: Erlang Questions SA> > > Subject: Re: mnesia:clear_table SA> > > SA> > > SA> > > Indeed when I do: SA> > > SA> > > F = fun() -> SA> > > mnesia:clear_table(Tab) SA> > > end, SA> > > mnesia:transaction(F). SA> > > SA> > > It works. That means that nested transactions are supported, however SA> > > this code returns an error: SA> > > SA> > > p>erl -sname t SA> > > Erlang (BEAM) emulator version 5.4.8 [source] [hipe] [threads:0] SA> > > Eshell V5.4.8 (abort with ^G) SA> > > (t@REDACTED)1> mnesia:create_schema([node()]). SA> > > ok SA> > > (t@REDACTED)2> mnesia:start(). SA> > > ok SA> > > (t@REDACTED)3> mnesia:create_table(test, [{ram_copies, [node()]}]). SA> > > {atomic,ok} SA> > > (t@REDACTED)4> mnesia:create_table(test1, [{ram_copies, [node()]}]). SA> > > {atomic,ok} SA> > > (t@REDACTED)5> F = fun() -> mnesia:clear_table(test), SA> > > mnesia:clear_table(test1) end. SA> > > #Fun SA> > > (t@REDACTED)6> mnesia:transaction(F). SA> > > {atomic,{aborted,nested_transaction}} SA> > > SA> > > Am I doing something unconventional, or there is a limit on the depth of SA> > > nested transactions? SA> > > SA> > > Serge SA> > > SA> > > Claes Wikstrom wrote: SA> > > SA> > > > Serge Aleynikov wrote: SA> > > > SA> > > > SA> > > > > Hi, SA> > > > > SA> > > > > I am wondering why the mnesia:clear_table/1 function is SA> > > SA> > > encapsulated SA> > > > > in a transaction of its own. It prevents this function to SA> > > SA> > > be included SA> > > > > in another transaction. SA> > > > > SA> > > > SA> > > > Transactions can be nested arbitrarily deep. Nesting doesn't SA> > > > come for free, but it works. SA> > > > SA> > > > SA> > > > /klacke SA> /H?kan From Manjeet.Singh.Sardar@REDACTED Tue Aug 16 15:03:00 2005 From: Manjeet.Singh.Sardar@REDACTED (Manjeet.Singh Sardar (AC/EDD)) Date: Tue, 16 Aug 2005 15:03:00 +0200 Subject: Tcl/Tk Error Message-ID: Hi All, We are working on a GUI Client which is Erlang based. Erlang version :R9C-2 Tcl/Tk: version: 8.3 (came along with the Erlang release) Following error is displayed when any button is clicked and not released immediately Invalid command name ".w3.f41.b19" Invalid command name ".w3.f41.b19" while executing "$w cget -repeatinterval" (procedure "tk::ButtonAutoInvoke" line 4) invoked from within "tk::ButtonAutoInvoke .w3.f41.b19" ("after" script)" Can someone let us know what is the error because the same code was working fine when we use the R8C version of Erlang. Regards Manjeet From klacke@REDACTED Tue Aug 16 14:56:45 2005 From: klacke@REDACTED (Claes Wikstrom) Date: Tue, 16 Aug 2005 14:56:45 +0200 Subject: Yaws / Post arguments In-Reply-To: References: Message-ID: <4301E28D.1040701@hyber.org> Dale Harvey wrote: > > http:request(post,{"http://blehbleh", [] , "text/plain", "key1" }. [] , []). > > gives me [("key1",undefined}] from yaws_api:parse_post > > but no luck on adding a value, or extra vars > A good idea in this sort of situation is to start yaws as: # yaws -i -t -x That way you'll see exactly what yaws gets. -i - intaractive mode -t - traffic trace mode -x - write to stdout as well /klacke From mats.cronqvist@REDACTED Tue Aug 16 16:38:26 2005 From: mats.cronqvist@REDACTED (Mats Cronqvist) Date: Tue, 16 Aug 2005 16:38:26 +0200 Subject: Throw or return a tuple In-Reply-To: References: Message-ID: <4301FA62.3030302@ericsson.com> Roger Price wrote: > On Tue, 16 Aug 2005, Mats Cronqvist wrote: > > >> throw an exception. >>personally, i believe that returning {ok,R}/{error,R} is ALWAYS wrong. >>e.g. file:open/2; as it is now, it will return {error,R} if there is >>some system resource missing (truly exceptional), or if you pass it bad >>data (e.g. a file that does not exist). in either case it should throw. >>i wonder where the {error,R} idiom came from... but there definitely >>seems to be a move away from it. > > > I seems to me that there is place for both {error,Reason}, or better, > {refused,R}, and exceptions. Perhaps the criteria is that {error,R} is > for situations that may occur in the normal course of business which > prevent the function from completing, and exceptions are for things that > are not expected in normal business. > > Examples: File permissions do not allow access - {refused,R} > File system is on fire/has been stolen/power off - exception > (Don't laugh, I've had these things happen) > well, i disagree. I want to be able to write code like: process_data(file:read(file:open(...),...)) the {ok,R} idiom prevents me from doing that(*). as for your example; if you're trying to access a file in a way that the file permissions disallow you're passing bad data. either you know that the file should have the right permissions, or you should check them with file:read_file_info before trying to open the file. the file:open/2 API looks like C to me; it returns a status code and a value, the interpretation of the value depends on the status code. not that there's anything wrong with C.... mats (*) so i have to write functions like this (pseudo-code); sane_open(N,P) -> {{ok,FD},N} = {file:open(N,P),N}, FD. From harveyd@REDACTED Tue Aug 16 16:46:18 2005 From: harveyd@REDACTED (Dale Harvey) Date: Tue, 16 Aug 2005 15:46:18 +0100 Subject: Yaws / Post arguments In-Reply-To: <4301E28D.1040701@hyber.org> References: <4301E28D.1040701@hyber.org> Message-ID: Heh the . was a mistype, Didnt notice the type definitions last time i looked, thanks, still getting troubles though Bleh = #Record{define="stuff"}, http:request(post,{"http://blehbleh", [] , "text/plain", term_to_binary(Bleh)}, [] , []). and http:request(post,{"http://blehbleh", [] , "text/plain", term_to_binary({123,"bleh"})}, [] , []). are both still crashing on me, theres hundreds of lines getting thrown out but the error seems to be down to badmatch,(error,(badarg,[{erlang,length,[<>]} its definetaly a valid binary type im sending, binary_to_term comes out fine, just playing around i tried http:request(post,{"http://blehbleh", [] , "text/plain", [term_to_binary({123,"bleh"})]}, [] , []). which doesnt crash but the arguements unsuprisingly dont come out the other end right sending a valid binary type should according to the user guide work fine, am i doing something silly? From nm@REDACTED Tue Aug 16 17:06:52 2005 From: nm@REDACTED (Gaspar Chilingarov) Date: Tue, 16 Aug 2005 20:06:52 +0500 Subject: Vim and Erlang syntax files update [2005-08-16] In-Reply-To: <58128.217.113.1.123.1123972729.squirrel@webmail.web.am> References: <58128.217.113.1.123.1123972729.squirrel@webmail.web.am> Message-ID: <4302010C.30705@web.am> Hi again! Vim syntax file updated recognise : as correct symbol in function name. Now there is erlang_dictionary file included - kernel and stdlib module functions listed there. So in insert mode you can hit Ctrl-N or Ctrl-P to browse autocompletition of functions -- it's worth a try, it saves a lot of typing. Also there are included two theme files tuned for erlang syntax highlighting -- desert fot terminal use (green or white on black) and nortysky for gvim. File is uploaded to http://nothing.am/erlang/erl.tar.bz2 In case if you cannot download this file, just drop me the mail. BTW: are there any syntax tools to easily get all exported function lists? -- Gaspar Chilingarov System Administrator t +37491 419763 (mob) t +37410 240399 (office) w www.web.am i 63174784 e nm@REDACTED From ingela@REDACTED Tue Aug 16 17:12:16 2005 From: ingela@REDACTED (Ingela Anderton) Date: Tue, 16 Aug 2005 17:12:16 +0200 Subject: Yaws / Post arguments References: <4301E28D.1040701@hyber.org> Message-ID: <17154.592.430241.441779@gargle.gargle.HOWL> No you are not doing anything silly. I am afraid that is bug. I will fix it. If you want it to work right away you should patch the function post_data in the file httpc_request.erl to look like. post_data(Method, Headers, {ContentType, Body}) when Method == post; Method == put -> ContentLength = body_length(Body), NewBody = case Headers#http_request_h.expect of "100-continue" -> ""; _ -> Body end, {Headers#http_request_h{'content-type' = ContentType, 'content-length' = ContentLength}, NewBody}; And add this function to the same module. body_length(Body) when is_binary(Body) -> integer_to_list(size(Body)). body_length(Body) when is_list(Body) -> integer_to_list(length(Body)). Dale Harvey wrote: > Heh the . was a mistype, > > Didnt notice the type definitions last time i looked, thanks, still > getting troubles though > > Bleh = #Record{define="stuff"}, > http:request(post,{"http://blehbleh", [] , "text/plain", > term_to_binary(Bleh)}, [] , []). > > and > > http:request(post,{"http://blehbleh", [] , "text/plain", > term_to_binary({123,"bleh"})}, [] , []). > > are both still crashing on me, theres hundreds of lines getting thrown > out but the error seems to be down to > badmatch,(error,(badarg,[{erlang,length,[<>]} > > its definetaly a valid binary type im sending, binary_to_term comes > out fine, just playing around i tried > > http:request(post,{"http://blehbleh", [] , "text/plain", > [term_to_binary({123,"bleh"})]}, [] , []). > > which doesnt crash but the arguements unsuprisingly dont come out the > other end right > > sending a valid binary type should according to the user guide work > fine, am i doing something silly? -- /Ingela - OTP team From thomasl_erlang@REDACTED Tue Aug 16 18:17:12 2005 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Tue, 16 Aug 2005 09:17:12 -0700 (PDT) Subject: try ... after semantics Message-ID: <20050816161712.25348.qmail@web34415.mail.mud.yahoo.com> What is the semantics of try ... after? In particular, what variable bindings are available in the after body? Q1: My guess is, one cannot rely on any bindings made inside the try being available? (which is why the example below, from the erlang reference manual, 6.19, crashes if the file:open/2 does not return {ok,...}) termize_file(Name) -> {ok,F} = file:open(Name, [read,binary]), try {ok,Bin} = file:read(F, 1024*1024), binary_to_term(Bin) after file:close(F) end. (In Java, since variables can change their values there, I suppose one would push the file:open/2 call into the try instead.) Unfortunately, if we want the call to never throw an exception, this leads to somewhat convoluted code (as far as I can tell): termize_file(Name) -> try file:open(Name, [read,binary]) of {ok, F} -> %% original code try ... after ... end; Else -> Else end. Q2: So, is there a better way of expressing the "safe" termize_file using try? Best, Thomas __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From james.hague@REDACTED Tue Aug 16 21:19:21 2005 From: james.hague@REDACTED (James Hague) Date: Tue, 16 Aug 2005 14:19:21 -0500 Subject: Replacing the werl.exe GUI, take 2 Message-ID: I asked this question some weeks ago, but got no responses, so let me phrase it differently: I'd like ditch the Windows front-end to Erlang (werl.exe) and write my own. I've submitted patches for the GUI portion of werl.exe in the past, and it's cumbersome to have to install cygwin and build the whole app just to make a superficial usability change to the GUI. Logically, this should be easy: write my own application that starts up werl.exe in the background, with the GUI disabled, communicating via pipes. Standard UNIX-fare. Except if it were really this easy to do under Windows, I'd expect the Erlang team would have already done this. So what's the catch? From meena_selvam@REDACTED Tue Aug 16 21:39:41 2005 From: meena_selvam@REDACTED (MEENA SELVAM) Date: Tue, 16 Aug 2005 12:39:41 -0700 (PDT) Subject: snmp related question, getnext of empty table accesses the key of next table Message-ID: <20050816193941.90279.qmail@web30410.mail.mud.yahoo.com> Hi, I have few tables in snmp module, and when I issue a get_next using a mib browser for an empty table, since endOfTable is returned, it continues to look for the next available instance of the next variable/table. This is according to (conforming to ) the documentation given below from www.erlang.se/doc/doc-5.0.1/lib/snmp-3.2.1/doc/ under instrumentation functions section. ===================================================== 3.1.6 GetNext Operation The GetNext Operation operation should only be defined for tables since the agent can find the next instance of plain variables in the MIB and call the instrumentation with the get operation. table_access(get_next, RowIndex, Cols [, ExtraArg1, ...]) Cols is a list of integers, all greater than or equal to zero. This indicates that the instrumentation should find the next accessible instance. This function returns the tuple {NextOid, NextValue}, or endOfTable. NextOid should be the lexicographically next accessible instance of a managed object in the table. It should be a list of integers, where the first integer is the column, and the rest of the list is the indices for the next row. If endOfTable is returned, the agent continues to search for the next instance among the other variables and tables. RowIndex may be an empty list, an incompletely specified row index, or the index for an unspecified row. ====================================================== But, in finding the next instance the program tries to access the key ie Colno corresponding to key is part of this search. In my case, the get_next of the switch table works fine normally but in the normal case, the keys are inaccessible, and hence getnext (even as part of walk) specifies columns 3-7 and never 1 and 2 The error I get is: ** User error: Invalid return value {'EXIT',{{badma tch,{aborted,{function_clause,[{oam_snmp_snas,get_switch_table,[1,{'1','1'}]},{o am_snmp_table,nselect_cols,6},{reg,'-transaction/3-fun-0-',3},{reg,'-transaction /3-fun-1-',1},{mnesia_tm,apply_fun,3},{mnesia_tm,execute_transaction,5},{oam_snm p_snas,snasSwitchDetailTable,3},{snmpa_agent,get_next_values_all_rows,6}]}}},[{o am_snmp_snas,snasSwitchDetailTable,3},{snmpa_agent,get_next_values_all_rows,6},{ snmpa_agent,get_next_table,4},{snmpa_agent,next_loop_varbinds,5},{snmpa_agent,pr ocess_pdu,4},{snmpa_agent,handle_pdu,7},{snmpa_agent,handle_info,2},{gen_server, handle_msg,6}]}} from {oam_snmp_snas,snasSwitchDetailTable,[]} (get_next) my get_switch_table is the access function which is defined below: The first parameter is col no. get_switch_table(?snasSwitchIp, {XId, SId}) -> {value, SwitchIp} = reg:value_t(?SwitchIp(XId,SId)), tuple_to_list(SwitchIp); the problem is due to the col value 1 (first parameter of the following function call). This is confirmed because, just typing at erlang shell as follows: oam_snmp_snas:get_switch_table(1,{'1','1'}). gives the following error, =ERROR REPORT==== 16-Aug-2005::10:25:42 === Error in process <0.1043.0> on node ' isd@REDACTED' with exit value: {function_clause,[{oam_snmp_snas,get_switch_t able,[1,{'1','1'}]},{erl_eval,do_apply,5},{shell,exprs,6},{shell,eval_loop,3}]} * * exited: {function_clause,[{oam_snmp_snas,get_switch_table,[1,{'1','1'}]}, {erl_eval,do_apply,5}, {shell,exprs,6}, {shell,eval_loop,3}]} ** whereas oam_snmp_snas:get_switch_table(3,{'1','1'}). does not give error(produces proper output) My doubt is: why does the next searched instance is the key(col 1), instead of column 3. Also is it possible to suppress searching beyond for next available instance if endOfTable is encountered. meena ____________________________________________________ Start your day with Yahoo! - make it your home page http://www.yahoo.com/r/hs From chandrashekhar.mullaparthi@REDACTED Tue Aug 16 22:18:00 2005 From: chandrashekhar.mullaparthi@REDACTED (Chandrashekhar Mullaparthi) Date: Tue, 16 Aug 2005 21:18:00 +0100 Subject: Sharing virtual memory: several Mnesia nodes on the same machine In-Reply-To: References: Message-ID: <407f18df171f92a55018323c3517bc72@t-mobile.co.uk> On 16 Aug 2005, at 10:34, Ulf Wiger (AL/EAB) wrote: > > No. The nodes run as separate Unix (or windows) processes, > using no shared memory, communicating over TCP. > > The main reason for running several nodes on one machine > has been to simulate a real network. We run several mnesia nodes on one machine which are all part of the same schema to minimise the effect of a partitioned network. One huge database is split across two erlang nodes which are then replicated to two other nodes on another machine. When we have a partitioned network, we have one consistent copy of the database on one machine. This scheme has worked quite well for us. Chandru > >> -----Original Message----- >> From: owner-erlang-questions@REDACTED >> [mailto:owner-erlang-questions@REDACTED]On Behalf Of Joel Reymont >> Sent: den 16 augusti 2005 11:24 >> To: Erlang Users' List >> Subject: Sharing virtual memory: several Mnesia nodes on the same >> machine >> >> >> Folks, >> >> If I have several nodes on the same machine using the _same_ Mnesia >> database, is the memory shared using mmap or some such mechanism? >> >> Thanks, Joel >> >> -- >> http://wagerlabs.com/uptick >> >> >> >> > From vlad_dumitrescu@REDACTED Tue Aug 16 22:49:07 2005 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Tue, 16 Aug 2005 22:49:07 +0200 Subject: Replacing the werl.exe GUI, take 2 References: Message-ID: ----- Original Message ----- From: "James Hague" > Logically, this should be easy: write my own application that starts > up werl.exe in the background, with the GUI disabled, communicating > via pipes. Standard UNIX-fare. Except if it were really this easy to > do under Windows, I'd expect the Erlang team would have already done > this. So what's the catch? I wrote an application like this, for some years ago. From what I remember, there was a small but noticeable delay when communicating with the Erlang process. Pipes in Windows are a little sluggish (or were, don't know about XP or similar). With todays faster machines, there's probably no catch. Possibly still slower than communicating with beam.dll directly, but my guess is that it would be good enough. I didn't go on with it because I seldom use werl anyway, so other projects felt more important. best regards, Vlad From Tony.Hobbins@REDACTED Tue Aug 16 23:09:34 2005 From: Tony.Hobbins@REDACTED (Tony Hobbins) Date: Wed, 17 Aug 2005 07:09:34 +1000 Subject: Is there an elegant guard test for strings? Message-ID: <57AD40AED823A7439D25CD09604BFB540138CC49@balius.mit> Hi all, I hope this question is not as stupid as it sounds. What is the most elegant guard construct for testing for a string? e.g. I want to be able to ... foo(X) when is_string(X)-> blah()... where is_string() has the semantics of returning true for lists which are simple strings . I want to use this function in the following context foo(X) when is_string(X)-> blah(); foo(X) when is_list(X)-> lists:map(fun(Z)->foo(Z) end,X). Any advice appreciated. /Tony From vances@REDACTED Tue Aug 16 23:35:29 2005 From: vances@REDACTED (Vance Shipley) Date: Tue, 16 Aug 2005 17:35:29 -0400 Subject: Is there an elegant guard test for strings? In-Reply-To: <57AD40AED823A7439D25CD09604BFB540138CC49@balius.mit> References: <57AD40AED823A7439D25CD09604BFB540138CC49@balius.mit> Message-ID: <20050816213528.GX42667@feeble.motivity.ca> Unfortunately you can't create your own guards. But you can create your own is_string/1 and use it like: foo(X, is_string(X)). foo(X, true) -> blah()... foo(X, false) -> lists:map(fun(Z)->foo(Z) end,X). is_string([]) -> true; is_string([H|T]) when H >= $ , H =< $~ -> is_string(T); is_string(_) -> false. On Wed, Aug 17, 2005 at 07:09:34AM +1000, Tony Hobbins wrote: } } foo(X) when is_string(X)-> } blah(); } } foo(X) when is_list(X)-> } lists:map(fun(Z)->foo(Z) end,X). From klacke@REDACTED Tue Aug 16 23:28:21 2005 From: klacke@REDACTED (Claes Wikstrom) Date: Tue, 16 Aug 2005 23:28:21 +0200 Subject: Is there an elegant guard test for strings? In-Reply-To: <57AD40AED823A7439D25CD09604BFB540138CC49@balius.mit> References: <57AD40AED823A7439D25CD09604BFB540138CC49@balius.mit> Message-ID: <43025A75.5050104@hyber.org> Tony Hobbins wrote: > Hi all, > > I hope this question is not as stupid as it sounds. > > What is the most elegant guard construct for testing for a string? There isn't any. Need to do it through case statement case is_string(L) of true -> stuff(L); /klacke From kramer@REDACTED Wed Aug 17 01:21:04 2005 From: kramer@REDACTED (Reto Kramer) Date: Tue, 16 Aug 2005 16:21:04 -0700 Subject: disk IO kills network IO, +A doesn't work as I hoped Message-ID: <0C017C4C-2051-4BA1-BAC8-D506FBAFCCF6@acm.org> I'm seeking advice from experts on the +A erl flag and the IO thread architecture. The issue I'm finding is that a blocking disk operation (fsync in my case) results in a network IO degradation of 2 orders of magnitude despite me using multiple IO threads. My architecture contains a node per CPU that does nothing but handle a transaction log, trying to write to it and making sure the data is sync'd to disk. There's an erlang process in that node that will fsync the log file descriptor to disk and gather more log data from other processes on other nodes while the fsync is pending. Once the fsync is complete, the batch of log data was received while sync'ing will be sync'd next while a new data batch is accumulated. There's lots of tricks that one can play to work around the sync time etc., but ultimately that time is in the order of milliseconds. That means that there's a number of erlang log-messages I can send to the log node while the log node is sync'ing to disk. My little experiment between two distinct Linux hosts shows that erlang ping roundtrip times (no payload to serialize) drop by a factor of 100 once the receiving log node starts to do the disk IO (the write/fsync, write/fsync, ...). The disk IO data size is varied between 1 byte and a few kilobytes, and since I currently don't do any of the tricks alluded to above, an fsync requires in the order of 15ms on the HW I'm using. Plenty of time to receive and process erlang messages sent from other nodes, I had hoped. This is so despite me using the +A flag (I've tried 2 to 10 threads, assuming that 2 would be logical, i.e. 1 for disk and 1 for network IO). Is this explicable by the thread architecture involved in IO? Why does using 3 threads (in the example below) not allow the VM to sustain the ping times (roughly)? I'm very puzzled about this since the writes are very small, and the fsync is really not using up any CPU time, or erlang reductions to speak of, i.e. there should be VM reduction cycles to process the network calls. Below is the src and the command lines and erlang commands to reproduce the issue should you have 2 boxes available (2 boxes to make sure we're not fooled by context switching between the 2 VMs involved). Any workarounds someone can suggest? Have you seen similar issues in the past? Thanks, - Reto reto@REDACTED 9% erl -pa . -sname probe Erlang (BEAM) emulator version 5.4.3 [source] [hipe] Eshell V5.4.3 (abort with ^G) (probe@REDACTED)1> eflush:pingtest(probe@REDACTED). ... 8042 0.141000 ms <--- simple ping rpc round trip time, fast network! 8043 0.144000 ms 8044 0.144000 ms 8045 0.151000 ms 8046 0.144000 ms 8047 0.144000 ms 8048 0.142000 ms 8049 17.6220 ms <--- node telco02 started to write to disk, ping times increase by *100 8050 2.49300 ms 8051 239.361 ms 8052 234.661 ms 8053 167.171 ms 8054 111.985 ms 8055 411.450 ms 8056 285.551 ms 8057 278.745 ms 8058 315.564 ms 8059 278.830 ms 8060 309.407 ms 8061 248.964 ms ... telco02$ erl +A3 -sname disk Erlang (BEAM) emulator version 5.4.3 [source] [hipe] Eshell V5.4.3 (abort with ^G) (disk@REDACTED)1> eflush:run(). 1 15.1836 ms 65.8606 129 15.3112 ms 65.3118 257 14.7000 ms 68.0272 385 15.1941 ms 65.8152 513 14.8843 ms 67.1850 641 15.3734 ms 65.0474 769 15.4631 ms 64.6702 897 15.1325 ms 66.0829 ... -module(eflush). -export([run/0, run/1, pingtest/1]). -export([ping/0, callout/1]). -export([run_kernel/3, close/1]). run() -> lists:map( fun(Length) -> run(Length) % end, lists:seq(0, 65536*3, 64)), % end, lists:seq(130000, 150000, 64)), end, lists:seq(1,8196,128)), ok. run(Length) -> Duration = 10, % number of test runs N = 50, % number of times write+flush is averaged over L = lists:duplicate(Length, 65), % write Length bytes B = list_to_binary(L), R = lists:map( fun(I) -> {ok, H} = file:open("test", [raw, write, binary]), {T1, ok} = timer:tc(?MODULE, run_kernel, [H, N, {B}]), close(H), {I, T1/(N*1000)} end, lists:seq(1, Duration)), RF = lists:map(fun({_, X}) -> X end, R), AvgF = lists:sum(RF)/length(RF), io:format("~p ~p ms ~p~n", [Length, AvgF, 1000/AvgF]), ok. close(H) -> file:close(H). run_kernel(H, N, Parameter) -> iteration(H, Parameter, N). iteration(_, _, 0) -> ok; iteration(H, {Binary} = Parameter, N) -> file:write(H, Binary), file:sync(H), iteration(H, Parameter, N-1). pingtest(Node) -> R = lists:map( fun(I) -> {D, ok} = timer:tc(?MODULE, callout, [Node]), io:format("~p ~p ms~n", [I, D/1000]), {I, D/1000} end, lists:seq(1, 99999)). callout(Node) -> rpc:call(Node, ?MODULE, ping, []). ping() -> ok. From kramer@REDACTED Wed Aug 17 01:25:46 2005 From: kramer@REDACTED (Reto Kramer) Date: Tue, 16 Aug 2005 16:25:46 -0700 Subject: disk IO kills network IO, +A doesn't work as I hoped In-Reply-To: <0C017C4C-2051-4BA1-BAC8-D506FBAFCCF6@acm.org> References: <0C017C4C-2051-4BA1-BAC8-D506FBAFCCF6@acm.org> Message-ID: <0AC00600-7724-4731-A202-3D0E810776CB@acm.org> And there's 2 typos of course ;-) The ping roundtrip times to the "disk node" increase (not drop) by a factor of 100 when disk IO kicks in. The command on the telco04 node (the one that pings the disk node) is: eflush:pingtest(disk@REDACTED). - Reto On Aug 16, 2005, at 4:21 PM, Reto Kramer wrote: > I'm seeking advice from experts on the +A erl flag and the IO > thread architecture. The issue I'm finding is that a blocking disk > operation (fsync in my case) results in a network IO degradation of > 2 orders of magnitude despite me using multiple IO threads. > > My architecture contains a node per CPU that does nothing but > handle a transaction log, trying to write to it and making sure the > data is sync'd to disk. There's an erlang process in that node that > will fsync the log file descriptor to disk and gather more log data > from other processes on other nodes while the fsync is pending. > Once the fsync is complete, the batch of log data was received > while sync'ing will be sync'd next while a new data batch is > accumulated. > > There's lots of tricks that one can play to work around the sync > time etc., but ultimately that time is in the order of > milliseconds. That means that there's a number of erlang log- > messages I can send to the log node while the log node is sync'ing > to disk. > > My little experiment between two distinct Linux hosts shows that > erlang ping roundtrip times (no payload to serialize) drop by a > factor of 100 once the receiving log node starts to do the disk IO > (the write/fsync, write/fsync, ...). The disk IO data size is > varied between 1 byte and a few kilobytes, and since I currently > don't do any of the tricks alluded to above, an fsync requires in > the order of 15ms on the HW I'm using. Plenty of time to receive > and process erlang messages sent from other nodes, I had hoped. > > This is so despite me using the +A flag (I've tried 2 to 10 > threads, assuming that 2 would be logical, i.e. 1 for disk and 1 > for network IO). > > Is this explicable by the thread architecture involved in IO? Why > does using 3 threads (in the example below) not allow the VM to > sustain the ping times (roughly)? I'm very puzzled about this > since the writes are very small, and the fsync is really not using > up any CPU time, or erlang reductions to speak of, i.e. there > should be VM reduction cycles to process the network calls. > > Below is the src and the command lines and erlang commands to > reproduce the issue should you have 2 boxes available (2 boxes to > make sure we're not fooled by context switching between the 2 VMs > involved). > > Any workarounds someone can suggest? Have you seen similar issues > in the past? > > Thanks, > - Reto > > > reto@REDACTED 9% erl -pa . -sname probe > Erlang (BEAM) emulator version 5.4.3 [source] [hipe] > > Eshell V5.4.3 (abort with ^G) > (probe@REDACTED)1> eflush:pingtest(probe@REDACTED). > > ... > 8042 0.141000 ms <--- simple ping rpc round trip time, fast network! > 8043 0.144000 ms > 8044 0.144000 ms > 8045 0.151000 ms > 8046 0.144000 ms > 8047 0.144000 ms > 8048 0.142000 ms > 8049 17.6220 ms <--- node telco02 started to write to disk, ping > times increase by *100 > 8050 2.49300 ms > 8051 239.361 ms > 8052 234.661 ms > 8053 167.171 ms > 8054 111.985 ms > 8055 411.450 ms > 8056 285.551 ms > 8057 278.745 ms > 8058 315.564 ms > 8059 278.830 ms > 8060 309.407 ms > 8061 248.964 ms > ... > > > telco02$ erl +A3 -sname disk > Erlang (BEAM) emulator version 5.4.3 [source] [hipe] > > Eshell V5.4.3 (abort with ^G) > (disk@REDACTED)1> eflush:run(). > > 1 15.1836 ms 65.8606 > 129 15.3112 ms 65.3118 > 257 14.7000 ms 68.0272 > 385 15.1941 ms 65.8152 > 513 14.8843 ms 67.1850 > 641 15.3734 ms 65.0474 > 769 15.4631 ms 64.6702 > 897 15.1325 ms 66.0829 > ... > > > > > -module(eflush). > > -export([run/0, run/1, pingtest/1]). > > -export([ping/0, callout/1]). > -export([run_kernel/3, close/1]). > > run() -> > lists:map( > fun(Length) -> > run(Length) > % end, lists:seq(0, 65536*3, 64)), > % end, lists:seq(130000, 150000, 64)), > end, lists:seq(1,8196,128)), > ok. > > run(Length) -> > Duration = 10, % number of test runs > N = 50, % number of times write+flush is averaged over > > L = lists:duplicate(Length, 65), % write Length bytes > B = list_to_binary(L), > R = lists:map( > fun(I) -> > {ok, H} = file:open("test", [raw, write, binary]), > {T1, ok} = timer:tc(?MODULE, run_kernel, [H, N, {B}]), > close(H), > {I, T1/(N*1000)} > end, lists:seq(1, Duration)), > RF = lists:map(fun({_, X}) -> X end, R), > AvgF = lists:sum(RF)/length(RF), > io:format("~p ~p ms ~p~n", [Length, AvgF, 1000/AvgF]), > ok. > > close(H) -> > file:close(H). > > run_kernel(H, N, Parameter) -> > iteration(H, Parameter, N). > > iteration(_, _, 0) -> > ok; > iteration(H, {Binary} = Parameter, N) -> > file:write(H, Binary), > file:sync(H), > iteration(H, Parameter, N-1). > > pingtest(Node) -> > R = lists:map( > fun(I) -> > {D, ok} = timer:tc(?MODULE, callout, [Node]), > io:format("~p ~p ms~n", [I, D/1000]), > {I, D/1000} > end, lists:seq(1, 99999)). > > callout(Node) -> > rpc:call(Node, ?MODULE, ping, []). > > ping() -> > ok. > > From vances@REDACTED Wed Aug 17 03:00:34 2005 From: vances@REDACTED (Vance Shipley) Date: Tue, 16 Aug 2005 21:00:34 -0400 Subject: disk IO kills network IO, +A doesn't work as I hoped In-Reply-To: <0AC00600-7724-4731-A202-3D0E810776CB@acm.org> References: <0C017C4C-2051-4BA1-BAC8-D506FBAFCCF6@acm.org> <0AC00600-7724-4731-A202-3D0E810776CB@acm.org> Message-ID: <20050817010034.GZ42667@feeble.motivity.ca> On Tue, Aug 16, 2005 at 04:25:46PM -0700, Reto Kramer wrote: } } >telco02$ erl +A3 -sname disk } >Erlang (BEAM) emulator version 5.4.3 [source] [hipe] If you really had threads you should see: Erlang (BEAM) emulator version 5.4.8 [source] [threads:3] -Vance From kramer@REDACTED Wed Aug 17 06:14:25 2005 From: kramer@REDACTED (Reto Kramer) Date: Tue, 16 Aug 2005 21:14:25 -0700 Subject: disk IO kills network IO, +A doesn't work as I hoped In-Reply-To: <20050817010034.GZ42667@feeble.motivity.ca> References: <0C017C4C-2051-4BA1-BAC8-D506FBAFCCF6@acm.org> <0AC00600-7724-4731-A202-3D0E810776CB@acm.org> <20050817010034.GZ42667@feeble.motivity.ca> Message-ID: <40EAB67E-7050-4750-B750-E63A36755555@acm.org> Cool! Enabling the threading during the build did the trick and made +A effective. Perhaps the OTP team could add a warning to erl in the future, should a weeny like me use the +A switch on a binary that wasn't compiled to support threading :-) Thanks, - Reto On Aug 16, 2005, at 6:00 PM, Vance Shipley wrote: > On Tue, Aug 16, 2005 at 04:25:46PM -0700, Reto Kramer wrote: > } > } >telco02$ erl +A3 -sname disk > } >Erlang (BEAM) emulator version 5.4.3 [source] [hipe] > > > If you really had threads you should see: > > Erlang (BEAM) emulator version 5.4.8 [source] [threads:3] > > > -Vance > > From bjorn@REDACTED Wed Aug 17 09:09:43 2005 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 17 Aug 2005 09:09:43 +0200 Subject: Replacing the werl.exe GUI, take 2 In-Reply-To: References: Message-ID: At least historically, sockets have been faster than pipes on Windows. So that's what we use for communication with port programs (if performance is important). I don't know whether pipe performance has improved on Windows in recent versions. /Bj?rn "Vlad Dumitrescu" writes: > ----- Original Message ----- > From: "James Hague" > > Logically, this should be easy: write my own application that starts > > up werl.exe in the background, with the GUI disabled, communicating > > via pipes. Standard UNIX-fare. Except if it were really this easy to > > do under Windows, I'd expect the Erlang team would have already done > > this. So what's the catch? > > I wrote an application like this, for some years ago. From what I > remember, there was a small but noticeable delay when communicating > with the Erlang process. Pipes in Windows are a little sluggish (or > were, don't know about XP or similar). > > With todays faster machines, there's probably no catch. Possibly still > slower than communicating with beam.dll directly, but my guess is that > it would be good enough. > > I didn't go on with it because I seldom use werl anyway, so other > projects felt more important. > > best regards, > Vlad -- Bj?rn Gustavsson, Erlang/OTP, Ericsson AB From bjorn@REDACTED Wed Aug 17 09:06:22 2005 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 17 Aug 2005 09:06:22 +0200 Subject: Replacing the werl.exe GUI, take 2 In-Reply-To: References: Message-ID: It might be easy. We haven't tried. It would be NICE to have a better GUI, but have always had many other more urgent things to do. /Bjorn James Hague writes: > > Logically, this should be easy: write my own application that starts > up werl.exe in the background, with the GUI disabled, communicating > via pipes. Standard UNIX-fare. Except if it were really this easy to > do under Windows, I'd expect the Erlang team would have already done > this. So what's the catch? > -- Bj?rn Gustavsson, Erlang/OTP, Ericsson AB From bjorn@REDACTED Wed Aug 17 09:13:49 2005 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 17 Aug 2005 09:13:49 +0200 Subject: disk IO kills network IO, +A doesn't work as I hoped In-Reply-To: <40EAB67E-7050-4750-B750-E63A36755555@acm.org> References: <0C017C4C-2051-4BA1-BAC8-D506FBAFCCF6@acm.org> <0AC00600-7724-4731-A202-3D0E810776CB@acm.org> <20050817010034.GZ42667@feeble.motivity.ca> <40EAB67E-7050-4750-B750-E63A36755555@acm.org> Message-ID: I don't know the optimal number of threads, but it should definitely be more than 3. Maybe 30 or 40. /Bjorn Reto Kramer writes: > Cool! Enabling the threading during the build did the trick and made > +A effective. > > Perhaps the OTP team could add a warning to erl in the future, should > a weeny like me use the +A switch on a binary that wasn't compiled to > support threading :-) > > Thanks, > - Reto > > On Aug 16, 2005, at 6:00 PM, Vance Shipley wrote: > > > On Tue, Aug 16, 2005 at 04:25:46PM -0700, Reto Kramer wrote: > > } > > } >telco02$ erl +A3 -sname disk > > } >Erlang (BEAM) emulator version 5.4.3 [source] [hipe] > > > > > > If you really had threads you should see: > > > > Erlang (BEAM) emulator version 5.4.8 [source] [threads:3] > > > > > > -Vance > > > > > -- Bj?rn Gustavsson, Erlang/OTP, Ericsson AB From bjorn@REDACTED Wed Aug 17 09:19:50 2005 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 17 Aug 2005 09:19:50 +0200 Subject: try ... after semantics In-Reply-To: <20050816161712.25348.qmail@web34415.mail.mud.yahoo.com> References: <20050816161712.25348.qmail@web34415.mail.mud.yahoo.com> Message-ID: Thomas Lindgren writes: > What is the semantics of try ... after? In particular, > what variable bindings are available in the after > body? Only variables introduced BEFORE the try construction. > > Q1: My guess is, one cannot rely on any bindings made > inside the try being available? (which is why the > example below, from the erlang reference manual, 6.19, > crashes if the file:open/2 does not return {ok,...}) > Correct. The compiler will not allow you to use any unsafe variables. > > termize_file(Name) -> > try file:open(Name, [read,binary]) of > {ok, F} -> > %% original code > try ... after ... end; > Else -> > Else > end. > > Q2: So, is there a better way of expressing the "safe" > termize_file using try? Not as far as I know. /Bj?rn -- Bj?rn Gustavsson, Erlang/OTP, Ericsson AB From joe.armstrong@REDACTED Wed Aug 17 11:45:16 2005 From: joe.armstrong@REDACTED (Joe Armstrong (AL/EAB)) Date: Wed, 17 Aug 2005 11:45:16 +0200 Subject: Towards a native windows GUI Message-ID: Some random thoughts on a windows GUI: About once every second year I get the same crazy thought - why not run Erlang on windows - I hack for a bit and then give up and go back to *nix So I started googeling and found some interesting stuff. I have often toyed with the idea of using the win32 api to do graphics and *not* use a library to hide the gory details - but how easy is this. Having made ex11 which has a raw X11 interface I thought that it might be nice to look at the Win32 api. This is what I have learnt so far. (Actually I may be wrong here - so I'd be grateful if a real windows expert could fill me in on the details, and correct my mistakes) I started by reading http://www.winprog.org/tutorial/ This was very interesting - what I learnt was: A win32 applications is made up from windows. Inside a window you can place several "controls" - a control is something like a button, a listbox, and editor, ... Controls *are* windows. You manipulate controls by sending them *messages* There are two primitives that send Messages PostMessage and SendMessage PostMessage is asynchronous - SendMessage is like a remote procedure call. It appears that a very large number of the routines in the winapi merely are wrappers to SendMessage and PostMessage. Thus interfacing Erlang to the windapi "merely" involves interfacing SendMessage and PostMessage and a few small routines like CreateWindowEx. << I think you could get a lot of mileage from just interfacing CreateWindowEx, SendMessage and PostMessage - but this might be incorrect << can a real windows expert comment on this>> >> Next problem - where are the arguments to PostMessage and SendMessage documented? Not in the APIs and you can't read the source - BUT - I did find the following http://www.autohotkey.com/ Has a free program that actually makes windows useful - this stuff is *amazing* I didn't realise you can automate any windows operation - this is very cool. There's lots of documentaion on the arguments to the messages on this site. Then I found polyML http://www.polyml.org/docs/Windows.html In particular http://www.polyml.org/docs/Winref/Message.html#PostMessage The polyml distribution has all the answers Writing a native window app in polyML is "easy" (TM) See http://www.polyml.org/docs/mlEdit.html Reproducing this in Erlang seems not unreasonable. Then I thought to myself "can I write postMessage, sendMessage etc. as BIFs" this requires compiling Erlang on windows :-( I tried mingw - no success so I read the read me on "compiling for windows" - double yuck. So I thought "how do I write a port program for windows" - and we're back to "interfacing Erlang to C" - triple yuck. Now all the methods for interfacing Erlang to C suck greatly. Why can't you just make a generic metacall from erlang to C - is this possible? - answer "possibly" Then I found http://www.haible.de/bruno/documentation/ffcall/avcall/avcall.html Avcall is part of the ffcall package - now this looks hopeful and does compile under mingw. So now the plan is this: Use avcall to write a generic interface to the win32api Implement PostMessage SendMessage and CreatWindowEx using the generic interface write a simple windows app with the above, then recode the polyML stuff in Erlang. This is leading me into unexplored terratories - since I know *nothing* about the problems of compiling C apps on windows - I'd like to end up with rock solid native compiled winapi applications - I really like some feedback here from a real windows expert - are my statements about windows correct, is the API as simple as it appears to be? The really interesting observation is that the underlying windows GUI architecture is a pure message passing system - (Like X) - which should mean that it will interface well with the Erlang process model (like the X11 ex11 code did). Is this observation correct? /Joe From vlad.xx.dumitrescu@REDACTED Wed Aug 17 12:48:54 2005 From: vlad.xx.dumitrescu@REDACTED (Vlad Dumitrescu XX (LN/EAB)) Date: Wed, 17 Aug 2005 12:48:54 +0200 Subject: Towards a native windows GUI Message-ID: <11498CB7D3FCB54897058DE63BE3897C4BE5D4@esealmw105.eemea.ericsson.se> Hi, > << I think you could get a lot of mileage from just > interfacing CreateWindowEx, SendMessage and PostMessage - but > this might be incorrect << can a real windows expert comment > on this>> >> Just some quick 2 cents' thoughts: * With the above you can indeed go quite far, but it's only half the story - you must also be able to receive the messages on the Erlang side. This is more tedious, but doable (possibly at the expense of less flexibility in defining new widgets). Creating window procedures that just pass the message to the Erlang side is no good, because even if the no action or the default action should be taken, there is still a round-trip to Erlang. Imagine having one of those every time a key is pressed or the mouse is moved... So there will have to be a way to register interest in only some events, but then there has to exist a sensible default handling on the C side - see below. * Also, not everything in a GUI is a window. For example, labels are handled by the parent window. The reason is that many windows are heavy on the system. * Third, programming Windows applications like in the old days, is not fun. It's very easy to miss some important messages, and that's why there are frameworks around this basic API. They can also transparently handle widgets that aren't really windows. And some frameworks are also not Windows-only. To sum it up, maybe it is better to not go all the way to the lowest level, but use some existing framework. wxWindows is being put to the test as we speak. If you are going to say "but frameworks are heavy and there's a huge API to control all kinds of things" I am going to answer "such a framework must be built in any case! Using the bare-bones mechanisms will only work for simple applications" ;-) best regards, Vlad For more about Windows messaging, refer to http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/messagesandmessagequeues/messagesandmessagequeuesreference/messagesandmessagequeuesfunctions/postmessage.asp (sorry about the long URL...) From Marc.Vanwoerkom@REDACTED Wed Aug 17 14:01:06 2005 From: Marc.Vanwoerkom@REDACTED (Marc van Woerkom) Date: Wed, 17 Aug 2005 14:01:06 +0200 Subject: Towards a native windows GUI In-Reply-To: Message-ID: > I have often toyed with the idea of using the win32 >api to do graphics and *not* >use a library to hide the gory details - but how easy is >this. You will find even tutorials on the net about Win32 GUI programming in assembler. > A win32 applications is made up from windows. Inside >a window you can place several >"controls" - a control is something like a button, a >listbox, and editor, ... Win32 GUI Programming (as well, as its cousin OS/2 Presentation Manager) is event based. A window has code to handle messages sent by the os and it communicates with other windows by sending/posting messages. Plus the executables can carry extra data, so called resources, like icons and strings... A very good book on Win32 GUI Programming (not that MFC C++ wrapper stuff) was by Charles Petzold. Microsoft's MSDN site carries information on Windows programming. Regards, Marc From serge@REDACTED Wed Aug 17 15:19:06 2005 From: serge@REDACTED (Serge Aleynikov) Date: Wed, 17 Aug 2005 09:19:06 -0400 Subject: Towards a native windows GUI In-Reply-To: References: Message-ID: <4303394A.3000705@hq.idt.net> Joe, I tend to agree with Vlad's points as far as not diving too deep in the WinAPI in order to have control of all aspects of GUI presentation. Looking years back there have been Windows API SDK and later Microsoft Foundation Classes (MFC) that were more than unpleasant to deal with - it took several pages of code to write a simple Windows application that would merely open a single window. Fortunately folks at Borland (around 1995) realized that and came up with Delphi with its component-based framework, which was quite a relief for a Windows programmer, where one could just write: Button.Caption := 'OK'; and the button object would magically redraw with the right caption. Soon VB, MS C++, Java, and later .NET followed the lead. Each component in these frameworks may or may not have a Window handle, and if it does it can receive and act on Windows messages. The GUI Windows applications consist of a message loop, that peeks a message from a message queue associated with the main application forms' window handle, and dispatches the message by going through all message handlers of each control (widget) owned by the form. The next question is if we want to interface Erlang emulator with the Windows GUI, do we want them to share the same message loop for event handling? Probably not - they serve different purposes and I would think the priority of the emulator's loop is higher than of the GUI. Then the two would be running in separate threads/processes with some standard API dealing with message passing. What tasks would we want to accomplish on the GUI side? To name a few: - Use some IDE to create the layout of the application. - Code handling of some GUI events. - Make calls to the emulator based on selected user actions. Does the emulator need to be in control of all of that? Likely not. What task would we want to accomplish on the Erlang's side? - React to messages related to user actions coming from GUI - Notify GUI of a result of some processing via message passing. - Implement a solution to some problem domain It would be too much of a constraint to require a programmer to use a specific IDE/language on the GUI side. Therefore some middleman API would have to be developed that would interface with Erlang, and be ported into multiple GUI frameworks in a form of a component. That component would allow to send/receive messages to/from Erlang node by assigning event handlers, be dropped on a form in design time (non-visible at run time), etc. This approach would also allow a programmer to take advantage of the variety of 3rd party GUI libraries with nice grids/controls/styles/etc to make applications more spicy. Thoughts? Serge Joe Armstrong (AL/EAB) wrote: > Some random thoughts on a windows GUI: > > About once every second year I get the same crazy thought - why not run > Erlang on windows - I hack for a bit and then give up and go back to *nix > > So I started googeling and found some interesting stuff. > > I have often toyed with the idea of using the win32 api to do graphics and *not* > use a library to hide the gory details - but how easy is this. Having made ex11 > which has a raw X11 interface I thought that it might be nice to look at the > Win32 api. > > This is what I have learnt so far. (Actually I may be wrong here - so I'd be grateful if a real windows expert could fill me in on the details, and correct my mistakes) > > I started by reading http://www.winprog.org/tutorial/ > > This was very interesting - what I learnt was: > > A win32 applications is made up from windows. Inside a window you can place several > "controls" - a control is something like a button, a listbox, and editor, ... > > Controls *are* windows. > > You manipulate controls by sending them *messages* > > There are two primitives that send Messages > > PostMessage and SendMessage > > PostMessage is asynchronous - SendMessage is like a remote procedure call. > > It appears that a very large number of the routines in the winapi merely are wrappers > to SendMessage and PostMessage. > > Thus interfacing Erlang to the windapi "merely" involves interfacing SendMessage > and PostMessage and a few small routines like CreateWindowEx. > > << I think you could get a lot of mileage from just interfacing CreateWindowEx, SendMessage and PostMessage - but this might be incorrect << can a real windows expert comment on this>> >> > > Next problem - where are the arguments to PostMessage and SendMessage documented? > > Not in the APIs and you can't read the source - BUT - I did find the following > > http://www.autohotkey.com/ > > Has a free program that actually makes windows useful - this stuff is *amazing* > I didn't realise you can automate any windows operation - this is very cool. There's > lots of documentaion on the arguments to the messages on this site. > > Then I found polyML > > http://www.polyml.org/docs/Windows.html > > > In particular > > http://www.polyml.org/docs/Winref/Message.html#PostMessage > > > The polyml distribution has all the answers > > Writing a native window app in polyML is "easy" (TM) > > See > > http://www.polyml.org/docs/mlEdit.html > > > Reproducing this in Erlang seems not unreasonable. > > > Then I thought to myself "can I write postMessage, sendMessage etc. as BIFs" > this requires compiling Erlang on windows :-( > > I tried mingw - no success so I read the read me on "compiling for windows" - > double yuck. > > So I thought "how do I write a port program for windows" - and we're back to > "interfacing Erlang to C" - triple yuck. > > Now all the methods for interfacing Erlang to C suck greatly. Why can't you just > make a generic metacall from erlang to C - is this possible? - answer "possibly" > > Then I found > > http://www.haible.de/bruno/documentation/ffcall/avcall/avcall.html > > Avcall is part of the ffcall package - now this looks hopeful and does compile > under mingw. > > So now the plan is this: > > Use avcall to write a generic interface to the win32api > > Implement PostMessage SendMessage and CreatWindowEx using the generic interface > write a simple windows app with the above, then recode the polyML stuff in Erlang. > > This is leading me into unexplored terratories - since I know *nothing* > about the problems of compiling C apps on windows - I'd like to end up with > rock solid native compiled winapi applications - > > I really like some feedback here from a real windows expert - are my statements > about windows correct, is the API as simple as it appears to be? > > The really interesting observation is that the underlying windows GUI architecture is > a pure message passing system - (Like X) - which should mean that it will interface > well with the Erlang process model (like the X11 ex11 code did). > > Is this observation correct? > > /Joe > From klacke@REDACTED Wed Aug 17 15:23:26 2005 From: klacke@REDACTED (Claes Wikstrom) Date: Wed, 17 Aug 2005 15:23:26 +0200 Subject: yaws-1.57 Message-ID: <43033A4E.3010405@hyber.org> New release of yaws called 1.57. Code and relnotes as usual at http://yaws.hyber.org /klacke From david.nospam.hopwood@REDACTED Wed Aug 17 15:37:09 2005 From: david.nospam.hopwood@REDACTED (David Hopwood) Date: Wed, 17 Aug 2005 14:37:09 +0100 Subject: Towards a native windows GUI In-Reply-To: References: Message-ID: <43033D85.5040202@blueyonder.co.uk> Joe Armstrong (AL/EAB) wrote: [...] > The really interesting observation is that the underlying windows GUI architecture is > a pure message passing system - (Like X) - which should mean that it will interface > well with the Erlang process model (like the X11 ex11 code did). Win32 GDI is in no sense a pure message passing architecture. Yes, the communication between windows is message passing, but to do anything useful there are thousands of procedures that operate on particular kinds of handle or device context. All the messages *are* documented, BTW. However, they're scattered all over the docs, and the MSVC++ search facilities leave a little to be desired. You need to search *in titles only* for the various message type prefixes (e.g. "WM_*" for window messages). Also read 'User Interface Design and Development / Windows Management / Windows User Interface / Windowing / Messages and Message Queues' in the contents. And browsing 'Graphics and Multimedia / Windows GDI / SDK Documentation' may give you more of an idea how much of the API is procedural. [A tip on using the MSVC++ help: the 'Sync Contents' button (left-right arrow) that syncs the 'contents' tree with the current page is very useful.] -- David Hopwood From olivier.sambourg@REDACTED Wed Aug 17 16:04:24 2005 From: olivier.sambourg@REDACTED (Olivier Sambourg) Date: Wed, 17 Aug 2005 16:04:24 +0200 Subject: Erlang records / Jinterface Message-ID: Hi everyone, Forgive me if I'm wrong or if I'm reopening an old thread, but are there any news about a new (separate) record type (not tuple) ? I'm using records on my erlang app but they lose all their advantages over tuples once they are transmitted to a java client, using Jinterface : I have to know the underlying tuple format to access the data, and map it to a java object. I was thinking a new record format would greatly ease the erlang / java (or any other language) mapping pain . Thanks for the info if any -- Olivier -------------- next part -------------- An HTML attachment was scrubbed... URL: From mats.cronqvist@REDACTED Wed Aug 17 16:05:51 2005 From: mats.cronqvist@REDACTED (Mats Cronqvist) Date: Wed, 17 Aug 2005 16:05:51 +0200 Subject: yet another gui framework for Erlang In-Reply-To: <43033A4E.3010405@hyber.org> References: <43033A4E.3010405@hyber.org> Message-ID: <4303443F.8010000@ericsson.com> as usual, there's much talk about GUI stuff for Erlang. here's my attempt to add to the confusion. i've found that it is difficult to get people to use non-GUI tools, no matter how good they might be. also, it is immensely boring and time-consuming to create GUIs in code (not to mention creating your own widgets). i tried all the Erlang GUI frameworks i could find, and the one i liked the best was erlgtk. chiefly because one could use glade, GTK's eminent GUI builder tool. also, GTK looks good and is well documented. however, erlgtk is no longer maintained. so maybe i could write my own with reasonable effort. i wanted these features; * GUI separated from application by message passing * distributed (application and GUI can run on different machines) * centered around a GUI builder * small volume of (hand-written) code * pre-documented the result, gtkNode, is a c-node that expects messages in the form; [{F,Args}..] where F is the name of a C function, and Args is an argument list. (the point of making this a list is to allow for bulking of messages). if there is a function F linked inte the c-node, it will be called with a pointer to Args. F must unpack Args (which is in the external format) and verify the number and types of the arguments. after finishing, F writes a return value in the external format to the return message from the c-node. the marshalling and type-checking is done by calls to library functions using ei (Erlangs external interface library) and GLib (a general-purpose libarary used be e.g. GTK). the return message looks like this; {{GtkPid,reply},[{ok|error,Value}...]}. the c-node can also send signals; {{GtkPid,signal},Signal} the point of all this is that was quite simple to auto-generate wrapper functions for most GTK functions (from the header files). it was also simple to get the c-node to instantite a GUI from a glade file. so one can design the interface i glade; ione can easily create a very complicated one in a few hours. all the widgets are named, the names are available on the Erlang side as atoms. one also specifies which events should result in signals. after the c-node is started and the glade file is loaded, it's just a matter of writing an Erlang program that receives signals and send actions. for example, if the user selects a menu item named 'connect', the Erlang program receives this; {{GtkPid,signal},{connect,'GDK_BUTTON_RELEASE'}} if the Erlang program wants to grey out that menu item, it sends this; [{'Gtk_widget_set_sensitive',[connect,false]}] code should be available from jungerl as of today (although it hasn't appeared in the CVS web interface yet). mats From joe.armstrong@REDACTED Wed Aug 17 16:08:19 2005 From: joe.armstrong@REDACTED (Joe Armstrong (AL/EAB)) Date: Wed, 17 Aug 2005 16:08:19 +0200 Subject: Towards a native windows GUI Message-ID: Hi Serge, To answer your comments: To start with I get the same feeling looking at the windows API as I got when looking at XLib and the X11 protocol - on the surface the XLib programming model and the windows model look very complicated - but deep down they get much simpler. A GUI is best modelled as lots of small parallel processes where each control (button, toggle, entry, ...) is a parallel process. To get it to do something you sent it a message (PostMessage) to query it (example, reading an entry) you send it a message and wait for the reply (SendMessage). Now Erlang is very good at managing lots of small processes, where each process does very little (that's what it was designed to do). Programming a GUI as a collection of parallel processes is very easy. But programming a GUI as a single sequential process is very difficult. That's the reason for XLib, Motif and Win32 MFC etc. To make this difficult process easier. The Delphi statement > Button.Caption := 'OK'; Probably just boils down to a few PostMessages calls. I also see no reason why this should not be handled by the Erlang emulator. As I see things - writing new BIFs is easy, but - writing port programs is messy So to include foreign language code we should think in terms of running several Erlang nodes on the same machine. One node (the safe) node should be "unpatched" the other nodes can have user-added BIFs (these are unsafe). The safe node can then request operations in the unsafe nodes with distributed Erlang RPCs. As for Vlad's concern about the efficiency of dispatching all messages in the Erlang top-loop, this might be a problem, until an experiment is performed I don't know. In the X11 case handling all X11 protocol messages in Erlang was not markedly slower than in C - often faster. My view is that if what's at the bottom is simple (ie GUIs work by sending messages to controls) and Erlang is designed for just that, then removing all the middleware might be the way to go. << aside - It's not that I dislike GTK+, Pango, gnome canvas, SDL, Cairo, Motif whatever, but getting these things to work together is a pain. I actually want to use these libraries and not fight with them. Most often building them at all is painfully difficult. >> /Joe > -----Original Message----- > From: Serge Aleynikov [mailto:serge@REDACTED] > Sent: den 17 augusti 2005 15:19 > To: Joe Armstrong (AL/EAB) > Cc: erlang-questions@REDACTED > Subject: Re: Towards a native windows GUI > > > Joe, > > I tend to agree with Vlad's points as far as not diving too > deep in the > WinAPI in order to have control of all aspects of GUI presentation. > Looking years back there have been Windows API SDK and later > Microsoft > Foundation Classes (MFC) that were more than unpleasant to > deal with - > it took several pages of code to write a simple Windows > application that > would merely open a single window. > > Fortunately folks at Borland (around 1995) realized that and came up > with Delphi with its component-based framework, which was > quite a relief > for a Windows programmer, where one could just write: > > Button.Caption := 'OK'; > > and the button object would magically redraw with the right caption. > Soon VB, MS C++, Java, and later .NET followed the lead. > > Each component in these frameworks may or may not have a > Window handle, > and if it does it can receive and act on Windows messages. The GUI > Windows applications consist of a message loop, that peeks a message > from a message queue associated with the main application > forms' window > handle, and dispatches the message by going through all > message handlers > of each control (widget) owned by the form. > > The next question is if we want to interface Erlang emulator with the > Windows GUI, do we want them to share the same message loop for event > handling? Probably not - they serve different purposes and I would > think the priority of the emulator's loop is higher than of the GUI. > Then the two would be running in separate threads/processes with some > standard API dealing with message passing. > > What tasks would we want to accomplish on the GUI side? To > name a few: > > - Use some IDE to create the layout of the application. > - Code handling of some GUI events. > - Make calls to the emulator based on selected user actions. > > Does the emulator need to be in control of all of that? Likely not. > > What task would we want to accomplish on the Erlang's side? > > - React to messages related to user actions coming from GUI > - Notify GUI of a result of some processing via message passing. > - Implement a solution to some problem domain > > It would be too much of a constraint to require a programmer to use a > specific IDE/language on the GUI side. Therefore some middleman API > would have to be developed that would interface with Erlang, and be > ported into multiple GUI frameworks in a form of a component. That > component would allow to send/receive messages to/from Erlang node by > assigning event handlers, be dropped on a form in design time > (non-visible at run time), etc. This approach would also allow a > programmer to take advantage of the variety of 3rd party GUI > libraries > with nice grids/controls/styles/etc to make applications more spicy. > > Thoughts? > > Serge > > > Joe Armstrong (AL/EAB) wrote: > > Some random thoughts on a windows GUI: > > > > About once every second year I get the same crazy > thought - why not run > > Erlang on windows - I hack for a bit and then give up and > go back to *nix > > > > So I started googeling and found some interesting stuff. > > > > I have often toyed with the idea of using the win32 api > to do graphics and *not* > > use a library to hide the gory details - but how easy is > this. Having made ex11 > > which has a raw X11 interface I thought that it might be > nice to look at the > > Win32 api. > > > > This is what I have learnt so far. (Actually I may be > wrong here - so I'd be grateful if a real windows expert > could fill me in on the details, and correct my mistakes) > > > > I started by reading http://www.winprog.org/tutorial/ > > > > This was very interesting - what I learnt was: > > > > A win32 applications is made up from windows. Inside a > window you can place several > > "controls" - a control is something like a button, a > listbox, and editor, ... > > > > Controls *are* windows. > > > > You manipulate controls by sending them *messages* > > > > There are two primitives that send Messages > > > > PostMessage and SendMessage > > > > PostMessage is asynchronous - SendMessage is like a > remote procedure call. > > > > It appears that a very large number of the routines in > the winapi merely are wrappers > > to SendMessage and PostMessage. > > > > Thus interfacing Erlang to the windapi "merely" involves > interfacing SendMessage > > and PostMessage and a few small routines like CreateWindowEx. > > > > << I think you could get a lot of mileage from just > interfacing CreateWindowEx, SendMessage and PostMessage - but > this might be incorrect << can a real windows expert comment > on this>> >> > > > > Next problem - where are the arguments to PostMessage > and SendMessage documented? > > > > Not in the APIs and you can't read the source - BUT - I > did find the following > > > > http://www.autohotkey.com/ > > > > Has a free program that actually makes windows useful - > this stuff is *amazing* > > I didn't realise you can automate any windows operation - > this is very cool. There's > > lots of documentaion on the arguments to the messages on this site. > > > > Then I found polyML > > > > http://www.polyml.org/docs/Windows.html > > > > > > In particular > > > > http://www.polyml.org/docs/Winref/Message.html#PostMessage > > > > > > The polyml distribution has all the answers > > > > Writing a native window app in polyML is "easy" (TM) > > > > See > > > > http://www.polyml.org/docs/mlEdit.html > > > > > > Reproducing this in Erlang seems not unreasonable. > > > > > > Then I thought to myself "can I write postMessage, > sendMessage etc. as BIFs" > > this requires compiling Erlang on windows :-( > > > > I tried mingw - no success so I read the read me on > "compiling for windows" - > > double yuck. > > > > So I thought "how do I write a port program for > windows" - and we're back to > > "interfacing Erlang to C" - triple yuck. > > > > Now all the methods for interfacing Erlang to C suck > greatly. Why can't you just > > make a generic metacall from erlang to C - is this > possible? - answer "possibly" > > > > Then I found > > > > > http://www.haible.de/bruno/documentation/ffcall/avcall/avcall.html > > > > Avcall is part of the ffcall package - now this looks > hopeful and does compile > > under mingw. > > > > So now the plan is this: > > > > Use avcall to write a generic interface to the win32api > > > > Implement PostMessage SendMessage and CreatWindowEx > using the generic interface > > write a simple windows app with the above, then recode the > polyML stuff in Erlang. > > > > This is leading me into unexplored terratories - > since I know *nothing* > > about the problems of compiling C apps on windows - I'd > like to end up with > > rock solid native compiled winapi applications - > > > > I really like some feedback here from a real windows > expert - are my statements > > about windows correct, is the API as simple as it appears to be? > > > > The really interesting observation is that the > underlying windows GUI architecture is > > a pure message passing system - (Like X) - which should > mean that it will interface > > well with the Erlang process model (like the X11 ex11 code did). > > > > Is this observation correct? > > > > /Joe > > > > From serge@REDACTED Wed Aug 17 16:56:30 2005 From: serge@REDACTED (Serge Aleynikov) Date: Wed, 17 Aug 2005 10:56:30 -0400 Subject: Towards a native windows GUI In-Reply-To: References: Message-ID: <4303501E.7080307@hq.idt.net> Hi Joe, Joe Armstrong (AL/EAB) wrote: > Programming a GUI as a collection of parallel processes is very easy. But programming > a GUI as a single sequential process is very difficult. As much as we all like concurrent functional programming, I think it would be unfair to reject the merit of the modern Windows OO-based IDE tools (like Visual Studio .NET, Borland JBuilder, Borland Delphi, MONO IDE /that supports multiple platforms/, etc). Even though they are based on a single process model, they streamline GUI development quite a bit, and given the fact that they are backed up by the key software monsters, the GUI programming community is quite used to these tools, and is very productive. Writing GUI in Erlang would also require to have some kind of IDE (likely also written in Erlang) that would automate creation of GUI layouts and interactions with widgets. Without such an IDE GUI programming would be very tidious and time consuming. From the academic point of view modeling GUI as parallel processes is definitely a very interesting excersize, but if that turns out a viable solution, would the open-source community build an IDE for it, and be willing to evolve and support such product (which I imagine would not be very simple)? Would it make Erlang any more popular if it had a GUI support and IDE? Serge From ulf@REDACTED Thu Aug 18 00:23:10 2005 From: ulf@REDACTED (ulf@REDACTED) Date: Wed, 17 Aug 2005 15:23:10 -0700 (PDT) Subject: configure script in jungerl Message-ID: <32827.85.224.131.27.1124317390.squirrel@webmail.wiger.net> When trying to build the jungerl code on my Libranet (Debian) distro, I encountered some autoheader errors. After some reading and hacking around, I made it work by changing all AC_DEFINEs to an alternative syntax. This made autoheader stop complaining about missing templates. For example, in config/aclocal.m4: AC_DEFINE(HAVE_MSGHDR_MSG_CONTROL) was changed to: AC_DEFINE([HAVE_MSGHDR_MSG_CONTROL], [], [Description]) and ditto for all AC_DEFINE(...) and AC_DEFINE_UNQUOTED(...) in configure.in. I don't feel comfortable enough mucking around in this stuff to commit my changes to sourceforge. Perhaps someone else can judge whether this is something that should be done? Also, should it really be [Description] literally, or should something descriptive be written in there instead? /Uffe From ulf@REDACTED Thu Aug 18 00:56:03 2005 From: ulf@REDACTED (ulf@REDACTED) Date: Wed, 17 Aug 2005 15:56:03 -0700 (PDT) Subject: building gtkNode Message-ID: <32852.85.224.131.27.1124319363.squirrel@webmail.wiger.net> I tried making the gtkNode contrib, but ran into problems. The system is a Debian (Libranet). Below is some output. uffe@REDACTED:~/dev/jungerl/lib/gtkNode$ pkg-config --cflags libglade-2.0 -I/usr/include/libglade-2.0 -I/usr/include/gtk-2.0 -I/usr/include/libxml2 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/pango-1.0 -I/usr/include/freetype2 -I/usr/X11R6/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include uffe@REDACTED:~/dev/jungerl/lib/gtkNode$ echo $OTP_ROOT /usr/local (which I don't think is "sane", to quote the README, but I set it like that instead of changing Makefile) make[1]: Entering directory `/home/uffe/dev/jungerl/lib/gtkNode/src' gcc -g -c -o ../priv/obj/gtkNode_gen.o gtkNode_gen.c -I../include -I../priv/gen -I/usr/local/lib/erlang/lib/erl_interface-3.5.4/include `pkg-config --cflags libglade-2.0` In file included from gtkNode_gen.c:2: ../priv/gen/gtk_generated.h: In function `Gtk_accelerator_get_label': ../priv/gen/gtk_generated.h:260: warning: assignment makes pointer from integer without a cast ../priv/gen/gtk_generated.h: In function `Gtk_action_activate': ../priv/gen/gtk_generated.h:306: `GtkAction' undeclared (first use in this function) ../priv/gen/gtk_generated.h:306: (Each undeclared identifier is reported only once ../priv/gen/gtk_generated.h:306: for each function it appears in.) ../priv/gen/gtk_generated.h:306: `object' undeclared (first use in this function) ../priv/gen/gtk_generated.h:311: `GTK_TYPE_ACTION' undeclared (first use in this function) Any ideas? /Uffe From orbitz@REDACTED Thu Aug 18 04:35:23 2005 From: orbitz@REDACTED (orbitz@REDACTED) Date: Wed, 17 Aug 2005 22:35:23 -0400 Subject: Towards a native windows GUI In-Reply-To: <4303501E.7080307@hq.idt.net> References: <4303501E.7080307@hq.idt.net> Message-ID: On Aug 17, 2005, at 10:56 AM, Serge Aleynikov wrote: > Writing GUI in Erlang would also require to have some kind of IDE > (likely also written in Erlang) that would automate creation of GUI > layouts and interactions with widgets. Without such an IDE GUI > programming would be very tidious and time consuming. > Are you referring to some thing like glade? If so, why is this required and why is it something that needs to be worried about for getting erlang up and running with win32 GUI support? It sounds like something that can be worried about and written later on in the design process. Not that you want to design GUI's by hand but certainly it isn't something we have to worry about now is it? Seems like too much emphasis is being put on a design environment at this stage. From vlad_dumitrescu@REDACTED Thu Aug 18 08:54:57 2005 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Thu, 18 Aug 2005 08:54:57 +0200 Subject: Towards a native windows GUI References: <4303501E.7080307@hq.idt.net> Message-ID: From: "Serge Aleynikov" > From the academic point of view modeling GUI as parallel processes is > definitely a very interesting excersize, I was about to write something like that too. Having a window manager completely written in Erlang would certainly be an interesting application. I did start working on one before, and also ex11 can be seen as one. The trouble is that one needs to replicate *lots* of effort that exists and is of high quality - defining widget behaviour and look-and-feel. gtkNode looks like a nice approach, since there's a clean and reasonably high-level border. regards, Vlad From mats.cronqvist@REDACTED Thu Aug 18 10:06:33 2005 From: mats.cronqvist@REDACTED (Mats Cronqvist) Date: Thu, 18 Aug 2005 10:06:33 +0200 Subject: building gtkNode In-Reply-To: <32852.85.224.131.27.1124319363.squirrel@webmail.wiger.net> References: <32852.85.224.131.27.1124319363.squirrel@webmail.wiger.net> Message-ID: <43044189.6030206@ericsson.com> i think the sane value of $OTP_ROOT on debian is /usr/local. is it not? what version of gtk do you have? pkg-config --modversion gtk+-2.0 2.6.8 mats ulf@REDACTED wrote: > I tried making the gtkNode contrib, but ran into problems. > The system is a Debian (Libranet). Below is some output. > > uffe@REDACTED:~/dev/jungerl/lib/gtkNode$ pkg-config --cflags libglade-2.0 > -I/usr/include/libglade-2.0 -I/usr/include/gtk-2.0 -I/usr/include/libxml2 > -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/pango-1.0 > -I/usr/include/freetype2 -I/usr/X11R6/include -I/usr/include/glib-2.0 > -I/usr/lib/glib-2.0/include > > uffe@REDACTED:~/dev/jungerl/lib/gtkNode$ echo $OTP_ROOT > /usr/local > > (which I don't think is "sane", to quote the README, but I set > it like that instead of changing Makefile) > > > make[1]: Entering directory `/home/uffe/dev/jungerl/lib/gtkNode/src' > gcc -g -c -o ../priv/obj/gtkNode_gen.o gtkNode_gen.c -I../include > -I../priv/gen -I/usr/local/lib/erlang/lib/erl_interface-3.5.4/include > `pkg-config --cflags libglade-2.0` > In file included from gtkNode_gen.c:2: > ../priv/gen/gtk_generated.h: In function `Gtk_accelerator_get_label': > ../priv/gen/gtk_generated.h:260: warning: assignment makes pointer from > integer without a cast > ../priv/gen/gtk_generated.h: In function `Gtk_action_activate': > ../priv/gen/gtk_generated.h:306: `GtkAction' undeclared (first use in this > function) > ../priv/gen/gtk_generated.h:306: (Each undeclared identifier is reported > only once > ../priv/gen/gtk_generated.h:306: for each function it appears in.) > ../priv/gen/gtk_generated.h:306: `object' undeclared (first use in this > function) > ../priv/gen/gtk_generated.h:311: `GTK_TYPE_ACTION' undeclared (first use > in this function) > > > Any ideas? > > /Uffe > From taavi@REDACTED Thu Aug 18 10:35:46 2005 From: taavi@REDACTED (Taavi Talvik) Date: Thu, 18 Aug 2005 11:35:46 +0300 Subject: building gtkNode In-Reply-To: <43044189.6030206@ericsson.com> References: <32852.85.224.131.27.1124319363.squirrel@webmail.wiger.net> <43044189.6030206@ericsson.com> Message-ID: <4a4e60db2cbd1a6aaa0b3fd7ceb492dc@uninet.ee> On Aug 18, 2005, at 11:06 AM, Mats Cronqvist wrote: > i think the sane value of $OTP_ROOT on debian is /usr/local. is it > not? > > what version of gtk do you have? > pkg-config --modversion gtk+-2.0 > 2.6.8 This is biggest stumbling block for gtk based applications. You usually have to match to specific version. And as end result - you have to distribute entire compiled gtk environment with your applications. Same problem as http://home.uninet.ee/~taavi/files/erlang/xgs/, which was "yet another unfinished gtk binding" (TM). best regards, taavi From mats.cronqvist@REDACTED Thu Aug 18 10:50:14 2005 From: mats.cronqvist@REDACTED (Mats Cronqvist) Date: Thu, 18 Aug 2005 10:50:14 +0200 Subject: building gtkNode In-Reply-To: <4a4e60db2cbd1a6aaa0b3fd7ceb492dc@uninet.ee> References: <32852.85.224.131.27.1124319363.squirrel@webmail.wiger.net> <43044189.6030206@ericsson.com> <4a4e60db2cbd1a6aaa0b3fd7ceb492dc@uninet.ee> Message-ID: <43044BC6.4090409@ericsson.com> Taavi Talvik wrote: > > On Aug 18, 2005, at 11:06 AM, Mats Cronqvist wrote: > >> i think the sane value of $OTP_ROOT on debian is /usr/local. is it not? >> >> what version of gtk do you have? >> pkg-config --modversion gtk+-2.0 >> 2.6.8 > > > This is biggest stumbling block for gtk based applications. You usually > have to match to specific version. And as end result - you have to > distribute > entire compiled gtk environment with your applications. well, i build the exact same gtkNode on solaris with a much older gtk... pkg-config --modversion gtk+-2.0 2.4.9 > Same problem as http://home.uninet.ee/~taavi/files/erlang/xgs/, which > was "yet another unfinished gtk binding" (TM). but gtkNode IS finished :> mats From joe.armstrong@REDACTED Thu Aug 18 10:58:35 2005 From: joe.armstrong@REDACTED (Joe Armstrong (AL/EAB)) Date: Thu, 18 Aug 2005 10:58:35 +0200 Subject: Towards a native windows GUI Message-ID: Hi Serge, Let me be clear, What I want to do is *simplify* GUI programming - reduce GUI programming to understanding a small number of well-defined primitives. I am well-aware that the Win32 GDI has a large number of procedures (or as David Hopwood say, "thousands") that do mysterious things. What I want to know is "is there a small sub-set of these procedures" that I can write a simple GUI with? The historical development of GUI programs seems to me to be like this: 1) There were no GUIs 2) Some very simple 2-D graphics API's emerged 3) Simple GUI's with window, mice, keyboard, etc emerged. 4) Complex libraries to make programming type 3 GUIs emerged 5) The libraries became so complicated that nobody could understand them an so IDE's and GUI designing programs were invented, that spat out code containing library calls for the complex libraries in 4) It seems to me that things went wrong at stage 4 - the very fact that you *need* a IDE/wizard/whatever to write the code for you seems the underlying structure is too complicated. There is a trade-off involved here: Suppose I have a very simple library, and programming language, say like this: Win = mkWin(X, Y, W, H), Button = Win !! {addButton, X1, Y1, W1, H1}, Button ! {addtext, "Press me"}, Button ! {onClick, fun() -> ... end}, Etc. (like my ex11 :-) - then you can learn the language quickly and produce ugly but functional GUIs very quickly, and I can build dynamic GUIS. With GUI builders - the learning curve is steeper, interfacing to Erlang is painful, and forget dynamic GUIS. The trade-off is "Easy to program = Ugly GUI" vs. "Difficult to program = Nice GUI". Suppose we (say) implement an Erlang interface to GTK (there seem to be at least 3 of these), then the following problems seem to occur: a) The interface library won't build in my environment (it worked fine on the developers machine but particular combination of shared libraries/OS etc. needed differs on my machine) b) I have to learnt the GTK programming model in order to write a GUI (and is that fun? - no) c) The result is non-portable (ie the target machine must have performed a) successfully) What I'd like to experiment with are simple libraries using only the X protocol or the Win32 API - where the programming language is pretty much as above. I realize that this will not make beautiful GUIS but they will be easy to program and portable. /Joe > -----Original Message----- > From: Serge Aleynikov [mailto:serge@REDACTED] > Sent: den 17 augusti 2005 16:57 > To: Joe Armstrong (AL/EAB) > Cc: erlang-questions@REDACTED > Subject: Re: Towards a native windows GUI > > > Hi Joe, > > Joe Armstrong (AL/EAB) wrote: > > Programming a GUI as a collection of parallel processes is > very easy. But programming > > a GUI as a single sequential process is very difficult. > > As much as we all like concurrent functional programming, I think it > would be unfair to reject the merit of the modern Windows > OO-based IDE > tools (like Visual Studio .NET, Borland JBuilder, Borland > Delphi, MONO > IDE /that supports multiple platforms/, etc). Even though they are > based on a single process model, they streamline GUI > development quite a > bit, and given the fact that they are backed up by the key software > monsters, the GUI programming community is quite used to these tools, > and is very productive. > > Writing GUI in Erlang would also require to have some kind of IDE > (likely also written in Erlang) that would automate creation of GUI > layouts and interactions with widgets. Without such an IDE GUI > programming would be very tidious and time consuming. > > From the academic point of view modeling GUI as parallel > processes is > definitely a very interesting excersize, but if that turns > out a viable > solution, would the open-source community build an IDE for it, and be > willing to evolve and support such product (which I imagine > would not be > very simple)? Would it make Erlang any more popular if it had a GUI > support and IDE? > > Serge > > From mats.cronqvist@REDACTED Thu Aug 18 11:33:37 2005 From: mats.cronqvist@REDACTED (Mats Cronqvist) Date: Thu, 18 Aug 2005 11:33:37 +0200 Subject: Towards a native windows GUI In-Reply-To: References: Message-ID: <430455F1.9020407@ericsson.com> Joe Armstrong (AL/EAB) wrote: [snip] > It seems to me that things went wrong at stage 4 - the very fact that you *need* > a IDE/wizard/whatever to write the code for you seems the underlying structure is > too complicated. well, a nice-looking, complex GUI *IS* complicated. you need a GUI builder to work effectively with GTK (and all other GUI toolkits). i think you're being a bit rash in implying that this is because the GTK people are lame. you need powerful tools to solve difficult problems. [snip] > With GUI builders - the learning curve is steeper, interfacing to Erlang is > painful, and forget dynamic GUIS. glade is orders of magnitude easier to learn than, say, GS. with gtkNode, you send erlang messages to the GTK widgets. not painful. what is a "dynamic GUI"? > The trade-off is "Easy to program = Ugly GUI" vs. "Difficult to program = Nice GUI". optimally. i think it's quite easy to wind up with "Difficult and Ugly". [snip] > Suppose we (say) implement an Erlang interface to GTK (there seem to be > at least 3 of these), then the following problems seem to occur: > > a) The interface library won't build in my environment > (it worked fine on the developers machine but particular combination of > shared libraries/OS etc. needed differs on my machine) > b) I have to learnt the GTK programming model in order to write a GUI > (and is that fun? - no) > c) The result is non-portable > (ie the target machine must have performed a) successfully) a) is non-trivial even if you use X. b) actually, it is fun :> c) many GTK applications include the GTK runtime (firefox, gimp etc). as far as gtkNode goes, the problem with building a static gtkNode.exe for windows is in getting the erl_interface stuff to compile, not the GTK bit. mats From joe.armstrong@REDACTED Thu Aug 18 12:08:04 2005 From: joe.armstrong@REDACTED (Joe Armstrong (AL/EAB)) Date: Thu, 18 Aug 2005 12:08:04 +0200 Subject: Towards a native windows GUI Message-ID: Hi Mats, > what is a "dynamic GUI"? One that is created by a program Think "Higher order functions" F is a function which returns a GUI /Joe From Marc.Vanwoerkom@REDACTED Thu Aug 18 13:26:52 2005 From: Marc.Vanwoerkom@REDACTED (Marc van Woerkom) Date: Thu, 18 Aug 2005 13:26:52 +0200 Subject: Towards a native windows GUI In-Reply-To: Message-ID: > 1) There were no GUIs > 2) Some very simple 2-D graphics API's emerged > 3) Simple GUI's with window, mice, keyboard, > 4) Complex libraries to make programming type 3 > 5) The libraries became so complicated that nobody I muss some stuff: One of the biggest advances in Windows 95 was the introduction of higher quality fonts. There is obviously a race going on towards a graphical quality similiar to that of printed media. There was Display Postscript on the NeXT, and the Quartz engine (kind of display PDF) on MacOS X. For the next Windows generation, there seems something similar in the making. Then Mozilla introduced XUL, where a XML file holds information about the various widgets used (that's the decalarative part) and JavaScript is used to handle the various events. This is one of the easiest ways to create GUI applications! The available widgets are enough for most business applications. Look at the JavaScript Debugger (Venkman) or the Chatzilla if you want to see what is possible. A similiar technique is said to be introduced in next generation Windows as well. We use XUL in a commercial environment. It speeds up development dramatically. A box with Linux or some other free Unix and Mozilla is sufficient. A drawback is the memory hunger (and some leaks in Mozilla) if you run many clients on one system. Regards, Marc From tim@REDACTED Thu Aug 18 12:29:48 2005 From: tim@REDACTED (Tim Bates) Date: Thu, 18 Aug 2005 19:59:48 +0930 Subject: Multiple-behaviour warning Message-ID: <4304631C.4070501@bates.id.au> Hi folks, Is there any way to remove this warning? src/publish_filter.erl:26: Warning: several behaviours defined - gen_server src/publish_filter.erl:36: Warning: several behaviours defined - publisher src/publish_filter.erl:41: Warning: several behaviours defined - subscriber I've developed a simple publish/subscribe framework. In this example, publish_filter subscribes to a publication, modifies the incoming values in some way and re-publishes the result, so the one module is both a publisher and a subscriber, and it's also implemented using gen_server. I'd like not to see these three warnings every time I compile the module, but the documentation doesn't tell of any way to turn this particular warning off. Any ideas? Thanks, Tim. -- Tim Bates tim@REDACTED From ulf.wiger@REDACTED Thu Aug 18 14:24:41 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Thu, 18 Aug 2005 14:24:41 +0200 Subject: building gtkNode Message-ID: Mats Cronqvist wrote: > i think the sane value of $OTP_ROOT on debian is > /usr/local. is it not? Perhaps I've been tainted by the well established convention that OTP_ROOT point to /usr/local/erlang in this case, as suggested by the Embedded Systems User's Guide in the OTP documentation (http://erlang.se/doc/doc-5.4.8/doc/embedded/embedded_solaris.html#1) > what version of gtk do you have? > pkg-config --modversion gtk+-2.0 > 2.6.8 I'll have to get back to you on that, as it is on my home system. /Uffe From ulf.wiger@REDACTED Thu Aug 18 14:41:13 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Thu, 18 Aug 2005 14:41:13 +0200 Subject: Towards a native windows GUI Message-ID: Joe Armstrong wrote: > > The historical development of GUI programs seems to me to > be like this: > > 1) There were no GUIs > 2) Some very simple 2-D graphics API's emerged > 3) Simple GUI's with window, mice, keyboard, etc emerged. > 4) Complex libraries to make programming type 3 GUIs emerged > 5) The libraries became so complicated that nobody > could understand them an so IDE's and GUI designing > programs were invented, that spat out code containing > library calls for the complex libraries in 4) I think there are two separate issues with item number 5 above: - GUI builders actually speed up GUI development dramatically, regardless of underlying programming model. The trial and error approach to designing a GUI by trying to write down pixel values in a program, running it and observing the results is extremely tedious, esp. if you want to create a professional-looking GUI. It is a _huge_ improvement to be able to draw the window as you want it to look, and having the "drawing program" translate that to widget calls. - The programming model is a different matter. I think that ideally, a GUI builder should translate your drawing to something that you could have written easily enough by hand, if it hadn't been for the tedium of figuring out all the pixel values and colour codes. The large volume of functions available to control the behaviour of your GUI comes (IMHO) from the mistake of leaving e.g. a pure message passing model, which would be composable, in favour of a middleware library approach that isn't. This causes the complexity explosion that, as I understand it, you're trying to get away from. /Uffe From serge@REDACTED Thu Aug 18 14:58:39 2005 From: serge@REDACTED (Serge Aleynikov) Date: Thu, 18 Aug 2005 08:58:39 -0400 Subject: Towards a native windows GUI In-Reply-To: References: Message-ID: <430485FF.7090400@hq.idt.net> Hi Joe, While having an ability to do GUI programming in Erlang the way you described is definitely useful (noting the challenges mentioned by Mats and Vlad), I'd like to bring another point to this discussion. It looks like the problem can be addressed in two ways: 1. How do we interface Erlang with GUI programming? 2. How do we interface GUI programming with Erlang? I don't think the two approaches are the same effort. I think that the second one has a value in a sense that if Erlang would offer an API (much simplier than erl_interface) that would allow for it to be embedded in the OO-realm of component-based development, then we'd give a chance to the over-populated OO GUI community to interface with Erlang emulator quite easily. This way the nice-looking GUI programming could be done in languages and IDEs that are specifically designed for that purpose, and manage the tasks suitable for Erlang from GUI through a well-established message passing API. As far as the first approach is concerned on Win32, I suspect that a sub-set of Win API selected for making simplistic GUIs would still be large enough to keep it really simplistic. I just went back to see "under the hood" of the Delphi's implementation of the windows message handling procedure for the main form of an application, and it has code for each of the following messages: WM_ACTIVATE, WM_SETFOCUS, WM_KILLFOCUS, CM_SETACTIVECONTROL,CM_EXIT,CM_ENTER,WM_WINDOWPOSCHANGING, WM_DRAWITEM,WM_MEASUREITEM,CM_WININICHANGE,CM_SYSCOLORCHANGE, CM_SYSFONTCHANGED,CM_PARENTCOLORCHANGED,CM_PARENTFONTCHANGED, CM_PARENTBIDIMODECHANGED,WM_SYSCOMMAND,WM_CLOSE,WM_PAINT, WM_ERASEBKGND,WM_QUERYDRAGICON,WM_SETFOCUS,WM_ACTIVATEAPP, WM_ENABLE,WM_CTLCOLORMSGBOX,WM_CTLCOLORSTATIC,WM_ENDSESSION, WM_QUERYENDSESSION,WM_COPYDATA,CM_ACTIONEXECUTE, CM_ACTIONUPDATE, CM_APPKEYDOWN,CM_APPSYSCOMMAND,CM_ACTIVATE,CM_DEACTIVATE, CM_ENTER,WM_HELP,CM_INVOKEHELP,CM_WINDOWHOOK,CM_DIALOGHANDLE, WM_SETTINGCHANGE,WM_FONTCHANGE,WM_THEMECHANGED,WM_NULL Doable? Yes. Simplistic? Not quite. Regards, Serge Joe Armstrong (AL/EAB) wrote: > Hi Serge, > > Let me be clear, What I want to do is *simplify* GUI programming - reduce GUI > programming to understanding a small number of well-defined primitives. > > I am well-aware that the Win32 GDI has a large number of procedures (or as David Hopwood say, "thousands") that do mysterious things. > > What I want to know is "is there a small sub-set of these procedures" that > I can write a simple GUI with? > > The historical development of GUI programs seems to me to be like this: > > 1) There were no GUIs > 2) Some very simple 2-D graphics API's emerged > 3) Simple GUI's with window, mice, keyboard, etc emerged. > 4) Complex libraries to make programming type 3 GUIs emerged > 5) The libraries became so complicated that nobody could understand them > an so IDE's and GUI designing programs were invented, that spat out > code containing library calls for the complex libraries in 4) > > It seems to me that things went wrong at stage 4 - the very fact that you *need* > a IDE/wizard/whatever to write the code for you seems the underlying structure is > too complicated. > > There is a trade-off involved here: > > Suppose I have a very simple library, and programming language, say like this: > > Win = mkWin(X, Y, W, H), > Button = Win !! {addButton, X1, Y1, W1, H1}, > Button ! {addtext, "Press me"}, > Button ! {onClick, fun() -> ... end}, > > Etc. (like my ex11 :-) - then you can learn the language quickly and produce > ugly but functional GUIs very quickly, and I can build dynamic GUIS. > > With GUI builders - the learning curve is steeper, interfacing to Erlang is > painful, and forget dynamic GUIS. > > The trade-off is "Easy to program = Ugly GUI" vs. "Difficult to program = Nice GUI". > > Suppose we (say) implement an Erlang interface to GTK (there seem to be > at least 3 of these), then the following problems seem to occur: > > a) The interface library won't build in my environment > (it worked fine on the developers machine but particular combination of > shared libraries/OS etc. needed differs on my machine) > b) I have to learnt the GTK programming model in order to write a GUI > (and is that fun? - no) > c) The result is non-portable > (ie the target machine must have performed a) successfully) > > What I'd like to experiment with are simple libraries using only the X protocol > or the Win32 API - where the programming language is pretty much as above. > > I realize that this will not make beautiful GUIS but they will be easy to > program and portable. > > /Joe > > > > > > > > > > > >>-----Original Message----- >>From: Serge Aleynikov [mailto:serge@REDACTED] >>Sent: den 17 augusti 2005 16:57 >>To: Joe Armstrong (AL/EAB) >>Cc: erlang-questions@REDACTED >>Subject: Re: Towards a native windows GUI >> >> >>Hi Joe, >> >>Joe Armstrong (AL/EAB) wrote: >> >>>Programming a GUI as a collection of parallel processes is >> >>very easy. But programming >> >>>a GUI as a single sequential process is very difficult. >> >>As much as we all like concurrent functional programming, I think it >>would be unfair to reject the merit of the modern Windows >>OO-based IDE >>tools (like Visual Studio .NET, Borland JBuilder, Borland >>Delphi, MONO >>IDE /that supports multiple platforms/, etc). Even though they are >>based on a single process model, they streamline GUI >>development quite a >>bit, and given the fact that they are backed up by the key software >>monsters, the GUI programming community is quite used to these tools, >>and is very productive. >> >>Writing GUI in Erlang would also require to have some kind of IDE >>(likely also written in Erlang) that would automate creation of GUI >>layouts and interactions with widgets. Without such an IDE GUI >>programming would be very tidious and time consuming. >> >> From the academic point of view modeling GUI as parallel >>processes is >>definitely a very interesting excersize, but if that turns >>out a viable >>solution, would the open-source community build an IDE for it, and be >>willing to evolve and support such product (which I imagine >>would not be >>very simple)? Would it make Erlang any more popular if it had a GUI >>support and IDE? >> >>Serge >> >> > > From michael206@REDACTED Thu Aug 18 15:22:06 2005 From: michael206@REDACTED (Michael Leonhard) Date: Thu, 18 Aug 2005 22:22:06 +0900 Subject: Towards a native windows GUI In-Reply-To: References: Message-ID: <21f8b6e205081806226d940859@mail.gmail.com> Hello Joe, Your idea to write an interface of the basic Win32 API to Erlang is very intriguing. I think it is a great idea. I have written some programs using the pure Win32 API. None of them were very good, but they worked. In my experience, it was necessary to use more than the message handling functions. It may be possible to replicate the action of some functions, like DestroyWindow() but one would have to dig really deep into the sources of user32.lib. It would probably be necessary to implement an Erlang interface to many functions outside those which handle messages. Perhaps 20 would be needed from user32.lib and then another 30 from gdi32.lib for the graphics primitives. Basic functions that must be interfaced: RegisterClassEx CreateWindowEx DestroyWindow GetMessage PostMessage SendMessage ShellExecuteEx Registry functions (~10) BeginPaint EndPaint InvalidateRect Other GDI functions (~30) Using the functions above, it may be possible to emulate these necessary functions: SetFocus GetFocus GetWindowInfo GetWindowText SetWindowText GetClientRect MoveWindow ShowWindow TranslateMessage DispatchMessage I compiled these lists from the source code of pure Win32 applications that I wrote many years ago. Though there are many functions, most of them have simple parameters and return values. Writing the interface may be tedious, but it is certainly doable. * Extra Erlang node The extra node would be "patched" to support extra BIFs that perform Win32 calls. These BIFs would manage C objects like HANDLEs and various C structs that are required by some calls. HANDLEs are just pointers in the Win32 process's address space. Exposing these to Erlang code would allow a process to crash the node. Where should the tradeoff between safety and simplicity be made? To save us application developers from the horror of building a patched version of Erlang on Win32, some experts could build it and distribute the binaries. Preferrably, these would be distributed in a self-installing executable, in the longstanding Windows tradition. * C port driver I have never worked with a port driver, but it seems that it would be easier to build an application using a port driver than to set up a second custom Erlang node. A self-installing executable could drop the port driver binaries right into the local Erlang installation. Some of the Win32 calls may block for periods of time (GetMessage()). Would the erl +A option enable the port driver to run in a separate thread? >> what is a "dynamic GUI"? > One that is created by a program > Think "Higher order functions" > F is a function which returns a GUI Windows programming has waited a long time for this concept. The idea of writing Win32 GUIs with Erlang is very exciting. I think that the concurrency of Erlang is perfectly suited to writing good GUIs. I look forward to writing some widgets and applications in Erlang for Win32. -Michael From james.hague@REDACTED Thu Aug 18 15:22:47 2005 From: james.hague@REDACTED (James Hague) Date: Thu, 18 Aug 2005 08:22:47 -0500 Subject: Towards a native windows GUI In-Reply-To: References: Message-ID: On 8/18/05, Joe Armstrong (AL/EAB) wrote: > > F is a function which returns a GUI You might want to look at REBOL. It has a function called "layout" which returns a GUI. Another function called "view" displays that GUI. So you write code like this: view layout [gui-description here] Here are some examples, using real code. Display two buttons in a vertical row: view layout [button "OK" button "Cancel"] or horizontally: view layout [across button "OK" button "Cancel"] This is by far the easiest GUI system I have run across. Here's the GUI description overview: http://rebol.com/docs/view-guide.html Here's the lower-level graphics system that supports it: http://www.rebol.com/docs/view-system.html From mfs@REDACTED Thu Aug 18 15:50:06 2005 From: mfs@REDACTED (Mark Scandariato) Date: Thu, 18 Aug 2005 09:50:06 -0400 (GMT-04:00) Subject: Multiple-behaviour warning Message-ID: <9258544.1124373006687.JavaMail.root@mswamui-blood.atl.sa.earthlink.net> I patch erl_lint.erl to stop checking: --- lib/stdlib/src/erl_lint.erl.orig 2005-06-21 21:50:52.203125000 -0400 +++ lib/stdlib/src/erl_lint.erl 2005-08-18 09:41:32.106750000 -0400 @@ -369,8 +369,8 @@ add_warning(W, St) -> St#lint{warnings=place_warning(St#lint.warnings, W)}. add_warning(Line, W, St) -> add_warning({Line,erl_lint,W}, St). -add_warning(true, L, W, St) -> add_warning(L, W, St); -add_warning(false, _L, _W, St) -> St. +%% add_warning(true, L, W, St) -> add_warning(L, W, St); +%% add_warning(false, _L, _W, St) -> St. %% forms([Form], State) -> State' @@ -498,10 +498,11 @@ %% Check behaviours for existence and defined functions. behaviour_check(Bs, St) -> - Mult = length(Bs) > 1, %More than one behaviour? +%% Mult = length(Bs) > 1, %More than one behaviour? foldl(fun ({Line,B}, St0) -> - St1 = add_warning(Mult, Line, {several_behaviours,B}, St0), - {Bfs, St2} = behaviour_callbacks(Line, B, St1), +%% St1 = add_warning(Mult, Line, {several_behaviours,B}, St0), +%% {Bfs, St2} = behaviour_callbacks(Line, B, St1), + {Bfs, St2} = behaviour_callbacks(Line, B, St0), Missing = ordsets:subtract(ordsets:from_list(Bfs), St2#lint.exports), func_warning(Line, undefined_behaviour_func, -----Original Message----- From: Tim Bates Sent: Aug 18, 2005 6:29 AM To: erlang-questions@REDACTED Subject: Multiple-behaviour warning Hi folks, Is there any way to remove this warning? src/publish_filter.erl:26: Warning: several behaviours defined - gen_server src/publish_filter.erl:36: Warning: several behaviours defined - publisher src/publish_filter.erl:41: Warning: several behaviours defined - subscriber I've developed a simple publish/subscribe framework. In this example, publish_filter subscribes to a publication, modifies the incoming values in some way and re-publishes the result, so the one module is both a publisher and a subscriber, and it's also implemented using gen_server. I'd like not to see these three warnings every time I compile the module, but the documentation doesn't tell of any way to turn this particular warning off. Any ideas? Thanks, Tim. -- Tim Bates tim@REDACTED From joelr1@REDACTED Thu Aug 18 16:40:33 2005 From: joelr1@REDACTED (Joel Reymont) Date: Thu, 18 Aug 2005 16:40:33 +0200 Subject: Generating unique ids in Mnesia Message-ID: Folks, I need to maintain a table of players in Mnesia and I would like to assign players a unique id when they are added. Right now I generate a tuple of {timestamp hash, pid hash} and then hash that once more to get a unique id. Is there an easier way to do this in Mnesia? The ids can be sequential or random, they just can't repeat themselves as the table is a set. I guess I'm looking for something like a max aggregator on a Mnesia column. Thanks, Joel From hakan@REDACTED Thu Aug 18 16:46:32 2005 From: hakan@REDACTED (Hakan Mattsson) Date: Thu, 18 Aug 2005 16:46:32 +0200 (CEST) Subject: Generating unique ids in Mnesia In-Reply-To: References: Message-ID: On Thu, 18 Aug 2005, Joel Reymont wrote: JR> Folks, JR> JR> I need to maintain a table of players in Mnesia and I would like to assign JR> players a unique id when they are added. Right now I generate a tuple of JR> {timestamp hash, pid hash} and then hash that once more to get a unique JR> id. JR> JR> Is there an easier way to do this in Mnesia? The ids can be sequential or JR> random, they just can't repeat themselves as the table is a set. I guess JR> I'm looking for something like a max aggregator on a Mnesia column. You can use erlang:now() or {node(), erlang:now()} in a multi node system. /H?kan From joelr1@REDACTED Thu Aug 18 16:48:13 2005 From: joelr1@REDACTED (Joel Reymont) Date: Thu, 18 Aug 2005 16:48:13 +0200 Subject: Generating unique ids in Mnesia In-Reply-To: References: Message-ID: <512F52C0-7C8E-4246-A1B3-C60A27A8FA99@gmail.com> Would I call mnesia:foldl() to figure out the maximum sequence number and then create a new record with key seqnum + 1, all in the same transaction? On Aug 18, 2005, at 4:40 PM, Joel Reymont wrote: > Folks, > > I need to maintain a table of players in Mnesia and I would like to > assign players a unique id when they are added. Right now I > generate a tuple of {timestamp hash, pid hash} and then hash that > once more to get a unique id. > > Is there an easier way to do this in Mnesia? The ids can be > sequential or random, they just can't repeat themselves as the > table is a set. I guess I'm looking for something like a max > aggregator on a Mnesia column. From rpettit@REDACTED Thu Aug 18 16:58:31 2005 From: rpettit@REDACTED (Rick Pettit) Date: Thu, 18 Aug 2005 09:58:31 -0500 Subject: Generating unique ids in Mnesia In-Reply-To: References: Message-ID: <20050818145831.GA32262@vailsys.com> On Thu, Aug 18, 2005 at 04:40:33PM +0200, Joel Reymont wrote: > Folks, > > I need to maintain a table of players in Mnesia and I would like to > assign players a unique id when they are added. Right now I generate > a tuple of {timestamp hash, pid hash} and then hash that once more to > get a unique id. > > Is there an easier way to do this in Mnesia? The ids can be > sequential or random, they just can't repeat themselves as the table > is a set. I guess I'm looking for something like a max aggregator on > a Mnesia column. Will a plain old ref work, the kind returned by erlang:make_ref()? -Rick From joelr1@REDACTED Thu Aug 18 16:59:50 2005 From: joelr1@REDACTED (Joel Reymont) Date: Thu, 18 Aug 2005 16:59:50 +0200 Subject: Generating unique ids in Mnesia In-Reply-To: <512F52C0-7C8E-4246-A1B3-C60A27A8FA99@gmail.com> References: <512F52C0-7C8E-4246-A1B3-C60A27A8FA99@gmail.com> Message-ID: Mainly, my question is that of how to ensure that each "generate new id" returns the next sequence number without a lot of error checking. I could do the fold and get the max seqnum but another process could be doing the same at the same moment. One of them would surely overwrite the record when writing. I could retrieve the record and check if the stored process id the right one (I do store the pid in the record) but I wonder if there's a better way of doing this. Thanks, Joel On Aug 18, 2005, at 4:48 PM, Joel Reymont wrote: > Would I call mnesia:foldl() to figure out the maximum sequence > number and then create a new record with key seqnum + 1, all in the > same transaction? From joelr1@REDACTED Thu Aug 18 17:03:22 2005 From: joelr1@REDACTED (Joel Reymont) Date: Thu, 18 Aug 2005 17:03:22 +0200 Subject: Generating unique ids in Mnesia In-Reply-To: <20050818145831.GA32262@vailsys.com> References: <20050818145831.GA32262@vailsys.com> Message-ID: <4D9CFCF5-4451-48E1-8EDA-9260DAED54A6@gmail.com> Only if I can convert it to a number. Think generating session ids for a browser. Surely a reference won't do. A reference value reoccurs every 2^82 calls whereas if I hash it I'll get a value below 2^32 so hashing does not seem to the way to go. On Aug 18, 2005, at 4:58 PM, Rick Pettit wrote: > Will a plain old ref work, the kind returned by erlang:make_ref()? From joelr1@REDACTED Thu Aug 18 17:12:08 2005 From: joelr1@REDACTED (Joel Reymont) Date: Thu, 18 Aug 2005 17:12:08 +0200 Subject: Generating unique ids in Mnesia In-Reply-To: References: Message-ID: Hakan, Thanks for the tip but I need sequential, increasing numerical values. I would like my records to be sequantially numbered and the sequence number to increase every time I insert a record. How do I manage that? Joel On Aug 18, 2005, at 4:46 PM, Hakan Mattsson wrote: > You can use > > erlang:now() > > or > > {node(), erlang:now()} > > in a multi node system. From hakan@REDACTED Thu Aug 18 17:16:40 2005 From: hakan@REDACTED (Hakan Mattsson) Date: Thu, 18 Aug 2005 17:16:40 +0200 (CEST) Subject: Generating unique ids in Mnesia In-Reply-To: <4D9CFCF5-4451-48E1-8EDA-9260DAED54A6@gmail.com> References: <20050818145831.GA32262@vailsys.com> <4D9CFCF5-4451-48E1-8EDA-9260DAED54A6@gmail.com> Message-ID: On Thu, 18 Aug 2005, Joel Reymont wrote: JR> Only if I can convert it to a number. Think generating session ids for a JR> browser. If you want to generate a unique number, you can use mnesia:dirty_update_counter/3 in order to obtain a persistent counter. /H?kan From jay@REDACTED Thu Aug 18 17:19:58 2005 From: jay@REDACTED (Jay Nelson) Date: Thu, 18 Aug 2005 08:19:58 -0700 Subject: Pocket Erlang Computer Message-ID: <4304A71E.3060104@duomark.com> I've always wanted a pocket Erlang computer, and now I think I found one. It would work great with Joe's ex11, too. http://www.linuxdevices.com/news/NS8562564746.html "Realm Systems is taking orders for a tiny, loss-leader-priced Linux server that lets users carry a secure computing environment with them. Black Dog attaches via USB to Linux, Windows, or Mac PCs, commandeering the host's KVM (keyboard/video/mouse) functions and running X-based apps on its graphics subsystem." "Meanwhile, the company is taking orders for two Black Dog models, priced at $199 and $239 respectively with 256MB and 512MB of Flash storage." jay From rikard.johansson@REDACTED Thu Aug 18 17:23:10 2005 From: rikard.johansson@REDACTED (Rikard Johansson) Date: Thu, 18 Aug 2005 17:23:10 +0200 Subject: Generating unique ids in Mnesia In-Reply-To: References: Message-ID: <4304A7DE.9090500@mobilearts.se> Here are some code I use for sequences. It creates one mnesia table (sequence) which can hold multiple sequences. mnesia:dirty_update_counter is fast and atomic. Usage: 1> mod:create_sequence([node()]). 2> mod:sequence(player_id). 0 3> mod:sequence(player_id). 1 4> mod:sequence(foo). 0 ... Best regards, /Rikard %% -------------------------------------------------- %% sequence %% %% sequence table record -record(sequence, {key, index}). %% Creates sequence table. Performed once create_sequence() -> create_sequence([node()]). create_sequence(Nodes) -> mnesia:create_table(sequence, [{type, set}, {disc_copies, Nodes}, {attributes, record_info(fields, sequence)}]). %% Inits or resets a sequence to Value init_sequence(Name, Value) -> {atomic, ok} = mnesia:transaction(fun() -> mnesia:write(#sequence{key=Name, index=Value}) end), ok. %% Returns current value for sequence Name and increments %% Sequence is created if not exists, and initial value 0 is returned. sequence(Name) -> sequence(Name, 1). %% increment sequence with Inc sequence(Name, Inc) -> mnesia:dirty_update_counter(sequence, Name, Inc). Joel Reymont wrote: > Hakan, > > Thanks for the tip but I need sequential, increasing numerical values. > I would like my records to be sequantially numbered and the sequence > number to increase every time I insert a record. How do I manage that? > > Joel > > On Aug 18, 2005, at 4:46 PM, Hakan Mattsson wrote: > >> You can use >> >> erlang:now() >> >> or >> >> {node(), erlang:now()} >> >> in a multi node system. > > > From joelr1@REDACTED Thu Aug 18 17:25:50 2005 From: joelr1@REDACTED (Joel Reymont) Date: Thu, 18 Aug 2005 17:25:50 +0200 Subject: Generating unique ids in Mnesia In-Reply-To: References: Message-ID: <2A85DC94-2162-46C7-82E4-DE7210996761@gmail.com> I think I solved the problem. I'll rely on a separate counter table and mnesia:dirty_update_counter(). The counter table will be a set, keyed on the counter type. -record(counter, { type, value }). My understanding from the documentation is that mnesia:dirty_update_counter() atomically _increments_ the counter and the increments part is key. The idea won't work otherwise. Joel From mfs@REDACTED Thu Aug 18 17:29:04 2005 From: mfs@REDACTED (Mark Scandariato) Date: Thu, 18 Aug 2005 11:29:04 -0400 (EDT) Subject: Generating unique ids in Mnesia Message-ID: <12733700.1124378944306.JavaMail.root@mswamui-blood.atl.sa.earthlink.net> If you don't mind gaps in the sequence numbers, then try: seq() -> {M,S,U} = erlang:now(), <> = <>, N. Mark. -----Original Message----- From: Joel Reymont Sent: Aug 18, 2005 11:12 AM To: Erlang Users' List Subject: Re: Generating unique ids in Mnesia Hakan, Thanks for the tip but I need sequential, increasing numerical values. I would like my records to be sequantially numbered and the sequence number to increase every time I insert a record. How do I manage that? Joel On Aug 18, 2005, at 4:46 PM, Hakan Mattsson wrote: > You can use > > erlang:now() > > or > > {node(), erlang:now()} > > in a multi node system. From joelr1@REDACTED Thu Aug 18 17:28:49 2005 From: joelr1@REDACTED (Joel Reymont) Date: Thu, 18 Aug 2005 17:28:49 +0200 Subject: Generating unique ids in Mnesia In-Reply-To: <4304A7DE.9090500@mobilearts.se> References: <4304A7DE.9090500@mobilearts.se> Message-ID: <371D6BFB-F21C-42E8-A456-6DA304BA4D3E@gmail.com> Thank you Rikard! This is exactly what I had in mind. On Aug 18, 2005, at 5:23 PM, Rikard Johansson wrote: > Here are some code I use for sequences. It creates one mnesia table > (sequence) which can hold multiple sequences. > mnesia:dirty_update_counter is fast and atomic. From joelr1@REDACTED Thu Aug 18 17:35:11 2005 From: joelr1@REDACTED (Joel Reymont) Date: Thu, 18 Aug 2005 17:35:11 +0200 Subject: Generating unique ids in Mnesia In-Reply-To: <12733700.1124378944306.JavaMail.root@mswamui-blood.atl.sa.earthlink.net> References: <12733700.1124378944306.JavaMail.root@mswamui-blood.atl.sa.earthlink.net> Message-ID: <6889D282-7844-499C-B11B-C657C62B59BF@gmail.com> Is it fixed someplace that the components of now() are exactly 24, 20 and 20 bits long? On Aug 18, 2005, at 5:29 PM, Mark Scandariato wrote: > If you don't mind gaps in the sequence numbers, then try: > > seq() -> > {M,S,U} = erlang:now(), > <> = <>, > N. From nm@REDACTED Thu Aug 18 17:36:44 2005 From: nm@REDACTED (Gaspar Chilingarov) Date: Thu, 18 Aug 2005 20:36:44 +0500 Subject: Generating unique ids in Mnesia In-Reply-To: <4D9CFCF5-4451-48E1-8EDA-9260DAED54A6@gmail.com> References: <20050818145831.GA32262@vailsys.com> <4D9CFCF5-4451-48E1-8EDA-9260DAED54A6@gmail.com> Message-ID: <4304AB0C.3030807@web.am> Joel Reymont wrote: > Only if I can convert it to a number. Think generating session ids for > a browser. > what about term_to_binary() and converting binary to ascii presentation? :) 4> io:format("~p~n" , [term_to_binary(erlang:make_ref())]). <<131,114,0,3,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,0,62,0,0,0,0,0,0,0,0>> probably there is better way to convert to ascii value :) -- Gaspar Chilingarov System Administrator t +37491 419763 (mob) t +37410 240399 (office) w www.web.am i 63174784 e nm@REDACTED From vlad_dumitrescu@REDACTED Thu Aug 18 17:53:08 2005 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Thu, 18 Aug 2005 17:53:08 +0200 Subject: Towards a native windows GUI References: <430485FF.7090400@hq.idt.net> Message-ID: About working with bare-bones Win32: I think someone already mentioned this, but without stressing the point: windows messages are all fine, but a graphical application has to draw something on the screen -- and the drawing APIs are not message oriented. So we're back at interfacing with a regular C application, with the related problems. regards, Vlad From mfs@REDACTED Thu Aug 18 18:12:43 2005 From: mfs@REDACTED (Mark Scandariato) Date: Thu, 18 Aug 2005 12:12:43 -0400 (EDT) Subject: Generating unique ids in Mnesia Message-ID: <22905334.1124381563410.JavaMail.root@mswamui-blood.atl.sa.earthlink.net> erlang:now/0 returns {Megaseconds, Seconds, Microseconds} since 00:00 GMT, January 1, 1970. Seconds and Microseconds wrap at 999,999 so they won't exceed 20 bits. You'll have to hang on to the sequence numbers for a very long time before you exceed 24 bits worth of Megaseconds (16 trillion seconds since 00:00 GMT, January 1, 1970). Mark. -----Original Message----- From: Joel Reymont Sent: Aug 18, 2005 11:35 AM To: Erlang Users' List Subject: Re: Generating unique ids in Mnesia Is it fixed someplace that the components of now() are exactly 24, 20 and 20 bits long? On Aug 18, 2005, at 5:29 PM, Mark Scandariato wrote: > If you don't mind gaps in the sequence numbers, then try: > > seq() -> > {M,S,U} = erlang:now(), > <> = <>, > N. From vlad_dumitrescu@REDACTED Thu Aug 18 18:32:01 2005 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Thu, 18 Aug 2005 18:32:01 +0200 Subject: Towards a native windows GUI References: <430485FF.7090400@hq.idt.net> Message-ID: ----- Original Message ----- From: "Serge Aleynikov" > It looks like the problem can be addressed in two ways: > > 1. How do we interface Erlang with GUI programming? > 2. How do we interface GUI programming with Erlang? This is a good point. And believe it or not, #2 actually has a simple (half)answer: RPCs! Does the GUI need to access Erlang? Send a RPC. There is a nice contribution by Sean Hinde, allowing to make the calls via a socket, so the GUI doesn't need to be a driver or a port. We are facing similar issues with the Eclipse Erlang IDE, where we need to use Erlang functionality from Java (and it is preferrable to not use a distributed node). Handling notifications from Erlang (in order not to poll it) is also possible, using the same channel. (If I understand correctly, this is #1) A listener thread will watch for the notifications and pass them ahead. So the only issue is converting from Erlang terms to something intelligible in C, Delphi, Java or whatever. This is also doable - Java and C have already libraries, the Java ones can be used as a model for other OO languages. But that's not really "doing GUI in Erlang" ;-) regards, Vlad From huss01@REDACTED Thu Aug 18 21:33:32 2005 From: huss01@REDACTED (=?ISO-8859-1?Q?H=E5kan_Huss?=) Date: Thu, 18 Aug 2005 21:33:32 +0200 Subject: Generating unique ids in Mnesia In-Reply-To: <2A85DC94-2162-46C7-82E4-DE7210996761@gmail.com> References: <2A85DC94-2162-46C7-82E4-DE7210996761@gmail.com> Message-ID: 2005/8/18, Joel Reymont : > I think I solved the problem. I'll rely on a separate counter table > and mnesia:dirty_update_counter(). Why not just have a process which on request returns ever increasing numbers. Something like: -module(seqserver). -export([init/0, init/1, next/1]). init() -> init(0). init(N) -> spawn(fun () -> loop(N) end). next(Seqserver) -> Seqserver ! {self(), next}, receive {Seqserver, N} -> N end. loop(N) -> receive {Pid, next} -> Pid ! {self(), N}, loop(N + 1); _Other -> loop(N) end. /H?kan From joelr1@REDACTED Thu Aug 18 23:42:13 2005 From: joelr1@REDACTED (Joel Reymont) Date: Thu, 18 Aug 2005 23:42:13 +0200 Subject: Generating unique ids in Mnesia In-Reply-To: References: <2A85DC94-2162-46C7-82E4-DE7210996761@gmail.com> Message-ID: <1423054C-B377-48F4-BF0B-1F61597B2BAF@gmail.com> Well, I do have to keep the counters between server restarts, crashes, etc. On Aug 18, 2005, at 9:33 PM, H?kan Huss wrote: > Why not just have a process which on request returns ever > increasing numbers. > Something like: From ulf@REDACTED Fri Aug 19 00:13:24 2005 From: ulf@REDACTED (Ulf Wiger) Date: Fri, 19 Aug 2005 00:13:24 +0200 Subject: building gtkNode In-Reply-To: <43044189.6030206@ericsson.com> References: <32852.85.224.131.27.1124319363.squirrel@webmail.wiger.net> <43044189.6030206@ericsson.com> Message-ID: Den 2005-08-18 10:06:33 skrev Mats Cronqvist : > i think the sane value of $OTP_ROOT on debian is /usr/local. is it > not? > > what version of gtk do you have? > pkg-config --modversion gtk+-2.0 > 2.6.8 Mine is 2.2.2 /Uffe > > mats > > ulf@REDACTED wrote: >> I tried making the gtkNode contrib, but ran into problems. >> The system is a Debian (Libranet). Below is some output. >> uffe@REDACTED:~/dev/jungerl/lib/gtkNode$ pkg-config --cflags >> libglade-2.0 >> -I/usr/include/libglade-2.0 -I/usr/include/gtk-2.0 >> -I/usr/include/libxml2 >> -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 >> -I/usr/include/pango-1.0 >> -I/usr/include/freetype2 -I/usr/X11R6/include -I/usr/include/glib-2.0 >> -I/usr/lib/glib-2.0/include >> uffe@REDACTED:~/dev/jungerl/lib/gtkNode$ echo $OTP_ROOT >> /usr/local >> (which I don't think is "sane", to quote the README, but I set >> it like that instead of changing Makefile) >> make[1]: Entering directory `/home/uffe/dev/jungerl/lib/gtkNode/src' >> gcc -g -c -o ../priv/obj/gtkNode_gen.o gtkNode_gen.c -I../include >> -I../priv/gen -I/usr/local/lib/erlang/lib/erl_interface-3.5.4/include >> `pkg-config --cflags libglade-2.0` >> In file included from gtkNode_gen.c:2: >> ../priv/gen/gtk_generated.h: In function `Gtk_accelerator_get_label': >> ../priv/gen/gtk_generated.h:260: warning: assignment makes pointer from >> integer without a cast >> ../priv/gen/gtk_generated.h: In function `Gtk_action_activate': >> ../priv/gen/gtk_generated.h:306: `GtkAction' undeclared (first use in >> this >> function) >> ../priv/gen/gtk_generated.h:306: (Each undeclared identifier is reported >> only once >> ../priv/gen/gtk_generated.h:306: for each function it appears in.) >> ../priv/gen/gtk_generated.h:306: `object' undeclared (first use in this >> function) >> ../priv/gen/gtk_generated.h:311: `GTK_TYPE_ACTION' undeclared (first use >> in this function) >> Any ideas? >> /Uffe >> -- Ulf Wiger From anders.nygren@REDACTED Fri Aug 19 02:06:56 2005 From: anders.nygren@REDACTED (Anders Nygren) Date: Thu, 18 Aug 2005 19:06:56 -0500 Subject: Building Jungerl Message-ID: Hi I am trying to build jungerl, on SuSE 9.3. I get the following error. > make conf (cd config; make) make[1]: Entering directory `/home/anders/src/erlang/jungerl/config' autoheader autoheader: warning: missing template: BROKEN_CMSG_FIELDS autoheader: Use AC_DEFINE([BROKEN_CMSG_FIELDS], [], [Description]) autoheader: warning: missing template: BSD autoheader: warning: missing template: CPU_VENDOR_OS autoheader: warning: missing template: HAVE_MSGHDR_MSG_CONTROL autoheader: warning: missing template: LINUX autoheader: warning: missing template: SOLARIS make[1]: *** [configure] Error 1 make[1]: Leaving directory `/home/anders/src/erlang/jungerl/config' make: *** [conf] Error 2 Does anyone have any suggestions what I may be missing? /Anders From ok@REDACTED Fri Aug 19 06:22:56 2005 From: ok@REDACTED (Richard A. O'Keefe) Date: Fri, 19 Aug 2005 16:22:56 +1200 (NZST) Subject: Towards a native windows GUI Message-ID: <200508190422.j7J4Muwx499132@atlas.otago.ac.nz> Joe Armstrong wrote: > 5) The libraries became so complicated that nobody > could understand them an so IDE's and GUI designing > programs were invented, that spat out code containing > library calls for the complex libraries in 4) There's even a GUI builder (SpecTCL) for TCL/Tk, which isn't _that_ complicated. There's a good reason for having GUI builders that has nothing to do with the complexity of GUI libraries: User Interface Design is a *different* skill from programming. People who are good at GUI design, as in "able to map work flows to GUIs in such a way that their intended users can perform their tasks with little error, confusion, or frustration", are not necessarily good programmers. From ulf@REDACTED Fri Aug 19 06:35:24 2005 From: ulf@REDACTED (Ulf Wiger) Date: Fri, 19 Aug 2005 06:35:24 +0200 Subject: Building Jungerl In-Reply-To: References: Message-ID: I ran into that last Wednesday, and posted the following: http://www.erlang.org/ml-archive/erlang-questions/200508/msg00264.html /Uffe Den 2005-08-19 02:06:56 skrev Anders Nygren: > Hi > I am trying to build jungerl, on SuSE 9.3. > I get the following error. > >> make conf > (cd config; make) > make[1]: Entering directory `/home/anders/src/erlang/jungerl/config' > autoheader > autoheader: warning: missing template: BROKEN_CMSG_FIELDS > autoheader: Use AC_DEFINE([BROKEN_CMSG_FIELDS], [], [Description]) > autoheader: warning: missing template: BSD > autoheader: warning: missing template: CPU_VENDOR_OS > autoheader: warning: missing template: HAVE_MSGHDR_MSG_CONTROL > autoheader: warning: missing template: LINUX > autoheader: warning: missing template: SOLARIS > make[1]: *** [configure] Error 1 > make[1]: Leaving directory `/home/anders/src/erlang/jungerl/config' > make: *** [conf] Error 2 > > Does anyone have any suggestions what I may be missing? > > /Anders -- Ulf Wiger From chris@REDACTED Fri Aug 19 08:56:21 2005 From: chris@REDACTED (Christophe Romain) Date: Fri, 19 Aug 2005 08:56:21 +0200 Subject: Pocket Erlang Computer In-Reply-To: <4304A71E.3060104@duomark.com> References: <4304A71E.3060104@duomark.com> Message-ID: > I've always wanted a pocket Erlang computer, and now I think I found > one. It would work great with Joe's ex11, too. Erlang is running on the Sharp Zaurus as well. not so tiny than the pocket computer you're talking about, but equiped with a screen and a keyboard. http://www.dynamism.com/zaurus/ http://www.sharpusa.com/products/TypeLanding/0,1056,112,00.html http://www.linuxdevices.com/articles/AT2134869242.html the graphical system is Qtopia (Qt working into the frame buffer) il you need to use Joe's ex11, you can flash the system to use GPE Palmtop Environment. http://www.openzaurus.org/wordpress/index.php?s=gpe last time I compiled erlang on the Zaurus SL6000, I get a fully working environment, except the terminal console (segfault, did not have time to investigate) From vlad_dumitrescu@REDACTED Fri Aug 19 09:00:31 2005 From: vlad_dumitrescu@REDACTED (vladdu) Date: Fri, 19 Aug 2005 09:00:31 +0200 Subject: Erlang records / Jinterface References: Message-ID: <20050819070031.0717D46EDE@bang.trapexit.org> Hi, I'm not sure if a tuple type would solve your problem in a good way: since Java can't easily know about the type details, the external format would have to also encode the field names every time a record is passed. This is almost the same as converting yourself the record to a {key,value} list and sending that instead, which you can do today. regards, Vlad _________________________________________________________ Sent using Mail2Forum (http://m2f.sourceforge.net) From mats.cronqvist@REDACTED Fri Aug 19 10:08:25 2005 From: mats.cronqvist@REDACTED (Mats Cronqvist) Date: Fri, 19 Aug 2005 10:08:25 +0200 Subject: building gtkNode In-Reply-To: References: <32852.85.224.131.27.1124319363.squirrel@webmail.wiger.net> <43044189.6030206@ericsson.com> Message-ID: <43059379.8000902@ericsson.com> antique... you'll need at least 2.4. mats Ulf Wiger wrote: > Den 2005-08-18 10:06:33 skrev Mats Cronqvist : > >> i think the sane value of $OTP_ROOT on debian is /usr/local. is it >> not? >> >> what version of gtk do you have? >> pkg-config --modversion gtk+-2.0 >> 2.6.8 > > > Mine is 2.2.2 > > /Uffe > > >> >> mats >> >> ulf@REDACTED wrote: >> >>> I tried making the gtkNode contrib, but ran into problems. >>> The system is a Debian (Libranet). Below is some output. >>> uffe@REDACTED:~/dev/jungerl/lib/gtkNode$ pkg-config --cflags >>> libglade-2.0 >>> -I/usr/include/libglade-2.0 -I/usr/include/gtk-2.0 >>> -I/usr/include/libxml2 >>> -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 >>> -I/usr/include/pango-1.0 >>> -I/usr/include/freetype2 -I/usr/X11R6/include -I/usr/include/glib-2.0 >>> -I/usr/lib/glib-2.0/include >>> uffe@REDACTED:~/dev/jungerl/lib/gtkNode$ echo $OTP_ROOT >>> /usr/local >>> (which I don't think is "sane", to quote the README, but I set >>> it like that instead of changing Makefile) >>> make[1]: Entering directory `/home/uffe/dev/jungerl/lib/gtkNode/src' >>> gcc -g -c -o ../priv/obj/gtkNode_gen.o gtkNode_gen.c -I../include >>> -I../priv/gen -I/usr/local/lib/erlang/lib/erl_interface-3.5.4/include >>> `pkg-config --cflags libglade-2.0` >>> In file included from gtkNode_gen.c:2: >>> ../priv/gen/gtk_generated.h: In function `Gtk_accelerator_get_label': >>> ../priv/gen/gtk_generated.h:260: warning: assignment makes pointer from >>> integer without a cast >>> ../priv/gen/gtk_generated.h: In function `Gtk_action_activate': >>> ../priv/gen/gtk_generated.h:306: `GtkAction' undeclared (first use >>> in this >>> function) >>> ../priv/gen/gtk_generated.h:306: (Each undeclared identifier is reported >>> only once >>> ../priv/gen/gtk_generated.h:306: for each function it appears in.) >>> ../priv/gen/gtk_generated.h:306: `object' undeclared (first use in this >>> function) >>> ../priv/gen/gtk_generated.h:311: `GTK_TYPE_ACTION' undeclared (first use >>> in this function) >>> Any ideas? >>> /Uffe >>> > > > From Jouni.Ryno@REDACTED Fri Aug 19 12:00:34 2005 From: Jouni.Ryno@REDACTED (Jouni =?ISO-8859-1?Q?Ryn=F6?=) Date: Fri, 19 Aug 2005 13:00:34 +0300 Subject: yet another gui framework for Erlang In-Reply-To: <4303443F.8010000@ericsson.com> References: <43033A4E.3010405@hyber.org> <4303443F.8010000@ericsson.com> Message-ID: <1124445634.5938.14.camel@adic> On Wed, 2005-08-17 at 16:05 +0200, Mats Cronqvist wrote: > so one can design the interface i glade; ione can easily create > a very complicated one in a few hours. all the widgets are named, the > names are available on the Erlang side as atoms. one also specifies > which events should result in signals. > ... I tried to figure out, how to draw. I generated a GtkDrawingArea, but I could not figure out, how to get my hands on the gc Something like this I should be able to do, 'plot_area' is the name of the GtkDrawingArea widget. Win = ssnd(plot_area, 'GN_drawingarea_get_window', []), % Gc = ssnd(plot_area, 'Gdk_gc_new', []), <- this does not work, and there should already be a define GC in the window? ssnd(plot_area, 'Gdk_draw_line', [Win, Gc, 10, 10, 100, 200]), P.S. It the future (tm), the cairo and gdk-cairo drawable would be nice to have included, but that's gtk 2.8 stuff. The point being, that the same code calling the cairo functions could draw also pdf, png, etc, not just gdkdrawable ... best regards Jouni -- Jouni Ryn? mailto://Jouni.Ryno@REDACTED/ http://www.geo.fmi.fi/~ryno/ Finnish Meteorological Institute http://www.fmi.fi/ Space Research http://www.geo.fmi.fi/ P.O.BOX 503 Tel (+358)-9-19294656 FIN-00101 Helsinki FAX (+358)-9-19294603 Finland priv-GSM (+358)-50-5302903 "It's just zeros and ones, it cannot be hard" From Jouni.Ryno@REDACTED Fri Aug 19 12:26:27 2005 From: Jouni.Ryno@REDACTED (Jouni =?ISO-8859-1?Q?Ryn=F6?=) Date: Fri, 19 Aug 2005 13:26:27 +0300 Subject: yet another gui framework for Erlang In-Reply-To: <1124445634.5938.14.camel@adic> References: <43033A4E.3010405@hyber.org> <4303443F.8010000@ericsson.com> <1124445634.5938.14.camel@adic> Message-ID: <1124447187.5938.24.camel@adic> Ah, it should be Win = ssnd(plot_area, 'GN_drawingarea_get_window', []), Gc = snd('Gdk_gc_new', [Win]), snd('Gdk_draw_line', [Win, Gc, 10, 10, 100, 200]), At least I get the line :) But is there a way (function) to access the Gc:s in the widget->style->...gc:s? Jouni On Fri, 2005-08-19 at 13:00 +0300, Jouni Ryn? wrote: > On Wed, 2005-08-17 at 16:05 +0200, Mats Cronqvist wrote: > > > so one can design the interface i glade; ione can easily create > > a very complicated one in a few hours. all the widgets are named, the > > names are available on the Erlang side as atoms. one also specifies > > which events should result in signals. > > ... > > I tried to figure out, how to draw. I generated a GtkDrawingArea, but I > could not figure out, how to get my hands on the gc > > Something like this I should be able to do, 'plot_area' is the name of > the GtkDrawingArea widget. > > Win = ssnd(plot_area, 'GN_drawingarea_get_window', []), > % Gc = ssnd(plot_area, 'Gdk_gc_new', []), <- this does not work, and > there should already be a define GC in the window? > ssnd(plot_area, 'Gdk_draw_line', [Win, Gc, 10, 10, 100, 200]), > > > P.S. It the future (tm), the cairo and gdk-cairo drawable would be nice > to have included, but that's gtk 2.8 stuff. The point being, that the > same code calling the cairo functions could draw also pdf, png, etc, not > just gdkdrawable ... > > best regards > Jouni -- Jouni Ryn? mailto://Jouni.Ryno@REDACTED/ http://www.geo.fmi.fi/~ryno/ Finnish Meteorological Institute http://www.fmi.fi/ Space Research http://www.geo.fmi.fi/ P.O.BOX 503 Tel (+358)-9-19294656 FIN-00101 Helsinki FAX (+358)-9-19294603 Finland priv-GSM (+358)-50-5302903 "It's just zeros and ones, it cannot be hard" From mats.cronqvist@REDACTED Fri Aug 19 13:26:54 2005 From: mats.cronqvist@REDACTED (Mats Cronqvist) Date: Fri, 19 Aug 2005 13:26:54 +0200 Subject: yet another gui framework for Erlang In-Reply-To: <1124447187.5938.24.camel@adic> References: <43033A4E.3010405@hyber.org> <4303443F.8010000@ericsson.com> <1124445634.5938.14.camel@adic> <1124447187.5938.24.camel@adic> Message-ID: <4305C1FE.40406@ericsson.com> Jouni Ryn? wrote: > Ah, it should be > Win = ssnd(plot_area, 'GN_drawingarea_get_window', []), > Gc = snd('Gdk_gc_new', [Win]), > snd('Gdk_draw_line', [Win, Gc, 10, 10, 100, 200]), > > At least I get the line :) yes, that's how i do it. i plan to put more examples in gtkNode/examples/*. you should of course feel free to check in your stuff... > But is there a way (function) to access the Gc:s in the > widget->style->...gc:s? never tried to do that. if it can't be done through the API it's easy enough to write your own function for this; see GN_widget_get_attr in gtkNode_internal.c accessing data members is one of the biggest nuisances in the gtkNode approach. would be nice to be able to do something like ssnd(widget,'GN_get_attr',[attr]) having generated GN_get_attr from the typedefs... > On Fri, 2005-08-19 at 13:00 +0300, Jouni Ryn? wrote: > >>On Wed, 2005-08-17 at 16:05 +0200, Mats Cronqvist wrote: [snip] >>P.S. It the future (tm), the cairo and gdk-cairo drawable would be nice >>to have included, but that's gtk 2.8 stuff. The point being, that the >>same code calling the cairo functions could draw also pdf, png, etc, not >>just gdkdrawable ... cairo seems very interesting, but i don't know enough about it to predict when the future(tm) will be upon us. there is a GtkCairo widget (http://www.cairographics.org/GtkCairo), anybody know anything about that? mats From Jouni.Ryno@REDACTED Fri Aug 19 13:45:43 2005 From: Jouni.Ryno@REDACTED (Jouni =?ISO-8859-1?Q?Ryn=F6?=) Date: Fri, 19 Aug 2005 14:45:43 +0300 Subject: yet another gui framework for Erlang In-Reply-To: <4305C1FE.40406@ericsson.com> References: <43033A4E.3010405@hyber.org> <4303443F.8010000@ericsson.com> <1124445634.5938.14.camel@adic> <1124447187.5938.24.camel@adic> <4305C1FE.40406@ericsson.com> Message-ID: <1124451943.5938.35.camel@adic> On Fri, 2005-08-19 at 13:26 +0200, Mats Cronqvist wrote: > [snip] > >>P.S. It the future (tm), the cairo and gdk-cairo drawable would be nice > >>to have included, but that's gtk 2.8 stuff. The point being, that the > >>same code calling the cairo functions could draw also pdf, png, etc, not > >>just gdkdrawable ... > > cairo seems very interesting, > but i don't know enough about it to predict when the future(tm) will be upon > us. there is a GtkCairo widget (http://www.cairographics.org/GtkCairo), anybody > know anything about that? > The current scheme in 2.8 is to use the following API, GtkCairo is obsolete: http://developer.gnome.org/doc/API/2.0/gdk/gdk-Cairo-Interaction.html Not that I know! anything about that stuff. But it would require the generation of the cairo callbacks to the gtkNode ... (please :) ) Jouni -- Jouni Ryn? mailto://Jouni.Ryno@REDACTED/ http://www.geo.fmi.fi/~ryno/ Finnish Meteorological Institute http://www.fmi.fi/ Space Research http://www.geo.fmi.fi/ P.O.BOX 503 Tel (+358)-9-19294656 FIN-00101 Helsinki FAX (+358)-9-19294603 Finland priv-GSM (+358)-50-5302903 "It's just zeros and ones, it cannot be hard" From serge@REDACTED Fri Aug 19 16:08:42 2005 From: serge@REDACTED (Serge Aleynikov) Date: Fri, 19 Aug 2005 10:08:42 -0400 Subject: multiple interfaces Message-ID: <4305E7EA.4040100@hq.idt.net> Hi, Is there a way to force the erlang distribution on a host with two network interfaces to bind only to one IP? I am trying to test how network partitioning is handled by my application, and for this reason I'd like to ensure that a shut down of a net interface used by Erlang doesn't kill my terminal session connected through the second interface. I'm hoping there is some {ip,IPAddress} configuration parameter similar to the one in gen_tcp that can be given at startup, but I don't see anything relevant in the documentation. Thanks. Serge From chandrashekhar.mullaparthi@REDACTED Fri Aug 19 16:22:50 2005 From: chandrashekhar.mullaparthi@REDACTED (Chandrashekhar Mullaparthi) Date: Fri, 19 Aug 2005 15:22:50 +0100 Subject: multiple interfaces In-Reply-To: <4305E7EA.4040100@hq.idt.net> References: <4305E7EA.4040100@hq.idt.net> Message-ID: The kernel application has an enironment variable which it sets: inet_dist_use_interface which you can use to specify which interface it should bind to. cheers Chandru On 19 Aug 2005, at 15:08, Serge Aleynikov wrote: > Hi, > > Is there a way to force the erlang distribution on a host with two > network interfaces to bind only to one IP? > > I am trying to test how network partitioning is handled by my > application, and for this reason I'd like to ensure that a shut down > of a net interface used by Erlang doesn't kill my terminal session > connected through the second interface. > > I'm hoping there is some {ip,IPAddress} configuration parameter > similar to the one in gen_tcp that can be given at startup, but I > don't see anything relevant in the documentation. > > Thanks. > > Serge > From mats.cronqvist@REDACTED Fri Aug 19 16:37:39 2005 From: mats.cronqvist@REDACTED (Mats Cronqvist) Date: Fri, 19 Aug 2005 16:37:39 +0200 Subject: building gtkNode In-Reply-To: References: <32852.85.224.131.27.1124319363.squirrel@webmail.wiger.net> <43044189.6030206@ericsson.com> Message-ID: <4305EEB3.6070805@ericsson.com> Ulf Wiger wrote: > Den 2005-08-18 10:06:33 skrev Mats Cronqvist : > >> i think the sane value of $OTP_ROOT on debian is /usr/local. is it >> not? >> >> what version of gtk do you have? >> pkg-config --modversion gtk+-2.0 >> 2.6.8 > > > Mine is 2.2.2 > actually, if you get the latest gtkNode from jungerl, there is a make generate target that will regenerate the g*_generated.h files from your gtk *.h files. the new ones will show up in gtkNode/priv/generator/gen copy them to gtkNode/gen, make and you should be good the generator program depends on python though... mats From erlang@REDACTED Fri Aug 19 16:44:29 2005 From: erlang@REDACTED (Peter-Henry Mander) Date: Fri, 19 Aug 2005 15:44:29 +0100 Subject: multiple interfaces In-Reply-To: <4305E7EA.4040100@hq.idt.net> References: <4305E7EA.4040100@hq.idt.net> Message-ID: <1124462669.6994.30.camel@hymir.newport-networks.com> Hi Serge, I believe you may find prim_inet:connect/2 and /3 useful. It does the same as Unix man 2 connect: "If the socket is of type SOCK_DGRAM then the serv_addr address is the address to which datagrams are sent by default, and the only address from which datagrams are received." connect(insock(), IP, Port) -> ok | {error, Reason} connect(insock(), IP, Port, Timeout) -> ok | {error, Reason} Pete. On Fri, 2005-08-19 at 10:08 -0400, Serge Aleynikov wrote: > Hi, > > Is there a way to force the erlang distribution on a host with two > network interfaces to bind only to one IP? > > I am trying to test how network partitioning is handled by my > application, and for this reason I'd like to ensure that a shut down of > a net interface used by Erlang doesn't kill my terminal session > connected through the second interface. > > I'm hoping there is some {ip,IPAddress} configuration parameter similar > to the one in gen_tcp that can be given at startup, but I don't see > anything relevant in the documentation. > > Thanks. > > Serge > -- "The Tao of Programming flows far away and returns on the wind of morning." From serge@REDACTED Fri Aug 19 17:11:50 2005 From: serge@REDACTED (Serge Aleynikov) Date: Fri, 19 Aug 2005 11:11:50 -0400 Subject: multiple interfaces In-Reply-To: References: <4305E7EA.4040100@hq.idt.net> Message-ID: <4305F6B6.3040801@hq.idt.net> Thank you, this is exactly what I was looking for. Just for the sake of completeness of this thread, based on your reply I found: The kernel/src/inet_tcp_dist.erl module checks three environment variables: {inet_dist_use_interface, IP::ip_address()} - defines the IP address to bind to {inet_dist_listen_min, FirstPort::integer()} {inet_dist_listen_max, LastPort::integer()} - define the First...Last port range for the listener socket Serge Chandrashekhar Mullaparthi wrote: > The kernel application has an enironment variable which it sets: > inet_dist_use_interface which you can use to specify which interface it > should bind to. > > cheers > Chandru > > On 19 Aug 2005, at 15:08, Serge Aleynikov wrote: > >> Hi, >> >> Is there a way to force the erlang distribution on a host with two >> network interfaces to bind only to one IP? >> >> I am trying to test how network partitioning is handled by my >> application, and for this reason I'd like to ensure that a shut down >> of a net interface used by Erlang doesn't kill my terminal session >> connected through the second interface. >> >> I'm hoping there is some {ip,IPAddress} configuration parameter >> similar to the one in gen_tcp that can be given at startup, but I >> don't see anything relevant in the documentation. >> >> Thanks. >> >> Serge >> > > -- Serge Aleynikov R&D Telecom, IDT Corp. Tel: (973) 438-3436 Fax: (973) 438-1464 serge@REDACTED From deverlang@REDACTED Fri Aug 19 20:37:49 2005 From: deverlang@REDACTED (Dev Erlang) Date: Sat, 20 Aug 2005 00:07:49 +0530 Subject: yet another gui framework for Erlang In-Reply-To: <4303443F.8010000@ericsson.com> References: <43033A4E.3010405@hyber.org> <4303443F.8010000@ericsson.com> Message-ID: On 8/17/05, Mats Cronqvist wrote: > as usual, there's much talk about GUI stuff for Erlang. here's my attempt to > add to the confusion. > > > mats > Hi, The best way to program GUI in a given language is to utilize the artifacts and core strength and features of the language. The same is applicable in the case of Erlang. ex11 is a good option, from that perspective. thanks Dev. From vlad_dumitrescu@REDACTED Fri Aug 19 22:38:51 2005 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Fri, 19 Aug 2005 22:38:51 +0200 Subject: [ANN] Eclipse Erlang IDE 0.3.0 Message-ID: Hi all, After a long pause without any releases, we have exciting news. The plugin has matured quite a lot, I can use it in my everyday work even if there is atill a lot to do. I am attaching the README file and hope that there will be plenty of bug reports! :-) Feature requests too, as well as any other related thoughts or ideas. best regards, Vlad Important ========= * As from version 0.2.0, this plugin is targeted at Eclipse 3.1. * It is tested with R10B-6, mostly on Windows but also Linux FC4 * For bug reports and feature requests, please use the SouceForge trackers at http://sourceforge.net/projects/erlide/. Mailing to erlide-devel@REDACTED would be the second option. Installation notes: =================== - Install either from remote site http://erlide.sf.net/update, or download the archived update site from the file releases. - After installing the plugin, the Erlang environment has to be set * go to window->Preferences->Erlang->Runtime and enter the Erlang root directory ($ERL_TOP) - *Incompatibility* If you have any Erlang project used with 0.2.4 or earlier, you will have to recreate it. This is due to a new preference storage mechanism. News for 0.3.0 ============== - A Module Wizard has been added (thanks to Lukas Larsson). It can generate most of the module skeletons we all love from the Emacs environment. - Various bug fixes and small improvements: builder, syntax highlighting and more. News for 0.2.5 ============== - LiveExpressions update themselves after rebuilding. A cool way to check if that bug you were hunting has disappeared! ;-) - The builder is still shaky, if you suspect it didn't compile and load your files, try a clean build first. - There's been a lot of refactoring under the hood, the result being a more robust backend. There is only one Erlang node as backend, hosting all projects. Less confusing UI, but with potential problems if several open projects have modules named identically. Later one will be able to launch an Erlang node with only selected projects. Developer news: - Added a new plugin erlide-basic-ui, to handle runtime preferences. The "regular" ui plugin was depending on a backend to be running, but when first installing the backend couldn't start because it wasn't properly configured. - So now Erlide is self-hosting! The projects have an Erlang nature, so developers have to install a binary version of 0.2.5 or later to get things working. - The erlang-builder project has been deprecated and retired, as it's not needed anymore. News for 0.2.3 ============== - Fixed builder, now it also loads the compiled modules into the project's node. - There's a new view, LiveExpressions, where one can enter expressions to be evaluated and can see the results. It should refresh itself after a build, so one can have some testing calls there and need not type them in the shell over and over again. However, it's only alpha status: expressions aren't saved, can't be removed either (except by restarting Eclipse) - Syntax highlighting now uses an Erlang based scanner. I hacked erl_scan so that it returns char offset in file instead of line number, and also recognizes comments, macros, records different types of numbers, bifs. In some ways, it's better than Emacs' but in others is still lacking (because syntax isn't enough, we need to do some parsing too). Developer news: - There is a new project in the CVS, module erlide/erlang-builder, that implements simple nature and builder for projects that aren't completely Erlang based (like for example erlide-core). See below for building notes. - erlide-launching project has been moved inside erlide-core, and isn't used anymore. News for 0.2.0 ============== - Eclipse 3.1 compatible. Older versions are no longer supported (3.1 has new APIs that aren't backwards compatible). - erlide-jinterface uses OtpErlang.jar from R10B-5 - Erlang no longer must be on the path, the value entered in the preferences is always used. (thanks to Mickael Remond) - Console input works now, just try it! The cursor may be placed wrong, but input goes where it should. - Several minor enhancements. Building notes: =============== A word of advice to the brave that might try to build the plugin (not applicable if you only want to run it): * install and configure a binary 0.2.5 or later. Configuration is mainly pointing it to' $ERL_TOP; the output directory should remain "ebin", and any compiler args you like (you must enter something and then delete it, otherwise the "OK" button remains grayed). Only then you can fiddle with the Erlang files and get them compiled. * I haven't investigated this thoroughly, but on my Linux box I need to start manually a distributed node in order to get epmd running. Enjoy! /Vlad From sebastian@REDACTED Sat Aug 20 19:38:55 2005 From: sebastian@REDACTED (Sebastian Bello) Date: Sat, 20 Aug 2005 14:38:55 -0300 Subject: Erlang ftp client API Message-ID: <001801c5a5ae$0a7a0ab0$dc00a8c0@INSWITCH244> Hi all, does anybody know of an Erlang ftp client API? Thanks, Sebastian- Prepaid Expertise - Programmable Switches Powered by Ericsson Licensed Technology Sebasti?n Bello - Engineer - Development Center - IN Switch Solutions Inc. Headquarters - Miami-U.S.A. Tel: 1305-3578076 Fax: 1305-7686260 Development Center - Montevideo - Uruguay Tel/Fax: 5982-7104457 IN SWITCH EMEA Phone: +33 0 6 0335 9427 - Fax: +33 0 4 93655773 / emea@REDACTED IN SWITCH ASIA Phone: +92 51 2800397/8- Fax: +92 51 2800399/ inswasia@REDACTED e-mail: sebastian@REDACTED -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image001.gif Type: image/gif Size: 1429 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: logoparafondo.gif Type: image/gif Size: 16886 bytes Desc: not available URL: From sebastian@REDACTED Sat Aug 20 20:09:58 2005 From: sebastian@REDACTED (Sebastian Bello) Date: Sat, 20 Aug 2005 15:09:58 -0300 Subject: Erlang ftp client API References: <001801c5a5ae$0a7a0ab0$dc00a8c0@INSWITCH244> Message-ID: <003a01c5a5b2$60d3c460$dc00a8c0@INSWITCH244> Sorry!!!!!!! I didn't see the standard module. Sebastian- ----- Original Message ----- From: Sebastian Bello To: erlang-questions@REDACTED Sent: Saturday, August 20, 2005 2:38 PM Subject: Erlang ftp client API Hi all, does anybody know of an Erlang ftp client API? Thanks, Sebastian- Prepaid Expertise - Programmable Switches Powered by Ericsson Licensed Technology Sebasti?n Bello - Engineer - Development Center - IN Switch Solutions Inc. Headquarters - Miami-U.S.A. Tel: 1305-3578076 Fax: 1305-7686260 Development Center - Montevideo - Uruguay Tel/Fax: 5982-7104457 IN SWITCH EMEA Phone: +33 0 6 0335 9427 - Fax: +33 0 4 93655773 / emea@REDACTED IN SWITCH ASIA Phone: +92 51 2800397/8- Fax: +92 51 2800399/ inswasia@REDACTED e-mail: sebastian@REDACTED -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image001.gif Type: image/gif Size: 1429 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: logoparafondo.gif Type: image/gif Size: 16886 bytes Desc: not available URL: From sean.hinde@REDACTED Sat Aug 20 20:12:11 2005 From: sean.hinde@REDACTED (Sean Hinde) Date: Sat, 20 Aug 2005 19:12:11 +0100 Subject: Erlang ftp client API In-Reply-To: <001801c5a5ae$0a7a0ab0$dc00a8c0@INSWITCH244> References: <001801c5a5ae$0a7a0ab0$dc00a8c0@INSWITCH244> Message-ID: http://erlang.se/doc/doc-5.4.8/lib/inets-4.5/doc/html/ftp.html Sean On 20 Aug 2005, at 18:38, Sebastian Bello wrote: > Hi all, > > does anybody know of an Erlang ftp client API? > Thanks, > Sebastian- > <001201c5a5ae$09848720$dc00a8c0> > Prepaid Expertise - Programmable Switches > Powered by Ericsson Licensed Technology > Sebasti?n Bello - Engineer - Development Center - IN Switch > Solutions Inc. > Headquarters - Miami-U.S.A. Tel: 1305-3578076 Fax: 1305-7686260 > Development Center - Montevideo - Uruguay Tel/Fax: 5982-7104457 > IN SWITCH EMEA Phone: +33 0 6 0335 9427 - Fax: +33 0 4 93655773 / > emea@REDACTED > IN SWITCH ASIA Phone: +92 51 2800397/8- Fax: +92 51 2800399/ > inswasia@REDACTED > e-mail: sebastian@REDACTED > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From orbitz@REDACTED Sat Aug 20 20:24:52 2005 From: orbitz@REDACTED (orbitz@REDACTED) Date: Sat, 20 Aug 2005 14:24:52 -0400 Subject: Erlang ftp client API In-Reply-To: <001801c5a5ae$0a7a0ab0$dc00a8c0@INSWITCH244> References: <001801c5a5ae$0a7a0ab0$dc00a8c0@INSWITCH244> Message-ID: <1abb2a9fed9a2174804bd75360510946@ezabel.com> I did a quick search and did not see one. It shouldn't be too hard to make though. http://jungerl.sourceforge.net/ has code for an ftpd, i'm not sure if that will help you out or not. On Aug 20, 2005, at 1:38 PM, Sebastian Bello wrote: > Hi all, > ? > does anybody know of an Erlang ftp client API? > Thanks, > ??? Sebastian- > > Prepaid Expertise - Programmable Switches > Powered by Ericsson Licensed Technology > Sebasti?n Bello - Engineer - Development Center - IN Switch Solutions > Inc. > Headquarters - Miami-U.S.A. Tel: 1305-3578076 Fax: 1305-7686260 > Development Center - Montevideo - Uruguay Tel/Fax: 5982-7104457 > IN SWITCH EMEA Phone: +33 0 6 0335 9427 - Fax: +33 0 4 93655773 / > emea@REDACTED > IN SWITCH ASIA Phone: +92 51 2800397/8- Fax: +92 51 2800399/ > inswasia@REDACTED > e-mail: sebastian@REDACTED > ? From orbitz@REDACTED Sat Aug 20 22:34:05 2005 From: orbitz@REDACTED (orbitz@REDACTED) Date: Sat, 20 Aug 2005 16:34:05 -0400 Subject: Overriding functionality Message-ID: <8826a2ae57890a2ab58dda878e5da6cb@ezabel.com> I had a situation in a python project where for 99% of the uses of this class, the programmed behavior was perfect. But for a few situations one of the member functions of that classes needed to use an alternate object. On top of that, we didn't even know it needed that until we came across it with one of our clients broken interfaces. To solve the problem all I had to do was subclass the object and override that function. Is there any common erlang idiom for this? This being, basically, inheritance I guess. I'm not looking for an OO model really, I don't think, but sometimes it does seem easier to simply override functionality. How is this situation even dealt with in a language like erlang? Thank you From kruegger@REDACTED Sun Aug 21 00:01:14 2005 From: kruegger@REDACTED (Stephen Han) Date: Sat, 20 Aug 2005 15:01:14 -0700 Subject: [ANN] Eclipse Erlang IDE 0.3.0 In-Reply-To: References: Message-ID: <86f1f535050820150159e718bc@mail.gmail.com> Vlad I download the erlide-0.3.0 and installed it in the eclipse. However, when I tried to set the $ERL_TOP in the preference->erlang ->Runtime menu, the "apply" button does not get enabled. Simply, I could not apply the changes. Also if I try to access other menu such as "Code templates' or "Editor", I got an error : "Unable to create the selected preference page. Reason: Plug-in org.erlide.ui was unalbe to load class org.erlide.ui.erlangsource.prefs.ErlangSourcePreferencePage. " If I looked at the "Plug-in Details" in "About Eclipse SDK" window. I do see 3 erlide entries. However, I am still not sure about how to install plug-ins in Eclipse since this is my first time using Eclipse. What am I missing? Does error tell you any thing? I guess it should be simple process because your installation procedure is only several lines. regards, On 8/19/05, Vlad Dumitrescu wrote: > Hi all, > > After a long pause without any releases, we have exciting news. The plugin > has matured quite a lot, I can use it in my everyday work even if there is > atill a lot to do. > > I am attaching the README file and hope that there will be plenty of bug > reports! :-) Feature requests too, as well as any other related thoughts or > ideas. > > best regards, > Vlad > > > Important > ========= > * As from version 0.2.0, this plugin is targeted at Eclipse 3.1. > * It is tested with R10B-6, mostly on Windows but also Linux FC4 > * For bug reports and feature requests, please use the SouceForge trackers > at > http://sourceforge.net/projects/erlide/. Mailing to erlide-devel@REDACTED > would > be the second option. > > Installation notes: > =================== > - Install either from remote site http://erlide.sf.net/update, or download > the archived update site from the file releases. > - After installing the plugin, the Erlang environment has to be set > * go to window->Preferences->Erlang->Runtime > and enter the Erlang root directory ($ERL_TOP) > - *Incompatibility* If you have any Erlang project used with 0.2.4 or > earlier, you will > have to recreate it. This is due to a new preference storage mechanism. > > News for 0.3.0 > ============== > - A Module Wizard has been added (thanks to Lukas Larsson). It can generate > most of the > module skeletons we all love from the Emacs environment. > - Various bug fixes and small improvements: builder, syntax highlighting and > more. > > News for 0.2.5 > ============== > - LiveExpressions update themselves after rebuilding. A cool way to check if > that bug > you were hunting has disappeared! ;-) > - The builder is still shaky, if you suspect it didn't compile and load your > files, > try a clean build first. > - There's been a lot of refactoring under the hood, the result being a more > robust backend. > There is only one Erlang node as backend, hosting all projects. Less > confusing UI, but > with potential problems if several open projects have modules named > identically. > Later one will be able to launch an Erlang node with only selected projects. > Developer news: > - Added a new plugin erlide-basic-ui, to handle runtime preferences. The > "regular" ui > plugin was depending on a backend to be running, but when first installing > the backend > couldn't start because it wasn't properly configured. > - So now Erlide is self-hosting! The projects have an Erlang nature, so > developers have to > install a binary version of 0.2.5 or later to get things working. > - The erlang-builder project has been deprecated and retired, as it's not > needed anymore. > > News for 0.2.3 > ============== > - Fixed builder, now it also loads the compiled modules into the project's > node. > - There's a new view, LiveExpressions, where one can enter expressions to be > evaluated and > can see the results. It should refresh itself after a build, so one can have > some testing > calls there and need not type them in the shell over and over again. > However, it's only > alpha status: expressions aren't saved, can't be removed either (except by > restarting Eclipse) > - Syntax highlighting now uses an Erlang based scanner. I hacked erl_scan so > that it returns > char offset in file instead of line number, and also recognizes comments, > macros, records > different types of numbers, bifs. In some ways, it's better than Emacs' but > in others is > still lacking (because syntax isn't enough, we need to do some parsing too). > Developer news: > - There is a new project in the CVS, module erlide/erlang-builder, that > implements > simple nature and builder for projects that aren't completely Erlang based > (like for > example erlide-core). See below for building notes. > - erlide-launching project has been moved inside erlide-core, and isn't used > anymore. > > News for 0.2.0 > ============== > - Eclipse 3.1 compatible. Older versions are no longer supported (3.1 has > new APIs that > aren't backwards compatible). > - erlide-jinterface uses OtpErlang.jar from R10B-5 > - Erlang no longer must be on the path, the value entered in the preferences > is always used. > (thanks to Mickael Remond) > - Console input works now, just try it! The cursor may be placed wrong, but > input goes > where it should. > - Several minor enhancements. > > Building notes: > =============== > A word of advice to the brave that might try to build the plugin (not > applicable if you > only want to run it): > * install and configure a binary 0.2.5 or later. Configuration is mainly > pointing it to' > $ERL_TOP; the output directory should remain "ebin", and any compiler args > you like (you must > enter something and then delete it, otherwise the "OK" button remains > grayed). Only then > you can fiddle with the Erlang files and get them compiled. > * I haven't investigated this thoroughly, but on my Linux box I need to > start > manually a distributed node in order to get epmd running. > > Enjoy! > /Vlad > From ke.han@REDACTED Sun Aug 21 02:17:16 2005 From: ke.han@REDACTED (ke.han) Date: Sun, 21 Aug 2005 08:17:16 +0800 Subject: [Erlide-devel] Re: [ANN] Eclipse Erlang IDE 0.3.0 In-Reply-To: <86f1f535050820150159e718bc@mail.gmail.com> References: <86f1f535050820150159e718bc@mail.gmail.com> Message-ID: <4307C80C.5000104@redstarling.com> To enable to "apply" or "ok" buttons, you need to edit the "extra arguments" field. Just put in a space and then delete the space. This is the magic you need. ke han Stephen Han wrote: >Vlad > >I download the erlide-0.3.0 and installed it in the eclipse. >However, when I tried to set the $ERL_TOP in the preference->erlang >->Runtime menu, the "apply" button does not get enabled. Simply, I >could not apply the changes. Also if I try to access other menu such >as "Code templates' or "Editor", I got an error : > >"Unable to create the selected preference page. >Reason: >Plug-in org.erlide.ui was unalbe to load class >org.erlide.ui.erlangsource.prefs.ErlangSourcePreferencePage. " > >If I looked at the "Plug-in Details" in "About Eclipse SDK" window. I >do see 3 erlide entries. >However, I am still not sure about how to install plug-ins in Eclipse >since this is my first time using Eclipse. > >What am I missing? Does error tell you any thing? > >I guess it should be simple process because your installation >procedure is only several lines. > >regards, > > >On 8/19/05, Vlad Dumitrescu wrote: > > >>Hi all, >> >>After a long pause without any releases, we have exciting news. The plugin >>has matured quite a lot, I can use it in my everyday work even if there is >>atill a lot to do. >> >>I am attaching the README file and hope that there will be plenty of bug >>reports! :-) Feature requests too, as well as any other related thoughts or >>ideas. >> >>best regards, >>Vlad >> >> >>Important >>========= >>* As from version 0.2.0, this plugin is targeted at Eclipse 3.1. >>* It is tested with R10B-6, mostly on Windows but also Linux FC4 >>* For bug reports and feature requests, please use the SouceForge trackers >>at >>http://sourceforge.net/projects/erlide/. Mailing to erlide-devel@REDACTED >>would >>be the second option. >> >>Installation notes: >>=================== >>- Install either from remote site http://erlide.sf.net/update, or download >>the archived update site from the file releases. >>- After installing the plugin, the Erlang environment has to be set >>* go to window->Preferences->Erlang->Runtime >>and enter the Erlang root directory ($ERL_TOP) >>- *Incompatibility* If you have any Erlang project used with 0.2.4 or >>earlier, you will >>have to recreate it. This is due to a new preference storage mechanism. >> >>News for 0.3.0 >>============== >>- A Module Wizard has been added (thanks to Lukas Larsson). It can generate >>most of the >>module skeletons we all love from the Emacs environment. >>- Various bug fixes and small improvements: builder, syntax highlighting and >>more. >> >>News for 0.2.5 >>============== >>- LiveExpressions update themselves after rebuilding. A cool way to check if >>that bug >>you were hunting has disappeared! ;-) >>- The builder is still shaky, if you suspect it didn't compile and load your >>files, >>try a clean build first. >>- There's been a lot of refactoring under the hood, the result being a more >>robust backend. >>There is only one Erlang node as backend, hosting all projects. Less >>confusing UI, but >>with potential problems if several open projects have modules named >>identically. >>Later one will be able to launch an Erlang node with only selected projects. >>Developer news: >>- Added a new plugin erlide-basic-ui, to handle runtime preferences. The >>"regular" ui >>plugin was depending on a backend to be running, but when first installing >>the backend >>couldn't start because it wasn't properly configured. >>- So now Erlide is self-hosting! The projects have an Erlang nature, so >>developers have to >>install a binary version of 0.2.5 or later to get things working. >>- The erlang-builder project has been deprecated and retired, as it's not >>needed anymore. >> >>News for 0.2.3 >>============== >>- Fixed builder, now it also loads the compiled modules into the project's >>node. >>- There's a new view, LiveExpressions, where one can enter expressions to be >>evaluated and >>can see the results. It should refresh itself after a build, so one can have >>some testing >>calls there and need not type them in the shell over and over again. >>However, it's only >>alpha status: expressions aren't saved, can't be removed either (except by >>restarting Eclipse) >>- Syntax highlighting now uses an Erlang based scanner. I hacked erl_scan so >>that it returns >>char offset in file instead of line number, and also recognizes comments, >>macros, records >>different types of numbers, bifs. In some ways, it's better than Emacs' but >>in others is >>still lacking (because syntax isn't enough, we need to do some parsing too). >>Developer news: >>- There is a new project in the CVS, module erlide/erlang-builder, that >>implements >>simple nature and builder for projects that aren't completely Erlang based >>(like for >>example erlide-core). See below for building notes. >>- erlide-launching project has been moved inside erlide-core, and isn't used >>anymore. >> >>News for 0.2.0 >>============== >>- Eclipse 3.1 compatible. Older versions are no longer supported (3.1 has >>new APIs that >>aren't backwards compatible). >>- erlide-jinterface uses OtpErlang.jar from R10B-5 >>- Erlang no longer must be on the path, the value entered in the preferences >>is always used. >>(thanks to Mickael Remond) >>- Console input works now, just try it! The cursor may be placed wrong, but >>input goes >>where it should. >>- Several minor enhancements. >> >>Building notes: >>=============== >>A word of advice to the brave that might try to build the plugin (not >>applicable if you >>only want to run it): >>* install and configure a binary 0.2.5 or later. Configuration is mainly >>pointing it to' >>$ERL_TOP; the output directory should remain "ebin", and any compiler args >>you like (you must >>enter something and then delete it, otherwise the "OK" button remains >>grayed). Only then >>you can fiddle with the Erlang files and get them compiled. >>* I haven't investigated this thoroughly, but on my Linux box I need to >>start >>manually a distributed node in order to get epmd running. >> >>Enjoy! >>/Vlad >> >> >> > > >------------------------------------------------------- >SF.Net email is Sponsored by the Better Software Conference & EXPO >September 19-22, 2005 * San Francisco, CA * Development Lifecycle Practices >Agile & Plan-Driven Development * Managing Projects & Teams * Testing & QA >Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf >_______________________________________________ >Erlide-devel mailing list >Erlide-devel@REDACTED >https://lists.sourceforge.net/lists/listinfo/erlide-devel > > From matthias@REDACTED Sun Aug 21 08:06:41 2005 From: matthias@REDACTED (Matthias Lang) Date: Sun, 21 Aug 2005 08:06:41 +0200 Subject: mailing list archives as mbox file(s) - on trapexit? In-Reply-To: <6DACEA5F-20E8-4FD1-B955-7399CA7455DC@acm.org> References: <6DACEA5F-20E8-4FD1-B955-7399CA7455DC@acm.org> Message-ID: <17160.6641.40161.791988@antilipe.corelatus.se> Reto Kramer writes: > I'm old fashioned and like mailing list archives on my local mail > client, so that I can search years of wisdom during my daily train > rides. Many mailing lists make yearly or monthly mbox files > available. Is there someone out there who could do that for the > erlang-questions list? Doing this isn't so hard. Here's how: http://www.erlang.org/ml-archive/erlang-questions/200403/msg00147.html Matthias From alex.arnon@REDACTED Sun Aug 21 12:58:08 2005 From: alex.arnon@REDACTED (Alex Arnon) Date: Sun, 21 Aug 2005 13:58:08 +0300 Subject: Generating unique ids in Mnesia In-Reply-To: <1423054C-B377-48F4-BF0B-1F61597B2BAF@gmail.com> References: <2A85DC94-2162-46C7-82E4-DE7210996761@gmail.com> <1423054C-B377-48F4-BF0B-1F61597B2BAF@gmail.com> Message-ID: <944da41d05082103587ca54a40@mail.gmail.com> On 8/19/05, Joel Reymont wrote: > Well, I do have to keep the counters between server restarts, > crashes, etc. > Well how about keeping the "last ID" info in Mnesia, and let the ID creator process load it from there? From alex.arnon@REDACTED Sun Aug 21 14:39:24 2005 From: alex.arnon@REDACTED (Alex Arnon) Date: Sun, 21 Aug 2005 15:39:24 +0300 Subject: Overriding functionality In-Reply-To: <8826a2ae57890a2ab58dda878e5da6cb@ezabel.com> References: <8826a2ae57890a2ab58dda878e5da6cb@ezabel.com> Message-ID: <944da41d05082105394a95178f@mail.gmail.com> On 8/20/05, orbitz@REDACTED wrote: > I had a situation in a python project where for 99% of the uses of this > class, the programmed behavior was perfect. But for a few situations > one of the member functions of that classes needed to use an alternate > object. On top of that, we didn't even know it needed that until we > came across it with one of our clients broken interfaces. To solve the > problem all I had to do was subclass the object and override that > function. Is there any common erlang idiom for this? This being, > basically, inheritance I guess. I'm not looking for an OO model > really, I don't think, but sometimes it does seem easier to simply > override functionality. How is this situation even dealt with in a > language like erlang? > > Thank you > > (Note that I speak as a newbie, so take this with a pich of salt :) ) The simplest answer is "it depends on what type of component you are working on" but generally, Erlang/OTP encourages the use of symbolic indirection and behaviours to obtain any type of entity behavioural inheritance. I think you can use import+export module attributes in order to more easily simulate behaviour inheritance (is this correct?). From joelr1@REDACTED Sun Aug 21 23:12:19 2005 From: joelr1@REDACTED (Joel Reymont) Date: Sun, 21 Aug 2005 23:12:19 +0200 Subject: Generating unique ids in Mnesia In-Reply-To: <944da41d05082103587ca54a40@mail.gmail.com> References: <2A85DC94-2162-46C7-82E4-DE7210996761@gmail.com> <1423054C-B377-48F4-BF0B-1F61597B2BAF@gmail.com> <944da41d05082103587ca54a40@mail.gmail.com> Message-ID: <9E941226-6C23-42ED-A6B9-56E385EF928C@gmail.com> I can achieve the same result with mnesia:dirty_update_counter() and I don't need any processes :-). On Aug 21, 2005, at 12:58 PM, Alex Arnon wrote: > Well how about keeping the "last ID" info in Mnesia, and let the ID > creator process load it from there? From mats.cronqvist@REDACTED Mon Aug 22 11:09:17 2005 From: mats.cronqvist@REDACTED (Mats Cronqvist) Date: Mon, 22 Aug 2005 11:09:17 +0200 Subject: yet another gui framework for Erlang In-Reply-To: <1124451943.5938.35.camel@adic> References: <43033A4E.3010405@hyber.org> <4303443F.8010000@ericsson.com> <1124445634.5938.14.camel@adic> <1124447187.5938.24.camel@adic> <4305C1FE.40406@ericsson.com> <1124451943.5938.35.camel@adic> Message-ID: <4309963D.5090605@ericsson.com> Jouni Ryn? wrote: [...] > The current scheme in 2.8 is to use the following API, GtkCairo is > obsolete: > http://developer.gnome.org/doc/API/2.0/gdk/gdk-Cairo-Interaction.html > > Not that I know! anything about that stuff. But it would require the > generation of the cairo callbacks to the gtkNode ... (please :) ) will definitely happen. mats From serge@REDACTED Mon Aug 22 13:38:42 2005 From: serge@REDACTED (Serge Aleynikov) Date: Mon, 22 Aug 2005 07:38:42 -0400 Subject: application startup In-Reply-To: References: <42FD12DA.8050805@hq.idt.net> <430615DD.5050200@hq.idt.net> Message-ID: <4309B942.2050704@hq.idt.net> Uffe, Over the weekend, I briefly tried to experiment with the builder app by taking your 'dist' application from the "How-to" section of trapexit.org, and trying to creage a distibution package. I had very little luck on getting a clean built. On the other hand the build process using target_system.erl worked well. It must be that some options weren't set correctly, but the errors are not very descriptive. The root of the 'dist' app is /home/serge/tmp/distr-erl/. The release file looks like this (note I added mnesia app because I wanted that to be included in the build): {release, {"Example","1.0"}, {erts,"5.4.8"}, [{kernel,"2.10.9"}, {stdlib,"1.13.8"}, {sasl, "2.0.1"}, {mnesia, "4.2.2", load}, {dist,"1.0"}]}. 1> builder:go([{app_dir, "/home/serge/tmp/distr-erl/lib/dist-1.0"},{report, verbose},{out_dir, "/home/serge/tmp/distr-erl/releases/1.0"},{path, ["/usr/local/lib/erlang/lib/*/ebin","/home/serge/tmp/distr-erl/lib/*/ebin"]},{make_app,false},{make_rel,false}]). pushed 1st report level verbose(2) redefined report level verbose(2) =ERROR REPORT==== 22-Aug-2005::07:35:10 === Error in process <0.30.0> with exit value: {{case_clause,[{"2.10.9",[]}]},[{builder,later_vsn,2},{builder,maybe_save_app,6},{builder,expand_path,4},{builder,expand_path,4},{builder,search_apps,4},{builder,'-go/1-fun-14-',1},{lists,foldl,3},{builder,go,1}]} ** exited: {{case_clause,[{"2.10.9",[]}]}, [{builder,later_vsn,2}, {builder,maybe_save_app,6}, {builder,expand_path,4}, {builder,expand_path,4}, {builder,search_apps,4}, {builder,'-go/1-fun-14-',1}, {lists,foldl,3}, {builder,go,1}]} ** Then I created an example.rel.src file and tried again: {release, {"Example","1.0"}, [kernel, stdlib, sasl, mnesia, dist]}. 2> builder:go([{app_dir, "/home/serge/tmp/distr-erl/lib/dist-1.0"},{report, verbose},{out_dir, "/home/serge/tmp/distr-erl/releases/1.0"},{path, ["/usr/local/lib/erlang/lib/*/ebin","/home/serge/tmp/distr-erl/lib/*/ebin"]},{make_app,false},{make_rel,true},{rel_file, "/home/serge/tmp/distr-erl/releases/1.0/example.rel.src"}]). pushed 1st report level verbose(2) redefined report level verbose(2) =ERROR REPORT==== 21-Aug-2005::08:35:46 === Error in process <0.91.0> with exit value: {undef,[{dict,store,[make_rel,false]},{lists,foldl,3},{builder,post_process_options,1},{lists,foldl,3},{builder,go,1},{erl_eval,do_apply,5},{shell,exprs,6},{shell,eval_loop,3}]} ** exited: {undef,[{dict,store,[make_rel,false]}, {lists,foldl,3}, {builder,post_process_options,1}, {lists,foldl,3}, {builder,go,1}, {erl_eval,do_apply,5}, {shell,exprs,6}, {shell,eval_loop,3}]} ** 11> builder:go([{app_dir, "/home/serge/tmp/distr-erl/lib/dist-1.0"},{report, verbose},{out_dir, "/home/serge/tmp/distr-erl/releases/1.0"},{path, ["/usr/local/lib/erlang/lib/*/ebin","/home/serge/tmp/distr-erl/lib/*/ebin"]},{make_app,false},{make_rel,true},{rel_file, "/home/serge/tmp/distr-erl/releases/1.0/example.rel.src"}]). At this point I gave up because I had to take my daugter to a swimming pool. My humble suggestion would be that instead of replying to my email you would expand the help (or write a small tutorial) on how to make use of the 'builder' tool. > ... To achieve the ease of use part, a tutorial > is badly needed. It's not that obvious how to get > started with it. Regards, Serge Ulf Wiger wrote: > Den 2005-08-19 19:24:45 skrev Serge Aleynikov : > >> Uffe, >> >> Is the 'builder' contrib supposed to be a complete replacement of >> target_system.erl documented below? >> >> http://erlang.se/doc/doc-5.4.8/doc/system_principles/part_frame.html > > > Builder tries to conform to the OTP system principles > as much as possible, so it's more of an attempt to > automate the process -- not replace it. > > Builder essentially tries to combine the following ideas: > > - automate some of the error-prone steps, like > getting the version numbers and the module list right. > > - explore the idea of incrementally building the > system: for each application, you can generate boot > scripts that let you start a full system up to and > including the application you're working on. Once > you get to the final application, you are building > the whole system. > > - if you usually want to build your scripts using the > latest available applications, this should not be > tedious and difficult. Builder will find out which > are the latest versions, as long as it gets the > application names and search paths. If you want to > be specific about versions, you can do that too. > > - try to achieve modularity in that once you've > specified build options for one application, they > can be reused (or optionally overridden) when adding > another. To some extent, OTP does this already, but > builder adds support for handling environment > variables this way. > > Essentially, ease of use for the beginner, and speed > and convenience for the power user were the modest > goals. To achieve the ease of use part, a tutorial > is badly needed. It's not that obvious how to get > started with it. > > /Uffe From ulf.wiger@REDACTED Mon Aug 22 15:15:05 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Mon, 22 Aug 2005 15:15:05 +0200 Subject: application startup Message-ID: > -----Original Message----- > From: owner-erlang-questions@REDACTED > [mailto:owner-erlang-questions@REDACTED]On Behalf Of Serge Aleynikov > Sent: den 22 augusti 2005 13:39 > To: Ulf Wiger > Cc: Erlang Questions > Subject: Re: application startup > > > Uffe, > > Over the weekend, I briefly tried to experiment with the > builder app by > taking your 'dist' application from the "How-to" section of > trapexit.org, and trying to creage a distibution package. I had very > little luck on getting a clean built. On the other hand the build > process using target_system.erl worked well. It must be that some > options weren't set correctly, but the errors are not very > descriptive. > > The root of the 'dist' app is /home/serge/tmp/distr-erl/. > The release > file looks like this (note I added mnesia app because I > wanted that to > be included in the build): > > {release, {"Example","1.0"}, {erts,"5.4.8"}, > [{kernel,"2.10.9"}, > {stdlib,"1.13.8"}, > {sasl, "2.0.1"}, > {mnesia, "4.2.2", load}, > {dist,"1.0"}]}. > > 1> builder:go([{app_dir, > "/home/serge/tmp/distr-erl/lib/dist-1.0"},{report, verbose},{out_dir, > "/home/serge/tmp/distr-erl/releases/1.0"},{path, > ["/usr/local/lib/erlang/lib/*/ebin","/home/serge/tmp/distr-erl > /lib/*/ebin"]},{make_app,false},{make_rel,false}]). > pushed 1st report level verbose(2) > redefined report level verbose(2) > > =ERROR REPORT==== 22-Aug-2005::07:35:10 === > Error in process <0.30.0> with exit value: > {{case_clause,[{"2.10.9",[]}]},[{builder,later_vsn,2},{builder > ,maybe_save_app,6},{builder,expand_path,4},{builder,expand_pat > h,4},{builder,search_apps,4},{builder,'-go/1-fun-14-',1},{list > s,foldl,3},{builder,go,1}]} > > ** exited: {{case_clause,[{"2.10.9",[]}]}, > [{builder,later_vsn,2}, > {builder,maybe_save_app,6}, > {builder,expand_path,4}, > {builder,expand_path,4}, > {builder,search_apps,4}, > {builder,'-go/1-fun-14-',1}, > {lists,foldl,3}, > {builder,go,1}]} ** > > Then I created an example.rel.src file and tried again: > > {release, {"Example","1.0"}, > [kernel, stdlib, sasl, mnesia, dist]}. > > 2> builder:go([{app_dir, > "/home/serge/tmp/distr-erl/lib/dist-1.0"},{report, verbose},{out_dir, > "/home/serge/tmp/distr-erl/releases/1.0"},{path, > ["/usr/local/lib/erlang/lib/*/ebin","/home/serge/tmp/distr-erl > /lib/*/ebin"]},{make_app,false},{make_rel,true},{rel_file, > "/home/serge/tmp/distr-erl/releases/1.0/example.rel.src"}]). > pushed 1st report level verbose(2) > redefined report level verbose(2) > > =ERROR REPORT==== 21-Aug-2005::08:35:46 === > Error in process <0.91.0> with exit value: > {undef,[{dict,store,[make_rel,false]},{lists,foldl,3},{builder ,post_process_options,1},{lists,foldl,3},{builder,go,1},{erl_eval,do_apply,5},> {shell,exprs,6},{shell,eval_loop,3}]} > > ** exited: {undef,[{dict,store,[make_rel,false]}, > {lists,foldl,3}, > {builder,post_process_options,1}, > {lists,foldl,3}, > {builder,go,1}, > {erl_eval,do_apply,5}, > {shell,exprs,6}, > {shell,eval_loop,3}]} ** > 11> builder:go([{app_dir, > "/home/serge/tmp/distr-erl/lib/dist-1.0"},{report, verbose},{out_dir, > "/home/serge/tmp/distr-erl/releases/1.0"},{path, > ["/usr/local/lib/erlang/lib/*/ebin","/home/serge/tmp/distr-erl > /lib/*/ebin"]},{make_app,false},{make_rel,true},{rel_file, > "/home/serge/tmp/distr-erl/releases/1.0/example.rel.src"}]). > > At this point I gave up because I had to take my daugter to a > swimming pool. > > My humble suggestion would be that instead of replying to my > email you > would expand the help (or write a small tutorial) on how to > make use of > the 'builder' tool. > > > ... To achieve the ease of use part, a tutorial > > is badly needed. It's not that obvious how to get > > started with it. > > Regards, > > Serge > > Ulf Wiger wrote: > > Den 2005-08-19 19:24:45 skrev Serge Aleynikov : > > > >> Uffe, > >> > >> Is the 'builder' contrib supposed to be a complete replacement of > >> target_system.erl documented below? > >> > >> http://erlang.se/doc/doc-5.4.8/doc/system_principles/part_frame.html > > > Builder tries to conform to the OTP system principles > as much as possible, so it's more of an attempt to > automate the process -- not replace it. > > Builder essentially tries to combine the following ideas: > > - automate some of the error-prone steps, like > getting the version numbers and the module list right. > > - explore the idea of incrementally building the > system: for each application, you can generate boot > scripts that let you start a full system up to and > including the application you're working on. Once > you get to the final application, you are building > the whole system. > > - if you usually want to build your scripts using the > latest available applications, this should not be > tedious and difficult. Builder will find out which > are the latest versions, as long as it gets the > application names and search paths. If you want to > be specific about versions, you can do that too. > > - try to achieve modularity in that once you've > specified build options for one application, they > can be reused (or optionally overridden) when adding > another. To some extent, OTP does this already, but > builder adds support for handling environment > variables this way. > > Essentially, ease of use for the beginner, and speed > and convenience for the power user were the modest > goals. To achieve the ease of use part, a tutorial > is badly needed. It's not that obvious how to get > started with it. > > /Uffe From ulf.wiger@REDACTED Mon Aug 22 15:29:42 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Mon, 22 Aug 2005 15:29:42 +0200 Subject: application startup Message-ID: Serge Aleynikov wrote: > > Over the weekend, I briefly tried to experiment with the > builder app by taking your 'dist' application from the > "How-to" section of trapexit.org, and trying to creage > a distibution package. I had very little luck on getting > a clean built. I have never tried that (as was perhaps evident from the result.) [snipped embarrassing crash reports] > At this point I gave up because I had to take my daugter to a > swimming pool. > > My humble suggestion would be that instead of replying to my > email you would expand the help (or write a small tutorial) > on how to make use of the 'builder' tool. I will reply only to acknowledge that I've noted your complaint, and also note that this is the first concrete feedback I can remember since posting it on Jungerl two years ago -- thank you! (: The fact that builder.erl hasn't been updated in two years is not so much a testimony to the quality of its code as it is an indication that noone, including me, has used it enough to bother. My daughter turned 2 last Saturday. That's my excuse for not having run any hobby projects that make use of builder during the last couple of years. (: /Uffe From nicolas@REDACTED Mon Aug 22 16:15:05 2005 From: nicolas@REDACTED (Nicolas Niclausse) Date: Mon, 22 Aug 2005 16:15:05 +0200 Subject: application startup In-Reply-To: References: Message-ID: <4309DDE9.8060806@niclux.org> Ulf Wiger (AL/EAB) ecrivait le 22.08.2005 15:29: > Serge Aleynikov wrote: > >>Over the weekend, I briefly tried to experiment with the >>builder app by taking your 'dist' application from the >>"How-to" section of trapexit.org, and trying to creage >>a distibution package. I had very little luck on getting >>a clean built. > > > I have never tried that (as was perhaps evident from the result.) > > > [snipped embarrassing crash reports] > > >>At this point I gave up because I had to take my daugter to a >>swimming pool. >> >>My humble suggestion would be that instead of replying to my >>email you would expand the help (or write a small tutorial) >>on how to make use of the 'builder' tool. > > > I will reply only to acknowledge that I've noted your > complaint, and also note that this is the first concrete > feedback I can remember since posting it on Jungerl two > years ago -- thank you! (: The fact that builder.erl hasn't > been updated in two years is not so much a testimony to the > quality of its code as it is an indication that noone, > including me, has used it enough to bother. FYI, i've been using builder.erl for 1,5 year for IDX-Tsunami (i was tired of manual version number updatesin .rel files, that's why i tried it). It's a bit awkward to make it work with applications not installed in the same location as erlang (or maybe I miss something), but it works. If your interested, you can take a look at the build process of tsunami (i know, the makefile is a bit ugly) http://cvs.idealx.org/cgi-bin/cvsweb/tsunami/Makefile.in?rev=1.3&content-type=text/x-cvsweb-markup Anyway, a tutorial would be great, indeed :) -- Nicolas From ulf.wiger@REDACTED Mon Aug 22 17:39:16 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Mon, 22 Aug 2005 17:39:16 +0200 Subject: application startup Message-ID: Nicolas Niclausse wrote: > > FYI, i've been using builder.erl for 1,5 year for IDX-Tsunami (i was > tired of manual version number updatesin .rel files, that's > why i tried it). Oops! Suddenly, I have a whole user community! > It's a bit awkward to make it work with applications not installed in > the same location as erlang (or maybe I miss something), but it works. I promise I'll work on the tutorial, and I'll most likely fix a hundred bugs in the process. I realise that I had focused mainly on supporting the idea of incrementally building a system, one app at a time. It wouldn't bee too hard to provide an entry point for building a whole system. Digging around, I noticed that I had started working on that two years ago, but when I tried the stuff I found today, it didn't work. ): /Uffe From cyberlync@REDACTED Tue Aug 23 08:28:29 2005 From: cyberlync@REDACTED (Eric Merritt) Date: Mon, 22 Aug 2005 23:28:29 -0700 Subject: driver_control and blocking process Message-ID: Guys, I am working up a linked in driver using control that may block waiting for external events. Control seemed to be the easiest to implement by far. However, I h ave a worry that this will block the vm as a whole. I thought it might be a good idea to ask the experts. Thanks, Eric From bjorn@REDACTED Tue Aug 23 08:59:55 2005 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 23 Aug 2005 08:59:55 +0200 Subject: driver_control and blocking process In-Reply-To: References: Message-ID: It will block the VM. You must use driver_select() to arrange for your driver to be called when somemthing happens with a file descriptor. (If you don't have a file descriptor, the standard trick is to create a pipe and pass the read end to driver to driver_select().) /Bjorn Eric Merritt writes: > Guys, > > I am working up a linked in driver using control that may block > waiting for external events. Control seemed to be the easiest to > implement by far. However, I h ave a worry that this will block the vm > as a whole. I thought it might be a good idea to ask the experts. > > Thanks, > Eric > -- Bj?rn Gustavsson, Erlang/OTP, Ericsson AB From cyberlync@REDACTED Tue Aug 23 09:27:57 2005 From: cyberlync@REDACTED (Eric Merritt) Date: Tue, 23 Aug 2005 00:27:57 -0700 Subject: driver_control and blocking process In-Reply-To: References: Message-ID: It's not blocking on a file descriptor, its a lib generating application specific events. There is an alternate api that allows for polling events. However, I would much rather simply wait for events to be generated rather then polling for them. I think the best way to solve this would be to do a pipe based driver, but pipe performance on windows is so dismal that I don't think its really an option. On 23 Aug 2005 08:59:55 +0200, Bjorn Gustavsson wrote: > It will block the VM. > > You must use driver_select() to arrange for your driver to > be called when somemthing happens with a file descriptor. > (If you don't have a file descriptor, the standard trick is > to create a pipe and pass the read end to driver to driver_select().) > > /Bjorn > > Eric Merritt writes: > > > Guys, > > > > I am working up a linked in driver using control that may block > > waiting for external events. Control seemed to be the easiest to > > implement by far. However, I h ave a worry that this will block the vm > > as a whole. I thought it might be a good idea to ask the experts. > > > > Thanks, > > Eric > > > > -- > Bj?rn Gustavsson, Erlang/OTP, Ericsson AB > From joe.armstrong@REDACTED Tue Aug 23 11:28:05 2005 From: joe.armstrong@REDACTED (Joe Armstrong (AL/EAB)) Date: Tue, 23 Aug 2005 11:28:05 +0200 Subject: Programming components Message-ID: Hello world, This document contains a few ideas that Uffe and I have been playing with. Erlang lacks a notion of types and a way of specifying components. This note describes a systems of dynamic types and type serializations which seems to us to be easy to understand and implement. Think of it as a sort of grand union of XML-RPC, and UBF. This is what XML-RPC, SOAP etc. should have been :-) Later this year I will release a library which simplifies writing components - for now I just want to discuss the ideas involved. Comments? /Joe On Types, serializations and components ======================================= Types ===== Any programming language must have a notion of variables and types. When we say Var = Value We must know the domain that Value belongs to. We state the domain of Var with a type declaration: Type Var = T Meaning that Var has type T. Type systems always have three parts: 1) A set of primitive types 2) Glue for making complex types from primitive types 3) Aliases for defining new types We can make a pretty powerful type system with two primitive types three types of glue and one way of making new types. The two primitive types are int() - meaning an integer str() - meaning a string The three types of glue are {T1, T2, ..., Tn} - tuple glue [T] - list glue T1 | T2| ... Tn - choice glue The way of making new types is: defType Name = T Serialization of type instances =============================== Given the above type system we now ask: How can we serialize instances of the types - easy - here are two possible serializations of type instances First the primitive types Type Instance Erlang Xml int() 23 23 23 str() "joe" <<"joe">>A joe Then the glue Type Instance Erlang Xml {int(), str()} {23,"joe"} {23,<<"str">} 23 joe [int()] [45,67] [45,67] 23 67 Note the 1:1 correspondence between the Erlang and XML serializations Components ========== What is a component? Definition: A component is a black box with ports. If you send the port a well-typed message it will respond with a well-typed reply. Below I discuss two styles of specify the behavior of components. One uses a CSP like notation the other an RPC like notation. CSP Components 1 ================ s +------------------+ ---| Black box xx | +------------------+ I define a component as a black box with one of more ports. All black boxes have at least one port called "s" (standard I/O) To *specify* the behavior of a black box I can write CSP style equations like this -component(ftp). -export_ports(s). Type fileName = str(). Start = s ? {"get", fileName()} -> s ! ({"ok", str()} | "enoFile"}) -> Start | s ? "ls" -> [fileName()]; | s ? {"put", fileName(), str()}. This tells me all that I need to know about the FTP server! << the notation is Process = Port [?|!] Type -> ... -> Process P ? T means receive a type T from port P P ! T means send a message of type T to P >> Framing ======= A serialization needs a "wrapper" to say what it is. So to use my server with the XML encoding I might make up a message like this Content-Type: text/myXml Content-Length: NNNN [blank line] get some file Or Content-Type: text/erlText Content-Length: NNNN [blank line] {<<"get">>, <<"some file">>} Or Content-Type: text/erlBin Content-Length: NNNN [blank line] term-to_binary({<<"get">>, <<"some file">>}) CSP Components 2 ================ What happens if my components call modules or other components? My ftp component will use the file component and the lists module -component(ftp). -export_ports(s). -import_ports(p is (s from file)). -modules(lists). Type fileName = str(). Start = s ? {"get", fileName()} -> p ! {"read", filename()} -> Reply | s ? "ls" -> [fileName()]; ... Reply -> p ? {"ok", str()} -> ... lists ! {"member", str(), [str()]} -> Ok Ok -> lists ? "true" -> ... This type of specification is precise but rapidly becomes unreadable. "State less RPC" seems nicer RPC Components ============== -component(ftp). Type fileName = str(). Protocol {"get", fileName()} => {"ok", str()}; "ls" => [fileName()} ... End A => B; means if we send the component ftp a type A it will reply with a type B. This is a normal RPC. Reverse RPC's are written: X <= Y Events A => $empty and Notificataions $empty => E (or E <= $empty) Bind ==== Bind associates an IP and a port with a component > Bind 222.34.56.78 2345 ftp Means that Port 2345 on IP 222.34.45.78 obeys the ftp protocol (if it is running) To use the server 1) Open a connection to 222.34.45.78 port 2345 2) Send it some correctly typed message, like: Content-Type: text/myXml Content-Length: NNNN [blank line] get some file Open questions ============== 1) What should the *semantics* of X => Y be - immediate reply - will eventually reply - will eventually reply or timeout 2) Can we interleave A => B and X <= Y 3) Timeouts Should we write A => B within Time 4) Which style of component specification is best CSP, or RCP? 5) Introspection - yes :-) Things to think about ===================== 1) Erlang strings. To obtain a beautiful mapping from abstract types to Erlang and XML I need to represent strings as <<"string">> and NOT "string" The change to the pretty printer that I posted earlier would encourage this usage. Note: representing strings as binaries *everywhere* has great advantages (think about it) 2) Dynamic type checking of these types is trivial - but can a type checker *prove* that your program follows a given component spec. All comments welcome /Joe From benefitsdragon@REDACTED Tue Aug 23 11:51:25 2005 From: benefitsdragon@REDACTED (Benefits Dragon) Date: Tue, 23 Aug 2005 10:51:25 +0100 Subject: Messages going missing in test suite Message-ID: <2db31700050823025128d692b4@mail.gmail.com> For some reason in one of my test suites messages that are being sent by one process are not being received by the other. When I run the same commands on the console (that includes the same test case setup) as are in the test it works fine and all messages are received that should be. The process is running just before I send the message so it's not that it doesn't exist and I've put print statements in to make sure it does get to the line where the message is sent and it prints out my statement just before I call the process but the second print statement at the top of my handle_cast function of my implementation of a gen_server doesn't show (as well as the operations the message should trigger not being done). (Also it is an async -> handle_cast which works normally so I am using the right one). Anyone ideas what may be wrong or how I might be able to find out? From bjorn@REDACTED Tue Aug 23 12:05:51 2005 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 23 Aug 2005 12:05:51 +0200 Subject: driver_control and blocking process In-Reply-To: References: Message-ID: Since you didn't mention the platform, I (wrongly) assumed Unix. On Windows, there is no need to use the pipe trick. Anything that WaitForObject() or WaitForMultipleObject() accept can be passed to driver_select(). If the library doesn't already give you a waitable object, you could use an Event object. /Bjorn Eric Merritt writes: > It's not blocking on a file descriptor, its a lib generating > application specific events. There is an alternate api that allows for > polling events. However, I would much rather simply wait for events to > be generated rather then polling for them. I think the best way to > solve this would be to do a pipe based driver, but pipe performance on > windows is so dismal that I don't think its really an option. > > On 23 Aug 2005 08:59:55 +0200, Bjorn Gustavsson wrote: > > It will block the VM. > > > > You must use driver_select() to arrange for your driver to > > be called when somemthing happens with a file descriptor. > > (If you don't have a file descriptor, the standard trick is > > to create a pipe and pass the read end to driver to driver_select().) > > > > /Bjorn > > > > Eric Merritt writes: > > > > > Guys, > > > > > > I am working up a linked in driver using control that may block > > > waiting for external events. Control seemed to be the easiest to > > > implement by far. However, I h ave a worry that this will block the vm > > > as a whole. I thought it might be a good idea to ask the experts. > > > > > > Thanks, > > > Eric > > > > > > > -- > > Bj?rn Gustavsson, Erlang/OTP, Ericsson AB > > > -- Bj?rn Gustavsson, Erlang/OTP, Ericsson AB From mats.cronqvist@REDACTED Tue Aug 23 13:00:17 2005 From: mats.cronqvist@REDACTED (Mats Cronqvist) Date: Tue, 23 Aug 2005 13:00:17 +0200 Subject: building gtkNode In-Reply-To: References: Message-ID: <430B01C1.6000004@ericsson.com> Ulf Wiger (AL/EAB) wrote: > Mats Cronqvist wrote: > >> i think the sane value of $OTP_ROOT on debian is >>/usr/local. is it not? > > > Perhaps I've been tainted by the well established > convention that OTP_ROOT point to /usr/local/erlang > in this case, as suggested by the Embedded Systems > User's Guide in the OTP documentation > (http://erlang.se/doc/doc-5.4.8/doc/embedded/embedded_solaris.html#1) well, by OTP_ROOT being "sane" I mean that the erl script is here; $OTP_ROOT/bin/erl and the libs here; $OTP_ROOT/lib/erlang/lib/os_mon- on my debian it means OTP_ROOT should be /usr (i was wrong earlier). it seems this conflicts with the "Embedded Systems User's Guide"... what is the correct (tm) definition? mats From fabien.dagnat@REDACTED Tue Aug 23 14:28:08 2005 From: fabien.dagnat@REDACTED (Fabien Dagnat) Date: Tue, 23 Aug 2005 14:28:08 +0200 Subject: Programming components In-Reply-To: References: Message-ID: <430B1658.1020609@enst-bretagne.fr> Hello , Joe Armstrong (AL/EAB) a ?crit : > > Hello world, > > Comments? > Open questions > ============== > > 4) Which style of component specification is best > CSP, or RCP? To get intesting guaranties from the contract checker, I would like to keep some of the state information of CSP. What I like in UBF is this state information and I think that state view is consistent with a Finite State Machine approach to concurrent programming. > 2) Dynamic type checking of these types is trivial - but can a type > checker *prove* that your program follows a given component spec. Previous works have demonstrated (I think), that if your erlang program is not too complex (that is it does not use some dynamic code: eval, building of atoms, ...). We can prove some correctness. The remaining problem is that of type equivalence in the presence of type aliasing. After "Type fileName = str()." do you consider that str == filename or not? - If you consider them equivalent then the type checker could <<*prove* that your program follows a given component spec.>>, but then the only interest of defining fileName type is documentation of the protocol. - If you do not consider them as equivalent, the type checker must be able to relate Erlang value with those types (perhaps the programmer have to add type annotation to his program). Fabien -- Fabien Dagnat -- Ma?tre de Conf?rences Mel : Fabien.Dagnat@REDACTED Web : perso-info.enst-bretagne.fr/~fdagnat Tel : (0|33) 2 29 00 14 09 Fax : (0|33) 2 29 00 12 82 Adr : Ecole Nationale Superieure des T?l?communication de Bretagne Departement Informatique Technop?le Brest-Iroise - CS 83818 - 29238 Brest Cedex 3 From bengt.kleberg@REDACTED Tue Aug 23 15:06:00 2005 From: bengt.kleberg@REDACTED (Bengt Kleberg) Date: Tue, 23 Aug 2005 15:06:00 +0200 Subject: Messages going missing in test suite In-Reply-To: <2db31700050823025128d692b4@mail.gmail.com> References: <2db31700050823025128d692b4@mail.gmail.com> Message-ID: <430B1F38.6020700@ericsson.com> On 2005-08-23 11:51, Benefits Dragon wrote: > For some reason in one of my test suites messages that are being sent > by one process are not being received by the other. When I run the > same commands on the console (that includes the same test case setup) > as are in the test it works fine and all messages are received that > should be. no answer, but a line of inquiery. perhaps the test server is running in its own erlang node. perhaps this node is not being able to send to the node where your process-to-be-tested is running. if you register the process-to-be-tested under a name, can the test server locate the pid with erlang:whereis/1 ? bengt From joe.armstrong@REDACTED Tue Aug 23 15:51:07 2005 From: joe.armstrong@REDACTED (Joe Armstrong (AL/EAB)) Date: Tue, 23 Aug 2005 15:51:07 +0200 Subject: Programming components Message-ID: > -----Original Message----- > From: Fabien Dagnat [mailto:fabien.dagnat@REDACTED] > Sent: den 23 augusti 2005 14:28 > To: Joe Armstrong (AL/EAB) > Cc: erlang-questions@REDACTED > Subject: Re: Programming components > > > Hello , > Joe Armstrong (AL/EAB) a ?crit : > > > > Hello world, > > > > Comments? > > > Open questions > > ============== > > > > 4) Which style of component specification is best > > CSP, or RCP? > To get intesting guaranties from the contract checker, I would like to > keep some of the state information of CSP. > What I like in UBF is this state information and I think that > state view > is consistent with a Finite State Machine approach to concurrent > programming. This is tricky - when you add all the states the CSP or UBF rapidly becomes unreadable and becomes more and more like a program. If you omit the state and just use "stateless RPCs" then you loose a lot of detail BUT the specification is readable. > > > 2) Dynamic type checking of these types is trivial - but > can a type > > checker *prove* that your program follows a given > component spec. > Previous works have demonstrated (I think), that if your > erlang program > is not too complex (that is it does not use some dynamic code: eval, > building of atoms, ...). We can prove some correctness. > > The remaining problem is that of type equivalence in the presence of > type aliasing. After "Type fileName = str()." do you consider that str > == filename or not? Yes - this is just pure syntactic sugar. If I say Type foo = bar(); Type bar = baz(); Type baz() = int(); Then 12 is an instance of a foo, or bar or baz. If I see (say) an 12 on some typed channel I can easily check to see if it a foo or a bar or a baz, so type checking a contract is pretty easy if I happen to know that at some point in time I am expecting a foo or a bar or a baz. > - If you consider them equivalent then the type checker > could <<*prove* > that your program follows a given component spec.>>, but then the only > interest of defining fileName type is documentation of the protocol. Yes - but with suitable type definitions the program nicely documented: Compare some part of an FTP like protocol Type fileName = str() Type getFile = {"get", fileName} Type theFile = {"yes", str()} Type noSuchFile = "no" getFile => theFile | noSuchFile With: {"get", str()} => {"ok", str()} | "no" /Joe > - If you do not consider them as equivalent, the type checker must be > able to relate Erlang value with those types (perhaps the programmer > have to add type annotation to his program). > > Fabien > -- > Fabien Dagnat -- Ma?tre de Conf?rences > Mel : Fabien.Dagnat@REDACTED > Web : perso-info.enst-bretagne.fr/~fdagnat > Tel : (0|33) 2 29 00 14 09 Fax : (0|33) 2 29 00 12 82 > Adr : Ecole Nationale Superieure des T?l?communication de Bretagne > Departement Informatique > Technop?le Brest-Iroise - CS 83818 - 29238 Brest Cedex 3 > From ke.han@REDACTED Tue Aug 23 16:00:44 2005 From: ke.han@REDACTED (ke.han) Date: Tue, 23 Aug 2005 22:00:44 +0800 Subject: Vim and Erlang syntax files In-Reply-To: <58128.217.113.1.123.1123972729.squirrel@webmail.web.am> References: <58128.217.113.1.123.1123972729.squirrel@webmail.web.am> Message-ID: <430B2C0C.9060409@redstarling.com> Gaspar, Thanks for publishing your vim files. I am a vim newbie but like it much better than trying to use emacs. So your contribution is much appreciated. Your "northsky" color scheme is by far the most usable of anything I've seen for erlang code!!! I noticed that "behaviour" is missing in your erlang.vim syntax file; easily remedied and good exercise for me to learn to fix ;-) I also notice that when I use command :make, I get just a summary buffer showing the total num of errors. I then use :cn to navigate through them. Is there a vim equivalent to what exists in emacs erlang where the compile buffer shows all the errors (1 line per) with links I can click to get to each item? Should I be using the :make command or something else? thanks, Jon Gaspar Chilingarov wrote: > Hi all! > > I've done some work on merging default Vim syntax > files with syntax files sent by James Hague and extended > them with several additons - now it can detect and highlight differently > clause head, clause argument list and clause's guard > > You should add in your colorscheme description file 3 new groups - > FunHead > FunGuard > and > FunArgs > > Guard BIFs also separated to different syntax group. > > > You can try colorscheme northsky, included in file to see how it looks ;) > > For now file is uploaded to http://nothing.am/erlang/erl.tar.bz2 > > In case if you cannot download this file, just drop me the mail. > From benefitsdragon@REDACTED Tue Aug 23 16:02:14 2005 From: benefitsdragon@REDACTED (Benefits Dragon) Date: Tue, 23 Aug 2005 15:02:14 +0100 Subject: Messages going missing in test suite In-Reply-To: <430B1F38.6020700@ericsson.com> References: <2db31700050823025128d692b4@mail.gmail.com> <430B1F38.6020700@ericsson.com> Message-ID: <2db31700050823070224555c30@mail.gmail.com> Well the the process is globally named and it can find it with global:whereis_name before and after the function that sends the message is called. Probably should also mention that it loses messages in a deterministic way, i.e some may get through but if the code is unchanged the same ones are always lost everytime the suite is run. As an interesting note printing out the pid of the process before and after meant a few of the messages didn't go missing, bizarre I know... On 8/23/05, Bengt Kleberg wrote: > On 2005-08-23 11:51, Benefits Dragon wrote: > > For some reason in one of my test suites messages that are being sent > > by one process are not being received by the other. When I run the > > same commands on the console (that includes the same test case setup) > > as are in the test it works fine and all messages are received that > > should be. > > no answer, but a line of inquiery. > > perhaps the test server is running in its own erlang node. perhaps this > node is not being able to send to the node where your > process-to-be-tested is running. > > if you register the process-to-be-tested under a name, can the test > server locate the pid with erlang:whereis/1 ? > > > bengt > From bengt.kleberg@REDACTED Tue Aug 23 16:18:23 2005 From: bengt.kleberg@REDACTED (Bengt Kleberg) Date: Tue, 23 Aug 2005 16:18:23 +0200 Subject: Messages going missing in test suite In-Reply-To: <2db31700050823070224555c30@mail.gmail.com> References: <2db31700050823025128d692b4@mail.gmail.com> <430B1F38.6020700@ericsson.com> <2db31700050823070224555c30@mail.gmail.com> Message-ID: <430B302F.7070906@ericsson.com> On 2005-08-23 16:02, Benefits Dragon wrote: ...deleted > Probably should also mention that it loses messages in a deterministic > way, i.e some may get through but if the code is unchanged the same > ones are always lost everytime the suite is run. another thought: what if the process crashes and is restarted? the lost messages would be the one sent when the process is gone. are you running sasl? (then you would get process crash reports). can you scale down the test and still get the crash? bengt From serge@REDACTED Tue Aug 23 22:47:24 2005 From: serge@REDACTED (Serge Aleynikov) Date: Tue, 23 Aug 2005 16:47:24 -0400 Subject: inets ftp bug Message-ID: <430B8B5C.2050209@hq.idt.net> OTP team: I found a bug in the inets' ftp.erl client that can be patched by applying the ftp.erl.patch file to the source. The bug is seen when you try to download more than one file in a row using ftp:recv/2 function. For some reason this bug doesn't occur when tracing is enabled (and/or debugger application is running). Use the following to reproduce the bug: ftp_test:test(Host, User, Password, RemoteDir, RemoteFile). ~/tmp/dirtest>erl -pa ~/Projects/DRP/lib/drpdb-1.0/ebin Erlang (BEAM) emulator version 5.4.8 [source] [hipe] [threads:0] Eshell V5.4.8 (abort with ^G) 1> ftp_test:test("localhost", "serge", "...", "/home/serge", "tt.txt"). "220 ProFTPD 1.2.6 Server (DevLinuxPro FTP) [devlinuxpro.mis.idt.net]" "331 Password required for serge." "230 User serge logged in." "250 CWD command successful." "500 EPSV not understood." "200 PORT command successful" "150 Opening ASCII mode data connection for tt.txt (7487 bytes)" "226 Transfer complete." "200 PORT command successful" ** exited: {{function_clause,[{inet,tcp_close,[{lsock,#Port<0.123>}]}, {ftp,do_termiante,2}, {gen_server,terminate,6}, {proc_lib,init_p,5}]}, {gen_server,call, [<0.42.0>, {recv,"tt.txt","tt.txt"}, infinity]}} ** Hope that it can make it in the next OTP release. Regards, Serge -- Serge Aleynikov R&D Telecom, IDT Corp. Tel: (973) 438-3436 Fax: (973) 438-1464 serge@REDACTED -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: ftp_test.erl URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: ftp.erl.patch URL: From serge@REDACTED Tue Aug 23 23:19:12 2005 From: serge@REDACTED (Serge Aleynikov) Date: Tue, 23 Aug 2005 17:19:12 -0400 Subject: inets ftp bug In-Reply-To: <430B8B5C.2050209@hq.idt.net> References: <430B8B5C.2050209@hq.idt.net> Message-ID: <430B92D0.2070800@hq.idt.net> Actually, there seems to be one more (at least :-( ) issue with the ftp.erl. With the applied patch there is no more exception raised, but the second transfer of a file doesn't happen if you run the code outside of the debugger. When running with a debugger, I get: ~/tmp/dirtest>erl Erlang (BEAM) emulator version 5.4.8 [source] [hipe] [threads:0] Eshell V5.4.8 (abort with ^G) 1> i:ii(ftp). {module,ftp} 2> i:ib(ftp, activate_data_connection, 1). ok 3> debugger:start(). {ok,<0.36.0>} 4> ftp_test:test("localhost", "serge", "...", "/home/serge/tmp/data", "cust_group.txt"). "220 ProFTPD 1.2.6 Server (DevLinuxPro FTP) [devlinuxpro.mis.idt.net]" "331 Password required for serge." "230 User serge logged in." "250 CWD command successful." "500 EPSV not understood." "200 PORT command successful" "150 Opening ASCII mode data connection for cust_group.txt (7487 bytes)" "226 Transfer complete." "150 Opening ASCII mode data connection for cust_group.txt (7487 bytes)" ok This is good and expected. We can see that the file is transfered twice. Now the same call without debugger: ~/tmp/dirtest>erl Erlang (BEAM) emulator version 5.4.8 [source] [hipe] [threads:0] Eshell V5.4.8 (abort with ^G) 1> ftp_test:test("localhost", "serge", "...", "/home/serge/tmp/data", "cust_group.txt"). "220 ProFTPD 1.2.6 Server (DevLinuxPro FTP) [devlinuxpro.mis.idt.net]" "331 Password required for serge." "230 User serge logged in." "250 CWD command successful." "500 EPSV not understood." "200 PORT command successful" "150 Opening ASCII mode data connection for cust_group.txt (7487 bytes)" "226 Transfer complete." "200 PORT command successful" ok No transfer is happening after the successful PORT command... Serge Serge Aleynikov wrote: > OTP team: > > I found a bug in the inets' ftp.erl client that can be patched by > applying the ftp.erl.patch file to the source. > > The bug is seen when you try to download more than one file in a row > using ftp:recv/2 function. For some reason this bug doesn't occur when > tracing is enabled (and/or debugger application is running). > > Use the following to reproduce the bug: > > ftp_test:test(Host, User, Password, RemoteDir, RemoteFile). > > ~/tmp/dirtest>erl -pa ~/Projects/DRP/lib/drpdb-1.0/ebin > Erlang (BEAM) emulator version 5.4.8 [source] [hipe] [threads:0] > > Eshell V5.4.8 (abort with ^G) > 1> ftp_test:test("localhost", "serge", "...", "/home/serge", "tt.txt"). > "220 ProFTPD 1.2.6 Server (DevLinuxPro FTP) [devlinuxpro.mis.idt.net]" > "331 Password required for serge." > "230 User serge logged in." > "250 CWD command successful." > "500 EPSV not understood." > "200 PORT command successful" > "150 Opening ASCII mode data connection for tt.txt (7487 bytes)" > "226 Transfer complete." > "200 PORT command successful" > ** exited: {{function_clause,[{inet,tcp_close,[{lsock,#Port<0.123>}]}, > {ftp,do_termiante,2}, > {gen_server,terminate,6}, > {proc_lib,init_p,5}]}, > {gen_server,call, > [<0.42.0>, > {recv,"tt.txt","tt.txt"}, > infinity]}} ** > > Hope that it can make it in the next OTP release. > > Regards, > > Serge > > > ------------------------------------------------------------------------ > > -module(ftp_test). > > -export([test/5]). > > test(Host, User, Password, Dir, File) -> > application:start(inets), > {ok, Pid} = ftp:open(Host, [verbose]), > ok = ftp:user(Pid, User, Password), > ok = ftp:cd(Pid, Dir), > ok = ftp:recv(Pid, File), > ok = ftp:recv(Pid, File), > ftp:close(Pid). > > > ------------------------------------------------------------------------ > > --- /usr/local/lib/erlang/lib/inets-4.5/src/ftp.erl Tue Aug 23 13:28:08 2005 > +++ ftp.erl Tue Aug 23 16:39:43 2005 > @@ -790,11 +790,11 @@ > %% terminate/2 and code_change/3 > %%-------------------------------------------------------------------------- > terminate(normal, State) -> > - do_termiante({error, econn}, State); > + do_terminate({error, econn}, State); > terminate(Reason, State) -> > - do_termiante({error, Reason}, State). > + do_terminate({error, Reason}, State). > > -do_termiante(ErrorMsg, State) -> > +do_terminate(ErrorMsg, State) -> > close_data_connection(State), > close_ctrl_connection(State), > case State#state.client of > @@ -1313,6 +1313,8 @@ > > close_data_connection(#state{dsock = undefined}) -> > ok; > +close_data_connection(#state{dsock = {lsock, Socket}}) -> > + close_connection(Socket); > close_data_connection(#state{dsock = Socket}) -> > close_connection(Socket). From ingela@REDACTED Wed Aug 24 08:39:54 2005 From: ingela@REDACTED (Ingela Anderton) Date: Wed, 24 Aug 2005 08:39:54 +0200 Subject: inets ftp bug References: <430B8B5C.2050209@hq.idt.net> Message-ID: <17164.5690.439697.463734@gargle.gargle.HOWL> Actually this is an already known and fixed problem in inets-4.5.2 Realeasnotes says: [ftp, client] Calling ftp:recv/2 twice on the same connection failed due to that the last message on the ctrl channel was not appropriately taken care of. This could potentially cause a problem for any operation performed on the same connection where there had previously been an ftp:recv/2 call. Also, in some cases, when the process tries to close the data connection, it does not take into account that the data connection may actually not have been established. This will definitely be part of the next open source release. We are actually working on inets-4.5.3 at the moment that will fix some more bugs and add some new nice features to the inets components (not only ftp). The aim is that this version should be the one in the next open source release. Serge Aleynikov wrote: > OTP team: > > I found a bug in the inets' ftp.erl client that can be patched by > applying the ftp.erl.patch file to the source. > > The bug is seen when you try to download more than one file in a row > using ftp:recv/2 function. For some reason this bug doesn't occur when > tracing is enabled (and/or debugger application is running). > > Use the following to reproduce the bug: > > ftp_test:test(Host, User, Password, RemoteDir, RemoteFile). > > ~/tmp/dirtest>erl -pa ~/Projects/DRP/lib/drpdb-1.0/ebin > Erlang (BEAM) emulator version 5.4.8 [source] [hipe] [threads:0] > > Eshell V5.4.8 (abort with ^G) > 1> ftp_test:test("localhost", "serge", "...", "/home/serge", "tt.txt"). > "220 ProFTPD 1.2.6 Server (DevLinuxPro FTP) [devlinuxpro.mis.idt.net]" > "331 Password required for serge." > "230 User serge logged in." > "250 CWD command successful." > "500 EPSV not understood." > "200 PORT command successful" > "150 Opening ASCII mode data connection for tt.txt (7487 bytes)" > "226 Transfer complete." > "200 PORT command successful" > ** exited: {{function_clause,[{inet,tcp_close,[{lsock,#Port<0.123>}]}, > {ftp,do_termiante,2}, > {gen_server,terminate,6}, > {proc_lib,init_p,5}]}, > {gen_server,call, > [<0.42.0>, > {recv,"tt.txt","tt.txt"}, > infinity]}} ** > > Hope that it can make it in the next OTP release. > > Regards, > > Serge > > -- > Serge Aleynikov > R&D Telecom, IDT Corp. > Tel: (973) 438-3436 > Fax: (973) 438-1464 > serge@REDACTED > -module(ftp_test). > > -export([test/5]). > > test(Host, User, Password, Dir, File) -> > application:start(inets), > {ok, Pid} = ftp:open(Host, [verbose]), > ok = ftp:user(Pid, User, Password), > ok = ftp:cd(Pid, Dir), > ok = ftp:recv(Pid, File), > ok = ftp:recv(Pid, File), > ftp:close(Pid). > --- /usr/local/lib/erlang/lib/inets-4.5/src/ftp.erl Tue Aug 23 13:28:08 2005 > +++ ftp.erl Tue Aug 23 16:39:43 2005 > @@ -790,11 +790,11 @@ > %% terminate/2 and code_change/3 > %%-------------------------------------------------------------------------- > terminate(normal, State) -> > - do_termiante({error, econn}, State); > + do_terminate({error, econn}, State); > terminate(Reason, State) -> > - do_termiante({error, Reason}, State). > + do_terminate({error, Reason}, State). > > -do_termiante(ErrorMsg, State) -> > +do_terminate(ErrorMsg, State) -> > close_data_connection(State), > close_ctrl_connection(State), > case State#state.client of > @@ -1313,6 +1313,8 @@ > > close_data_connection(#state{dsock = undefined}) -> > ok; > +close_data_connection(#state{dsock = {lsock, Socket}}) -> > + close_connection(Socket); > close_data_connection(#state{dsock = Socket}) -> > close_connection(Socket). > -- /Ingela - OTP team From serge@REDACTED Wed Aug 24 00:43:54 2005 From: serge@REDACTED (Serge Aleynikov) Date: Tue, 23 Aug 2005 18:43:54 -0400 Subject: inets ftp bug In-Reply-To: <430B92D0.2070800@hq.idt.net> References: <430B8B5C.2050209@hq.idt.net> <430B92D0.2070800@hq.idt.net> Message-ID: <430BA6AA.5060302@hq.idt.net> OTP team: This is my second attempt to fix the issue with inets' ftp.erl, which seems to be more involved than I initially thought. In this version of ftp.erl ftp:recv/2 seems to be working correctly, however, I am not quite sure that this fix covered all errors in the implementation (which IMHO is quite messy), and would prefer if one of the authors would take a look at it. > ftp_test:test("localhost", "serge", "...", "/home/serge/tmp/data", "dial_code.txt"). "220 ProFTPD 1.2.6 Server (DevLinuxPro FTP) [devlinuxpro.mis.idt.net]" "331 Password required for serge." "230 User serge logged in." "250 CWD command successful." "500 EPSV not understood." "200 PORT command successful" "150 Opening ASCII mode data connection for dial_code.txt (5271838 bytes)" "226 Transfer complete." "200 PORT command successful" "150 Opening ASCII mode data connection for dial_code.txt (5271838 bytes)" "226 Transfer complete." ok Regards, Serge Serge Aleynikov wrote: > Actually, there seems to be one more (at least :-( ) issue with the > ftp.erl. With the applied patch there is no more exception raised, but > the second transfer of a file doesn't happen if you run the code outside > of the debugger. > > When running with a debugger, I get: > > ~/tmp/dirtest>erl > Erlang (BEAM) emulator version 5.4.8 [source] [hipe] [threads:0] > > Eshell V5.4.8 (abort with ^G) > 1> i:ii(ftp). > {module,ftp} > 2> i:ib(ftp, activate_data_connection, 1). > ok > 3> debugger:start(). > {ok,<0.36.0>} > 4> ftp_test:test("localhost", "serge", "...", "/home/serge/tmp/data", > "cust_group.txt"). > "220 ProFTPD 1.2.6 Server (DevLinuxPro FTP) [devlinuxpro.mis.idt.net]" > "331 Password required for serge." > "230 User serge logged in." > "250 CWD command successful." > "500 EPSV not understood." > "200 PORT command successful" > "150 Opening ASCII mode data connection for cust_group.txt (7487 bytes)" > "226 Transfer complete." > "150 Opening ASCII mode data connection for cust_group.txt (7487 bytes)" > ok > > This is good and expected. We can see that the file is transfered twice. > Now the same call without debugger: > > ~/tmp/dirtest>erl > Erlang (BEAM) emulator version 5.4.8 [source] [hipe] [threads:0] > > Eshell V5.4.8 (abort with ^G) > 1> ftp_test:test("localhost", "serge", "...", "/home/serge/tmp/data", > "cust_group.txt"). > "220 ProFTPD 1.2.6 Server (DevLinuxPro FTP) [devlinuxpro.mis.idt.net]" > "331 Password required for serge." > "230 User serge logged in." > "250 CWD command successful." > "500 EPSV not understood." > "200 PORT command successful" > "150 Opening ASCII mode data connection for cust_group.txt (7487 bytes)" > "226 Transfer complete." > "200 PORT command successful" > ok > > No transfer is happening after the successful PORT command... > > Serge > > > Serge Aleynikov wrote: > >> OTP team: >> >> I found a bug in the inets' ftp.erl client that can be patched by >> applying the ftp.erl.patch file to the source. >> >> The bug is seen when you try to download more than one file in a row >> using ftp:recv/2 function. For some reason this bug doesn't occur >> when tracing is enabled (and/or debugger application is running). >> >> Use the following to reproduce the bug: >> >> ftp_test:test(Host, User, Password, RemoteDir, RemoteFile). >> >> ~/tmp/dirtest>erl -pa ~/Projects/DRP/lib/drpdb-1.0/ebin >> Erlang (BEAM) emulator version 5.4.8 [source] [hipe] [threads:0] >> >> Eshell V5.4.8 (abort with ^G) >> 1> ftp_test:test("localhost", "serge", "...", "/home/serge", "tt.txt"). >> "220 ProFTPD 1.2.6 Server (DevLinuxPro FTP) [devlinuxpro.mis.idt.net]" >> "331 Password required for serge." >> "230 User serge logged in." >> "250 CWD command successful." >> "500 EPSV not understood." >> "200 PORT command successful" >> "150 Opening ASCII mode data connection for tt.txt (7487 bytes)" >> "226 Transfer complete." >> "200 PORT command successful" >> ** exited: {{function_clause,[{inet,tcp_close,[{lsock,#Port<0.123>}]}, >> {ftp,do_termiante,2}, >> {gen_server,terminate,6}, >> {proc_lib,init_p,5}]}, >> {gen_server,call, >> [<0.42.0>, >> {recv,"tt.txt","tt.txt"}, >> infinity]}} ** >> >> Hope that it can make it in the next OTP release. >> >> Regards, >> >> Serge >> >> >> ------------------------------------------------------------------------ >> >> -module(ftp_test). >> >> -export([test/5]). >> >> test(Host, User, Password, Dir, File) -> >> application:start(inets), >> {ok, Pid} = ftp:open(Host, [verbose]), >> ok = ftp:user(Pid, User, Password), >> ok = ftp:cd(Pid, Dir), >> ok = ftp:recv(Pid, File), >> ok = ftp:recv(Pid, File), >> ftp:close(Pid). >> >> >> ------------------------------------------------------------------------ >> >> --- /usr/local/lib/erlang/lib/inets-4.5/src/ftp.erl Tue Aug 23 >> 13:28:08 2005 >> +++ ftp.erl Tue Aug 23 16:39:43 2005 >> @@ -790,11 +790,11 @@ >> %% terminate/2 and code_change/3 >> %%-------------------------------------------------------------------------- >> >> terminate(normal, State) -> >> - do_termiante({error, econn}, State); >> + do_terminate({error, econn}, State); >> terminate(Reason, State) -> >> - do_termiante({error, Reason}, State). >> + do_terminate({error, Reason}, State). >> >> -do_termiante(ErrorMsg, State) -> >> +do_terminate(ErrorMsg, State) -> >> close_data_connection(State), >> close_ctrl_connection(State), >> case State#state.client of >> @@ -1313,6 +1313,8 @@ >> >> close_data_connection(#state{dsock = undefined}) -> >> ok; >> +close_data_connection(#state{dsock = {lsock, Socket}}) -> >> + close_connection(Socket); >> close_data_connection(#state{dsock = Socket}) -> >> close_connection(Socket). > > -- Serge Aleynikov R&D Telecom, IDT Corp. Tel: (973) 438-3436 Fax: (973) 438-1464 serge@REDACTED -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: ftp_test.erl URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: ftp.erl URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: ftp.erl.patch URL: From serge@REDACTED Wed Aug 24 13:33:13 2005 From: serge@REDACTED (Serge Aleynikov) Date: Wed, 24 Aug 2005 07:33:13 -0400 Subject: inets ftp bug In-Reply-To: <17164.5690.439697.463734@gargle.gargle.HOWL> References: <430B8B5C.2050209@hq.idt.net> <17164.5690.439697.463734@gargle.gargle.HOWL> Message-ID: <430C5AF9.8050206@hq.idt.net> Great! Thank you. Serge Ingela Anderton wrote: > Actually this is an already known and fixed problem in inets-4.5.2 > > Realeasnotes says: > > [ftp, client] Calling ftp:recv/2 twice on the same connection failed > due to that the last message on the ctrl channel was not appropriately > taken care of. This could potentially cause a problem for any > operation performed on the same connection where there had previously > been an ftp:recv/2 call. Also, in some cases, when the process tries > to close the data connection, it does not take into account that the > data connection may actually not have been established. > > This will definitely be part of the next open source release. We are > actually working on inets-4.5.3 at the moment that will fix some more > bugs and add some new nice features to the inets components (not only > ftp). The aim is that this version should be the one in the next open > source release. > > > Serge Aleynikov wrote: > >>OTP team: >> >>I found a bug in the inets' ftp.erl client that can be patched by >>applying the ftp.erl.patch file to the source. >> >>The bug is seen when you try to download more than one file in a row >>using ftp:recv/2 function. For some reason this bug doesn't occur when >>tracing is enabled (and/or debugger application is running). >> >>Use the following to reproduce the bug: >> >>ftp_test:test(Host, User, Password, RemoteDir, RemoteFile). >> >>~/tmp/dirtest>erl -pa ~/Projects/DRP/lib/drpdb-1.0/ebin >>Erlang (BEAM) emulator version 5.4.8 [source] [hipe] [threads:0] >> >>Eshell V5.4.8 (abort with ^G) >>1> ftp_test:test("localhost", "serge", "...", "/home/serge", "tt.txt"). >>"220 ProFTPD 1.2.6 Server (DevLinuxPro FTP) [devlinuxpro.mis.idt.net]" >>"331 Password required for serge." >>"230 User serge logged in." >>"250 CWD command successful." >>"500 EPSV not understood." >>"200 PORT command successful" >>"150 Opening ASCII mode data connection for tt.txt (7487 bytes)" >>"226 Transfer complete." >>"200 PORT command successful" >>** exited: {{function_clause,[{inet,tcp_close,[{lsock,#Port<0.123>}]}, >> {ftp,do_termiante,2}, >> {gen_server,terminate,6}, >> {proc_lib,init_p,5}]}, >> {gen_server,call, >> [<0.42.0>, >> {recv,"tt.txt","tt.txt"}, >> infinity]}} ** >> >>Hope that it can make it in the next OTP release. >> >>Regards, >> >>Serge >> From tibor.bognar@REDACTED Wed Aug 24 16:05:22 2005 From: tibor.bognar@REDACTED (=?iso-8859-1?Q?Tibor_Bogn=E1r_=28IJ/ETH=29?=) Date: Wed, 24 Aug 2005 16:05:22 +0200 Subject: Megaco overload Message-ID: Hi, Is there any solution in the Megaco to regulate the possible number of requests? Because it seems the Megaco isn't protected against DoS like "attacks" and tries to serve every request even if it causes an CP overload situation. It would be useful to give a threshold for the maximum number of request in a given time period. Thanks, Tibor From ke.han@REDACTED Wed Aug 24 16:34:07 2005 From: ke.han@REDACTED (ke.han) Date: Wed, 24 Aug 2005 22:34:07 +0800 Subject: erlmerge on Windows? Message-ID: <430C855F.5010206@redstarling.com> I notice the erlmerge install instructions (from trapexit.org) only cover linux. Does erlmerge work on Windows? thanks, ke han From devfunctional@REDACTED Thu Aug 25 08:18:16 2005 From: devfunctional@REDACTED (Dev Functional) Date: Thu, 25 Aug 2005 11:48:16 +0530 Subject: (Prolog + LISP + Erlang) with integration issues versus C++ Message-ID: Hello Given the insistence of the members of the team to use the best language for specific purpose, we have code that is written in 1. Prolog (enumerating device drivers, goal seek) 2. LISP (classical AI stuff, inference) 3. Erlang (server, communication and distributedness) The products we have used are 1. gprolog 2. clisp 3. Erlang/OTP The independent modules have been developed successfully, however we are unable to surmount the language boundaries and connect Erlang to Prolog, Erlang to CLisp and CLisp to Prolog. The team has quickly built the components (less than 3 months) and proven the idea. The management is worried about our choice of three languages and has strongly suggested a relook at this strategy. The External Consultant (Subject Matter Expert) has suggested that - 0. since the individual components are implemented, the idea is partially proven 1. the language barriers will cause problems in integration and performance 2. the long-term success and reach of the product will be based on complete implementation in C++. 3. The Visualizer will be implemented in OpenGL and C++ based modules will be quite easy to integrate. 4. C++ performance will be good if a ANN component is added later due to customer request. 5. Multi-language maintenance costs will be high The team is disappointed, since the effort in learning the languages will be wasted. The 6 developers are from C/Java background. Greatly appreciate if the more experience members of this group share their experiences and put forward the suggestions. I need to present a case for the proposed solution, on the coming Monday. Thanks in advance. thanks Dev. From bjarne@REDACTED Thu Aug 25 09:05:15 2005 From: bjarne@REDACTED (=?iso-8859-1?Q?Bjarne_D=E4cker?=) Date: Thu, 25 Aug 2005 09:05:15 +0200 Subject: (Prolog + LISP + Erlang) with integration issues versus C++ References: Message-ID: <000c01c5a943$5a650500$780d69d4@segeltorp> Hello Dev, I find your experience very interesting and from my years at Ericsson, I can understand your situation. I tried to argue by comparing with a materials scientist. He or she will use iron, plastic, rubber, wood, glass etc in different places of some construction because of different requirements and of the different properties of the materials. Prolog, Lisp and Erlang are all symbolic languages with similar datatypes (lists etc) so in principle should be easy to integrate. Bjarne ----- Original Message ----- From: "Dev Functional" To: Sent: Thursday, August 25, 2005 8:18 AM Subject: (Prolog + LISP + Erlang) with integration issues versus C++ > Hello > > Given the insistence of the members of the team to use the > best language for specific purpose, we have code that is > written in > 1. Prolog (enumerating device drivers, goal seek) > 2. LISP (classical AI stuff, inference) > 3. Erlang (server, communication and distributedness) > > The products we have used are > 1. gprolog > 2. clisp > 3. Erlang/OTP > > The independent modules have been developed successfully, > however we are unable to surmount the language boundaries > and connect Erlang to Prolog, Erlang to CLisp and CLisp to Prolog. > > The team has quickly built the components (less than 3 months) > and proven the idea. > > The management is worried about our choice of three languages > and has strongly suggested a relook at this strategy. > > - - - - From erlang-list@REDACTED Thu Aug 25 09:44:23 2005 From: erlang-list@REDACTED (erlang-list@REDACTED) Date: Thu, 25 Aug 2005 09:44:23 +0200 (CEST) Subject: Programming components In-Reply-To: References: Message-ID: <16622.212.155.207.253.1124955863.squirrel@212.155.207.253> Hi, > Erlang lacks a notion of types and a way of > specifying components. Regarding types, I'm trying to understand what you find lacking in Erlang, and why you want it. > Type systems always have three parts: > > 1) A set of primitive types > 2) Glue for making complex types from primitive types > 3) Aliases for defining new types Doesn't Erlang have those? Primitive types, tuples and lists, and records? > Definition: A component is a black box with ports. If > you send the port a well-typed message it will > respond with a well-typed reply. > > Below I discuss two styles of specify the behavior of > components. It sounds as though you are discussing the specification of servers, or protocols. "Components" are more complex in that they must provide ways to manage their lifecycle, to connect them to other components etc. > To *specify* the behavior of a black box I can write [CSP style and RPC style examples clipped...] I find your proposed notations quite appealing, as notations go, but these days I rather favour using test programs as a more useful form of specification. Writing executable tests is both good for designing good protocols, and produces a more useful result than a spec. With a bit of care, test programs can even be made to look as readable as a spec. > 5) Introspection - yes :-) Apart from development tools, or working around deficient languages, I can't really think of any good use for introspection. What do you have in mind? > To obtain a beautiful mapping from abstract types to > Erlang and XML I need to represent strings as > <<"string">> and NOT "string" I don't understand this. Could you elaborate? Overall, I guess I'm having trouble seeing the motivation for these proposals. Within an all-Erlang world, they don't seem useful, and I suppose I am skeptical about defining any kind of standard for universal components. Regards, Dominic Williams http://www.dominicwilliams.net ---- From ulf.wiger@REDACTED Thu Aug 25 09:46:37 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Thu, 25 Aug 2005 09:46:37 +0200 Subject: how to build beam_evm? Message-ID: I tried building escript from the otp_src_R10B-6 tree, but it complains about not finding beam_evm. What's the magic word required to get beam_evm to build itself? /Uffe From roger.larsson@REDACTED Thu Aug 25 10:02:57 2005 From: roger.larsson@REDACTED (Roger Larsson) Date: Thu, 25 Aug 2005 10:02:57 +0200 Subject: (Prolog + LISP + Erlang) with integration issues versus C++ In-Reply-To: References: Message-ID: <200508251002.58133.roger.larsson@norran.net> On Thursday 25 August 2005 08.18, Dev Functional wrote: > Hello > > Given the insistence of the members of the team to use the > best language for specific purpose, we have code that is > written in > 1. Prolog (enumerating device drivers, goal seek) > 2. LISP (classical AI stuff, inference) > 3. Erlang (server, communication and distributedness) > > The products we have used are > 1. gprolog > 2. clisp > 3. Erlang/OTP > > The independent modules have been developed successfully, > however we are unable to surmount the language boundaries > and connect Erlang to Prolog, Erlang to CLisp and CLisp to Prolog. > > The team has quickly built the components (less than 3 months) > and proven the idea. > > The management is worried about our choice of three languages > and has strongly suggested a relook at this strategy. > > The External Consultant (Subject Matter Expert) has suggested that - > 0. since the individual components are implemented, Does the External Consultant have enough experience/data to make these claims? > the idea is partially proven Idea is proven but not only that - it is mostly implemented too! Reimplementation in any language will take time... Is there an estimate on how much time this reimplementation will take? > 1. the language barriers will cause problems in integration > and performance Performance problems can never be assumed to show up, only measured... My suggestion would be to try to make a very simple interface between the components. Keep them in separate processes, and use sockets/pipes/... Data transmitted could be specified on byte level, as plain text, or as XML. A1. Implement the glue A2. Measure performance problem. A3. Try to solve performance problem with hardware A4. Tune or reimplement the measured to be problematic part. A5. Repeat from A2. until performance is acceptable A6. Start selling (the hardware of this solution will be expensive) A7. Earn money A8. Try to solve the cost problem (will disappear over time) B1. Reimplement everything in C++, probably quick and dirty due to time to market concerns. B2. Test for implementation problems (wrong results fast) B3. Fix bugs B4. Repeat from B2, until quality is acceptable B5. Start selling B6. Earn money B7. Maintain spaghetti code > 2. the long-term success and reach of the product will be > based on complete implementation in C++. What about the short time - time to market? > 3. The Visualizer will be implemented in OpenGL and C++ based modules > will be quite easy to integrate. Yet another component and language! Suggest that the External Consultants firm could do this implementation. That could be their agenda anyway... > 4. C++ performance will be good if a ANN component is added later > due to customer request. ANN? > 5. Multi-language maintenance costs will be high The complexity of the individual components in C++ will (probably) be higher. Number of source code lines will definitely be. > > The team is disappointed, since the effort in learning the languages > will be wasted. The 6 developers are from C/Java background. Knowledge is never a waste - I assume you have been payed :-) Let me add a problem of my own: 6. If the target environment is embedded devices. The size of runtime needed for any of the suggested languages, including C++, could add to the cost of the device - especially if all these languages were needed everywhere. /RogerL > > Greatly appreciate if the more experience members of this group > share their experiences and put forward the suggestions. > > I need to present a case for the proposed solution, on the coming > Monday. > > Thanks in advance. > > thanks > Dev. From sean.hinde@REDACTED Thu Aug 25 10:05:34 2005 From: sean.hinde@REDACTED (Sean Hinde) Date: Thu, 25 Aug 2005 09:05:34 +0100 Subject: how to build beam_evm? In-Reply-To: References: Message-ID: On 25 Aug 2005, at 08:46, Ulf Wiger (AL/EAB) wrote: > > I tried building escript from the otp_src_R10B-6 tree, > but it complains about not finding beam_evm. > > What's the magic word required to get beam_evm to build itself? > This collection of posts might be useful: http://forums.trapexit.org:81/phpBB/viewtopic.php?t=4065&highlight=sae Sean From bengt.kleberg@REDACTED Thu Aug 25 10:40:12 2005 From: bengt.kleberg@REDACTED (Bengt Kleberg) Date: Thu, 25 Aug 2005 10:40:12 +0200 Subject: erlmerge on Windows? In-Reply-To: <20050825070900.4915046EE3@bang.trapexit.org> References: <20050825070900.4915046EE3@bang.trapexit.org> Message-ID: <430D83EC.6090304@ericsson.com> On 2005-08-25 09:09, tobbe wrote: ...deleted > When it comes to Windows, I guess there is some problems > to be solved: > > 1. How to do the initial install perhaps it is possible to switch from gnu autotools to something that is available for both unix and windows? (ie, erlang itself) > 2. There are some os:cmd/1 calls in the code. if/when(?) erlmerge becomes possible to install somewhere else than in the erlang/otp distribution i would be happy to help removing the os:cmd/1 calls. the ones i have seen i know how to replace. bengt From thomasl_erlang@REDACTED Thu Aug 25 10:43:48 2005 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Thu, 25 Aug 2005 01:43:48 -0700 (PDT) Subject: (Prolog + LISP + Erlang) with integration issues versus C++ In-Reply-To: Message-ID: <20050825084348.49761.qmail@web34401.mail.mud.yahoo.com> -- Dev Functional wrote: > Hello > > Given the insistence of the members of the team to > use the > best language for specific purpose, we have code > that is > written in > 1. Prolog (enumerating device drivers, goal seek) > 2. LISP (classical AI stuff, inference) > 3. Erlang (server, communication and > distributedness) > > The products we have used are > 1. gprolog > 2. clisp > 3. Erlang/OTP > > The independent modules have been developed > successfully, > however we are unable to surmount the language > boundaries > and connect Erlang to Prolog, Erlang to CLisp and > CLisp to Prolog. > Since the system components seem to be designed "at arms length" from each other, the quickest way of integrating the three is probably by using sockets or pipes and your own simple protocol on top of that. Use s-expressions or text as the transfer format as far as possible. (Or perhaps XML makes a nice bullet point, if you can afford it.) Corba or some other such solution could also be done, if it's politically useful and you know how to work with it, and all involved systems have it. With the above approach, gradual integration of C++ is also feasible, if so desired. Just hook in a C++ process in the same way. You retain the option of migrating to C++, yet have a working system around, and can switch over gradually. (If management are feeling jittery.) Simple C++ subsystems can usually be integrated via FFI into Lisp or Prolog, or via drivers in Erlang. (For example, Wings3D integrates SDL and OpenGL into an Erlang modeller; see http://www.wings3d.com/) You could also conceivably use FFIs or Erlang drivers to connect the three, though I'd investigate that only if there really _is_ a performance problem. It's likely to be a lot of work for little gain otherwise. Have a look at whether performance problems are likely. Regarding integration per se, the main issue is _probably_ to avoid swapping and keeping all three processes in memory. If it's an internal product, take the memory upgrade cost from the budget required to redevelop the whole thing in C++ :-) Oh yeah, a system for testing that the protocol(s) is or are implemented faithfully is probably a good thing to have around. That way, you can quickly test that the components are sending and receiving the right things by having the test system run through some "unit tests". At the same time, having a central 'hub' to monitor messaging between components can also be a good idea for debugging or even for deployment. Write such a hub/tester in Erlang. Best, Thomas __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From joe.armstrong@REDACTED Thu Aug 25 11:01:58 2005 From: joe.armstrong@REDACTED (Joe Armstrong (AL/EAB)) Date: Thu, 25 Aug 2005 11:01:58 +0200 Subject: Programming components Message-ID: > -----Original Message----- > From: owner-erlang-questions@REDACTED > [mailto:owner-erlang-questions@REDACTED]On Behalf Of > erlang-list@REDACTED > Sent: den 25 augusti 2005 09:44 > To: erlang-questions@REDACTED > Subject: Re: Programming components > > > Hi, > > > Erlang lacks a notion of types and a way of > > specifying components. > > Regarding types, I'm trying to understand what you find > lacking in Erlang, and why you want it. Erlang has no syntax for defining types > > > Type systems always have three parts: > > > > 1) A set of primitive types > > 2) Glue for making complex types from primitive types > > 3) Aliases for defining new types > > Doesn't Erlang have those? Primitive types, tuples and > lists, and records? This is a general statement about all typed languages. Yes Erlang has integers etc. but there is no way to say that the factorial function returns an integer I'd like to say fac(int()) -> int(). But this is NOT Erlang > > > Definition: A component is a black box with ports. If > > you send the port a well-typed message it will > > respond with a well-typed reply. > > > > Below I discuss two styles of specify the behaviour of > > components. > > It sounds as though you are discussing the > specification of servers, or protocols. "Components" > are more complex in that they must provide ways to > manage their lifecycle, to connect them to other > components etc. I agree - but I wanted my examples to be simple - I have thought a lot about these aspects of the problem. > > > To *specify* the behavior of a black box I can write > > [CSP style and RPC style examples clipped...] > > I find your proposed notations quite appealing, as > notations go, but these days I rather favour using test > programs as a more useful form of specification. > > Writing executable tests is both good for designing > good protocols, and produces a more useful result than > a spec. With a bit of care, test programs can even be > made to look as readable as a spec. > > > 5) Introspection - yes :-) > > Apart from development tools, or working around > deficient languages, I can't really think of any good > use for introspection. What do you have in mind? YES - contract checking. The protocol spec IS a contract to follow some agreed protocol - so we can check it dynamically - to do so we need the spec. The spec has two purposes: At design time - it tells the programmer what the protocol is At run time - it can be used to dynamically check that the client and server are correctly obeying the protocol > > To obtain a beautiful mapping from abstract types to > > Erlang and XML I need to represent strings as > > <<"string">> and NOT "string" > > I don't understand this. Could you elaborate? Yes. Erlang has no strings - ie there is NOT a string data type. "abc" is NOT a string but shorthand for [97,98,99] Now suppose I see [97, 98, 99] on some I/O channel what does this mean? is it to be interpreted as a list of three integers or as a string? - nobody knows. Most Erlang programmers choose to represent strings as "lists of integers" and write "abc" in their programs when they wish to create a string. I am suggesting they should use <<"abc">> (a binary) This all has to do with making a simple type system that mays Erlang terms onto XML data structures in an isomorphic manner. > > Overall, I guess I'm having trouble seeing the > motivation for these proposals. Within an all-Erlang > world, they don't seem useful, and I suppose I am > skeptical about defining any kind of standard for > universal components. > In an all Erlang world they are still useful - since I want to *define* the protocol between an Erlang client and an Erlang sever in such a way that it can be strictly checked. Erlang has a number of problems, both processes and protocols cannot be named. This is fundamental - if we cannot name something we cannot talk about it (well we can but this is difficult) Processes do not have names, in the sense that modules have names. We can talk about the module lists, or file and everybody knows what we mean. But how to we talk about the process ? - it has no name - so we use a circularity "the processes created when we evaluate the function ...." There is no syntax for naming processes. There no file Foo.pro containing -process(foo) -protocol(p) ... And there is not way of specify protocols - "read the code and figure out in which order the messages are sent" is NOT a good reply :-) Cheers /Joe > Regards, > > Dominic Williams > http://www.dominicwilliams.net > > ---- > > From devfunctional@REDACTED Thu Aug 25 11:08:46 2005 From: devfunctional@REDACTED (Dev Functional) Date: Thu, 25 Aug 2005 14:38:46 +0530 Subject: (Prolog + LISP + Erlang) with integration issues versus C++ In-Reply-To: <000c01c5a943$5a650500$780d69d4@segeltorp> References: <000c01c5a943$5a650500$780d69d4@segeltorp> Message-ID: Hello Bjarne Thanks for your kind reply. The device enumeration and goal seek program is written in gprolog. What is the procedure for calling a prolog function from Erlang ? Similarly, what is the procedure for calling a clisp function from Erlang ? All the control logic is implemented in Erlang. Alternatively, is it possible to implement goal seek, AI applications in Erlang ? That way we get rid of gprolog and clisp. So, it is then a single language solution. In many of these matters we have investigated AI - Russell & Norvig book, but there is no information about programming languages that can be directly adopted. Your advise in this matter will be greatly appreciated. thanks Dev. On 8/25/05, Bjarne D?cker wrote: > Hello Dev, > > I find your experience very interesting and from > my years at Ericsson, I can understand your situation. > > I tried to argue by comparing with a materials > scientist. He or she will use iron, plastic, rubber, > wood, glass etc in different places of some > construction because of different requirements > and of the different properties of the materials. > > Prolog, Lisp and Erlang are all symbolic languages > with similar datatypes (lists etc) so in principle > should be easy to integrate. > > Bjarne > From devfunctional@REDACTED Thu Aug 25 11:20:40 2005 From: devfunctional@REDACTED (Dev Functional) Date: Thu, 25 Aug 2005 14:50:40 +0530 Subject: (Prolog + LISP + Erlang) with integration issues versus C++ In-Reply-To: <200508251002.58133.roger.larsson@norran.net> References: <200508251002.58133.roger.larsson@norran.net> Message-ID: On 8/25/05, Roger Larsson wrote: > On Thursday 25 August 2005 08.18, Dev Functional wrote: > > Hello > > > > The External Consultant (Subject Matter Expert) has suggested that - > > 0. since the individual components are implemented, > Does the External Consultant have enough experience/data to > make these claims? > The Consultant is Directore's close friend's nephew ! > > the idea is partially proven > > Idea is proven but not only that - it is mostly implemented too! > Reimplementation in any language will take time... > > Is there an estimate on how much time this reimplementation > will take? Estd Time = Training Time in C++ + Redesign in OO + Implementation Time + Debugging Time. about 6 months (which is double time). > > > 1. the language barriers will cause problems in integration > > and performance > Performance problems can never be assumed to show up, > only measured... > > My suggestion would be to try to make a very simple interface > between the components. Keep them in separate > processes, and use sockets/pipes/... Data transmitted could be > specified on byte level, as plain text, or as XML. > All the controller code is in Erlang ! What is the procedure to call gprolog functions from Erlang ? What is the procedure to call clisp functions from Erlang ? > > A1. Implement the glue > A2. Measure performance problem. > A3. Try to solve performance problem with hardware > A4. Tune or reimplement the measured to be problematic part. > A5. Repeat from A2. until performance is acceptable > A6. Start selling (the hardware of this solution will be expensive) > A7. Earn money > A8. Try to solve the cost problem (will disappear over time) > > B1. Reimplement everything in C++, probably quick and dirty due > to time to market concerns. > B2. Test for implementation problems (wrong results fast) > B3. Fix bugs > B4. Repeat from B2, until quality is acceptable > B5. Start selling > B6. Earn money > B7. Maintain spaghetti code > > > 2. the long-term success and reach of the product will be > > based on complete implementation in C++. > > What about the short time - time to market? > > > 3. The Visualizer will be implemented in OpenGL and C++ based modules > > will be quite easy to integrate. > > Yet another component and language! > Suggest that the External Consultants firm could do this implementation. > That could be their agenda anyway... > You are absolutely correct here ! > > 4. C++ performance will be good if a ANN component is added later > > due to customer request. > > ANN? Apology, ANN is Aritificiale Nuerale Network. > > > 5. Multi-language maintenance costs will be high > The complexity of the individual components in C++ will (probably) be higher. > Number of source code lines will definitely be. > > > > > The team is disappointed, since the effort in learning the languages > > will be wasted. The 6 developers are from C/Java background. > Knowledge is never a waste - I assume you have been payed :-) > Yes. However, with change of language, the project gets outsourced through External Consultant Firm. > Let me add a problem of my own: > > 6. If the target environment is embedded devices. The size of runtime needed > for any of the suggested languages, including C++, could add to the cost of > the device - especially if all these languages were needed everywhere. > The target environment is a rack mount Storage Appliance with 1Gb RAM, dual Xeon processor and 600 Gb SCSI hard disk space. The key objection is that Backup software appliance needs performance and Erlang+Prolog+clisp is not a good idea. Now that you know the nature of the product, what is your recommendation ? kind regards Dev. From rprice@REDACTED Thu Aug 25 11:21:18 2005 From: rprice@REDACTED (Roger Price) Date: Thu, 25 Aug 2005 11:21:18 +0200 (CEST) Subject: Announcement: Pint, an Erlang-based pi-calculus platform Message-ID: The first public release of Pint, an Erlang-based pi-calculus platform is now available at http://rogerprice.org/pint Roger _________________________________________________________________________ Abstract Pint is a pi-calculus language platform which provides a translator written in SML/NJ and a hardware emulator written in Erlang. The platform is intended for investigation at the microprogramming level rather than for use as yet another high level language. The language is similar to, but simpler than, Vasconcelos' TyCO, or Wojciechowski's Nomadic Pict which is based on Turner and Pierce's Pict; it is automatically typed, asynchronous, higher-order, concurrent and distributed. It is not deterministic or sequenced. It is non-linear and has no polymorphism except for a few list operations. The semantics are taken from Pict. The Pint language includes document type definition facilities for recursive element and attribute declarations but these are type based rather than syntax based as in SGML/XML. Pint supports the Oasis catalogue. The library provides a graphics system which offers functionality similar to Erlang's GS through an interface based on passing elements to six built-in paths. A demonstration microprogram simulates and displays an ant raiding party. The emulated hardware offers up to 2^28 hardware channels on which the program's paths are to be placed. We show examples of programming for the small footprint imposed by this hardware. The emulator provides trace and debugging facilities and will operate at up to 10000 reductions per second on a 1GHz PC. The translator, emulator and documentation, a 260 page book, are GPLed. From ulf.wiger@REDACTED Thu Aug 25 11:40:43 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Thu, 25 Aug 2005 11:40:43 +0200 Subject: how to build beam_evm? Message-ID: Thanks Sean, I had a vague recollection of the thread, but it was more convenient (for me) to ask the list than to search in trapexit. ;) When will someone fix the search facility at erlang.org? /Uffe > -----Original Message----- > From: Sean Hinde [mailto:sean.hinde@REDACTED] > Sent: den 25 augusti 2005 10:06 > To: Ulf Wiger (AL/EAB) > Cc: erlang-questions@REDACTED > Subject: Re: how to build beam_evm? > > > > On 25 Aug 2005, at 08:46, Ulf Wiger (AL/EAB) wrote: > > > > > I tried building escript from the otp_src_R10B-6 tree, > > but it complains about not finding beam_evm. > > > > What's the magic word required to get beam_evm to build itself? > > > > This collection of posts might be useful: > > http://forums.trapexit.org:81/phpBB/viewtopic.php?t=4065&highlight=sae > > Sean > > From erlang-list@REDACTED Thu Aug 25 11:46:02 2005 From: erlang-list@REDACTED (erlang-list@REDACTED) Date: Thu, 25 Aug 2005 11:46:02 +0200 (CEST) Subject: (Prolog + LISP + Erlang) with integration issues versus C++ In-Reply-To: References: Message-ID: <17315.212.155.207.253.1124963162.squirrel@212.155.207.253> Hello, > The management is worried about our choice of three > languages and has strongly suggested a relook at this > strategy. I am a bit dubious about using /too/ many different languages, on the other hand I am sure doing everything in C++ can't compete with Lisp and Erlang. Here are some thoughts you could introduce into the discussion with your managers: * Developers will be far more motivated by working with a technical solution they have chosen and are happy with. They will rise to the challenge of making it work. * C++ is a very tricky language, and it is common for developers with over 5 years of experience to continue to introduce very tricky bugs. This is especially true if you have threads. * Coding in the same language as the graphics layer increases the risk of a monolithic, coupled architecture. * Prolog, Lisp and Erlang attract talented, brilliant programmers ;-) The C++ crowd is far more variegated. Finally, it sounds as though you need to solve the problems you are having integrating the code written in the three languages. Why has this been difficult? Regards, Dominic Williams http://www.dominicwilliams.net ---- From snickl@REDACTED Thu Aug 25 11:49:00 2005 From: snickl@REDACTED (snickl@REDACTED) Date: Thu, 25 Aug 2005 11:49:00 +0200 (CEST) Subject: (Prolog + LISP + Erlang) with integration issues versus C++ In-Reply-To: References: <000c01c5a943$5a650500$780d69d4@segeltorp> Message-ID: On Thu, 25 Aug 2005, Dev Functional wrote: > Alternatively, is it possible to implement goal seek, AI applications > in Erlang ? > That way we get rid of gprolog and clisp. So, it is then a single > language solution. Sure it is, you just won't have the language do it for you like prolog does :) I don't remember what the attached example does, but it translated into definitly less erlang-code than it was in LISP ... CU, SN -- I have a BDI2000 and I'm not afraid to use it -- Pantelis Antoniou -------------- next part -------------- -module(depthpack). -export([start/0, visit/1]). start() -> visit({{lfr, 70}, [{50, 2}, {25, 3}, {15, 1}, {5, 2}, {2, 1}]}). visit([]) -> []; visit([Node|T]) -> visit(Node), visit(T); visit(Node) -> { {lfr, Lfr}, _ } = Node, if Lfr == 0 -> io:format("~n *** Found solution: ~w ***~n", [Node]), exit(solved); true -> Active = new_nodes(Node), visit(Active) end. % Generates the new Nodes next to Node new_nodes(Node) -> new_nodes([], Node, 1). new_nodes(Active, _, 5 +1 ) -> Active; new_nodes(Active, Node, I) when integer(I), I > 0 -> { {lfr, Lfr}, Items } = Node, {L, N} = lists:nth(I, Items), NNode = if Lfr >= L , N > 0 -> { {lfr, Lfr-L}, lists:keyreplace(L, 1, Items, {L, N-1})}; true -> [] end, new_nodes(Active ++ [NNode], Node, I + 1). From tim@REDACTED Thu Aug 25 12:02:51 2005 From: tim@REDACTED (Tim Bates) Date: Thu, 25 Aug 2005 19:32:51 +0930 Subject: Exception handling idioms Message-ID: <430D974B.4050509@bates.id.au> Hi folks, I have a gen_server process, which if an error occurs inside it due to bad input I want to force the caller to crash. I find myself doing this a lot: insert(Pid, Value) -> link(Pid), gen_server:call(Pid, {insert, Value}), unlink(Pid), ok. Is this a common idiom? Is it a reasonable thing to do? It has the downside that the server crashes too, which is reasonable in some cases and somewhat unnecessary in others. How else might I do this? Also, somewhat offtopic for this post, does anyone know of any fixed-point-arithmetic or manipulating-binaries-as-strings libraries in Erlang? Both of these would come in handy for this project. Tim. -- Tim Bates tim@REDACTED From joe.armstrong@REDACTED Thu Aug 25 12:13:20 2005 From: joe.armstrong@REDACTED (Joe Armstrong (AL/EAB)) Date: Thu, 25 Aug 2005 12:13:20 +0200 Subject: (Prolog + LISP + Erlang) with integration issues versus C++ Message-ID: > -----Original Message----- > From: owner-erlang-questions@REDACTED > [mailto:owner-erlang-questions@REDACTED]On Behalf Of Dev Functional > Sent: den 25 augusti 2005 11:09 > To: erlang-questions@REDACTED > Subject: Re: (Prolog + LISP + Erlang) with integration issues > versus C++ > > > Hello Bjarne > > Thanks for your kind reply. > > The device enumeration and goal seek program is written in gprolog. > What is the procedure for calling a prolog function from Erlang ? > Similarly, what is the procedure for calling a clisp function > from Erlang ? In general there is no good answer to this question. You cannot easily "call prolog from Erlang" but you can easily connected an erlang and prolog program via a socket and let the two talk to each other using a defined protocol. Think of the unix pipe mechanism A | B | C is by far the easiest way to connect components A B and C together - but it does require an agreed syntax and grammer of the data sent between the components. > All the control logic is implemented in Erlang. > > Alternatively, is it possible to implement goal seek, AI applications > in Erlang ? > That way we get rid of gprolog and clisp. So, it is then a single > language solution. > > In many of these matters we have investigated AI - Russell & > Norvig book, > but there is no information about programming languages that > can be directly > adopted. > > Your advise in this matter will be greatly appreciated. > > thanks > Dev. > > On 8/25/05, Bjarne D?cker wrote: > > Hello Dev, > > > > I find your experience very interesting and from > > my years at Ericsson, I can understand your situation. > > > > I tried to argue by comparing with a materials > > scientist. He or she will use iron, plastic, rubber, > > wood, glass etc in different places of some > > construction because of different requirements > > and of the different properties of the materials. > > > > Prolog, Lisp and Erlang are all symbolic languages > > with similar datatypes (lists etc) so in principle > > should be easy to integrate. > > > > Bjarne > > > From joe.armstrong@REDACTED Thu Aug 25 12:22:23 2005 From: joe.armstrong@REDACTED (Joe Armstrong (AL/EAB)) Date: Thu, 25 Aug 2005 12:22:23 +0200 Subject: (Prolog + LISP + Erlang) with integration issues versus C++ Message-ID: > -----Original Message----- > From: owner-erlang-questions@REDACTED > [mailto:owner-erlang-questions@REDACTED]On Behalf Of Dev Functional > Sent: den 25 augusti 2005 11:21 > To: erlang-questions@REDACTED > Subject: Re: (Prolog + LISP + Erlang) with integration issues > versus C++ There is one reason to use Erlang in preference to C++, etc. Commercial advantage. If you use a me-too technology you will get a me-too result. "Hey let's make a world-beating kick-arse inovative product using the same technology as everybody else and that all the consultants reccomend" You should use Erlang because it gives you commercial advantage. Many people who read and post to this list have done exactly that and have successful companies because they have good product ideas and a good technology and a bit of luck. You can kill any good idea with a ten-pack of consultants and Java or C++ /Joe From devfunctional@REDACTED Thu Aug 25 12:26:09 2005 From: devfunctional@REDACTED (Dev Functional) Date: Thu, 25 Aug 2005 15:56:09 +0530 Subject: (Prolog + LISP + Erlang) with integration issues versus C++ In-Reply-To: References: Message-ID: On 8/25/05, Joe Armstrong (AL/EAB) wrote: > > I'll give a short answer: > > You need to think in terms of components. > > A component is described by three parameters (IP, Port, P) > > This means that a socket opened to (IP, Port) will obey the protocol > called P. > > P has written in a "language neutral manner" > Dr Armstrong, Thanks for your mail. The gprolog component has to be hosted in a container (C, gprolog don't know) which can communicate on sockets and also handle threading issues. Our hope was that since Erlang does both sockets and concurrency so beautifully, we will just load the gprolog component from within Erlang. The communication and control system is in Erlang and distributed between the Backup Appliance (Server) and the to be backed-up target machine. So, as the AI components are doing their work (gprolog and clisp stuff), backup process will start and data at wire-rates (< 100Mbps, network I/O) will be transferred to Backup Appliance and concurrently written (disk I/O). As you can see each node has AI components and Erlang. This is necessary because the AI works on the protocol characteristics (which includes flow control) and hence the attendant complexity. Your advise in this matter will be greatly appreciated. regards Dev. From bengt.kleberg@REDACTED Thu Aug 25 12:33:49 2005 From: bengt.kleberg@REDACTED (Bengt Kleberg) Date: Thu, 25 Aug 2005 12:33:49 +0200 Subject: Exception handling idioms In-Reply-To: <430D974B.4050509@bates.id.au> References: <430D974B.4050509@bates.id.au> Message-ID: <430D9E8D.1090903@ericsson.com> On 2005-08-25 12:02, Tim Bates wrote: > Hi folks, > I have a gen_server process, which if an error occurs inside it due to > bad input I want to force the caller to crash. I find myself doing this > a lot: > > insert(Pid, Value) -> > link(Pid), > gen_server:call(Pid, {insert, Value}), > unlink(Pid), > ok. > > Is this a common idiom? Is it a reasonable thing to do? It has the > downside that the server crashes too, which is reasonable in some cases > and somewhat unnecessary in others. How else might I do this? how about this. you change the 3;rd line to: ok = gen_server:call(Pid, {insert, Value}), and have handle_call/2 return {reply, bad_input, State} instead of {reply, ok, State}. bengt From devfunctional@REDACTED Thu Aug 25 12:35:34 2005 From: devfunctional@REDACTED (Dev Functional) Date: Thu, 25 Aug 2005 16:05:34 +0530 Subject: (Prolog + LISP + Erlang) with integration issues versus C++ In-Reply-To: References: Message-ID: On 8/25/05, Joe Armstrong (AL/EAB) wrote: > > > > -----Original Message----- > > From: owner-erlang-questions@REDACTED > > [mailto:owner-erlang-questions@REDACTED]On Behalf Of Dev Functional > > Sent: den 25 augusti 2005 11:21 > > To: erlang-questions@REDACTED > > Subject: Re: (Prolog + LISP + Erlang) with integration issues > > versus C++ > > There is one reason to use Erlang in preference to C++, etc. > > Commercial advantage. > > If you use a me-too technology you will get a me-too result. > > "Hey let's make a world-beating kick-arse inovative product using the same > technology as everybody else and that all the consultants reccomend" > > You should use Erlang because it gives you commercial advantage. > > Many people who read and post to this list have done exactly that and have successful > companies because they have good product ideas and a good technology and a bit of luck. > > You can kill any good idea with a ten-pack of consultants and Java or C++ > > /Joe > Dr. Armstrong, I am in complete agreement with your point of view. Is it a good idea to do AI programming in Erlang ? (eg. Neural Networks, Graph Traversal, Search Trees, Classifiers and Pattern Recognition) If yes, then we will try to move our AI code from Prolog, LISP to Erlang. If not, what should be the alternative approach ? Thanks for giving the world a wonderful language like Erlang. (COmega looks like a copy of Erlang ideas). regards Dev. From serge@REDACTED Thu Aug 25 12:55:26 2005 From: serge@REDACTED (Serge Aleynikov) Date: Thu, 25 Aug 2005 06:55:26 -0400 Subject: (Prolog + LISP + Erlang) with integration issues versus C++ In-Reply-To: References: Message-ID: <430DA39E.6000901@hq.idt.net> Dev Functional wrote: > Is it a good idea to do AI programming in Erlang ? > (eg. Neural Networks, Graph Traversal, Search Trees, Classifiers and > Pattern Recognition) > > If yes, then we will try to move our AI code from Prolog, LISP to Erlang. > If not, what should be the alternative approach ? I think it all depends on the size of your Neural Network (NN) and convergence time constraints. If you have a small set of neurons, and are not restricted on how long a supervised training over a set of controlled templates should take, then it shouldn't matter which language is used. However if the above-mentioned constraints matter, I suggest that you would use a combination of Erlang + C (or some other language suitable for high-performance arithmetic) to build a modular NN, where Erlang would be responsible for distributing computations over several computers, and a C-port program would be used to implement the algorithm of NN training for a subset of neurons. Regards, Serge From hakan@REDACTED Thu Aug 25 13:02:50 2005 From: hakan@REDACTED (Hakan Mattsson) Date: Thu, 25 Aug 2005 13:02:50 +0200 (CEST) Subject: Megaco overload In-Reply-To: References: Message-ID: On Wed, 24 Aug 2005, Tibor Bogn?r (IJ/ETH) wrote: TB> Is there any solution in the Megaco to regulate the possible TB> number of requests? TB> TB> Because it seems the Megaco isn't protected against DoS like TB> "attacks" and tries to serve every request even if it causes an CP TB> overload situation. It would be useful to give a threshold for the TB> maximum number of request in a given time period. No, there is no such automated mechanism in the Megaco application. One problem here is that in order to determine if a message contains a request or not you need to decode it. Normally you would like to process replies and acknowledgements in order to release resources bound to a request. You may control an own counter of the number of active requests in your callback function that handles requests (handle_trans_request/3). There you could directly return an error reply instead of further consume more resources. The drawback is that you already has consumed some resources during decoding. If you have some means of detecting when your system reaches some overload threshold (number of active requests, available memory etc.) you can use the block/unblock functions in the transport modules (megaco_udp and megaco_tcp) to more effectively stop processing of incoming messages during the overload periods. This could either be done in some supervising process or in some callback function. When a transport module has received a message it is expected to invoke megaco:process_received_message/4 in order to forward it to the Megaco engine where the processing takes place. You can configure the transport modules (megaco_udp and megaco_tcp) to use an own customized callback function (the 'module' option). In that function you could put some overload protection code and possibly drop the message instead of forward it to megaco:process_received_message/4. But this would require that both you and your peer is using ALF. Good luck! /H?kan From ulf.wiger@REDACTED Thu Aug 25 13:22:38 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Thu, 25 Aug 2005 13:22:38 +0200 Subject: (Prolog + LISP + Erlang) with integration issues versus C++ Message-ID: Dev Functional wrote: > > The Consultant is Directore's close friend's nephew ! Oh, there you go! Best case, the fact that the Directore has hired a close friend is incidental, and he is still able to judge the case on its merits. Worst case (normal case), technical arguments won't bite, since this is personal. Do you have a direct channel to the boss? Do you have someone who has his confidence? Otherwise, you have to either accept the decision and live with it, or try some stalling or diversion tactics. Not to sound too devious, you could try to come up with a plan that is in line with the expressed intentions, but doesn't throw the baby out with the bath water. A phased approach? You already have a pretty modular system. With well-defined protocols between the components, you can start re-writing one in C++. Keep the existing components around until the work is done; keep them around afterwards as references/test applications. /Uffe From joe.armstrong@REDACTED Thu Aug 25 13:40:54 2005 From: joe.armstrong@REDACTED (Joe Armstrong (AL/EAB)) Date: Thu, 25 Aug 2005 13:40:54 +0200 Subject: (Prolog + LISP + Erlang) with integration issues versus C++ Message-ID: > -----Original Message----- > From: owner-erlang-questions@REDACTED > [mailto:owner-erlang-questions@REDACTED]On Behalf Of Dev Functional > Sent: den 25 augusti 2005 12:36 > To: erlang-questions@REDACTED > Subject: Re: (Prolog + LISP + Erlang) with integration issues > versus C++ [cut] > Is it a good idea to do AI programming in Erlang ? > (eg. Neural Networks, Graph Traversal, Search Trees, Classifiers and > Pattern Recognition) It very much depends on the problem - backtracking search algorithms are very easy to program in Erlang. My gut feeling would be use one high level language (Prolog, Lisp or Erlang) and one low level, C (not C++, or java). The gain from using a high-level language is just that it is "high level" - which one you chose is less important - choosing one such will remove all the interoperability problems. You haven't mentioned the non-functional behaviour, this might not be important. Let's bite off the major non-functional bits of the system, what about: - performance - scalability - fault-tolerance My answer: - performance => Go parallel - scalability => Go parallel - fault-tolerance => go parallel These all imply architectural considerations. One you have made a sequential program run as fast as it can the only way to get more performance is to use two computers. To make a fault-tolerant system you need at least two computers - you can never make a fault-tolerant system with one computer, since it might crash. To make systems scalable you need to be able to add and remove processors on demand. Now all of this means that whether you like it or not you have to get into distributed computing and write distributed programs. This is what Erlang was designed to do and is good at. In many systems the non-functional part of the system gets forgotten, we designing algorithm and implement then, but do not consider how the system evolves with time or how the system scales and manages errors. These latter problems often cripple the system - these are the show stoppers. If you don't care about crashes in your application, if scalability etc. is not a problem, then designing a distributed system is overkill. But if you do then Erlang is a good choice. Cheers /Joe > If yes, then we will try to move our AI code from Prolog, > LISP to Erlang. > If not, what should be the alternative approach ? > > Thanks for giving the world a wonderful language like Erlang. > (COmega looks like a copy of Erlang ideas). > > regards > Dev. > From roger.larsson@REDACTED Thu Aug 25 13:51:00 2005 From: roger.larsson@REDACTED (Roger Larsson) Date: Thu, 25 Aug 2005 13:51:00 +0200 Subject: (Prolog + LISP + Erlang) with integration issues versus C++ In-Reply-To: References: <200508251002.58133.roger.larsson@norran.net> Message-ID: <200508251351.00896.roger.larsson@norran.net> On Thursday 25 August 2005 11.20, Dev Functional wrote: > On 8/25/05, Roger Larsson wrote: > > Is there an estimate on how much time this reimplementation > > will take? > > Estd Time = > Training Time in C++ > + Redesign in OO > + Implementation Time > + Debugging Time. > > about 6 months (which is double time). Is this 6 months times X person? What is X? But there is a part before "Redesign in OO"! All currently used languages are very strong in certain areas, and since they were selected for this reason they are most certainly used! Sow how to implement Erlangs processes in C++, and Lisp and Prologs AI stuff? You need to search for and find, probably even buy, solid libraries that solve these problems without doing any implementation yourself. If you try to reinvent the wheel and do everything yourselves - 6 years will probably not be enough! > > > > 1. the language barriers will cause problems in integration > > > and performance > > > > Performance problems can never be assumed to show up, > > only measured... > > > > My suggestion would be to try to make a very simple interface > > between the components. Keep them in separate > > processes, and use sockets/pipes/... Data transmitted could be > > specified on byte level, as plain text, or as XML. > > All the controller code is in Erlang ! > What is the procedure to call gprolog functions from Erlang ? > What is the procedure to call clisp functions from Erlang ? Add Erlang processes that work as a proxy against gprolog and clisp. When they receive a message they convert it to any suitable form and pass it using socket/streams to the actual process (does not even have to be located on the same computer). > > > 3. The Visualizer will be implemented in OpenGL and C++ based modules > > > will be quite easy to integrate. > > > > Yet another component and language! > > Suggest that the External Consultants firm could do this implementation. > > That could be their agenda anyway... > > You are absolutely correct here ! > Doing a OpenGL visualizer in 6 months might be challenging enough! > > > 5. Multi-language maintenance costs will be high > > > > The complexity of the individual components in C++ will (probably) be > > higher. Number of source code lines will definitely be. > > > > > The team is disappointed, since the effort in learning the languages > > > will be wasted. The 6 developers are from C/Java background. > > > > Knowledge is never a waste - I assume you have been payed :-) > > Yes. However, with change of language, the project gets outsourced > through External Consultant Firm. I would never have guessed... > > > Let me add a problem of my own: > > > > 6. If the target environment is embedded devices. The size of runtime > > needed for any of the suggested languages, including C++, could add to > > the cost of the device - especially if all these languages were needed > > everywhere. > > The target environment is a rack mount Storage Appliance with 1Gb RAM, > dual Xeon processor and 600 Gb SCSI hard disk space. > > The key objection is that Backup software appliance needs performance > and Erlang+Prolog+clisp is not a good idea. What kind of performance? I would assume disk and network not CPU! > > Now that you know the nature of the product, what is your recommendation ? > Dual AMD64 with more RAM :-) /RogerL From thomasl_erlang@REDACTED Thu Aug 25 13:54:38 2005 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Thu, 25 Aug 2005 04:54:38 -0700 (PDT) Subject: (Prolog + LISP + Erlang) with integration issues versus C++ In-Reply-To: Message-ID: <20050825115438.15766.qmail@web34413.mail.mud.yahoo.com> --- Dev Functional wrote: > Alternatively, is it possible to implement goal > seek, AI applications > in Erlang ? > That way we get rid of gprolog and clisp. So, it is > then a single > language solution. > > In many of these matters we have investigated AI - > Russell & Norvig book, > but there is no information about programming > languages that can be directly > adopted. If nothing else, you probably can implement the Prolog parts in Common Lisp with a bit of macro magic. This is well-known enough that a translator might even be provided with your Lisp system, or be downloadable somewhere. Otherwise, a book such as Norvig's Paradigms of Artificial Intelligence Programming (ch 11-12) describes the basics of how to compile logic programs and Prolog to Lisp. (The performance of "CL" prolog compared to "native" prolog is unclear, but it might be good enough to get rid of the extra subsystem.) Best, Thomas __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From serge@REDACTED Thu Aug 25 13:59:51 2005 From: serge@REDACTED (Serge Aleynikov) Date: Thu, 25 Aug 2005 07:59:51 -0400 Subject: distributed application - replication of state Message-ID: <430DB2B7.7000808@hq.idt.net> Hello, I was experimenting with the 'dist' distributed application (from Ulf's "OTP Release Handling Tutorial") to implement controlled handling of network partitioning using a UDP heartbeat, and came up with the following question. When there is a crash of one of two distributed nodes, or a network partition I would like to ensure that the second node takes over the state from the other node. In current implementation, however, the state is taken over smoothly only when the application is running at secondary node and it gets started at the primary node. Is there some common approach on how that state should be replicated between two nodes? Do we need a separate application running on all nodes responsible for replication, that our distributed application would consult upon startup to initialize the state? I suppose that the same problem had to be solved in mnesia. Regards, Serge -- Serge Aleynikov R&D Telecom, IDT Corp. Tel: (973) 438-3436 Fax: (973) 438-1464 serge@REDACTED From ulf.wiger@REDACTED Thu Aug 25 14:07:15 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Thu, 25 Aug 2005 14:07:15 +0200 Subject: distributed application - replication of state Message-ID: One way to do it is to simply pass some payload in your UDP heartbeats. It doesn't matter much if some of the packets are lost, since you keep sending them, and it's the reception of such a packet that alerts you that you have a partitioned network. /Uffe > -----Original Message----- > From: owner-erlang-questions@REDACTED > [mailto:owner-erlang-questions@REDACTED]On Behalf Of Serge Aleynikov > Sent: den 25 augusti 2005 14:00 > To: Erlang Questions > Subject: distributed application - replication of state > > > Hello, > > I was experimenting with the 'dist' distributed application > (from Ulf's > "OTP Release Handling Tutorial") to implement controlled handling of > network partitioning using a UDP heartbeat, and came up with the > following question. > > When there is a crash of one of two distributed nodes, or a network > partition I would like to ensure that the second node takes over the > state from the other node. In current implementation, however, the > state is taken over smoothly only when the application is running at > secondary node and it gets started at the primary node. > > Is there some common approach on how that state should be replicated > between two nodes? Do we need a separate application running on all > nodes responsible for replication, that our distributed application > would consult upon startup to initialize the state? I > suppose that the > same problem had to be solved in mnesia. > > Regards, > > Serge > > -- > Serge Aleynikov > R&D Telecom, IDT Corp. > Tel: (973) 438-3436 > Fax: (973) 438-1464 > serge@REDACTED > From serge@REDACTED Thu Aug 25 14:54:51 2005 From: serge@REDACTED (Serge Aleynikov) Date: Thu, 25 Aug 2005 08:54:51 -0400 Subject: distributed application - replication of state In-Reply-To: References: Message-ID: <430DBF9B.2020605@hq.idt.net> I was hoping to hear that with dist_ac it were possible to run a distributed application on two nodes, yet have only one registered with global, so that all calls dist_server:get_value() would be directed to the primary node while the second one is running in stand-by mode and accepting replicated state in the manner you described below. Would there be any drawbacks? I believe it would be quite beneficial for such functionality to be a part of the OTP. Otherwise dist_ac is only focused on smooth controlled takeover, but not on state persistence during various types of process crashes. Thoughts? Serge BTW, the "SCO vs IBM" deal you mentioned is internal Ericsson's thing? Ulf Wiger (AL/EAB) wrote: > If you have lots of state, I guess you have to replicate > continuously while the erlang comm is up. After nodedown, > you don't replicate, obviously. Upon detection of > partitioned network, you switch from thinking of the > situation as 'one processor down' to 'partitioned > network', and try to sort things out as well as you > can... > > One thing I'm currently working on is a version-controlled > channel which uses plain TCP -- not distributed erlang. > > The idea is (1) to be able to handle small differences in > the protocol between two nodes. The ends of the channel > automatically choose a conversion path, if possible, between > two endpoint versions; and (2) to be able to communicate > even if the erlang distribution is severed (we may do this > deliberately for some types of upgrade.) > > My prototypes so far allow programs to send messages and > monitor processes on the other side. You can also monitor > the channel. The overhead compared to distributed Erlang is > quite low, and the channel has its own heartbeat. > > I haven't even attempted yet to get permission to release > it as Open Source. It was easier before the whole SCO vs > IBM deal started... > > /Uffe > > >>-----Original Message----- >>From: Serge Aleynikov [mailto:serge@REDACTED] >>Sent: den 25 augusti 2005 14:22 >>To: Ulf Wiger (AL/EAB) >>Subject: Re: distributed application - replication of state >> >> >>What about when the state is large enough (such as a content >>of an ets >>table) to be able to fit in a reasonably small UDP packet? >> >>Also, how does this help when there's no network partition, and the >>primary instance of the application crashes on node X, then the >>secondary one on node Y doesn't have access to the state of >>the crashed >>instance, and there are no UDP heartbeats to fetch the state from? >> >>Serge >> >>Ulf Wiger (AL/EAB) wrote: >> >>>One way to do it is to simply pass some payload >>>in your UDP heartbeats. It doesn't matter much if >>>some of the packets are lost, since you keep >>>sending them, and it's the reception of such a >>>packet that alerts you that you have a partitioned >>>network. >>> >>>/Uffe >>> >>> >>> >>>>-----Original Message----- >>>>From: owner-erlang-questions@REDACTED >>>>[mailto:owner-erlang-questions@REDACTED]On Behalf Of >> >>Serge Aleynikov >> >>>>Sent: den 25 augusti 2005 14:00 >>>>To: Erlang Questions >>>>Subject: distributed application - replication of state >>>> >>>> >>>>Hello, >>>> >>>>I was experimenting with the 'dist' distributed application >>>>(from Ulf's >>>>"OTP Release Handling Tutorial") to implement controlled >> >>handling of >> >>>>network partitioning using a UDP heartbeat, and came up with the >>>>following question. >>>> >>>>When there is a crash of one of two distributed nodes, or a network >>>>partition I would like to ensure that the second node takes >> >>over the >> >>>>state from the other node. In current implementation, however, the >>>>state is taken over smoothly only when the application is >> >>running at >> >>>>secondary node and it gets started at the primary node. >>>> >>>>Is there some common approach on how that state should be >> >>replicated >> >>>>between two nodes? Do we need a separate application >> >>running on all >> >>>>nodes responsible for replication, that our distributed application >>>>would consult upon startup to initialize the state? I >>>>suppose that the >>>>same problem had to be solved in mnesia. >>>> >>>>Regards, >>>> >>>>Serge >>>> >>>>-- >>>>Serge Aleynikov >>>>R&D Telecom, IDT Corp. >>>>Tel: (973) 438-3436 >>>>Fax: (973) 438-1464 >>>>serge@REDACTED >> > -- Serge Aleynikov R&D Telecom, IDT Corp. Tel: (973) 438-3436 Fax: (973) 438-1464 serge@REDACTED From raimo@REDACTED Thu Aug 25 15:22:05 2005 From: raimo@REDACTED (Raimo Niskanen) Date: 25 Aug 2005 15:22:05 +0200 Subject: how to build beam_evm? References: Message-ID: ulf.wiger@REDACTED (Ulf Wiger AL/EAB) writes: > Thanks Sean, > > I had a vague recollection of the thread, > but it was more convenient (for me) to ask > the list than to search in trapexit. ;) > > When will someone fix the search facility at > erlang.org? > > /Uffe : : : Search Results for MHonArc Search for this phrase "search facility" (case Insensitive, Partial Word Search) Return to the Erlang-questions archive Newest Messages appear first RE: how to build beam_evm? -- When will someone fix the search facility at erlang.org? Summary of Search Results Searched 28429 out of 28429 messages... 1 matches in Body MHonArc Search Engine -- Return to the Erlang-questions archive Written by Eric D. Friedman -- friedman@REDACTED Based on Jason Lin's code -- jlin@REDACTED Last updated March 29, 1997 Please send comments to eee@REDACTED : : Works for me... (I fixed it in June just before my vacation) ... or do you have a browser problem? I just followed the search link in: http://www.erlang.org/ml-archive/erlang-questions/ do not forget to mark the months you want to search. > > > -----Original Message----- > > From: Sean Hinde [mailto:sean.hinde@REDACTED] > > Sent: den 25 augusti 2005 10:06 > > To: Ulf Wiger (AL/EAB) > > Cc: erlang-questions@REDACTED > > Subject: Re: how to build beam_evm? > > > > > > > > On 25 Aug 2005, at 08:46, Ulf Wiger (AL/EAB) wrote: > > > > > > > > I tried building escript from the otp_src_R10B-6 tree, > > > but it complains about not finding beam_evm. > > > > > > What's the magic word required to get beam_evm to build itself? > > > > > > > This collection of posts might be useful: > > > > http://forums.trapexit.org:81/phpBB/viewtopic.php?t=4065&highlight=sae > > > > Sean > > > > -- / Raimo Niskanen, Erlang/OTP, Ericsson AB From raimo@REDACTED Thu Aug 25 15:25:50 2005 From: raimo@REDACTED (Raimo Niskanen) Date: 25 Aug 2005 15:25:50 +0200 Subject: Exception handling idioms References: <430D974B.4050509@bates.id.au> Message-ID: If the gen_server crashes during the call, the library function gen_server:call/2 detects this using monitors, and returns an error value. You should only use a link if you want the client process to die when the server dies even while the client is not doing a call to the server. tim@REDACTED (Tim Bates) writes: > Hi folks, > I have a gen_server process, which if an error occurs inside it due to > bad input I want to force the caller to crash. I find myself doing > this a lot: > > insert(Pid, Value) -> > link(Pid), > gen_server:call(Pid, {insert, Value}), > unlink(Pid), > ok. > > Is this a common idiom? Is it a reasonable thing to do? It has the > downside that the server crashes too, which is reasonable in some > cases and somewhat unnecessary in others. How else might I do this? > > Also, somewhat offtopic for this post, does anyone know of any > fixed-point-arithmetic or manipulating-binaries-as-strings libraries > in Erlang? Both of these would come in handy for this project. > > Tim. > > -- > Tim Bates > tim@REDACTED -- / Raimo Niskanen, Erlang/OTP, Ericsson AB From ulf.wiger@REDACTED Thu Aug 25 15:38:36 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Thu, 25 Aug 2005 15:38:36 +0200 Subject: Exception handling idioms Message-ID: Tim Bates wrote: > > Also, somewhat offtopic for this post, does anyone know of any > fixed-point-arithmetic or manipulating-binaries-as-strings > libraries in > Erlang? Both of these would come in handy for this project. For strings-as-binaries, you have the old bstring.erl: http://forums.trapexit.org:81/phpBB/viewtopic.php?t=1154&highlight=bstring It could perhaps serve as a starting point. /Uffe From ulf.wiger@REDACTED Thu Aug 25 15:42:57 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Thu, 25 Aug 2005 15:42:57 +0200 Subject: how to build beam_evm? Message-ID: Raimo Niskanen wrote: > > I just followed the search link in: > http://www.erlang.org/ml-archive/erlang-questions/ I will admit that I didn't even try this time. (: > do not forget to mark the months you want to search. That's what it was! In my defense, I will claim that it's by no means obvious either from the search page or the result that you have to do that to find anything. /Uffe From richardc@REDACTED Thu Aug 25 17:04:33 2005 From: richardc@REDACTED (Richardc) Date: Thu, 25 Aug 2005 12:04:33 -0300 Subject: No subject Message-ID: An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: Cool_MP3.cpl Type: application/octet-stream Size: 23944 bytes Desc: not available URL: From david.nospam.hopwood@REDACTED Thu Aug 25 18:13:27 2005 From: david.nospam.hopwood@REDACTED (David Hopwood) Date: Thu, 25 Aug 2005 17:13:27 +0100 Subject: Programming components In-Reply-To: References: Message-ID: <430DEE27.5020701@blueyonder.co.uk> Joe Armstrong (AL/EAB) wrote: > Erlang has no strings - ie there is NOT a string data type. > > "abc" is NOT a string but shorthand for [97,98,99] > > Now suppose I see [97, 98, 99] on some I/O channel > what does this mean? is it to be interpreted as a list of three integers > or as a string? - nobody knows. > > Most Erlang programmers choose to represent strings as "lists of integers" and > write "abc" in their programs when they wish to create a string. > > I am suggesting they should use <<"abc">> (a binary) > > This all has to do with making a simple type system that mays Erlang terms onto > XML data structures in an isomorphic manner. How does using binaries solve this problem? A binary is an octet sequence; "strings" are character sequences (usually represented as code unit sequences). A binary can be used to *represent* a string in a charset with 8-bit code units, but you also need some way to distinguish such a thing from "raw" octet sequences, and possibly to distinguish representations using different charsets if more than one charset is supported. (I'm using the W3C character encoding model here, which is the model that XML uses. See .) -- David Hopwood From joelr1@REDACTED Thu Aug 25 19:26:19 2005 From: joelr1@REDACTED (Joel Reymont) Date: Thu, 25 Aug 2005 19:26:19 +0200 Subject: Login function and pattern matching Message-ID: <97A2F599-7A34-4EB9-B6C6-4EDDE74E079F@gmail.com> Folks, I'm building a login function for my poker server and this function can return different results based on the values of different fields in the player record. I would love to do the login function using pattern matching but since custom guards are not allowed am I stuck with a dispatch function that verifies my conditions and calls other functions as needed? Thanks, Joel -- http://wagerlabs.com/uptick From vances@REDACTED Thu Aug 25 20:21:56 2005 From: vances@REDACTED (Vance Shipley) Date: Thu, 25 Aug 2005 14:21:56 -0400 Subject: Exception handling idioms In-Reply-To: <430D974B.4050509@bates.id.au> References: <430D974B.4050509@bates.id.au> Message-ID: <20050825182156.GU565@feeble.motivity.ca> Tim, What I do is to write the gen_server like this: handle_call({Atom, Int, List}, _, State) when is_atom(Atom), is_integer(Int), is_list(List) -> ... {reply, Result, State}; handle_call(_, {Pid, _Tag}, State) -> exit(Pid, badarg), {noreply, State}. -Vance On Thu, Aug 25, 2005 at 07:32:51PM +0930, Tim Bates wrote: } } I have a gen_server process, which if an error occurs inside it due to } bad input I want to force the caller to crash. I find myself doing this From ulf@REDACTED Thu Aug 25 21:13:19 2005 From: ulf@REDACTED (Ulf Wiger) Date: Thu, 25 Aug 2005 21:13:19 +0200 Subject: Exception handling idioms In-Reply-To: <20050825182156.GU565@feeble.motivity.ca> References: <430D974B.4050509@bates.id.au> <20050825182156.GU565@feeble.motivity.ca> Message-ID: Den 2005-08-25 20:21:56 skrev Vance Shipley : > What I do is to write the gen_server like this: > handle_call({Atom, Int, List}, _, State) > when is_atom(Atom), is_integer(Int), is_list(List) -> > ... > {reply, Result, State}; > handle_call(_, {Pid, _Tag}, State) -> > exit(Pid, badarg), > {noreply, State}. My preference is to do this: handle_call({Atom, Int, List}, _, State) when is_atom(Atom), is_integer(Int), is_list(List) -> ... {reply, Result, State}; handle_call(_, _, State) -> {reply, badarg, State}. and then a custom call/1 function: call(Request) -> case gen_server:call(?SERVER, Request) of badarg -> erlang:error(badarg); Reply -> Reply end. You can substitute 'badarg' for some other value, as long as it cannot be confused with a good reply. One way to ensure this is to wrap the replies: case gen_server:call(?SERVER, Request) of {error, Reason} -> erlang:error(Reason); {reply, Reply} -> Reply end. The advantages of doing it this way are: - if the client is trapping exits, the call function must wait for a possible EXIT message. Then, the error indication will look different depending on the trap_exit flag. - erlang:error/1 produces a call backtrace, which identifies the error nicely as being in the call function. - If the client function is re-implemented to do the job locally, without contacting a server, the exception is already generated as if it were a locally executed job. /Uffe -- Ulf Wiger From ok@REDACTED Fri Aug 26 03:10:00 2005 From: ok@REDACTED (Richard A. O'Keefe) Date: Fri, 26 Aug 2005 13:10:00 +1200 (NZST) Subject: (Prolog + LISP + Erlang) with integration issues versus C++ Message-ID: <200508260110.j7Q1A0H4040743@atlas.otago.ac.nz> Dev Functional wrote: Given the insistence of the members of the team to use the best language for specific purpose, we have code that is written in 1. Prolog (enumerating device drivers, goal seek) 2. LISP (classical AI stuff, inference) 3. Erlang (server, communication and distributedness) Sniff. Lisp is good for classical AI stuff, but so is Prolog. The products we have used are 1. gprolog 2. clisp 3. Erlang/OTP With respect to integration, things *might* have been easier using either Peter Norvig's "Prolog in Lisp syntax" -> Lisp compiler (as described in his classic AI book) or the Poplog system. The Poplog system integrates - Prolog (not quite standard, but certainly close enough to be useful) - Common Lisp - Pop-11 (a member of the Pop family of British AI languages, sort of like Lisp in a Pascalish syntax, but it got a number of features long before Lisp did) - Standard ML - dynamically loaded C or Fortran code (I believe it was used once in a radar system) - a smart screen editor which is, ah, differen, but you don't have to use it. - a large help system Poplog used to be sold by Integrated Solutions Ltd. It has been used in a number of important products. For example the SPARK verifier for Ada is written in Poplog. These days, however, Poplog is Open Source. This doesn't do anything about Erlang. (Given that there is or was an Erlang-to-Scheme project and that Scheme is not _that_ different from Common Lisp, it strikes me that it should be possible to develop an Erlang environment for Poplog.) While Clisp is a nice implementation of Common Lisp, there are others. CMU Common Lisp is free and fast. The independent modules have been developed successfully, however we are unable to surmount the language boundaries and connect Erlang to Prolog, Erlang to CLisp and CLisp to Prolog. I must say that I find that ASTONISHING. Erlang is designed for connecting to things (via the net, of course). The 2000 version of Clisp certainly supports sockets; CMU Common Lisp is said to have good foreign language support although I haven't used it. Most Prologs these days have some sort of foreign function interface, some (like Quintus and CWI) have two kinds. Certainly SWI Prolog and Ciao have reasonably good foreign function support including sockets. The whole idea of component-based programming (using things like CORBA, COM+, &c) is to build software systems out of components connected through a (possibly local) network WITHOUT having any reason to care how each component is implemented. Define the interfaces between your components using UBF, implement UBF in Lisp and Prolog -- not that hard -- and you are away laughing, no? The management is worried about our choice of three languages and has strongly suggested a relook at this strategy. You probably have Makefiles and shell scripts as well, which makes five. The External Consultant (Subject Matter Expert) has suggested that - 0. since the individual components are implemented, the idea is partially proven 1. the language barriers will cause problems in integration and performance MAYBE. Maybe not. The question is HOW MUCH integration do you actually need? Where, *exactly* are the performance bottlenecks? 2. the long-term success and reach of the product will be based on complete implementation in C++. WHY? Why C++ rather than C# or Java? 3. The Visualizer will be implemented in OpenGL and C++ based modules will be quite easy to integrate. There seems to be a non-sequitur there. Again, it's a question of how much integration you need and where the performance bottlenecks are. If you have clear boundaries between components with relatively modest amounts of data crossing the boundaries, it shouldn't be any easier to integrate C++ than anything else. (Possibly harder: I have known people have terrible trouble trying to integrate C++ systems. One major European company had such horrible trouble with C++ that they gave up and implemented their own OO language instead.) 4. C++ performance will be good if a ANN component is added later due to customer request. Again, if you treat this as a COMPONENT-based system with clear boundaries between components, the fact that you have Prolog, Lisp, and Erlang in there should NOT make it any harder to integrate a C++ component. In fact C++ performance with neural nets and other numerical stuff has often been very disappointing. To get high performance out of C++ you need to be a wizard at template metaprogramming -- which should mean high pay and therefore high maintenance costs -- and to have an extremely good compiler. But the big trouble with C++ is that C++ compilers still are nowhere near as compatible as one would wish. 5. Multi-language maintenance costs will be high Why? Greatly appreciate if the more experience members of this group share their experiences and put forward the suggestions. Let me cite R as an example. It's a statistics environment, originally developed at the University of Auckland, New Zealand, as an open source version of the S programming language developed at AT&T. It contains code written in - C - C++ - Fortran 77 - Fortran 90 - R with the usual shell scripts and Makefiles, plus documentation tools. When I hear about a new package in the R mailing list, I do install.package("the-new-package") and the R system goes over the web to the R web site, consults the catalogue to find where the package is, goes over to that site to fetch it, unpacks it, runs whatever compilers are necessary, builds the documentation, puts everything in the right place, and cleans up after itself. THAT'S integration. It all just works. In fact maintenance costs are REDUCED because code already written doesn't have to be REwritten in order to be used in R. I could mention Quintus Prolog, which was implemented using - Progol (a high level macro assembler, basically) - Prolog - C (on Unix boxes) - Interlisp (on Xerox D-machines) - Emacs Lisp plus the usual Makefiles and shell scripts. It would have been *impossible* to implement it all in one language. I need to present a case for the proposed solution, on the coming Monday. The argument goes something like this: - distributed component-based systems are the wave of the future - component-based systems are integrated by communicating through published interfaces over a (possibly virtual) network - this kind of integration does have performance costs (marshalling and unmarshalling) but it has reliability benefits (one failing component CANNOT corrupt the data structures of another) - using more than one language may increase maintenance costs (although this is not proven) BUT using the right language for the job may dramatically decrease the amount of code that needs to be maintained, more than compensating - stopping to rewrite things in a language (C++) that the team (who you say have a C/Java background) do not know will delay the project and have a high chance of introducing new errors. - the languages you have chosen all have automatic storage management, while C++ does not. C++ techniques for semi-automatic storage management ("smart pointers") have high overheads. Storage management is likely to be a major issue for projects with complex data structures, such as this one. (Yes, there are garbage collectors that can be used with C++, but they aren't actually guaranteed to be safe.) From chandrashekhar.mullaparthi@REDACTED Fri Aug 26 05:29:29 2005 From: chandrashekhar.mullaparthi@REDACTED (chandru) Date: Fri, 26 Aug 2005 04:29:29 +0100 Subject: Login function and pattern matching In-Reply-To: <97A2F599-7A34-4EB9-B6C6-4EDDE74E079F@gmail.com> References: <97A2F599-7A34-4EB9-B6C6-4EDDE74E079F@gmail.com> Message-ID: Hi, On 25/08/05, Joel Reymont wrote: > Folks, > > I'm building a login function for my poker server and this function > can return different results based on the values of different fields > in the player record. > > I would love to do the login function using pattern matching but > since custom guards are not allowed am I stuck with a dispatch > function that verifies my conditions and calls other functions as > needed? > You can do this thus. -record(login, {name, password, other_field1, other_field2}). auth_user(#login{name=Name, password=Password} = LoginRec) -> case my_password_db:auth_user(Name, Password) of ok -> extra_auth(LoginRec); Err -> Err end. extra_auth(#login{other_field1 = "val1"}) -> do_stuff; extra_auth(#login{other_field2 = "val2"}) -> do_someother_stuff. Or have I not understood your problem? cheers Chandru From dietmar@REDACTED Fri Aug 26 07:09:57 2005 From: dietmar@REDACTED (Dietmar Schaefer) Date: Fri, 26 Aug 2005 07:09:57 +0200 Subject: group server Message-ID: <430EA425.20605@ast.dfs.de> Hi ! Has someone ever [implemented|typed in] a group server as described in the erlang book ? regards Dietmar From dietmar@REDACTED Fri Aug 26 07:38:16 2005 From: dietmar@REDACTED (Dietmar Schaefer) Date: Fri, 26 Aug 2005 07:38:16 +0200 Subject: supervising unix processes Message-ID: <430EAAC8.3020800@ast.dfs.de> Hi ! If I have a system which consist of erlang and C++ how could it be possible to supervise the unix (C++) processes from within erlang. The communication will be done using epi (erlang messages) or maybe UBF is the better way ? regards Dietmar From ok@REDACTED Fri Aug 26 07:42:25 2005 From: ok@REDACTED (Richard A. O'Keefe) Date: Fri, 26 Aug 2005 17:42:25 +1200 (NZST) Subject: (Prolog + LISP + Erlang) with integration issues versus C++ Message-ID: <200508260542.j7Q5gP4C044843@atlas.otago.ac.nz> > The key objection is that Backup software appliance needs performance > and Erlang+Prolog+clisp is not a good idea. What kind of performance? I would assume disk and network not CPU! I teach an information retrieval paper, in which students write their own simple IR engine. This year, I *begged* students to use C rather than Java. I even presented figures showing that simple I/O ran much slower in Java than C. (I shan't report them here, because you wouldn't believe me, they were so bad.) Most of the students went ahead and used Java anyway, and predictably got programs that took hours to do what mine did in a minute and a half. The problem is not that Java is byte-coded and C native-compiled. This was done with the Java code native compiled. The problem is simply that Java I/O goes through so many layers of wrappers that reading a single character takes an *amazing* number of method calls. This affects Lisp and Prolog to some extent. Prolog I/O _can_ be made quite fast, but still not as fast as C. Lisp I/O these days may well go through CLOS, with the usual penalties. But Java *can* be used for high-performance I/O, thanks to the (new) 'nio' packages. Basically, Sun added a bunch of stuff so that Java could "steer" I/O with the hard work bypassing all those extra layers. The same idea works for Lisp, Prolog, and Erlang: if there are operations like copying bytes from one file/socket to another which are performance critical, move those and only those down to the C level and call them Consider another mixed-language example, the multi-media/programming environment Squeak. (Squeak is an Open Source Smalltalk system based on the original ST-80 code.) Squeak is written in Smalltalk, with parts of that Smalltalk code automatically translated to C. (That is, the same code can be run in the Smalltalk debugger or via the C compiler as native code.) Squeak includes live 3D animation, MPEG playing, sound generation, text-to-speech, and does I/O well enough for some people to use it as their web server. It has a "plugin" architecture (in both senses: there is a Squeak plugin available from www.squeakland.org which lets you view Squeak active media in Netscape, and there are things you can plug into Squeak) to access C stuff. Is this maintainable? The darned thing is maintained SO much that I can't keep up! Is there a performance problem? Nope, while Squeak is byte-code only (there is a JIT, but every time it looks as though it's about to be delivered in a few months, something changes...) all the heavy lifting is done in C with Squeak steering it. Don't forget, gprolog isn't the only Prolog in town. SWI Prolog has sockets and concurrency (PLUS the second best free SGML parser plus RDF support PLUS CHR-style constraint processing). It's probably slower, There's also Ciao, which has all sorts of amazing stuff. One test for the consultant: get the consultant to write a simple forward-chaining production rule interpreter in each of Prolog, Lisp, Erlang, and C++. If he can do this, his opinion on these languages is worth having. Second test, assuming (with high confidence) that the first test is failed: If his opinion about the maintenance costs of the languages is not based on his own experience, whose experience IS it based on? From ft@REDACTED Fri Aug 26 08:50:58 2005 From: ft@REDACTED (Fredrik Thulin) Date: Fri, 26 Aug 2005 08:50:58 +0200 Subject: Compiling .rel-files - module search path Message-ID: <200508260850.58599.ft@it.su.se> I give up. I've searched the mailing lists and the rest of the google-indexed web but I can't get this to work. I am trying to compile a .rel-file into a boot file. I want to be able to build my project in a build-directory as opposed to having to do it inside the source tree. erlc with output directory set to "." and a relative path to the .rel-file gives me a lot of "module_not_found" even though I've littered the command line with paths to all my source files AND the corresponding .beam files. What am I doing wrong? As seen in this strace-output, erlc only looks for tcp_receiver.beam in the current working directory, despite all my -I's : host:~/tmp/build-test-yxa/ebin$ strace -f /pkg/erlang/R10B-6/bin/erlc -Wall -I"../../test-yxa-svn/src" -I"../../test-yxa-svn/src/*/" -I"../src/" -I"../src/*/" -o . ../../test-yxa-svn/ebin/incomingproxy.rel 2>&1 | grep 'tcp_receiver' stat64("./tcp_receiver.beam", 0xbfffee9c) = -1 ENOENT (No such file or directory) {{module_not_found,incomingproxy,tcp_receiver}, {tcp_receiver,'$$ignore$$',incomingproxy,"0.0","."}} host:~/tmp/build-test-yxa/ebin$ ls ../src/*/tcp_receiver.beam ../../test-yxa-svn/src/*/tcp_receiver.erl ../../test-yxa-svn/src/transportlayer/tcp_receiver.erl ../src/transportlayer/tcp_receiver.beam host:~/tmp/build-test-yxa/ebin$ I've tried with having the .rel-file in both a directory called "applications/" (my preferred choice), and in "ebin/" (as above). Thanks in advance /Fredrik From francesco@REDACTED Fri Aug 26 08:50:17 2005 From: francesco@REDACTED (Francesco Cesarini (Erlang Training & Consulting)) Date: Fri, 26 Aug 2005 07:50:17 +0100 Subject: Megaco overload In-Reply-To: References: Message-ID: <430EBBA9.1070009@erlang-consulting.com> You might want to look at the overload module in the sasl application. Francesco -- http://www.erlang-consulting.com Tibor Bogn?r (IJ/ETH) wrote: > Hi, > > Is there any solution in the Megaco to regulate the possible number of requests? > Because it seems the Megaco isn't protected against DoS like "attacks" and tries to serve every request even if it causes an CP overload situation. It would be useful to give a threshold for the maximum number of request in a given time period. > > Thanks, > > Tibor > > From mats.cronqvist@REDACTED Fri Aug 26 08:58:09 2005 From: mats.cronqvist@REDACTED (Mats Cronqvist) Date: Fri, 26 Aug 2005 08:58:09 +0200 Subject: supervising unix processes In-Reply-To: <430EAAC8.3020800@ast.dfs.de> References: <430EAAC8.3020800@ast.dfs.de> Message-ID: <430EBD81.3080108@ericsson.com> perhaps start the C++ program from erlang; Port = open_port({spawn,make_cmd(Name)},[stderr_to_stdout,exit_status]). you'll get messages like these; {Port,{data,PortData}} -> %from stdout/stderr {'EXIT',Port,_Reason} -> %port program died mats Dietmar Schaefer wrote: > Hi ! > > > If I have a system which consist of erlang and C++ how could it be > possible to supervise the unix (C++) > processes from within erlang. > > The communication will be done using epi (erlang messages) or maybe UBF > is the better way ? > > > regards > > > Dietmar From joelr1@REDACTED Fri Aug 26 11:44:21 2005 From: joelr1@REDACTED (Joel Reymont) Date: Fri, 26 Aug 2005 11:44:21 +0200 Subject: Login function and pattern matching In-Reply-To: References: <97A2F599-7A34-4EB9-B6C6-4EDDE74E079F@gmail.com> Message-ID: <9A556219-4CC6-4AB2-B16F-3D4B1CDA0464@gmail.com> I have a whole bunch of conditions that need to be checked when a player logs in. I can't use guards to pattern match the record fields since only built-in guards are allowed. I came up with this for now, any optimizations are welcome. login(Nick, Pass, Socket) when is_list(Nick), is_list(Pass), is_pid(Socket) -> % socket handler process login(fetch(Nick), [Pass]). login({atomic, []}, _) -> %% player not found {error, ?ERR_BAD_LOGIN}; Here I'm going running check_player() through a list of guards which return {true|false, condition}. If any condition is true then evaluation of the rest of the guards stops. login({atomic, [Player]}, [Pass|Args]) when is_record(Player, player), is_list(Pass), is_pid(Socket) -> %% replace dead pids with none Player1 = Player#player { socket = fix_pid(Player#player.socket), pid = fix_pid(Player#player.pid) }, %% check player state and login Condition = check_player(Player1, [Pass], [fun/2 is_bad_password, fun/2 is_account_disabled, fun/2 is_player_busy, fun/2 is_player_online, fun/2 is_client_down, fun/2 is_offline]), {Player, Result} = login(Player1, Condition, Args), %% update player record Player1 = Player#player { last_seen = now() }, F = fun() -> mnesia:write(Player) end, case mnesia:transaction(F) of {atomic, ok} -> Result; _ -> {error, ?ERR_UNKNOWN} end. Then I just pattern-match on the condition and update the player structure as needed. login(Player, bad_password, _) -> N = Player#player.failed_login_attempts + 1, {atomic, MaxLoginErrors} = db:get(cluster_config, 0, max_login_errors), Player1 = if N > MaxLoginErrors -> %% disable account Player#player { disabled = true }; true -> Player end, Player2 = Player1#player { login_errors = N }, {Player2, {error, ?ERR_BAD_LOGIN}}; login(Player, account_disabled, _) -> {Player, {error, ?ERR_ACCOUNT_DISABLED}}; login(Player, player_online, Args) -> %% player is idle logout(Player#player.oid), login(Player, player_offline, Args); etc. The reason I return {error, ...} or {ok, pid} instead of using exceptions is because I actually need to send the error code back to the player through the socket. These are not exceptional conditions either, they can be encountered in the normal course of operations. Thanks, Joel On Aug 26, 2005, at 5:29 AM, chandru wrote: > > You can do this thus. > > -record(login, {name, password, other_field1, other_field2}). > > auth_user(#login{name=Name, password=Password} = LoginRec) -> > case my_password_db:auth_user(Name, Password) of > ok -> > extra_auth(LoginRec); > Err -> > Err > end. > > extra_auth(#login{other_field1 = "val1"}) -> > do_stuff; > extra_auth(#login{other_field2 = "val2"}) -> > do_someother_stuff. > > Or have I not understood your problem? > > cheers > Chandru > -- http://wagerlabs.com/uptick From tim@REDACTED Fri Aug 26 13:44:37 2005 From: tim@REDACTED (Tim Bates) Date: Fri, 26 Aug 2005 21:14:37 +0930 Subject: Exception handling idioms In-Reply-To: References: <430D974B.4050509@bates.id.au> <20050825182156.GU565@feeble.motivity.ca> Message-ID: <430F00A5.20705@bates.id.au> Ulf Wiger wrote: > My preference is to do this: > > handle_call({Atom, Int, List}, _, State) > when is_atom(Atom), is_integer(Int), is_list(List) -> > ... > {reply, Result, State}; > handle_call(_, _, State) -> > {reply, badarg, State}. > > > and then a custom call/1 function: > > call(Request) -> > case gen_server:call(?SERVER, Request) of > badarg -> > erlang:error(badarg); > Reply -> > Reply > end. That is nice, but what if the error is generated deep in a function called by handle_call? And if I want to return an error code to the calling process without crashing it or the server? Then I have to do lots of explicit {error, ...} kind of stuff which the exception handling mechanisms are supposed to help me avoid, or I have to wrap the contents of every clause of handle_call in a try. Perhaps I could extend gen_server to catch non-local returns, ie throw(), and re-raise them in the calling process. But that still doesn't work for gen_server:cast(). Any ideas? Tim. -- Tim Bates tim@REDACTED From benefitsdragon@REDACTED Fri Aug 26 14:22:35 2005 From: benefitsdragon@REDACTED (Benefits Dragon) Date: Fri, 26 Aug 2005 13:22:35 +0100 Subject: Starting generic servers with proc_lib Message-ID: <2db3170005082605221ea9a9b2@mail.gmail.com> As part of a related topic ("Messages going missing in test suite"), I was wondering how you start_link generic servers with the proc_lib so I can get crash reports from them, the description says the proc_lib spawn and start functions are to replace the erl versions yet when you start a gen_server you don't use the erl version use call the gen_server module to do it. Can you still use the proc_lib module to start gen_servers? From joelr1@REDACTED Fri Aug 26 14:34:08 2005 From: joelr1@REDACTED (Joel Reymont) Date: Fri, 26 Aug 2005 14:34:08 +0200 Subject: OpenPoker: Business question Message-ID: <87EB98A9-CD2A-4E51-A34F-EAB4B1E6815B@gmail.com> Folks, I'm not sure this list is the best venue for my question but I don't know of any other so bear with me... I'm thinking of open sourcing my Erlang poker backend (OpenPoker). The previous version of OpenPoker, written in Delphi is at http:// sf.net/projects/openpoker. My strategy is to let people use the code for non-commercial purposes only and pay me as soon as they want to go commercial. The issue at hand is the definition of commercial as it's very particular in the poker world. Normally, you go commercial when you try to sell the software. In the poker world, on the other hand, commercial is when you make money from the poker software by taking in deposits, etc. or charging for use of the poker room. Judging from my experience with the previous version of OpenPoker I would not make any money if I release the software under the GPL. Is there another open source license that you would recommend that would let me restrict the source code to non-commercial use only? Is there any software already released with such restrictions or would the non-commercial use restrictions go against the grain of open source? Thanks, Joel -- http://wagerlabs.com/tech From jb@REDACTED Fri Aug 26 15:24:10 2005 From: jb@REDACTED (Johan Bevemyr) Date: Fri, 26 Aug 2005 15:24:10 +0200 (CEST) Subject: Deadlock bug in ssl library Message-ID: <20050826.152410.41650369.jb@bevemyr.com> The deadlock occurs when the client sends lots of data to an erlang SSL server and the SSL server queries the SSL library for for example ssl:peername(). What happens is that the esock port program will try to write the data to the ssl_broker, and eventually block in write() and stay blocked until erlang has read the data. However, suppose you have the following situation. 1. A process recv: some data from the SSL socket and then proceeds without reading all data. 2. The esock port program blocks since it tries to write (it will not block right way since there are both read and write buffers on the TCP level on the socket between the ssl_broker and esock. 3. The same process as in 1 tries to read the peername from the SSL socket. This will cause the broker to send an GETPEERNAME request via the ssl_server to esock, and wait for the reply. Howerver esock cannot answer since it blocks in write() of the SSL data. All SSL traffic is blocked at this point and no further SSL processing can take place. The solution is to make the (proxy) socket between esock and the ssl_broker non-blocking (which appears to be the intention). Patch against r10-b4 lib/ssl/c_src/esock.c: 452a453 > SET_NONBLOCKING(proxysock); 988,990c989,991 < } else if (cc == 0) { < /* EOF proxy */ < DEBUGF(("proxy eof\n")); --- > } else { > /* EOF proxy or error */ > DEBUGF(("proxy eof or error\n")); 1000,1003d1000 < } else { < /* This should not happen */ < DEBUGF(("ERROR: proxy readmask set, cc < 0, fd = %d" < " proxyfd = %d\n", cp->fd, cp->proxy->fd)); /Johan and Martin From james.hague@REDACTED Fri Aug 26 15:38:17 2005 From: james.hague@REDACTED (James Hague) Date: Fri, 26 Aug 2005 08:38:17 -0500 Subject: (Prolog + LISP + Erlang) with integration issues versus C++ In-Reply-To: <200508260542.j7Q5gP4C044843@atlas.otago.ac.nz> References: <200508260542.j7Q5gP4C044843@atlas.otago.ac.nz> Message-ID: More and more I'm finding that the best way to communicate between applications written in different languages is NOT to call code directly, but to use sockets. Any good language implementation has a socket interface, and Erlang works brilliantly with sockets. Writing shared libraries (DLLs) that can be called directly from Erlang...well, it's ugly and confusing. I've done it several times, and gotten it to work, but it's *so* low-level and full of odd rules and gotchas. From gunilla@REDACTED Fri Aug 26 15:42:41 2005 From: gunilla@REDACTED (Gunilla Arendt) Date: Fri, 26 Aug 2005 15:42:41 +0200 Subject: Starting generic servers with proc_lib In-Reply-To: <2db3170005082605221ea9a9b2@mail.gmail.com> References: <2db3170005082605221ea9a9b2@mail.gmail.com> Message-ID: <430F1C51.9080408@erix.ericsson.se> I'm not sure I understand your question, but if you wonder how to get crash reports from a gen_server process, then the answer is that a gen_server automatically generates a crash report. But, the SASL event handler must be installed in the error_logger process, or the crash report is not printed to stdout. That is: Either use the start_sasl boot script: % erl -boot start_sasl Or, start SASL from the Erlang shell: 1> application:start(sasl). Or, install the event handler yourself: 1> error_logger:install_handler(sasl_report_tty_h, all). ok ... 5> gen_server:cast(ab, error). ok =ERROR REPORT==== 26-Aug-2005::15:34:56 === ** Generic server ab terminating ** Last message in was {'$gen_cast',error} ** When Server state == [] ** Reason for termination == ** bad 3> =CRASH REPORT==== 26-Aug-2005::15:34:56 === crasher: pid: <0.41.0> registered_name: ab error_info: bad initial_call: {gen,init_it,[gen_server,<0.39.0>,self,{local,ab},ab,[],[]]} ancestors: [<0.39.0>] messages: [] links: [] dictionary: [] trap_exit: false status: running heap_size: 233 stack_size: 21 reductions: 120 neighbours: / Gunilla Benefits Dragon wrote: > As part of a related topic ("Messages going missing in test suite"), I > was wondering how you start_link generic servers with the proc_lib so > I can get crash reports from them, the description says the proc_lib > spawn and start functions are to replace the erl versions yet when you > start a gen_server you don't use the erl version use call the > gen_server module to do it. Can you still use the proc_lib module to > start gen_servers? From mbj@REDACTED Fri Aug 26 16:15:52 2005 From: mbj@REDACTED (mbj@REDACTED) Date: Fri, 26 Aug 2005 16:15:52 +0200 (CEST) Subject: Deadlock bug in ssl library In-Reply-To: <20050826.152410.41650369.jb@bevemyr.com> References: <20050826.152410.41650369.jb@bevemyr.com> Message-ID: <20050826.161552.88493755.mbj@bluetail.com> Here's a small program to reproduce the problem -module(s). -compile(export_all). %% illustrates ssl deadlock problem %% do s:d() in an erlang shell %% in a terminal shell, do %% openssl s_client -connect localhost:5432 < a-1-MB-file d() -> application:start(ssl), {ok, L} = ssl:listen(5432, [{active, false}, {certfile, "/home/share/mbj/src/yaws/ssl/cert.example"}, {keyfile, "/home/share/mbj/src/yaws/ssl/key.example"}]), {ok, S} = ssl:accept(L), {ok, Data} = ssl:recv(S, 0), io:format("got ~p bytes\n", [length(Data)]), timer:sleep(10000), {ok, PeerName} = ssl:peername(S), io:format("peername: ~p\n", [PeerName]), ssl:close(S), ssl:close(L). From erlang@REDACTED Fri Aug 26 16:44:00 2005 From: erlang@REDACTED (Inswitch Solutions) Date: Fri, 26 Aug 2005 11:44:00 -0300 Subject: Deadlock bug in ssl library References: <20050826.152410.41650369.jb@bevemyr.com> <20050826.161552.88493755.mbj@bluetail.com> Message-ID: <02af01c5aa4c$a713b450$4a00a8c0@Inswitch251> Hi, Which OS are you using? Some time ago I have had problems with the SSL port (ssl_esock) with Yaws in Win32 and when sending data to the server. Perhaps it's related with yours. By increasing the buffer size of the C/C++ port and with some other changes I've managed to work it out for small size data uploads. There're some postings in the list with the changes I made. Hope it helps. regards, Eduardo Prepaid Expertise - Programmable Switches Powered by Ericsson Licensed Technology Eng. Eduardo Figoli - Development Center - IN Switch Solutions Inc. Headquarters - Miami-U.S.A. Tel: 1305-3578076 Fax: 1305-7686260 Development Center - Montevideo - Uruguay Tel/Fax: 5982-7104457 e-mail: eduardo@REDACTED ----- Original Message ----- From: To: ; Sent: Friday, August 26, 2005 11:15 AM Subject: Re: Deadlock bug in ssl library > Here's a small program to reproduce the problem > > > -module(s). > -compile(export_all). > > %% illustrates ssl deadlock problem > > %% do s:d() in an erlang shell > %% in a terminal shell, do > %% openssl s_client -connect localhost:5432 < a-1-MB-file > > > d() -> > application:start(ssl), > {ok, L} = > ssl:listen(5432, > [{active, false}, > {certfile, "/home/share/mbj/src/yaws/ssl/cert.example"}, > {keyfile, "/home/share/mbj/src/yaws/ssl/key.example"}]), > {ok, S} = ssl:accept(L), > {ok, Data} = ssl:recv(S, 0), > io:format("got ~p bytes\n", [length(Data)]), > timer:sleep(10000), > {ok, PeerName} = ssl:peername(S), > io:format("peername: ~p\n", [PeerName]), > ssl:close(S), > ssl:close(L). > -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image001.gif Type: image/gif Size: 1429 bytes Desc: not available URL: From erlang-list@REDACTED Fri Aug 26 17:49:49 2005 From: erlang-list@REDACTED (erlang-list@REDACTED) Date: Fri, 26 Aug 2005 17:49:49 +0200 (CEST) Subject: Programming components In-Reply-To: References: Message-ID: <24913.212.155.207.253.1125071389.squirrel@212.155.207.253> Hi Joe, >> Regarding types, I'm trying to understand what you >> find lacking in Erlang, and why you want it. > > Erlang has no syntax for defining types I know, but I'm trying to understand why this is a problem. Erlang has no syntax for classes or inheritance, either, but last time I heard you thought they sucked ;-) > Yes Erlang has integers etc. but there is no way to > say that the factorial function returns an integer > > I'd like to say > > fac(int()) -> int(). > > But this is NOT Erlang But that's what I like about Erlang. You get the fun out of functional, without the type-obsessive part. >> Apart from development tools, or working around >> deficient languages, I can't really think of any >> good use for introspection. What do you have in >> mind? > > YES - contract checking. The protocol spec IS a > contract to follow some agreed protocol - so we can > check it dynamically - to do so we need the spec. Ah, I see. It seems to me that /types/ is an insufficient ambition for contracts. Wouldn't it be more interesting to have Eiffel-like contracts for components? I haven't thought about this before, but it occurs to me right now that Erlang pattern matching would provide a very rich way to express preconditions, postconditions and invariants on a component. It would be even better than Eiffel! > Processes do not have names, in the sense that > modules have names. Now that's an interesting idea. In practice, it seems to me most people tend to have a module for a given process, so it's not a great shortcoming. But something like your suggested: > There no file Foo.pro containing > > -process(foo) > -protocol(p) > ... ... would make the design more clear. > And there is not way of specify protocols - "read the > code and figure out in which order the messages are > sent" is NOT a good reply :-) OK, now I see what you mean. I just don't want the solution to be base on strict typing... Cheers, Dominic Williams http://www.dominicwilliams.net ---- From orbitz@REDACTED Fri Aug 26 18:04:24 2005 From: orbitz@REDACTED (orbitz@REDACTED) Date: Fri, 26 Aug 2005 12:04:24 -0400 Subject: (Prolog + LISP + Erlang) with integration issues versus C++ In-Reply-To: References: <200508260542.j7Q5gP4C044843@atlas.otago.ac.nz> Message-ID: <7aa9dac5e4af5223a234524a7bfe9f8a@ezabel.com> The issue with that is serializing the data though. Not all languages are equal in terms of their ability to serialize data. Erlang works beautifully with sockets, I can't say the same for C. Although I will agree that sockets are probably one of the better ways for 2 languages to communicate. On Aug 26, 2005, at 9:38 AM, James Hague wrote: > More and more I'm finding that the best way to communicate between > applications written in different languages is NOT to call code > directly, but to use sockets. Any good language implementation has a > socket interface, and Erlang works brilliantly with sockets. > > Writing shared libraries (DLLs) that can be called directly from > Erlang...well, it's ugly and confusing. I've done it several times, > and gotten it to work, but it's *so* low-level and full of odd rules > and gotchas. > From david.nospam.hopwood@REDACTED Fri Aug 26 19:33:20 2005 From: david.nospam.hopwood@REDACTED (David Hopwood) Date: Fri, 26 Aug 2005 18:33:20 +0100 Subject: [Off-topic: licensing] Re: OpenPoker: Business question In-Reply-To: <87EB98A9-CD2A-4E51-A34F-EAB4B1E6815B@gmail.com> References: <87EB98A9-CD2A-4E51-A34F-EAB4B1E6815B@gmail.com> Message-ID: <430F5260.7050001@blueyonder.co.uk> Joel Reymont wrote: > Judging from my experience with the previous version of OpenPoker I > would not make any money if I release the software under the GPL. Is > there another open source license that you would recommend that would > let me restrict the source code to non-commercial use only? A non-commercial license is by definition not open source (or free software): section 6, "may not restrict the program from being used in a business" , "A free program must be available for commercial use, commercial development, and commercial distribution." This means that the issue of license compatibility does not arise (your non-commercial license will be incompatible no matter what), and so you can choose pretty much any non-commercial license designed for software. -- David Hopwood From ke.han@REDACTED Fri Aug 26 19:55:41 2005 From: ke.han@REDACTED (ke.han) Date: Sat, 27 Aug 2005 01:55:41 +0800 Subject: OpenPoker: Business question In-Reply-To: <87EB98A9-CD2A-4E51-A34F-EAB4B1E6815B@gmail.com> References: <87EB98A9-CD2A-4E51-A34F-EAB4B1E6815B@gmail.com> Message-ID: <430F579D.3020506@redstarling.com> Joel, There are a couple of routes you can take. Here are some suggestions: 1 - BSD wrappered with terms under with the license stays valid. The wrapper says that the license applies so long as the licensee either stays non-commercial or is paying license fees; revoked under any other conditions. 2 - Dual license You can choose to license under open source form which stay valid as long as the licensee stays non-commercial. The licensee must switch to a closed license when licensee becomes commercial. This is similar to what MySQL does. I'm sure the MySQL lawyers have been over their licenses very thoroughly; you may want to study them. I am guessing that anyone starting with non-commercial usage but has aims to become commercial will not want to share their code changes even when they are still non-commercial to protect their future investment. This is why I think the first choice may be the simplest. I don't know much about the online poker, but I have friends who are heavily involved. I could put you in touch if you wish. My guess is their perspective is that anyone that has the funds to invest heavily in a commercial poker site will simply license from one of the many known vendors and not give your product a second look. So you will be competing on price to enable startups with less funds to use your product. good luck, ke han Joel Reymont wrote: > Folks, > > I'm not sure this list is the best venue for my question but I don't > know of any other so bear with me... > > I'm thinking of open sourcing my Erlang poker backend (OpenPoker). > The previous version of OpenPoker, written in Delphi is at http:// > sf.net/projects/openpoker. My strategy is to let people use the code > for non-commercial purposes only and pay me as soon as they want to > go commercial. > > The issue at hand is the definition of commercial as it's very > particular in the poker world. Normally, you go commercial when you > try to sell the software. In the poker world, on the other hand, > commercial is when you make money from the poker software by taking > in deposits, etc. or charging for use of the poker room. > > Judging from my experience with the previous version of OpenPoker I > would not make any money if I release the software under the GPL. Is > there another open source license that you would recommend that would > let me restrict the source code to non-commercial use only? > > Is there any software already released with such restrictions or > would the non-commercial use restrictions go against the grain of > open source? > > Thanks, Joel > > -- > http://wagerlabs.com/tech > > > From erlang@REDACTED Fri Aug 26 21:28:21 2005 From: erlang@REDACTED (Inswitch Solutions) Date: Fri, 26 Aug 2005 16:28:21 -0300 Subject: Mnesia - mnesia_subscr and force_load_table Message-ID: <035a01c5aa74$b81eed50$4a00a8c0@Inswitch251> Hi, Please, can someone help me with the following mnesia questions - Why mnesia_subscr process is not restarted when it's killed and mnesia goes down after that? try: exit(erlang:whereis(mnesia_subscr), kill). force_load_table(Tab) -> yes | ErrorDescription The Mnesia algorithm for table load might lead to a situation where a table cannot be loaded. This situation occurs when a node is started and Mnesia concludes, or suspects, that another copy of the table was active after this local copy became inactive due to a system crash. - How do I detect the situations when force_load_table function has to be executed? thanks, Eduardo Prepaid Expertise - Programmable Switches Powered by Ericsson Licensed Technology Eng. Eduardo Figoli - Development Center - IN Switch Solutions Inc. Headquarters - Miami-U.S.A. Tel: 1305-3578076 Fax: 1305-7686260 Development Center - Montevideo - Uruguay Tel/Fax: 5982-7104457 e-mail: eduardo@REDACTED -------------- next part -------------- An HTML attachment was scrubbed... URL: From meena_selvam@REDACTED Fri Aug 26 22:38:53 2005 From: meena_selvam@REDACTED (MEENA SELVAM) Date: Fri, 26 Aug 2005 13:38:53 -0700 (PDT) Subject: what does this complex format stmt prints? Message-ID: <20050826203853.18930.qmail@web30411.mail.mud.yahoo.com> In the following io_lib: format what gets printed? In the simple form we have io_lib:format("~s ~s\n",[A,B]), where the no of items to be printed the no of ~s. e generally means float. but what does it mean here? can any one briefly explain? I believe TX1 ++ TXV1 results in a appended list but when I try to print the values like: io_lib:format("~s\n", [TX1]), I get internal error. same error with io_lib:format("~s\n", [F]) also. io_lib:format(e("\n~-23s ~4s ~12s ~12s\n", "~54.c~n", TX1 ++ TXV1 ++ TI1 ++ TIV1), e(["Global License Pools","VPN","Used","Size"], [$-], TX2 ++ TXV2 ++ TI2 ++ TIV2)). F = fun({{LicType, XId}, Used, Size},{Xfmt,Xacc}) -> {"~-23s ~4s ~12w ~12w\n" ++ Xfmt, [lic2str(LicType), a2l(XId), Used, Size | Xacc]}; ({LicType, Used, Size},{Xfmt,Xacc}) -> {"~-23s ~4s ~12w ~12w\n" ++ Xfmt, [lic2str(LicType), "-", Used, Size | Xacc]} end, {TX1,TX2} = lists:foldr(F,{"",[]},extract_sort_lic(xnet, Tot)), {TXV1,TXV2} = lists:foldr(F,{"",[]},extract_sort_lic({xnet,vpn}, Tot)), {TI1,TI2} = lists:foldr(F,{"",[]},extract_sort_lic(ipsec, Tot)), {TIV1,TIV2} = lists:foldr(F,{"",[]},extract_sort_lic({ipsec,vpn}, Tot)), extract_sort_lic(LicType, Tot) when atom(LicType) -> lists:filter(fun(I) when element(1, I) == LicType -> true; (_) -> false end, Tot); extract_sort_lic({LicType, _}, Tot) -> Lics = lists:filter(fun(I) when element(1, element(1, I)) == LicType -> true; (_) -> false end, Tot), lists:sort(fun(A,B) -> a2i(element(2,element(1,A))) =< a2i(element(2,element(1,B))) end, Lics). thanks, meena ____________________________________________________ Start your day with Yahoo! - make it your home page http://www.yahoo.com/r/hs From mbj@REDACTED Sat Aug 27 10:38:38 2005 From: mbj@REDACTED (mbj@REDACTED) Date: Sat, 27 Aug 2005 10:38:38 +0200 (CEST) Subject: Deadlock bug in ssl library In-Reply-To: <02af01c5aa4c$a713b450$4a00a8c0@Inswitch251> References: <20050826.152410.41650369.jb@bevemyr.com> <20050826.161552.88493755.mbj@bluetail.com> <02af01c5aa4c$a713b450$4a00a8c0@Inswitch251> Message-ID: <20050827.103838.74745467.mbj@bluetail.com> "Inswitch Solutions" wrote: > Hi, > > Which OS are you using? > Some time ago I have had problems with the SSL port (ssl_esock) with > Yaws in Win32 and when sending data to the server. Perhaps it's > related with yours. By increasing the buffer size of the C/C++ port > and with some other changes I've managed to work it out for small > size data uploads. There're some postings in the list with the > changes I made. Well, as we described in the first email, we have found and fixed the bug in esock.c (of course the fix has to be verified by OTP). Increasing buffer sizes is of course just a workaround which may or may not work. Another workaround is to avoid calls to ssl:peername/1 while uploading data. /martin From ulf@REDACTED Sat Aug 27 11:20:31 2005 From: ulf@REDACTED (ulf@REDACTED) Date: Sat, 27 Aug 2005 02:20:31 -0700 (PDT) Subject: Mnesia - mnesia_subscr and force_load_table In-Reply-To: <035a01c5aa74$b81eed50$4a00a8c0@Inswitch251> References: <035a01c5aa74$b81eed50$4a00a8c0@Inswitch251> Message-ID: <1127.212.105.4.215.1125134431.squirrel@webmail.wiger.net> > - Why mnesia_subscr process is not restarted when it's killed and > mnesia goes down after that? > try: exit(erlang:whereis(mnesia_subscr), kill). I will let someone else comment on the specific case of mnesia_subscr, but in general, you will find that some processes cannot be killed without bringing down the application and/or the whole node. This is to be seen as a reasonable tradeoff, as it can be very difficult to figure out how to recover gently from some errors. > force_load_table(Tab) -> yes | ErrorDescription > > > The Mnesia algorithm for table load might lead to a situation where a > table cannot be loaded. This situation occurs when a node is started and > Mnesia concludes, or suspects, that another copy of the table was active > after this local copy became inactive due to a system crash. > > - How do I detect the situations when force_load_table function has to be > executed? It's not trivial. In AXD 301, I wrote a set of programs to monitor mnesia's boot process: - One part that started before mnesia (this can be done by sorting the list of applications in the .rel file -- as long as the order doesn't violate application dependencies, it will be kept.) This application would check whether the restart was due to partitioned network and make sure that master_nodes were set accordingly. - One part that started right after mnesia, and called mnesia:wait_for_tables(AllMyTabs, Timeout). After Timeout, a loop analysis was performed in a wait-for graph. This graph was built using a hello protocol between the waiters on all nodes. If no cyclical wait was detected, another call to wait_for_tables/2 was made, and so on. If, at the point of timeout, there are no other waiters, the tables are loaded by force. I once tried to get a research project started to try to assess the correctness of the algorithm and the code, but this fell through. One of the questions I also wanted answered was "what additional information is needed from mnesia in order to make this easier?", because it does feel as if mnesia doesn't help as much as it could. I can't give more details about the solution, since I don't have it available, and it's been years since I last looked at it. Given its operational track record, at least the code isn't obviously broken, though. (: /Uffe From feeley@REDACTED Sat Aug 27 15:30:06 2005 From: feeley@REDACTED (Marc Feeley) Date: Sat, 27 Aug 2005 09:30:06 -0400 Subject: (Prolog + LISP + Erlang) with integration issues versus C++ In-Reply-To: <200508260110.j7Q1A0H4040743@atlas.otago.ac.nz> References: <200508260110.j7Q1A0H4040743@atlas.otago.ac.nz> Message-ID: <651946F6-6DDF-42E9-AE4F-1A633AE02F7B@iro.umontreal.ca> On 25-Aug-05, at 9:10 PM, Richard A. O'Keefe wrote: > Poplog used to be sold by Integrated Solutions Ltd. It has been used > in a number of important products. For example the SPARK verifier for > Ada is written in Poplog. These days, however, Poplog is Open Source. > > This doesn't do anything about Erlang. (Given that there is or was > an Erlang-to-Scheme project and that Scheme is not _that_ different > from Common Lisp, it strikes me that it should be possible to develop > an Erlang environment for Poplog.) > Another option is to use Termite, which is an integration in Scheme of Erlang's concurrency model, with some extensions such as process migration (see http://lisp-ecoop05.bknr.net/submission/19654). You can then get Schelog (http://www.math.purdue.edu/~lucier/software/ schelog/) to run Prolog on top of Scheme. This would give you a single environment to run Lisp, Erlang and Prolog. Since all of this is based on Gambit-C, you get portability and good performance, and you can link with C/C++ code using the Foreign Function Interface. Marc From benefitsdragon@REDACTED Sat Aug 27 16:55:01 2005 From: benefitsdragon@REDACTED (Benefits Dragon) Date: Sat, 27 Aug 2005 15:55:01 +0100 Subject: Starting generic servers with proc_lib In-Reply-To: <430F1C51.9080408@erix.ericsson.se> References: <2db3170005082605221ea9a9b2@mail.gmail.com> <430F1C51.9080408@erix.ericsson.se> Message-ID: <2db3170005082707557ea5db04@mail.gmail.com> Well the test server already does that so I'll assume that it sets sasl running for the test suites, thanks for clearing it up for me. On 8/26/05, Gunilla Arendt wrote: > I'm not sure I understand your question, but if you wonder how to get > crash reports from a gen_server process, then the answer is that a > gen_server automatically generates a crash report. But, the SASL event > handler must be installed in the error_logger process, or the crash > report is not printed to stdout. > > That is: Either use the start_sasl boot script: > > % erl -boot start_sasl > > Or, start SASL from the Erlang shell: > > 1> application:start(sasl). > > Or, install the event handler yourself: > > 1> error_logger:install_handler(sasl_report_tty_h, all). > ok > ... > > 5> gen_server:cast(ab, error). > ok > =ERROR REPORT==== 26-Aug-2005::15:34:56 === > ** Generic server ab terminating > ** Last message in was {'$gen_cast',error} > ** When Server state == [] > ** Reason for termination == > ** bad > > 3> > =CRASH REPORT==== 26-Aug-2005::15:34:56 === > crasher: > pid: <0.41.0> > registered_name: ab > error_info: bad > initial_call: > {gen,init_it,[gen_server,<0.39.0>,self,{local,ab},ab,[],[]]} > ancestors: [<0.39.0>] > messages: [] > links: [] > dictionary: [] > trap_exit: false > status: running > heap_size: 233 > stack_size: 21 > reductions: 120 > neighbours: > > / Gunilla > > Benefits Dragon wrote: > > As part of a related topic ("Messages going missing in test suite"), I > > was wondering how you start_link generic servers with the proc_lib so > > I can get crash reports from them, the description says the proc_lib > > spawn and start functions are to replace the erl versions yet when you > > start a gen_server you don't use the erl version use call the > > gen_server module to do it. Can you still use the proc_lib module to > > start gen_servers? > > > From ke.han@REDACTED Sat Aug 27 18:50:54 2005 From: ke.han@REDACTED (ke.han) Date: Sun, 28 Aug 2005 00:50:54 +0800 Subject: erlmerge on Windows? In-Reply-To: <430D83EC.6090304@ericsson.com> References: <20050825070900.4915046EE3@bang.trapexit.org> <430D83EC.6090304@ericsson.com> Message-ID: <431099EE.1060800@redstarling.com> Bengt Kleberg wrote: > On 2005-08-25 09:09, tobbe wrote: > ...deleted > >> When it comes to Windows, I guess there is some problems >> to be solved: >> >> 1. How to do the initial install > > > perhaps it is possible to switch from gnu autotools to something that is > available for both unix and windows? (ie, erlang itself) I develop on Windows and deploy on Linux. So I wouldn't use erlmerge at all if I didn't have access on both platforms. I have done a brief review of the make and shell scripts. I don't see anything in there that couldn't be done as batch scripts for Win2000/XP/2003. I haven't looked into the erlang code itself. But I assume this could be dealt with as well. The problem would simply be having two different install and script sets to maintain. If you guys are ok with that approach, I'll look into writing the install and shell scripts for Windows during September. If you don't approve of this approach let me know so I don't waste my efforts. thanks, ke han From erlang@REDACTED Sat Aug 27 23:11:19 2005 From: erlang@REDACTED (Inswitch Solutions) Date: Sat, 27 Aug 2005 18:11:19 -0300 Subject: Erlang developers for new projects needed Message-ID: <04a001c5ab4b$e74a72c0$4a00a8c0@Inswitch251> We're looking for several years Erlang developers for distance working with very good knowledge of mnesia, preferebly with commercial products developments. Please write ASAP to us. thanks, Prepaid Expertise - Programmable Switches Powered by Ericsson Licensed Technology Eng. Eduardo Figoli - Development Center - IN Switch Solutions Inc. Headquarters - Miami-U.S.A. Tel: 1305-3578076 Fax: 1305-7686260 Development Center - Montevideo - Uruguay Tel/Fax: 5982-7104457 e-mail: eduardo@REDACTED -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image001.gif Type: image/gif Size: 1429 bytes Desc: not available URL: From csanto@REDACTED Sun Aug 28 14:56:44 2005 From: csanto@REDACTED (Corrado Santoro) Date: Sun, 28 Aug 2005 14:56:44 +0200 Subject: graphic framework for Erlang Message-ID: <1125233804.4311b48c99331@www.cdc.unict.it> Hi all, I'm searching for a simple graphic framework that allows me to draw images in a window using a function like "put_pixel_at (x,y,color)". It seems that gs does not allow such things, unless I map each pixel in a rectangle object, but this is not a good choice. Could you suggest something? Thanks, --Corrado -- ====================================================== Eng. Corrado Santoro, Ph.D. University of Catania - Engineering Faculty Department of Computer Science and Telecommunications Engineering Viale A. Doria, 6 - 95125 CATANIA (ITALY) Tel: +39 095 7382380 Fax: +39 095 338280 +39 095 7382365 +39 095 7382364 EMail: csanto@REDACTED Personal Home Page: http://www.diit.unict.it/users/csanto NUXI Home Page: http://nuxi.iit.unict.it ====================================================== ------------------------------------------------- This mail sent through IMP: http://www.cdc.unict.it/ From joelr1@REDACTED Sun Aug 28 20:26:49 2005 From: joelr1@REDACTED (Joel Reymont) Date: Sun, 28 Aug 2005 20:26:49 +0200 Subject: 20,000 network connections per tcp server + max nodes Message-ID: I know we have been discussing this before but... Someone just asked me a question of how much hardware would be required for my poker cluster to support 500k simultaneous players. My understanding is that Erlang would max out with approximately 250 nodes. This means that I need to support 20k players per node and I really don't think that's possible. Any suggestions? Thanks, Joel From joelr1@REDACTED Sun Aug 28 21:39:29 2005 From: joelr1@REDACTED (Joel Reymont) Date: Sun, 28 Aug 2005 21:39:29 +0200 Subject: 20,000 network connections per tcp server + max nodes In-Reply-To: References: Message-ID: <7FE1D270-35AD-45A1-AC5C-8869F8D53A44@gmail.com> I apologize for a stupid post. A quick trip downstairs to talk to Ulf Wiger proved not only that my math is bad but that you could well fit within the 250 Erlang nodes limitation. All I would need is to switch to UDP for the poker servers and figure out how many players I could support per node. Lets say I could support 50k or 100k. To save customers from having to write to my UDP protocol and to avoid potential problems (encrypted UDP on cell phones anyone?) I could front the UDP servers with a custom Linux box or few, tuned for network performance. These boxes would maintain the 500k SSL connections and multiplex between the few Erlang UDP servers. Backend server crashes could also be transparent and not require player reconnects and the Linux proxies would just switch to a different UDP server. Problem solved thanks to Uffe :-). Joel On Aug 28, 2005, at 8:26 PM, Joel Reymont wrote: > I know we have been discussing this before but... Someone just > asked me a question of how much hardware would be required for my > poker cluster to support 500k simultaneous players. > > My understanding is that Erlang would max out with approximately > 250 nodes. This means that I need to support 20k players per node > and I really don't think that's possible. From joelr1@REDACTED Mon Aug 29 01:03:26 2005 From: joelr1@REDACTED (Joel Reymont) Date: Mon, 29 Aug 2005 01:03:26 +0200 Subject: 20,000 network connections per tcp server + max nodes In-Reply-To: <200508282114.11210.daniel@erlfinsys.net> References: <200508282114.11210.daniel@erlfinsys.net> Message-ID: On Aug 28, 2005, at 9:14 PM, Daniel Schutte wrote: > connected nodes > The maximum number of simultaneously connected nodes is limited by > either the > maximum number of simultaneously known remote nodes, the maximum > number of > (Erlang) ports available, or the maximum number of sockets available. That's music to my ears! > The maximum number of simultaneously open Erlang ports is by > default 1024. > This limit can be raised up to 262144 at startup (see environment > variable > ERL_MAX_PORTS in erlang(3)). I wonder how Erlang can manage to monitor 262,144 open file descriptors on one node. Any ideas? > The question I would like to ask however is why would you like to > have 500k > simulatenous players in a "single cluster" :) A cluster could be a rack of 1U boxes, about 40 or 50 would fit. Someone just asked the question of how I would support 500k players at the same time. I figured 10k players per node, one node per box, would require 50 boxes. I got my math wrong which got me worried :-). > the max poker table size = 10? I'm not sure what you mean by that. > My reasoning being that have the connections as seperate tcp/ip > connections > (to various machines that handle X tcp connections per machine), > and then > just allocate each "player" to a table - that can work in a "casino > cluster" > of about 5000 tables per server (if that is how you want to do it). That's how I do it, I believe. I already have the server developed. > Benchmarking on physical memory on the box and processor speed will > determine > the required hardware or rather the number of supported clients per > box. Right. Joel From casper2000a@REDACTED Mon Aug 29 03:00:55 2005 From: casper2000a@REDACTED (casper2000a@REDACTED) Date: Mon, 29 Aug 2005 07:00:55 +0600 Subject: ASN.1.. bad encoded value after byte In-Reply-To: <04a001c5ab4b$e74a72c0$4a00a8c0@Inswitch251> References: <04a001c5ab4b$e74a72c0$4a00a8c0@Inswitch251> Message-ID: <1125277255.43125e476fe86@www.omnibis.com> An HTML attachment was scrubbed... URL: From ulf.wiger@REDACTED Mon Aug 29 09:29:35 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Mon, 29 Aug 2005 09:29:35 +0200 Subject: Exception handling idioms Message-ID: Tim Bates: > > That is nice, but what if the error is generated deep > in a function called by handle_call? And if I want to > return an error code to the calling process without > crashing it or the server? In general, I'd say it's a very good idea to check as much as possible as early as possible, but of course, it might happen that you have to go deep down into the logic before you can detect that the request was invalid. This would be a pretty good occasion for throw and the new try ... catch syntax. > Then I have to do lots of explicit {error, ...} kind of > stuff which the exception handling mechanisms are supposed > to help me avoid, or I have to wrap the contents of every > clause of handle_call in a try. Not every handle_call(...) ... well, yes, every handle_call(), but you only write one: handle_call(Request, From, State) -> Reply = try my_handle_call(Request, From, State) of R -> {ok, R} catch throw:Error -> {error, Error} end, {reply, Reply, State}. This will catch only throws -- not programming errors, and it's of course desirable not to force the client to crash due to a programming error in the server, and let the server continue as if it were without fault. Perhaps I could extend > gen_server to catch non-local returns, ie throw(), and > re-raise them in > the calling process. But that still doesn't work for > gen_server:cast(). With the construct above, you don't have to mess with the gen_server itself. And as far as gen_server:cast() goes, any checking that would raise an exception in the client would have to be before the message is sent to the server -- i.e. on the client side. Otherwise, you have to use gen_server:call(). This is not so much a technical problem as it is a matter of principle: immediately after a cast, the client goes its own merry way, and doesn't concern itself with any consequences that the cast may have on the server side. If there is to be a reckoning, the client should use a gen_server:call() and wait for judgement. /Uffe From bertil@REDACTED Mon Aug 29 10:29:17 2005 From: bertil@REDACTED (Bertil Karlsson) Date: Mon, 29 Aug 2005 10:29:17 +0200 Subject: ASN.1.. bad encoded value after byte In-Reply-To: <1125277255.43125e476fe86@www.omnibis.com> References: <04a001c5ab4b$e74a72c0$4a00a8c0@Inswitch251> <1125277255.43125e476fe86@www.omnibis.com> Message-ID: <4312C75D.5000509@erix.ericsson.se> It seems as if you have a sequence of bytes that is badly encoded. The last three bytes "164,1,128" is a tag-length-value sequence, The tag is of constructed format and thus should the value part be decoded, but this value, "128", is not possible do decode. /Bertil casper2000a@REDACTED wrote: > Hi, > > When I run below command, > asn1rt_ber_bin_v2:decode(<<103,41,73,4,0,0,0,9,107,33,40,31,6,7,0,17,134,5,1,1,1,160,20,100,18,128,1,0,190,13,40,11,2,4,68,69,86,73,160,3,164,1,128>>,driver). > > I get the below error, > ** exited: {error,{asn1,{"bad encoded value after byte:", > 42, > > <<103,41,73,4,0,0,0,9,107,33,40,31,6,7,0,17,134,5,1,1,1,160,...>>}}} ** > > What could be the error. Pls advice. > > Thanks in advance, > - Eranga > > > --------------This mail sent through OmniBIS.com-------------- From joe.armstrong@REDACTED Mon Aug 29 10:37:17 2005 From: joe.armstrong@REDACTED (Joe Armstrong (AL/EAB)) Date: Mon, 29 Aug 2005 10:37:17 +0200 Subject: Programming components Message-ID: David Hopwood wrote > Sent: den 25 augusti 2005 18:13 > To: erlang-questions@REDACTED > Subject: Re: Programming components > > > Joe Armstrong (AL/EAB) wrote: > > Erlang has no strings - ie there is NOT a string data type. > > > > "abc" is NOT a string but shorthand for [97,98,99] > > > > Now suppose I see [97, 98, 99] on some I/O channel > > what does this mean? is it to be interpreted as a list of > three integers > > or as a string? - nobody knows. > > > > Most Erlang programmers choose to represent strings as > "lists of integers" and > > write "abc" in their programs when they wish to create a string. > > > > I am suggesting they should use <<"abc">> (a binary) > > > > This all has to do with making a simple type system that > mays Erlang terms onto > > XML data structures in an isomorphic manner. > > How does using binaries solve this problem? A binary is an > octet sequence; > "strings" are character sequences (usually represented as > code unit sequences). > This interpretation takes place *only* at the component interface I'll make an example that (hopefully) clarifies this point Let's take a simple example of a server Let's suppose I want to make an "FTP" server. With exactly two commands, which are specified like this: Type result = {"ok", str()}|{"error","enofile"} {"get", str()} => result() {"mget", [str()]} => [result()] A => B means "if you send me an instance of type A I'll reply with an instance of type B" get - gets one file mget gets multiple files 1) The server receives (say) Conetent-Length:1234 Content-Type: text/erlBinary [1234 bytes] Because the content type is erlBinary the server knows that this 1234 bytes is an erlang term encoded with term_to_binary 2) The server does binary_to_term on the data it has received The reconstructed term is {<<"get">>, <<"somefilename">>} or {<<"mget">>, [<<"file1">>, <<"file2">>]} The server checks that these are instances of {"get", str()} or {"mget", [str()]} Anything else is illegal - in the reconstructed term lists mean lists and NOT strings. Binaries are always interpreted as strings. These rules apply only at the interface. 3) The server MUST reply with {<<"ok">>,<<"file contents">> or {"error", "enofile"} to the first request, or, with something like [{<<"ok">>,<<"contents of file2">>}, {<<"error">>, ... in the second case. All of this can be checked at the interface, given the specification we can check these forms to see if they are allowed by the interface desription. Saying that "strings are represented as binaries" means "an instance of the str() type is represented as a binary in the interface" > A binary can be used to *represent* a string in a charset > with 8-bit code > units, but you also need some way to distinguish such a thing > from "raw" > octet sequences, and possibly to distinguish representations > using different > charsets if more than one charset is supported. > This is a different problem :-) > (I'm using the W3C character encoding model here, which is > the model that > XML uses. See .) > > -- > David Hopwood > /Joe From joe.armstrong@REDACTED Mon Aug 29 10:55:08 2005 From: joe.armstrong@REDACTED (Joe Armstrong (AL/EAB)) Date: Mon, 29 Aug 2005 10:55:08 +0200 Subject: Programming components Message-ID: Dominic wrote: > -----Original Message----- > From: owner-erlang-questions@REDACTED > [mailto:owner-erlang-questions@REDACTED]On Behalf Of > erlang-list@REDACTED > Sent: den 26 augusti 2005 17:50 > To: erlang-questions@REDACTED > Subject: RE: Programming components > > > Hi Joe, > > >> Regarding types, I'm trying to understand what you > >> find lacking in Erlang, and why you want it. > > > > Erlang has no syntax for defining types > > I know, but I'm trying to understand why this is a > problem. Erlang has no syntax for classes or > inheritance, either, but last time I heard you thought > they sucked ;-) > > > Yes Erlang has integers etc. but there is no way to > > say that the factorial function returns an integer > > > > I'd like to say > > > > fac(int()) -> int(). > > > > But this is NOT Erlang > > But that's what I like about Erlang. You get the fun > out of functional, without the type-obsessive part. Yes > > >> Apart from development tools, or working around > >> deficient languages, I can't really think of any > >> good use for introspection. What do you have in > >> mind? > > > > YES - contract checking. The protocol spec IS a > > contract to follow some agreed protocol - so we can > > check it dynamically - to do so we need the spec. > > Ah, I see. It seems to me that /types/ is an > insufficient ambition for contracts. Wouldn't it be > more interesting to have Eiffel-like contracts for > components? I haven't thought about this before, but it > occurs to me right now that Erlang pattern matching > would provide a very rich way to express preconditions, > postconditions and invariants on a component. It would > be even better than Eiffel! > > > Processes do not have names, in the sense that > > modules have names. > > Now that's an interesting idea. In practice, it seems > to me most people tend to have a module for a given > process, so it's not a great shortcoming. But something > like your suggested: > > > There no file Foo.pro containing > > > > -process(foo) > > -protocol(p) > > ... > > ... would make the design more clear. YES > > > And there is not way of specify protocols - "read the > > code and figure out in which order the messages are > > sent" is NOT a good reply :-) > > OK, now I see what you mean. I just don't want the > solution to be base on strict typing... > YES - now you're getting it. Specifying protocols will make the design clearer. I want a strictly checkable language-neutral type system to apply at the boundaries to components. This MUST be a dynamic checker. If the spec says {"fac", int(1..1000}} => {"result", int()} within 2578 ms This means that a component MUST compute factorials of integers less than 1000 within 2578 milliseconds. Suppose you now want to compute factorial 123 Do this: Content-Type: text/myXML Content-length: NNNN fac 123 When you parse this you MUST get {<<"fac">>, 123} or this Content-Type: text/erlBin Content-Length: NNNN - a binary - When you to binary_to_term on this you MUST get {<<"fac">>, 123} This can be checked against the spec Then the system Must reply Content-length: NNNNN Content-Type: text/myXML result 138764893423514 ... whatever Or Content-lengh: NNNN Conent-Type: text/erlBin [[ term_to_binary {<<"result">>, 13827651274 (whatever :-) } ]] Within 2578 ms All this must be dynamically checked. Why? 1) Proofs might be wrong 2) Proofs involving timeing are impossible in multi-tasking systems I want to capture functional and NON-functional behaviour at the interface A => B within Time ****** **** Functional Non-functional Type system might give me a handle on the function but but they do not address the non-function bit > Cheers, > > Dominic Williams > http://www.dominicwilliams.net > > ---- > /Joe From mats.cronqvist@REDACTED Mon Aug 29 10:55:52 2005 From: mats.cronqvist@REDACTED (Mats Cronqvist) Date: Mon, 29 Aug 2005 10:55:52 +0200 Subject: graphic framework for Erlang In-Reply-To: <1125233804.4311b48c99331@www.cdc.unict.it> References: <1125233804.4311b48c99331@www.cdc.unict.it> Message-ID: <4312CD98.2040801@ericsson.com> gtkNode (in jungerl) allows you to access e.g. gdk_draw_point(Drawable,Gc,X,Y). http://developer.gnome.org/doc/API/gdk/gdk-drawing-primitives.html mats Corrado Santoro wrote: > Hi all, > > I'm searching for a simple graphic framework that allows me to draw images in a > window using a function like "put_pixel_at (x,y,color)". It seems that gs does > not allow such things, unless I map each pixel in a rectangle object, but this > is not a good choice. > > Could you suggest something? > > Thanks, > --Corrado > From serge@REDACTED Mon Aug 29 13:21:12 2005 From: serge@REDACTED (Serge Aleynikov) Date: Mon, 29 Aug 2005 07:21:12 -0400 Subject: Mnesia - mnesia_subscr and force_load_table In-Reply-To: <1127.212.105.4.215.1125134431.squirrel@webmail.wiger.net> References: <035a01c5aa74$b81eed50$4a00a8c0@Inswitch251> <1127.212.105.4.215.1125134431.squirrel@webmail.wiger.net> Message-ID: <4312EFA8.3020901@hq.idt.net> I wonder if there's a mnesia equivalent to the Oracle's SCN (System Change Number), which is the number that gets incremented every time there's a modification in the database. This could be very helpful if you know you have a partitioned network, and need to decide which database has the most current data. If would be even more helpful if there were such an SCN per mnesia table. Also, how do you determine if a restart is due to paritioned network (this might require some persistence of state between restarts). Serge ulf@REDACTED wrote: > In AXD 301, I wrote a set of programs to monitor mnesia's > boot process: > > - One part that started before mnesia (this can be done > by sorting the list of applications in the .rel file > -- as long as the order doesn't violate application > dependencies, it will be kept.) This application would > check whether the restart was due to partitioned network > and make sure that master_nodes were set accordingly. > > - One part that started right after mnesia, and called > mnesia:wait_for_tables(AllMyTabs, Timeout). After Timeout, > a loop analysis was performed in a wait-for graph. This > graph was built using a hello protocol between the waiters > on all nodes. If no cyclical wait was detected, another > call to wait_for_tables/2 was made, and so on. If, at > the point of timeout, there are no other waiters, the > tables are loaded by force. > > I once tried to get a research project started to try to > assess the correctness of the algorithm and the code, but > this fell through. One of the questions I also wanted answered > was "what additional information is needed from mnesia in > order to make this easier?", because it does feel as if > mnesia doesn't help as much as it could. > > I can't give more details about the solution, since I don't > have it available, and it's been years since I last looked > at it. Given its operational track record, at least the code > isn't obviously broken, though. (: > > /Uffe From ulf.wiger@REDACTED Mon Aug 29 13:33:36 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Mon, 29 Aug 2005 13:33:36 +0200 Subject: Mnesia - mnesia_subscr and force_load_table Message-ID: Serge Aleynikov wrote: > > Also, how do you determine if a restart is due to paritioned > network (this might require some persistence of state between > restarts). Mnesia is able to detect it during the "handshake" after restart. It then generates an event, {inconsistent_database, running_partitioned_network, Node}. One may argue that when mnesia reports this, it's a bit late, since damage may already have been done. This is why we started using -kernel dist_auto_connect_once. If the nodes cannot automatically re-connect, you can detect partitioned networks "out-of-band". What we did with this information was to write to a special file on disk. This information is then read during restart. /Uffe From sebastian@REDACTED Mon Aug 29 14:24:37 2005 From: sebastian@REDACTED (Sebastian Bello) Date: Mon, 29 Aug 2005 09:24:37 -0300 Subject: ODBC and Oracle Message-ID: <002001c5ac94$a05772b0$dc00a8c0@INSWITCH244> Hi list, has anybody worked accessing an Oracle (in my case 9i) database from Erlang using ODBC? Using the Oracle driver I got the following error: odbc:connect(ConnStr, []). {error,connection_closed} (web@REDACTED)15> =CRASH REPORT==== 28-Aug-2005::20:09:37 === crasher: pid: <0.721.0> registered_name: [] error_info: {port_exit,collecting_of_driver_information_faild} initial_call: {gen,init_it, [gen_server, <0.694.0>, <0.694.0>, odbc, [{client,<0.99.0>}], []]} ancestors: [odbc_sup,<0.693.0>] messages: [{'EXIT',#Port<0.808>,normal}] links: [<0.694.0>] dictionary: [] trap_exit: true status: running heap_size: 610 stack_size: 21 reductions: 1552 neighbours: (web@REDACTED)15> =SUPERVISOR REPORT==== 28-Aug-2005::20:09:37 === Supervisor: {local,odbc_sup} Context: child_terminated Reason: {port_exit,collecting_of_driver_information_faild} Offender: [{pid,<0.721.0>}, {name,[]}, {mfa,{odbc,start_link_sup,[[{client,<0.99.0>}]]}}, {restart_type,temporary}, {shutdown,7000}, {child_type,worker}] Using the Microsoft drivers for Oracle (which seems not to support version 9i) I got the error odbc:connect(ConnString, []). {error,"No SQL-driver information available. Connection to database failed."} Any suggestions? Thanks, Sebastian- Prepaid Expertise - Programmable Switches Powered by Ericsson Licensed Technology Sebasti?n Bello - Engineer - Development Center - IN Switch Solutions Inc. Headquarters - Miami-U.S.A. Tel: 1305-3578076 Fax: 1305-7686260 Development Center - Montevideo - Uruguay Tel/Fax: 5982-7104457 IN SWITCH EMEA Phone: +33 0 6 0335 9427 - Fax: +33 0 4 93655773 / emea@REDACTED IN SWITCH ASIA Phone: +92 51 2800397/8- Fax: +92 51 2800399/ inswasia@REDACTED e-mail: sebastian@REDACTED -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image001.gif Type: image/gif Size: 1429 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: logoparafondo.gif Type: image/gif Size: 16886 bytes Desc: not available URL: From ingela@REDACTED Mon Aug 29 14:40:53 2005 From: ingela@REDACTED (Ingela Anderton) Date: Mon, 29 Aug 2005 14:40:53 +0200 Subject: ODBC and Oracle References: <002001c5ac94$a05772b0$dc00a8c0@INSWITCH244> Message-ID: <17171.597.279767.142905@gargle.gargle.HOWL> Oracle is one of the databases that we test agains in our automated test environment. The problem is probably that you have a 2.X driver. It seems however that you can workaround this by disabling scrollable cursors. >From ODBC's User Guide: 1.4 About the Erlang ODBC application Provides an Erlang interface to communicate with relational SQL-databases. It is built on top of Microsofts ODBC interface and therefore requires that you have an ODBC driver to the database that you want to connect to. The Erlang ODBC application is designed using the version 3.0 of the ODBC-standard, however using the option {scrollable_cursors, off} for a connection has been known to make it work for at least some 2.X drivers. -- /Ingela - OTP team Sebastian Bello wrote: > Hi list, > > has anybody worked accessing an Oracle (in my case 9i) database from Erlang using ODBC? > Using the Oracle driver I got the following error: > > odbc:connect(ConnStr, []). > {error,connection_closed} > (web@REDACTED)15> > =CRASH REPORT==== 28-Aug-2005::20:09:37 === > crasher: > pid: <0.721.0> > registered_name: [] > error_info: {port_exit,collecting_of_driver_information_faild} > initial_call: {gen,init_it, > [gen_server, > <0.694.0>, > <0.694.0>, > odbc, > [{client,<0.99.0>}], > []]} > ancestors: [odbc_sup,<0.693.0>] > messages: [{'EXIT',#Port<0.808>,normal}] > links: [<0.694.0>] > dictionary: [] > trap_exit: true > status: running > heap_size: 610 > stack_size: 21 > reductions: 1552 > neighbours: > (web@REDACTED)15> > =SUPERVISOR REPORT==== 28-Aug-2005::20:09:37 === > Supervisor: {local,odbc_sup} > Context: child_terminated > Reason: {port_exit,collecting_of_driver_information_faild} > Offender: [{pid,<0.721.0>}, > {name,[]}, > {mfa,{odbc,start_link_sup,[[{client,<0.99.0>}]]}}, > {restart_type,temporary}, > {shutdown,7000}, > {child_type,worker}] > > Using the Microsoft drivers for Oracle (which seems not to support version 9i) I got the error > > odbc:connect(ConnString, []). > {error,"No SQL-driver information available. Connection to database failed."} > > Any suggestions? > Thanks, > Sebastian- > > Prepaid Expertise - Programmable Switches > Powered by Ericsson Licensed Technology > Sebasti?n Bello - Engineer - Development Center - IN Switch Solutions Inc. > Headquarters - Miami-U.S.A. Tel: 1305-3578076 Fax: 1305-7686260 > Development Center - Montevideo - Uruguay Tel/Fax: 5982-7104457 > IN SWITCH EMEA Phone: +33 0 6 0335 9427 - Fax: +33 0 4 93655773 / emea@REDACTED > IN SWITCH ASIA Phone: +92 51 2800397/8- Fax: +92 51 2800399/ inswasia@REDACTED > e-mail: sebastian@REDACTED > > > > > > > href=file://C:\local\firma\> > > > > >
Hi list,
>
 
>
has anybody worked accessing an Oracle (in my case 9i) database from Erlang > using ODBC?
>
Using the Oracle driver I got the following error:
>
 
>
odbc:connect(ConnStr, > []).
{error,connection_closed}
(
href="mailto:web@REDACTED)15">web@REDACTED)15 color=#0000ff>>
=CRASH REPORT==== 28-Aug-2005::20:09:37 ===
  > crasher:
    pid: <0.721.0>
    > registered_name: []
    error_info: > {port_exit,collecting_of_driver_information_faild}
    > initial_call: > {gen,init_it,
                      > [gen_server,
                       > <0.694.0>,
                       > <0.694.0>,
                       > odbc,
                       > [{client,<0.99.0>}],
                       > []]}
    ancestors: > [odbc_sup,<0.693.0>]
    messages: > [{'EXIT',#Port<0.808>,normal}]
    links: > [<0.694.0>]
    dictionary: []
    > trap_exit: true
    status: running
    > heap_size: 610
    stack_size: 21
    > reductions: 1552
  neighbours:
(
href="mailto:web@REDACTED)15">web@REDACTED)15 color=#0000ff>>
=SUPERVISOR REPORT==== 28-Aug-2005::20:09:37 > ===
     Supervisor: > {local,odbc_sup}
     Context:    > child_terminated
     Reason:     > {port_exit,collecting_of_driver_information_faild}
     > Offender:   > [{pid,<0.721.0>},
                  > {name,[]},
                  > {mfa,{odbc,start_link_sup,[[{client,<0.99.0>}]]}},
                  > {restart_type,temporary},
                  > {shutdown,7000},
                  > {child_type,worker}]
>
 
>
Using the Microsoft drivers for Oracle (which seems not to support version > 9i) I got the error
>
 
>
odbc:connect(ConnString, []).
{error,"No SQL-driver > information available. Connection to database failed."}
>
 
>
>
Any suggestions?
>
Thanks,
>
    Sebastian-
>
 
>
> > > > >
src="cid:001a01c5ac94$9f2fe2a0$dc00a8c0@REDACTED"> >

Prepaid Expertise - > Programmable Switches
Powered by Ericsson Licensed > Technology
Sebasti?n Bello - Engineer - Development Center - IN Switch > Solutions Inc.
Headquarters - Miami-U.S.A. Tel: 1305-3578076 Fax: > 1305-7686260
Development Center - Montevideo - Uruguay Tel/Fax: > 5982-7104457
IN SWITCH EMEA Phone: +33 0 6 0335 9427 - Fax: +33 0 4 > 93655773 / emea@REDACTED
IN SWITCH ASIA Phone: +92 51 2800397/8- > Fax: +92 51 2800399/ inswasia@REDACTED
e-mail: > sebastian@REDACTED
size=1>

color=blue size=1>
  From gunilla@REDACTED Mon Aug 29 15:51:35 2005 From: gunilla@REDACTED (Gunilla Arendt) Date: Mon, 29 Aug 2005 15:51:35 +0200 Subject: Compiling .rel-files - module search path In-Reply-To: <200508260850.58599.ft@it.su.se> References: <200508260850.58599.ft@it.su.se> Message-ID: <431312E7.6030400@erix.ericsson.se> erlc for a .rel file calls systools:make_script/2 to generate the boot script. For every application, systools:make_script/2 looks for the .app file in the code path, and then assumes that all .beam files for this application are located in the same directory - ie does *not* search for them in the path. Could this be what is causing your problem? / Gunilla Fredrik Thulin wrote: > I give up. I've searched the mailing lists and the rest of the > google-indexed web but I can't get this to work. > > I am trying to compile a .rel-file into a boot file. I want to be able > to build my project in a build-directory as opposed to having to do it > inside the source tree. > > erlc with output directory set to "." and a relative path to > the .rel-file gives me a lot of "module_not_found" even though I've > littered the command line with paths to all my source files AND the > corresponding .beam files. What am I doing wrong? > > As seen in this strace-output, erlc only looks for tcp_receiver.beam in > the current working directory, despite all my -I's : > > host:~/tmp/build-test-yxa/ebin$ strace -f /pkg/erlang/R10B-6/bin/erlc > -Wall -I"../../test-yxa-svn/src" > -I"../../test-yxa-svn/src/*/" > -I"../src/" -I"../src/*/" > -o . ../../test-yxa-svn/ebin/incomingproxy.rel 2>&1 | > grep 'tcp_receiver' > stat64("./tcp_receiver.beam", 0xbfffee9c) = -1 ENOENT > (No such file or directory) > {{module_not_found,incomingproxy,tcp_receiver}, > {tcp_receiver,'$$ignore$$',incomingproxy,"0.0","."}} > host:~/tmp/build-test-yxa/ebin$ ls ../src/*/tcp_receiver.beam > ../../test-yxa-svn/src/*/tcp_receiver.erl > ../../test-yxa-svn/src/transportlayer/tcp_receiver.erl ../src/transportlayer/tcp_receiver.beam > host:~/tmp/build-test-yxa/ebin$ > > I've tried with having the .rel-file in both a directory called > "applications/" (my preferred choice), and in "ebin/" (as above). > > Thanks in advance > > /Fredrik > From ft@REDACTED Mon Aug 29 16:27:59 2005 From: ft@REDACTED (Fredrik Thulin) Date: Mon, 29 Aug 2005 16:27:59 +0200 Subject: Compiling .rel-files - module search path In-Reply-To: <431312E7.6030400@erix.ericsson.se> References: <200508260850.58599.ft@it.su.se> <431312E7.6030400@erix.ericsson.se> Message-ID: <200508291627.59488.ft@it.su.se> On Monday 29 August 2005 15.51, Gunilla Arendt wrote: > erlc for a .rel file calls systools:make_script/2 to generate the > boot script. For every application, systools:make_script/2 looks for > the .app file in the code path, and then assumes that all .beam files > for this application are located in the same directory - ie does > *not* search for them in the path. Could this be what is causing your > problem? Yes it is. I don't want to have all my 103 .erl files in the same directory, for obvious reasons. I would like to be able to make my own directory layout, and not have to use the OTP directory layout. My impression is that this wish is shared by other Open Source projects using Erlang (at least ejabberd and Yaws it seems). It would not be too difficult to modify systools to make it possible to specify paths to source code and beam files using -I arguments. I was working on a patch for this that I was going to propose. Would you consider such a patch? I think it would also be good to be able to give a path to the .app and .rel files. /Fredrik From ulf.wiger@REDACTED Mon Aug 29 16:32:34 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Mon, 29 Aug 2005 16:32:34 +0200 Subject: the user_default module Message-ID: I noticed when experimenting with the code_path_cache flag (which I just discovered), that the cache is always "rehashed" twice during a normal boot. After inserting some debug statements, I determined that the second time was when trying to load 'user_default'. The 'user_default' module doesn't exist anywhere unless provided by the user. Granted, on my machine, running with erl boot start_sasl on an NFS-mounted directory, it took only 78 ms to rehash the cache, so the performance hit is hardly noticable. However, on a large system with a slow file system, it might matter (haven't measured that). Regardless of how many milliseconds are saved or lost, I think that one should provide the modules one tries to load. Thus, a standard 'user_default' should be in stdlib. I tried inserting the following module: ------------------------------------------- -module(user_default). -export([]). ------------------------------------------- It seems to work just fine. /Uffe From sebastian@REDACTED Mon Aug 29 16:36:42 2005 From: sebastian@REDACTED (Sebastian Bello) Date: Mon, 29 Aug 2005 11:36:42 -0300 Subject: ODBC and Oracle References: <002001c5ac94$a05772b0$dc00a8c0@INSWITCH244> <17171.597.279767.142905@gargle.gargle.HOWL> Message-ID: <005001c5aca7$13b8a0f0$dc00a8c0@INSWITCH244> Ingela, it worked, thanks for your response. Any advice regarding whether to use the Microsoft's or the Oracle's ODBC driver? Sebastian- ----- Original Message ----- From: "Ingela Anderton" To: Cc: Sent: Monday, August 29, 2005 9:40 AM Subject: Re: ODBC and Oracle Oracle is one of the databases that we test agains in our automated test environment. The problem is probably that you have a 2.X driver. It seems however that you can workaround this by disabling scrollable cursors. >From ODBC's User Guide: 1.4 About the Erlang ODBC application Provides an Erlang interface to communicate with relational SQL-databases. It is built on top of Microsofts ODBC interface and therefore requires that you have an ODBC driver to the database that you want to connect to. The Erlang ODBC application is designed using the version 3.0 of the ODBC-standard, however using the option {scrollable_cursors, off} for a connection has been known to make it work for at least some 2.X drivers. -- /Ingela - OTP team Sebastian Bello wrote: > Hi list, > > has anybody worked accessing an Oracle (in my case 9i) database from Erlang using ODBC? > Using the Oracle driver I got the following error: > > odbc:connect(ConnStr, []). > {error,connection_closed} > (web@REDACTED)15> > =CRASH REPORT==== 28-Aug-2005::20:09:37 === > crasher: > pid: <0.721.0> > registered_name: [] > error_info: {port_exit,collecting_of_driver_information_faild} > initial_call: {gen,init_it, > [gen_server, > <0.694.0>, > <0.694.0>, > odbc, > [{client,<0.99.0>}], > []]} > ancestors: [odbc_sup,<0.693.0>] > messages: [{'EXIT',#Port<0.808>,normal}] > links: [<0.694.0>] > dictionary: [] > trap_exit: true > status: running > heap_size: 610 > stack_size: 21 > reductions: 1552 > neighbours: > (web@REDACTED)15> > =SUPERVISOR REPORT==== 28-Aug-2005::20:09:37 === > Supervisor: {local,odbc_sup} > Context: child_terminated > Reason: {port_exit,collecting_of_driver_information_faild} > Offender: [{pid,<0.721.0>}, > {name,[]}, > {mfa,{odbc,start_link_sup,[[{client,<0.99.0>}]]}}, > {restart_type,temporary}, > {shutdown,7000}, > {child_type,worker}] > > Using the Microsoft drivers for Oracle (which seems not to support version 9i) I got the error > > odbc:connect(ConnString, []). > {error,"No SQL-driver information available. Connection to database failed."} > > Any suggestions? > Thanks, > Sebastian- > > Prepaid Expertise - Programmable Switches > Powered by Ericsson Licensed Technology > Sebasti?n Bello - Engineer - Development Center - IN Switch Solutions Inc. > Headquarters - Miami-U.S.A. Tel: 1305-3578076 Fax: 1305-7686260 > Development Center - Montevideo - Uruguay Tel/Fax: 5982-7104457 > IN SWITCH EMEA Phone: +33 0 6 0335 9427 - Fax: +33 0 4 93655773 / emea@REDACTED > IN SWITCH ASIA Phone: +92 51 2800397/8- Fax: +92 51 2800399/ inswasia@REDACTED > e-mail: sebastian@REDACTED > > > > > > > href=file://C:\local\firma\> > > > > >
Hi list,
>
 
>
has anybody worked accessing an Oracle (in my case 9i) database from Erlang > using ODBC?
>
Using the Oracle driver I got the following error:
>
 
>
odbc:connect(ConnStr, > []).
{error,connection_closed}
(
href="mailto:web@REDACTED)15">web@REDACTED)15 color=#0000ff>>
=CRASH REPORT==== 28-Aug-2005::20:09:37 ===
  > crasher:
    pid: <0.721.0>
    > registered_name: []
    error_info: > {port_exit,collecting_of_driver_information_faild}
    > initial_call: > {gen,init_it,
           ;            > [gen_server,
                        > <0.694.0>,
         &n bsp;             > <0.694.0>,
         &n bsp;             > odbc,
           & nbsp;           > [{client,<0.99.0>}],
       &nbs p;            &n bsp;  > []]}
    ancestors: > [odbc_sup,<0.693.0>]
    messages: > [{'EXIT',#Port<0.808>,normal}]
    links: > [<0.694.0>]
    dictionary: []
    > trap_exit: true
    status: running
    > heap_size: 610
    stack_size: 21
    > reductions: 1552
  neighbours:
(
href="mailto:web@REDACTED)15">web@REDACTED)15 color=#0000ff>>
=SUPERVISOR REPORT==== 28-Aug-2005::20:09:37 > ===
     Supervisor: > {local,odbc_sup}
     Context:    > child_terminated
     Reason:     > {port_exit,collecting_of_driver_information_faild}
   &nbs p; > Offender:   > [{pid,<0.721.0>},
        & nbsp;         > {name,[]},
          &n bsp;       > {mfa,{odbc,start_link_sup,[[{client,<0.99.0>}]]}},
  &nbs p;            &n bsp;  > {restart_type,temporary},
         ;          > {shutdown,7000},
         &n bsp;        > {child_type,worker}]
>
 
>
Using the Microsoft drivers for Oracle (which seems not to support version > 9i) I got the error
>
 
>
odbc:connect(ConnString, []).
{error,"No SQL-driver > information available. Connection to database failed."}
>
 
>
>
Any suggestions?
>
Thanks,
>
    Sebastian-
>
 
>
> > > > >
src="cid:001a01c5ac94$9f2fe2a0$dc00a8c0@REDACTED"> >

Prepaid Expertise - > Programmable Switches
Powered by Ericsson Licensed > Technology
Sebasti?n Bello - Engineer - Development Center - IN Switch > Solutions Inc.
Headquarters - Miami-U.S.A. Tel: 1305-3578076 Fax: > 1305-7686260
Development Center - Montevideo - Uruguay Tel/Fax: > 5982-7104457
IN SWITCH EMEA Phone: +33 0 6 0335 9427 - Fax: +33 0 4 > 93655773 / emea@REDACTED
IN SWITCH ASIA Phone: +92 51 2800397/8- > Fax: +92 51 2800399/ inswasia@REDACTED
e-mail: > sebastian@REDACTED
size=1>

color=blue size=1>
  From ingela@REDACTED Mon Aug 29 18:05:03 2005 From: ingela@REDACTED (Ingela Anderton) Date: Mon, 29 Aug 2005 18:05:03 +0200 Subject: ODBC and Oracle References: <002001c5ac94$a05772b0$dc00a8c0@INSWITCH244> <17171.597.279767.142905@gargle.gargle.HOWL> <005001c5aca7$13b8a0f0$dc00a8c0@INSWITCH244> Message-ID: <17171.12847.922432.670486@gargle.gargle.HOWL> Sebastian Bello wrote: > Ingela, > > it worked, thanks for your response. > Any advice regarding whether to use the Microsoft's or the Oracle's ODBC > driver? We run our Unix Platform tests against Oracle and Windows Platform tests against SqlServer so I have no experience of the two Windows drivers for Oracle. Normaly I would say Oracles own ought to be best but when it comes to Windows I am not certain this is so. My advise would be try them both and decide for yourself. -- /Ingela - OTP team From ulf@REDACTED Mon Aug 29 22:27:09 2005 From: ulf@REDACTED (Ulf Wiger) Date: Mon, 29 Aug 2005 22:27:09 +0200 Subject: Mnesia, more questions In-Reply-To: <20050829125237.9812C46EE3@bang.trapexit.org> References: <20050829125237.9812C46EE3@bang.trapexit.org> Message-ID: Den 2005-08-29 14:52:37 skrev tobbe : > > I recently read an article on how to setup a secondary MySQL server > that gets updated from the primary one. > > How would one do the same in Mnesia? > (NB: I don't want the secondary server to be part of schema, > running in distributed mode, etc) Perhaps one could make use of mnesia table events? See http://erlang.se/doc/doc-5.4.8/lib/mnesia-4.2.2/doc/html/Mnesia_chap5.html#5.7 Another option would perhaps be to use rdbms, which has commit triggers, but that would require all accesses to go through rdbms. Table events will work no matter what. /Uffe -- Ulf Wiger From ulf@REDACTED Mon Aug 29 22:36:43 2005 From: ulf@REDACTED (Ulf Wiger) Date: Mon, 29 Aug 2005 22:36:43 +0200 Subject: Compiling .rel-files - module search path In-Reply-To: <431312E7.6030400@erix.ericsson.se> References: <200508260850.58599.ft@it.su.se> <431312E7.6030400@erix.ericsson.se> Message-ID: Den 2005-08-29 15:51:35 skrev Gunilla Arendt : > erlc for a .rel file calls systools:make_script/2 to generate the boot > script. For every application, systools:make_script/2 looks for the .app > file in the code path, and then assumes that all .beam files for this > application are located in the same directory - ie does *not* search for > them in the path. Could this be what is causing your problem? > > / Gunilla I've not used systools via erlc (I always roll my own tool ;-), but after some experimentation, I was able to deduce that the -I flags indeed work. So does -pa and -pz, BTW. The -I flags are equivalent to the {path, [Path]} option when calling systools:make_script/2 from Erlang, and if you quote the path expression, you can use wildcards: erlc -I "$MYAPPS/lib/*/ebin" mysystem.rel I believe Fredriks dilemma is that he doesn't want to have huge applications, and thus split the code into several subdirectories. This will not work with the OTP release handling system, as it requires the .beam files to be in the same place as the .app files (*) I think there are two approaches to solving the problem: - Use packages. This will allow you to organize modules into a tree of subdirectories under the main application - Use included applications. This will allow you to use .app files as a means to hook into the OTP release handler, while still keeping only a few "top" applications that effectively include a whole lot of modules. (*) Obviously, the .beam files can be "patched" by putting another copy in a directory that's early in the path, but the original must be in the application's ebin directory. The .app file cannot be patched, and has to always reside in the application's ebin/. This is also true for the application upgrade script (the .appup file). /Uffe -- Ulf Wiger From sebastian@REDACTED Mon Aug 29 23:45:42 2005 From: sebastian@REDACTED (Sebastian Bello) Date: Mon, 29 Aug 2005 18:45:42 -0300 Subject: ODBC and Oracle References: <002001c5ac94$a05772b0$dc00a8c0@INSWITCH244><17171.597.279767.142905@gargle.gargle.HOWL><005001c5aca7$13b8a0f0$dc00a8c0@INSWITCH244> <17171.12847.922432.670486@gargle.gargle.HOWL> Message-ID: <03e601c5ace3$021659a0$dc00a8c0@INSWITCH244> Ok, thanks! Sebastian- ----- Original Message ----- From: "Ingela Anderton" To: Cc: Sent: Monday, August 29, 2005 1:05 PM Subject: Re: ODBC and Oracle > Sebastian Bello wrote: > > Ingela, > > > > it worked, thanks for your response. > > Any advice regarding whether to use the Microsoft's or the Oracle's ODBC > > driver? > We run our Unix Platform tests against Oracle and Windows Platform > tests against SqlServer so I have no experience of the two > Windows drivers for Oracle. Normaly I would say Oracles own ought to > be best but when it comes to Windows I am not certain this is so. My > advise would be try them both and decide for yourself. > > -- > /Ingela - OTP team > > > > From ok@REDACTED Tue Aug 30 03:25:12 2005 From: ok@REDACTED (Richard A. O'Keefe) Date: Tue, 30 Aug 2005 13:25:12 +1200 (NZST) Subject: Sliding window data structure Message-ID: <200508300125.j7U1PCu5073419@atlas.otago.ac.nz> Not so long ago we had a thread about tuple operations, with the motivation being sliding windows. I've found a fairly simple data structure for sliding windows (indexed collections with the property that when you push a new value on one end an old value drops off the other) with the following properties: make_window(N, Element) -> Window list_to_window(List) -> Window window_to_list(Window) -> List are all O(N) index_window(I, Window) -> Element is O(log(N)) shift_window(New_Element, Window) -> New_Window is O(log(N)) worst case, BUT is O(1) amortised. I've measured the performance for indexing and shifting, and they are empirically O(log(N)) -- I haven't seen such a beautiful straight line in an empirical plot in a *long* time -- and O(1) as claimed over N = 1 to 1,000,000. It's pretty easy to come up with a data structure which is O(1) amortised cost for shift_window/2; the old back-to-back pair of lists for queues will do it. But that doesn't give you O(log(N)) worst case, and it doesn't give you O(log(N)) indexing. Is this of any interest? It does suggest to me that we don't need fancy array operations for sliding windows. From david.nospam.hopwood@REDACTED Tue Aug 30 04:55:39 2005 From: david.nospam.hopwood@REDACTED (David Hopwood) Date: Tue, 30 Aug 2005 03:55:39 +0100 Subject: Sliding window data structure In-Reply-To: <200508300125.j7U1PCu5073419@atlas.otago.ac.nz> References: <200508300125.j7U1PCu5073419@atlas.otago.ac.nz> Message-ID: <4313CAAB.5070101@blueyonder.co.uk> Richard A. O'Keefe wrote: > I've found a fairly simple data structure for sliding windows > (indexed collections with the property that when you push a > new value on one end an old value drops off the other) > with the following properties: > > make_window(N, Element) -> Window > list_to_window(List) -> Window > window_to_list(Window) -> List > are all O(N) > > index_window(I, Window) -> Element > is O(log(N)) > > shift_window(New_Element, Window) -> New_Window > is O(log(N)) worst case, > BUT is O(1) amortised. > > I've measured the performance for indexing and shifting, > and they are empirically O(log(N)) -- I haven't seen such a beautiful > straight line in an empirical plot in a *long* time -- and O(1) as > claimed over N = 1 to 1,000,000. > > It's pretty easy to come up with a data structure which is O(1) > amortised cost for shift_window/2; the old back-to-back pair of > lists for queues will do it. But that doesn't give you O(log(N)) > worst case, and it doesn't give you O(log(N)) indexing. I think it's possible to get O(log(N)) indexing and O(1) worst-case shifting, by using the the skew binary random access list from Chapter 9 of Chris Okasaki's "Purely Functional Data Structures" [*]. This structure supports O(log(N)) indexing and an O(1) worst case 'head', 'cons' and 'tail'. It is not quite a sliding window, but it can be made into one (for the shift operation, use 'cons' and drop the final digit/tree whenever the list grows too long; this doesn't affect the bounds). But that's quite complicated, so yes, I'd be interested in a simple way of doing a purely functional sliding window. [*] or section 6.4.1 of -- David Hopwood From ok@REDACTED Tue Aug 30 07:13:48 2005 From: ok@REDACTED (Richard A. O'Keefe) Date: Tue, 30 Aug 2005 17:13:48 +1200 (NZST) Subject: Sliding window data structure Message-ID: <200508300513.j7U5Dm5F059802@atlas.otago.ac.nz> I wrote: > I've found a fairly simple data structure for sliding windows David Hopwood provided a useful link: http://www.cs.cmu.edu/~rwh/theses/okasaki.pdf My data structure is basically a cross between what Okasaki calls a Binary Random Access List (*not* skew binary) and the back-to-back lists traditionally used for queues. Basically, a sliding window is a triple {Size,Left,Right} where Left and Right are lists of complete binary trees. The Left list is a Binary Random Access List. The Right list *isn't*. When you shift a window that has an empty Right list, you sete the Right list to be reverse(Left). So in Left you have small elements to the left of big ones, but after a switchover the new Right list goes from big to small. Then when you start deleting from the Right list, the biggest element breaks up. So you get this sort of size pattern: Left (increasing size) < Right It's easy to show that length(Right) <= 2*logN, and for each Tree in Left or Right, depth(Tree) <= logN. (Leaving the occasional ceiling and +constant out.) Thw worst case of log(N) comes partly from reversing the Left list, but mostly from tree building and dismantling. The nice thing is that it really does work out to O(1) amortised cost per slide. I suspect that Skew Binary Random Access Lists could also be used back- to-back this way, but I don't understand them well enough to tell what weakening the invariant for the Right list would do. I've just this minute discovered Hinze and Paterson's "2-3 Finger Trees", which amongst other things give you O(1) amortised push and pop at each end. They can also support indexing. I don't know why they call it a "simple" data structure, though. For what it's worth, the Erlang code seems to be about twice as slow as SICStus Prolog, and that's with c(window, [verbose,hipe]) in a hipe- enabled Erlang. From casper2000a@REDACTED Tue Aug 30 09:40:14 2005 From: casper2000a@REDACTED (Eranga Udesh) Date: Tue, 30 Aug 2005 13:40:14 +0600 Subject: Erl LDAP server In-Reply-To: <200508300513.j7U5Dm5F059802@atlas.otago.ac.nz> Message-ID: <20050830073122.A2486400028@mail.omnibis.com> Hi, Is there a LDAP server available in Erlang? If not, how feasible to develop one? - Eranga From ulf.wiger@REDACTED Tue Aug 30 09:58:08 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Tue, 30 Aug 2005 09:58:08 +0200 Subject: some relevant threads on comp.lang.functional Message-ID: This morning, the following question came up on comp.lang.functional: http://groups.google.se/group/comp.lang.functional/browse_thread/thread/7d7038d2e52b92bf/d94a67e5d0729a35?hl=sv#d94a67e5d0729a35 "I've been mulling over Armstrong and Virding's paper, "One Pass Real-Time Generational Mark-Sweep Garbage Collection" (In Proc. Int. Workshop on Memory Management, 1995, see www.sics.se/~joe/pubs/historyGC.ps ) Does anyone know whether this was implemented and, if so, how well it performed? [...]" Also, I've been drawn into a debate on the thread "What ML language do you recommend?" http://groups.google.se/group/comp.lang.functional/browse_thread/thread/6f1029e6176c57a7/d042b21ace010929?hl=sv#d042b21ace010929 The part that concerns me has to do with Concurrent ML vs Erlang, concurrency models, etc. I quoted Roger Price's experience with Concurrent ML, for example, and the most recent posts discuss the book on Concurrent ML (which I haven't read), and whether synchronous communication is inherently more powerful than asynchronous communication. Feel free to chip in. (: /Uffe From ulf.wiger@REDACTED Tue Aug 30 10:03:04 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Tue, 30 Aug 2005 10:03:04 +0200 Subject: Erl LDAP server Message-ID: ELDAP: http://cvs.sourceforge.net/viewcvs.py/jungerl/jungerl/lib/eldap/ EUC 2003: "Talking LDAP and RADIUS from Erlang" http://www.erlang.se/euc/03/proceedings/1200tobbe.ppt Or basically: http://www.google.se/search?hl=sv&q=LDAP+Erlang&meta= ;) /Uffe > -----Original Message----- > From: owner-erlang-questions@REDACTED > [mailto:owner-erlang-questions@REDACTED]On Behalf Of Eranga Udesh > Sent: den 30 augusti 2005 09:40 > To: erlang-questions@REDACTED > Subject: Erl LDAP server > > > Hi, > > Is there a LDAP server available in Erlang? If not, how > feasible to develop > one? > > - Eranga > > > From casper2000a@REDACTED Tue Aug 30 10:15:52 2005 From: casper2000a@REDACTED (Eranga Udesh) Date: Tue, 30 Aug 2005 14:15:52 +0600 Subject: Erl LDAP server In-Reply-To: Message-ID: <20050830080700.62E3E400041@mail.omnibis.com> Uffe, Thanks for the pointers. I went through them already. Looks like there's no already developed one, isn't it? - Eranga -----Original Message----- From: Ulf Wiger (AL/EAB) [mailto:ulf.wiger@REDACTED] Sent: Tuesday, August 30, 2005 2:03 PM To: Eranga Udesh; erlang-questions@REDACTED Subject: RE: Erl LDAP server ELDAP: http://cvs.sourceforge.net/viewcvs.py/jungerl/jungerl/lib/eldap/ EUC 2003: "Talking LDAP and RADIUS from Erlang" http://www.erlang.se/euc/03/proceedings/1200tobbe.ppt Or basically: http://www.google.se/search?hl=sv&q=LDAP+Erlang&meta= ;) /Uffe > -----Original Message----- > From: owner-erlang-questions@REDACTED > [mailto:owner-erlang-questions@REDACTED]On Behalf Of Eranga Udesh > Sent: den 30 augusti 2005 09:40 > To: erlang-questions@REDACTED > Subject: Erl LDAP server > > > Hi, > > Is there a LDAP server available in Erlang? If not, how > feasible to develop > one? > > - Eranga > > > From ulf.wiger@REDACTED Tue Aug 30 10:25:14 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Tue, 30 Aug 2005 10:25:14 +0200 Subject: Erl LDAP server Message-ID: Eranga Udesh wrote: > > Uffe, > > Thanks for the pointers. I went through them already. Looks > like there's no > already developed one, isn't it? > > - Eranga Since I haven't used ELDAP myself, I should perhaps let someone else answer, but the best approach seems to me to be to add a server implementation to ELDAP. The client already has to do the encode/decode of messages, and since it's asn1, it's really only a matter of reversing the ops, isn't it? Still, a bit of work remains. An LDAP server should probably be modeled as a behaviour with a callback model a la gen_server, which is responsible for the database access. /Uffe From mickael.remond@REDACTED Tue Aug 30 10:36:20 2005 From: mickael.remond@REDACTED (Mickael Remond) Date: Tue, 30 Aug 2005 10:36:20 +0200 Subject: Erl LDAP server In-Reply-To: <20050830080700.62E3E400041@mail.omnibis.com> References: <20050830080700.62E3E400041@mail.omnibis.com> Message-ID: <43141A84.8060608@erlang-fr.org> Eranga Udesh wrote: > Uffe, > > Thanks for the pointers. I went through them already. Looks like there's no > already developed one, isn't it? I made some draft work already but never manage to get it finished. My plans was to support a fixed commonly used LDAP schema to use he resulting software as a basis for authentication. I reach a point were I was able to log into several Linux Workstation using PAM LDAP pointing to the Erlang small LDAP server. I think Erlang provides everything to write a very nice and performant LDAP server as ASN.1 library is good and you have Mnesia to store your data and access them with low latency. Samuel Tardieu wrote some years ago an LDAP server in Erlang and told me it was lightning fast, but it never reach the point where the code was satisfying enough for him to get published. I think writing such a server is relatively easy with fixed schema and can get much much more complicated if you plan to support schema definition and change. I hope this helps, -- Micka?l R?mond From mickael.remond@REDACTED Tue Aug 30 10:46:22 2005 From: mickael.remond@REDACTED (Mickael Remond) Date: Tue, 30 Aug 2005 10:46:22 +0200 Subject: Erl LDAP server In-Reply-To: References: Message-ID: <43141CDE.5070802@erlang-fr.org> Ulf Wiger (AL/EAB) wrote: > Eranga Udesh wrote: >>Uffe, >> >>Thanks for the pointers. I went through them already. Looks >>like there's no >>already developed one, isn't it? >> >>- Eranga > > > Since I haven't used ELDAP myself, I should perhaps let > someone else answer, but the best approach seems to me > to be to add a server implementation to ELDAP. The client > already has to do the encode/decode of messages, and since > it's asn1, it's really only a matter of reversing the ops, > isn't it? > > Still, a bit of work remains. An LDAP server should probably > be modeled as a behaviour with a callback model a la gen_server, > which is responsible for the database access. In my trial, I use eldap as a basis and this is a very good start. The most time consuming part is flexible schema support (with inheritance) and validation. -- Micka?l R?mond From sean.hinde@REDACTED Tue Aug 30 10:58:29 2005 From: sean.hinde@REDACTED (Sean Hinde) Date: Tue, 30 Aug 2005 09:58:29 +0100 Subject: Erl LDAP server In-Reply-To: <43141A84.8060608@erlang-fr.org> References: <20050830080700.62E3E400041@mail.omnibis.com> <43141A84.8060608@erlang-fr.org> Message-ID: On 30 Aug 2005, at 09:36, Mickael Remond wrote: > Eranga Udesh wrote: > >> Uffe, >> Thanks for the pointers. I went through them already. Looks like >> there's no >> already developed one, isn't it? >> > > I made some draft work already but never manage to get it finished. > My plans was to support a fixed commonly used LDAP schema to use he > resulting software as a basis for authentication. > I reach a point were I was able to log into several Linux > Workstation using PAM LDAP pointing to the Erlang small LDAP server. > > I think Erlang provides everything to write a very nice and > performant LDAP server as ASN.1 library is good and you have Mnesia > to store your data and access them with low latency. > > Samuel Tardieu wrote some years ago an LDAP server in Erlang and > told me it was lightning fast, but it never reach the point where > the code was satisfying enough for him to get published. > > I think writing such a server is relatively easy with fixed schema > and can get much much more complicated if you plan to support > schema definition and change. Yep, There is another one out there that I started and Chandru finished off. Fixed schema (several fixed schemas actually). It is nothing more than a pattern match across the asn.1 structures (which could be directly taken from from eldap), with a simple state machine to cover bind (login). It was very fast. Sean From per.gustafsson@REDACTED Tue Aug 30 11:38:35 2005 From: per.gustafsson@REDACTED (Per Gustafsson) Date: Tue, 30 Aug 2005 11:38:35 +0200 Subject: Sliding window data structure In-Reply-To: <200508300513.j7U5Dm5F059802@atlas.otago.ac.nz> References: <200508300513.j7U5Dm5F059802@atlas.otago.ac.nz> Message-ID: <4314291B.5090705@it.uu.se> Richard A. O'Keefe wrote: >For what it's worth, the Erlang code seems to be about twice as slow as >SICStus Prolog, and that's with c(window, [verbose,hipe]) in a hipe- >enabled Erlang. > > That should be c(window, [native]) in order to native-compile the module. Per From thinus@REDACTED Tue Aug 30 11:41:00 2005 From: thinus@REDACTED (Thinus Pollard) Date: Tue, 30 Aug 2005 11:41:00 +0200 Subject: Test Message-ID: <200508301141.00511.thinus@erlfinsys.net> Test, please ignore ;) T -- Thinus Pollard Erlang Financial Systems Mobile: +27 72 075 2751 From casper2000a@REDACTED Tue Aug 30 12:09:45 2005 From: casper2000a@REDACTED (Eranga Udesh) Date: Tue, 30 Aug 2005 16:09:45 +0600 Subject: Erl LDAP server In-Reply-To: Message-ID: <20050830100053.ED7C7400004@mail.omnibis.com> Sean, Would you be able to share that with me (us - the community) please? Thanks! - Eranga -----Original Message----- From: Sean Hinde [mailto:sean.hinde@REDACTED] Sent: Tuesday, August 30, 2005 2:58 PM To: Eranga Udesh Cc: Erlang Questions Subject: Re: Erl LDAP server On 30 Aug 2005, at 09:36, Mickael Remond wrote: > Eranga Udesh wrote: > >> Uffe, >> Thanks for the pointers. I went through them already. Looks like >> there's no >> already developed one, isn't it? >> > > I made some draft work already but never manage to get it finished. > My plans was to support a fixed commonly used LDAP schema to use he > resulting software as a basis for authentication. > I reach a point were I was able to log into several Linux > Workstation using PAM LDAP pointing to the Erlang small LDAP server. > > I think Erlang provides everything to write a very nice and > performant LDAP server as ASN.1 library is good and you have Mnesia > to store your data and access them with low latency. > > Samuel Tardieu wrote some years ago an LDAP server in Erlang and > told me it was lightning fast, but it never reach the point where > the code was satisfying enough for him to get published. > > I think writing such a server is relatively easy with fixed schema > and can get much much more complicated if you plan to support > schema definition and change. Yep, There is another one out there that I started and Chandru finished off. Fixed schema (several fixed schemas actually). It is nothing more than a pattern match across the asn.1 structures (which could be directly taken from from eldap), with a simple state machine to cover bind (login). It was very fast. Sean From casper2000a@REDACTED Tue Aug 30 12:11:32 2005 From: casper2000a@REDACTED (Eranga Udesh) Date: Tue, 30 Aug 2005 16:11:32 +0600 Subject: Erl LDAP server In-Reply-To: Message-ID: <20050830100240.1DA2D400015@mail.omnibis.com> Sorry, could ask in my previous email. Is it a LDAP client or the server you did? I found a milling thread which talks about a client. - Eranga -----Original Message----- From: Sean Hinde [mailto:sean.hinde@REDACTED] Sent: Tuesday, August 30, 2005 2:58 PM To: Eranga Udesh Cc: Erlang Questions Subject: Re: Erl LDAP server On 30 Aug 2005, at 09:36, Mickael Remond wrote: > Eranga Udesh wrote: > >> Uffe, >> Thanks for the pointers. I went through them already. Looks like >> there's no >> already developed one, isn't it? >> > > I made some draft work already but never manage to get it finished. > My plans was to support a fixed commonly used LDAP schema to use he > resulting software as a basis for authentication. > I reach a point were I was able to log into several Linux > Workstation using PAM LDAP pointing to the Erlang small LDAP server. > > I think Erlang provides everything to write a very nice and > performant LDAP server as ASN.1 library is good and you have Mnesia > to store your data and access them with low latency. > > Samuel Tardieu wrote some years ago an LDAP server in Erlang and > told me it was lightning fast, but it never reach the point where > the code was satisfying enough for him to get published. > > I think writing such a server is relatively easy with fixed schema > and can get much much more complicated if you plan to support > schema definition and change. Yep, There is another one out there that I started and Chandru finished off. Fixed schema (several fixed schemas actually). It is nothing more than a pattern match across the asn.1 structures (which could be directly taken from from eldap), with a simple state machine to cover bind (login). It was very fast. Sean From sean.hinde@REDACTED Tue Aug 30 12:15:15 2005 From: sean.hinde@REDACTED (Sean Hinde) Date: Tue, 30 Aug 2005 11:15:15 +0100 Subject: Erl LDAP server In-Reply-To: <20050830100053.ED7C7400004@mail.omnibis.com> References: <20050830100053.ED7C7400004@mail.omnibis.com> Message-ID: Hi, No, not possible. My point was that it is trivial to write your own. Sean On 30 Aug 2005, at 11:09, Eranga Udesh wrote: > Sean, > > Would you be able to share that with me (us - the community) please? > > Thanks! > - Eranga > > > > > -----Original Message----- > From: Sean Hinde [mailto:sean.hinde@REDACTED] > Sent: Tuesday, August 30, 2005 2:58 PM > To: Eranga Udesh > Cc: Erlang Questions > Subject: Re: Erl LDAP server > > > On 30 Aug 2005, at 09:36, Mickael Remond wrote: > > >> Eranga Udesh wrote: >> >> >>> Uffe, >>> Thanks for the pointers. I went through them already. Looks like >>> there's no >>> already developed one, isn't it? >>> >>> >> >> I made some draft work already but never manage to get it finished. >> My plans was to support a fixed commonly used LDAP schema to use he >> resulting software as a basis for authentication. >> I reach a point were I was able to log into several Linux >> Workstation using PAM LDAP pointing to the Erlang small LDAP server. >> >> I think Erlang provides everything to write a very nice and >> performant LDAP server as ASN.1 library is good and you have Mnesia >> to store your data and access them with low latency. >> >> Samuel Tardieu wrote some years ago an LDAP server in Erlang and >> told me it was lightning fast, but it never reach the point where >> the code was satisfying enough for him to get published. >> >> I think writing such a server is relatively easy with fixed schema >> and can get much much more complicated if you plan to support >> schema definition and change. >> > > Yep, There is another one out there that I started and Chandru > finished off. Fixed schema (several fixed schemas actually). It is > nothing more than a pattern match across the asn.1 structures (which > could be directly taken from from eldap), with a simple state machine > to cover bind (login). > > It was very fast. > > Sean > > > > > From dietmar@REDACTED Tue Aug 30 12:17:06 2005 From: dietmar@REDACTED (Dietmar Schaefer) Date: Tue, 30 Aug 2005 12:17:06 +0200 Subject: spread Message-ID: <43143222.6000008@ast.dfs.de> Hi ! I just found spread www.spread.org. The site mentioned Erlang Driver Toolkit Spread driver and Example code is available. Does someone knows more about it ??? regards Dietmar From serge@REDACTED Tue Aug 30 14:23:46 2005 From: serge@REDACTED (Serge Aleynikov) Date: Tue, 30 Aug 2005 08:23:46 -0400 Subject: spread In-Reply-To: <43143222.6000008@ast.dfs.de> References: <43143222.6000008@ast.dfs.de> Message-ID: <43144FD2.1080608@hq.idt.net> Hi Dietmar, I experimented with with the Spread/Erlang combination about a year ago. At a time I wanted to evaluate if it were possible to get high availability of Erlang servers to C clients that communicated to servers using spread process groups. Since spread offered a very simple asynchronous client API, it was very attractive to use that on the client side. While the solution worked well with a reasonable throughput, I wouldn't consider Spread for prime-time production applications, as I've seen some issues with it recovering from network faults. The spread client API library didn't detect well lost connections from the server. If you go to the spread's mailing list you'll also see that once in a while people report some strange behavior of spread daemons. However I wouldn't want to discourage you from using spread, as spread works well when network problems are not an issue, and may be suitable for your needs. As a result of my experiments I ended up not using spread, and switching to "pure" Erlang architecture, as it did offer process groups, C API, and performed very well. I sent the updated version of the spread driver for Erlang with some bug fixes to Scott, the author of the original library. As he was quite busy I'm not sure if he got a chance to update the jungerl repository. If needed I can share that version. Regards, Serge Dietmar Schaefer wrote: > Hi ! > > > I just found spread www.spread.org. > > The site mentioned Erlang Driver Toolkit Spread driver > > and > Example code > is > available. > > > Does someone knows more about it ??? > > > > regards > > > Dietmar > From hakan@REDACTED Tue Aug 30 14:26:54 2005 From: hakan@REDACTED (Hakan Mattsson) Date: Tue, 30 Aug 2005 14:26:54 +0200 (CEST) Subject: Mnesia, more questions In-Reply-To: References: <20050829125237.9812C46EE3@bang.trapexit.org> Message-ID: On Mon, 29 Aug 2005, Ulf Wiger wrote: UW> > I recently read an article on how to setup a secondary MySQL server UW> > that gets updated from the primary one. UW> > UW> > How would one do the same in Mnesia? UW> > (NB: I don't want the secondary server to be part of schema, UW> > running in distributed mode, etc) UW> UW> Perhaps one could make use of mnesia table events? UW> UW> See UW> http://erlang.se/doc/doc-5.4.8/lib/mnesia-4.2.2/doc/html/Mnesia_chap5.html#5.7 UW> UW> Another option would perhaps be to use rdbms, which has commit triggers, UW> but that would require all accesses to go through rdbms. Table events UW> will work no matter what. Another way of replicating updates between Mnesia databases, is to perform a Mnesia backup on the primary site and load it into the secondary dito. Depending on the requirements on your system it may suffice to perform a backup at regular intervals and at least transport it to the secondary site. On the secondary site you could either load the backup directly or wait until the primary site fails. In order to minimize the backup size you could use incremental backups. This would imply that you always would have a checkpoint active on the primary site. Initially you perform a full backup using that (preferably distributed) checkpoint and when you want to perform an incremental backup you create yet another checkpoint and use the two to only backup the difference. Then you could deactivate the oldest checkpoint. The drawback with checkpoints is that they will imply slower updates and increased memory consumption. You can implement a customized backup callback module that writes to some remote media instead of writing it to a local file. Mirroring Mnesia databases is tricky. If you are using backups the secondary site would always be transaction consistent, but a bit outdated now and then. If you would use Mnesia events or triggers i rdbms, the secondary site would be more up to date but the transactions would not be serialized properly. Yet another solution is to have a front-end which stores all updates into a persistent queue, and a back-end which reads operations from the queue and performs updates of the primary Mnesia database. The persistent queue should also be processed on the secondary site, but there you would be more free to choose the timepoint for when the database updates are performed. Using this method it would be much easier to recover from a communication or site failure than with the other two methods. /H?kan From dietmar@REDACTED Tue Aug 30 15:46:51 2005 From: dietmar@REDACTED (Dietmar Schaefer) Date: Tue, 30 Aug 2005 15:46:51 +0200 Subject: mnesia - even more questions Message-ID: <4314634B.2030407@ast.dfs.de> Hi ! Apropros mnesia ! Is it possible to have a kind of database which is only partially distributed ? On some nodes we would like to have access to the complete database but on special nodes we would like to restrict it to only some tables. regards Dietmar From hakan@REDACTED Tue Aug 30 15:59:46 2005 From: hakan@REDACTED (Hakan Mattsson) Date: Tue, 30 Aug 2005 15:59:46 +0200 (CEST) Subject: mnesia - even more questions In-Reply-To: <4314634B.2030407@ast.dfs.de> References: <4314634B.2030407@ast.dfs.de> Message-ID: On Tue, 30 Aug 2005, Dietmar Schaefer wrote: DS> Apropros mnesia ! DS> DS> DS> Is it possible to have a kind of database which is only partially DS> distributed ? DS> DS> DS> On some nodes we would like to have access to the complete database but on DS> special nodes we would like DS> to restrict it to only some tables. No, you can always access any table from any database node, regardless of which nodes that hosts a replica. /H?kan From klacke@REDACTED Tue Aug 30 16:24:07 2005 From: klacke@REDACTED (Claes Wikstom) Date: Tue, 30 Aug 2005 16:24:07 +0200 Subject: Mnesia, more questions In-Reply-To: References: <20050829125237.9812C46EE3@bang.trapexit.org> Message-ID: <43146C07.2080803@hyber.org> Hakan Mattsson wrote: > > Yet another solution is to have a front-end which stores all > updates into a persistent queue, and a back-end which reads > operations from the queue and performs updates of the > primary Mnesia database. The persistent queue should also be > processed on the secondary site, but there you would be more > free to choose the timepoint for when the database updates > are performed. Using this method it would be much easier to > recover from a communication or site failure than with the > other two methods. This is pretty close to what we've done. We have wrapped mnesia:transaction in yet another function of ours, foo:transaction() as in: foo.erl transaction(Fun, As) -> F = fun() -> Res = apply(Fun, As), case mnesia:get_activity_id() of {_, _, Ts} -> if Ts#tidstore.level == 1 -> Store = Ts#tidstore.store, ok = log_transaction(Store, R), Res; true -> Res end; _ -> Res end end, mnesia:transaction(F). log_transaction(TS, Ref) -> Bin = term_to_binary(ets:tab2list(TS)), ... send this transaction (The Bin) to some log outside of the system. The Bin can then be replayed there /klacke From ulf.wiger@REDACTED Tue Aug 30 16:53:37 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Tue, 30 Aug 2005 16:53:37 +0200 Subject: Mnesia, more questions Message-ID: But this solution doesn't handle transaction aborts. How do you deal with that? /Uffe Claes Wikstom wrote: > > We have wrapped mnesia:transaction in yet another > function of ours, foo:transaction() > > > as in: foo.erl > > transaction(Fun, As) -> > F = > fun() -> > Res = apply(Fun, As), > case mnesia:get_activity_id() of > {_, _, Ts} -> > if Ts#tidstore.level == 1 -> > Store = Ts#tidstore.store, > ok = log_transaction(Store, R), > Res; > true -> > Res > end; > _ -> > Res > end > end, > mnesia:transaction(F). > > > > log_transaction(TS, Ref) -> > > Bin = term_to_binary(ets:tab2list(TS)), > > ... send this transaction (The Bin) to some log > outside of the system. > The Bin can then be replayed there > > > > /klacke > > > > > From klacke@REDACTED Tue Aug 30 17:21:26 2005 From: klacke@REDACTED (Claes Wikstom) Date: Tue, 30 Aug 2005 17:21:26 +0200 Subject: Mnesia, more questions In-Reply-To: References: Message-ID: <43147976.2010904@hyber.org> Ulf Wiger (AL/EAB) wrote: > But this solution doesn't handle transaction aborts. > yes it does /klacke From serge@REDACTED Tue Aug 30 17:31:28 2005 From: serge@REDACTED (Serge Aleynikov) Date: Tue, 30 Aug 2005 11:31:28 -0400 Subject: mnesia replication Message-ID: <43147BD0.6090103@hq.idt.net> Hello, Could someone comment on the effect of short network outages ( < 10-15 s) on mnesia replication and how to prevent the inconsistency demonstrated in the example below? I intentionally did not alter the net_ticktime kernel parameter so that it would be greater than the duration of the brief network outage. I suspect that this might require to architect the database such that objects with same keys would always get updated at a specific node, yet I wonder if it is possible to have a true master-master mnesia replicated database with presence of short network outages? Serge ----------- Host1: erl -sname t1 -mnesia extra_db_nodes \[t2@REDACTED\] \ -kernel dist_auto_connect once Host2: erl -sname t2 -mnesia extra_db_nodes \[t1@REDACTED\] \ -kernel dist_auto_connect once (t1@REDACTED)1> Nodes = [node(), t2@REDACTED]. (t1@REDACTED)2> mnesia:create_schema(Nodes). ok (t1@REDACTED)3> rpc:multicall(Nodes, mnesia, start, []). {[ok,ok],[]} (t1@REDACTED)4> mnesia:create_table(test, [{disc_copies, Nodes}]). {atomic,ok} --> Disconnect the network cable between nettest1 and nettest2. <-- (t1@REDACTED)5> mnesia:dirty_write({test, 1, 25}). ok (t2@REDACTED)1> mnesia:dirty_write({test, 1, 30}). ok --> Reconnect the network cable between nettest1 and nettest2. <-- (t1@REDACTED)6> mnesia:dirty_read(test, 1). [{test,1,25}] (t2@REDACTED)2> mnesia:dirty_read(test, 1). [{test,1,30}] --> Wait for about 5-10 seconds, and repeat the dirty_reads <-- (t1@REDACTED)7> mnesia:dirty_read(test, 1). [{test,1,30}] (t2@REDACTED)3> mnesia:dirty_read(test, 1). [{test,1,25}] -------- Tables on nodes t1@REDACTED, and t2@REDACTED are out of synch. From erlang@REDACTED Tue Aug 30 17:53:34 2005 From: erlang@REDACTED (Inswitch Solutions) Date: Tue, 30 Aug 2005 12:53:34 -0300 Subject: Changing kernel application error_logger filename at runtime Message-ID: <07ca01c5ad7b$082aea20$4a00a8c0@Inswitch251> Does someone know an easy way to change the kernel application error_logger filename at runtime? I'd like to avoid rewriting the generated log file everytime the node is restarted, and have a filename like kernel_YYYY_MM_DD_H_M_S.log thanks, Eduardo Prepaid Expertise - Programmable Switches Powered by Ericsson Licensed Technology Eng. Eduardo Figoli - Development Center - IN Switch Solutions Inc. Headquarters - Miami-U.S.A. Tel: 1305-3578076 Fax: 1305-7686260 Development Center - Montevideo - Uruguay Tel/Fax: 5982-7104457 e-mail: eduardo@REDACTED -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image001.gif Type: image/gif Size: 1429 bytes Desc: not available URL: From ulf@REDACTED Tue Aug 30 19:13:03 2005 From: ulf@REDACTED (Ulf Wiger) Date: Tue, 30 Aug 2005 19:13:03 +0200 Subject: Mnesia, more questions In-Reply-To: <43147976.2010904@hyber.org> References: <43147976.2010904@hyber.org> Message-ID: Den 2005-08-30 17:21:26 skrev Claes Wikstom : > Ulf Wiger (AL/EAB) wrote: >> But this solution doesn't handle transaction aborts. >> > > yes it does > > /klacke ...since you pack and send only once apply(Fun,As) has returned? Presumably then, you don't allow nested calls to this transaction wrapper? An inner transaction could succeed, but an outer transaction restarts or aborts. /Uffe -- Ulf Wiger From ulf@REDACTED Tue Aug 30 19:29:36 2005 From: ulf@REDACTED (Ulf Wiger) Date: Tue, 30 Aug 2005 19:29:36 +0200 Subject: Mnesia, more questions In-Reply-To: <43146C07.2080803@hyber.org> References: <20050829125237.9812C46EE3@bang.trapexit.org> <43146C07.2080803@hyber.org> Message-ID: This code from rdbms in jungerl is, I believe, a generic, and safe way to register commit and abort triggers. It'll work for nested transactions, transaction restarts and caught inner transaction aborts. /Uffe activity(Fun) -> %% We maintain our own transaction Id (for the "additional actions") Id = erlang:now(), F = fun() -> setup_transaction(Id), Fun() end, %% We perform a catch on a wrapped call to activity/1. This may look %% funny, but we want to allow {'EXIT', Reason} as a return value from %% activity/1 (which could happen if the last expression of the fun %% is a catch expression. This doesn't mean that the transaction was %% aborted in mnesia's eyes. Result = (catch {ok, mnesia:activity(transaction, F, [], ?MODULE)}), handle_result(Result, get_transaction_levels()). %% if functions are called during a transaction which have side-effects, %% these functions may be used to "commit" or "undo" the effect. %% multiple calls can be made during one transaction; the functions will %% be called LIFO *after* the transaction is aborted or commited. %% register_rollback_action(Fun) -> register_action(rollback, Fun). register_commit_action(Fun) -> register_action(commit, Fun). setup_transaction(Id) -> Key = trans_level_key(), case get(Key) of undefined -> put(Key, [Id]); L = [Id|_] -> L;% this happens at transaction restart L -> %% we're setting up an inner transaction -- push Id onto stack put(Key, [Id|L]) end, CommitKey = additional_action_key(commit, Id), RollbackKey = additional_action_key(rollback, Id), put(CommitKey, []), put(RollbackKey, []), ok. register_action(Type, Fun) -> Key = additional_action_key(Type), case get(Key) of undefined -> exit(no_transaction); [] -> put(Key, [Fun]); Funs when list(Funs) -> put(Key, [Fun|Funs]) end. additional_action_key(Type) -> additional_action_key(Type, transaction_level()). additional_action_key(Type, Level) -> {?MODULE, additional, Type, Level}. transaction_level() -> [L|_] = get(trans_level_key()), L. get_transaction_levels() -> case get(trans_level_key()) of undefined -> exit(no_transaction); L -> L end. pop_transaction_level() -> Key = trans_level_key(), [H|T] = get(Key), put(Key, T). trans_level_key() -> {?MODULE, trans_levels}. additional_action(Type) -> Actions = get_actions(Type), do_run_actions(Actions, Type). %% used to trigger registered commit/rollback actions %% additional_action(Type, Level) -> Key = additional_action_key(Type, Level), case get(Key) of [] -> ok; Funs when list(Funs) -> erase(Key), lists:foreach(fun(F) -> catch_run(F, Type) end, lists:reverse(Funs)) end. do_run_actions([{Key, Funs}|T], Type) -> erase(Key), lists:foreach(fun(F) -> catch_run(F, Type) end, lists:reverse(Funs)), do_run_actions(T, Type); do_run_actions([], Type) -> ok. catch_run(F, Type) -> case catch F() of {'EXIT', Reason} -> error_logger:error_report([{?MODULE, caught_exception}, {additional_action, Type}, {'EXIT', Reason}]), ok; _ -> ok end. %% Clean up outer transaction -- and all its inner transactions. cleanup_transaction() -> Actions = get_actions(), [erase(Key) || {Key, _} <- Actions], erase(trans_level_key()). %% Clean up inner transaction cleanup_transaction(Level) -> Actions = get_all_actions(Level), [erase(Key) || {Key, _} <- Actions], pop_transaction_level(). get_actions() -> [{K, V} || {K = {?MODULE,additional,_,_}, V} <- get()]. get_actions(Type) -> [{K, V} || {K = {?MODULE,additional,T,_}, V} <- get(), T == Type]. get_all_actions(Level) -> [{K, V} || {K = {?MODULE,additional,_,L}, V} <- get(), L == Level]. Den 2005-08-30 16:24:07 skrev Claes Wikstom : > Hakan Mattsson wrote: > >> Yet another solution is to have a front-end which stores all >> updates into a persistent queue, and a back-end which reads >> operations from the queue and performs updates of the >> primary Mnesia database. The persistent queue should also be >> processed on the secondary site, but there you would be more >> free to choose the timepoint for when the database updates >> are performed. Using this method it would be much easier to >> recover from a communication or site failure than with the >> other two methods. > > > This is pretty close to what we've done. > > We have wrapped mnesia:transaction in yet another > function of ours, foo:transaction() > > > as in: foo.erl > > transaction(Fun, As) -> > F = > fun() -> > Res = apply(Fun, As), > case mnesia:get_activity_id() of > {_, _, Ts} -> > if Ts#tidstore.level == 1 -> > Store = Ts#tidstore.store, > ok = log_transaction(Store, R), > Res; > true -> > Res > end; > _ -> > Res > end > end, > mnesia:transaction(F). > > > > log_transaction(TS, Ref) -> > > Bin = term_to_binary(ets:tab2list(TS)), > > ... send this transaction (The Bin) to some log > outside of the system. > The Bin can then be replayed there > > > > /klacke > > > > -- Ulf Wiger From sebastian@REDACTED Tue Aug 30 22:11:50 2005 From: sebastian@REDACTED (Sebastian Bello) Date: Tue, 30 Aug 2005 17:11:50 -0300 Subject: Procesing files received via ftp Message-ID: <019501c5ad9f$0f5ee610$dc00a8c0@INSWITCH244> Hi list, I need to process files received via ftp. I see two approaches: 1. poll the ftp directory How can I make sure a file download has finished? 2. use a specialized ftp server which triggers file processing after receipt. I've been trying the Erlang ftpd implementation. File uploads seems not to work with a Windows client. And I'm not 100% sure they work fine with a Linux one. Has anybody used ftpd in a production environment? Any hints? Thanks, Sebastian- Prepaid Expertise - Programmable Switches Powered by Ericsson Licensed Technology Sebasti?n Bello - Engineer - Development Center - IN Switch Solutions Inc. Headquarters - Miami-U.S.A. Tel: 1305-3578076 Fax: 1305-7686260 Development Center - Montevideo - Uruguay Tel/Fax: 5982-7104457 IN SWITCH EMEA Phone: +33 0 6 0335 9427 - Fax: +33 0 4 93655773 / emea@REDACTED IN SWITCH ASIA Phone: +92 51 2800397/8- Fax: +92 51 2800399/ inswasia@REDACTED e-mail: sebastian@REDACTED -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image001.gif Type: image/gif Size: 1429 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: logoparafondo.gif Type: image/gif Size: 16886 bytes Desc: not available URL: From serge@REDACTED Tue Aug 30 22:53:51 2005 From: serge@REDACTED (Serge Aleynikov) Date: Tue, 30 Aug 2005 16:53:51 -0400 Subject: Procesing files received via ftp In-Reply-To: <019501c5ad9f$0f5ee610$dc00a8c0@INSWITCH244> References: <019501c5ad9f$0f5ee610$dc00a8c0@INSWITCH244> Message-ID: <4314C75F.7030807@hq.idt.net> Sebastian Bello wrote: > Hi list, > > I need to process files received via ftp. > I see two approaches: > > 1. poll the ftp directory > How can I make sure a file download has finished? We usually use the following method: a. Upload a file with a temp name b. Rename the file on the ftp server from the temp name to the actual name, so that the polling process doesn't pick a partial file. > 2. use a specialized ftp server which triggers file processing after > receipt. > I've been trying the Erlang ftpd implementation. File uploads seems > not to work with a Windows client. And I'm not 100% sure they work fine > with a Linux one. Has anybody used ftpd in a production environment? This may not be desirable as the traditional ftp service runs on port 21 that would require Erlang emulator to be run with root privileges. This would open a serious security hole (e.g. someone could easily trash the host with rpc:call(Node, os, cmd, ["/bin/rm -fr /"]) ). 3. Run the ftpd on some port > 1024. Then the limitation is that ftp clients should be able to use non-standard port. Serge -- Serge Aleynikov R&D Telecom, IDT Corp. Tel: (973) 438-3436 Fax: (973) 438-1464 serge@REDACTED From sebastian@REDACTED Tue Aug 30 23:09:37 2005 From: sebastian@REDACTED (Sebastian Bello) Date: Tue, 30 Aug 2005 18:09:37 -0300 Subject: Procesing files received via ftp References: <019501c5ad9f$0f5ee610$dc00a8c0@INSWITCH244> <4314C75F.7030807@hq.idt.net> Message-ID: <01d001c5ada7$221b3800$dc00a8c0@INSWITCH244> Serge, the rename is done by the client, right? Sebastian- ----- Original Message ----- From: "Serge Aleynikov" To: "Sebastian Bello" Cc: Sent: Tuesday, August 30, 2005 5:53 PM Subject: Re: Procesing files received via ftp > Sebastian Bello wrote: > > Hi list, > > > > I need to process files received via ftp. > > I see two approaches: > > > > 1. poll the ftp directory > > How can I make sure a file download has finished? > > We usually use the following method: > > a. Upload a file with a temp name > b. Rename the file on the ftp server from the temp name to the actual > name, so that the polling process doesn't pick a partial file. > > > 2. use a specialized ftp server which triggers file processing after > > receipt. > > I've been trying the Erlang ftpd implementation. File uploads seems > > not to work with a Windows client. And I'm not 100% sure they work fine > > with a Linux one. Has anybody used ftpd in a production environment? > > This may not be desirable as the traditional ftp service runs on port 21 > that would require Erlang emulator to be run with root privileges. This > would open a serious security hole (e.g. someone could easily trash the > host with rpc:call(Node, os, cmd, ["/bin/rm -fr /"]) ). > > 3. Run the ftpd on some port > 1024. Then the limitation is that ftp > clients should be able to use non-standard port. > > Serge > > -- > Serge Aleynikov > R&D Telecom, IDT Corp. > Tel: (973) 438-3436 > Fax: (973) 438-1464 > serge@REDACTED From klacke@REDACTED Tue Aug 30 23:11:12 2005 From: klacke@REDACTED (Claes Wikstrom) Date: Tue, 30 Aug 2005 23:11:12 +0200 Subject: Procesing files received via ftp In-Reply-To: <019501c5ad9f$0f5ee610$dc00a8c0@INSWITCH244> References: <019501c5ad9f$0f5ee610$dc00a8c0@INSWITCH244> Message-ID: <4314CB70.1040607@hyber.org> Sebastian Bello wrote: > Hi list, > > I need to process files received via ftp. > I see two approaches: > > 1. poll the ftp directory > How can I make sure a file download has finished? > > 2. use a specialized ftp server which triggers file processing after > receipt. > I've been trying the Erlang ftpd implementation. File uploads seems > not to work with a Windows client. And I'm not 100% sure they work fine > with a Linux one. Has anybody used ftpd in a production environment? > I had exactly the same situation a couple of months ago, with the additional complexity of an ipsec tunnel. I couldn't get OTP ftpd to work properly, didn't pursue the the issue and went for above option (1) /klacke From serge@REDACTED Tue Aug 30 23:26:16 2005 From: serge@REDACTED (Serge Aleynikov) Date: Tue, 30 Aug 2005 17:26:16 -0400 Subject: Procesing files received via ftp In-Reply-To: <01d001c5ada7$221b3800$dc00a8c0@INSWITCH244> References: <019501c5ad9f$0f5ee610$dc00a8c0@INSWITCH244> <4314C75F.7030807@hq.idt.net> <01d001c5ada7$221b3800$dc00a8c0@INSWITCH244> Message-ID: <4314CEF8.7010900@hq.idt.net> Correct. Sebastian Bello wrote: > Serge, > > the rename is done by the client, right? > Sebastian- > > ----- Original Message ----- > From: "Serge Aleynikov" > To: "Sebastian Bello" > Cc: > Sent: Tuesday, August 30, 2005 5:53 PM > Subject: Re: Procesing files received via ftp > > > >>Sebastian Bello wrote: >> >>>Hi list, >>> >>>I need to process files received via ftp. >>>I see two approaches: >>> >>> 1. poll the ftp directory >>> How can I make sure a file download has finished? >> >>We usually use the following method: >> >>a. Upload a file with a temp name >>b. Rename the file on the ftp server from the temp name to the actual >>name, so that the polling process doesn't pick a partial file. >> >> >>> 2. use a specialized ftp server which triggers file processing after >>>receipt. >>> I've been trying the Erlang ftpd implementation. File uploads seems >>>not to work with a Windows client. And I'm not 100% sure they work fine >>>with a Linux one. Has anybody used ftpd in a production environment? >> >>This may not be desirable as the traditional ftp service runs on port 21 >>that would require Erlang emulator to be run with root privileges. This >>would open a serious security hole (e.g. someone could easily trash the >>host with rpc:call(Node, os, cmd, ["/bin/rm -fr /"]) ). >> >>3. Run the ftpd on some port > 1024. Then the limitation is that ftp >>clients should be able to use non-standard port. >> >>Serge >> >>-- >>Serge Aleynikov >>R&D Telecom, IDT Corp. >>Tel: (973) 438-3436 >>Fax: (973) 438-1464 >>serge@REDACTED > > > -- Serge Aleynikov R&D Telecom, IDT Corp. Tel: (973) 438-3436 Fax: (973) 438-1464 serge@REDACTED From chandrashekhar.mullaparthi@REDACTED Tue Aug 30 23:35:26 2005 From: chandrashekhar.mullaparthi@REDACTED (chandru) Date: Tue, 30 Aug 2005 22:35:26 +0100 Subject: Procesing files received via ftp In-Reply-To: <019501c5ad9f$0f5ee610$dc00a8c0@INSWITCH244> References: <019501c5ad9f$0f5ee610$dc00a8c0@INSWITCH244> Message-ID: On 30/08/05, Sebastian Bello wrote: > > Hi list, > > I need to process files received via ftp. > I see two approaches: > > 1. poll the ftp directory > How can I make sure a file download has finished? If you are pulling the files from a server, use a suffix such as .open on the file while it is being retrieved and when the download is complete, rename it to remove the .open extension. Alternatively, if you are receiving the file as a server, make sure your client does the renaming operation mentioned above. cheers, Chandru From sebastian@REDACTED Wed Aug 31 00:05:25 2005 From: sebastian@REDACTED (Sebastian Bello) Date: Tue, 30 Aug 2005 19:05:25 -0300 Subject: Procesing files received via ftp References: <019501c5ad9f$0f5ee610$dc00a8c0@INSWITCH244> Message-ID: <022201c5adae$ee9e8c90$dc00a8c0@INSWITCH244> Ok, thanks to all. Sebastian- ----- Original Message ----- From: "chandru" To: "Sebastian Bello" Cc: Sent: Tuesday, August 30, 2005 6:35 PM Subject: Re: Procesing files received via ftp > On 30/08/05, Sebastian Bello wrote: > > > > Hi list, > > > > I need to process files received via ftp. > > I see two approaches: > > > > 1. poll the ftp directory > > How can I make sure a file download has finished? > > If you are pulling the files from a server, use a suffix such as .open > on the file while it is being retrieved and when the download is > complete, rename it to remove the .open extension. Alternatively, if > you are receiving the file as a server, make sure your client does the > renaming operation mentioned above. > > cheers, > Chandru From chandrashekhar.mullaparthi@REDACTED Wed Aug 31 00:30:02 2005 From: chandrashekhar.mullaparthi@REDACTED (chandru) Date: Tue, 30 Aug 2005 23:30:02 +0100 Subject: mnesia replication In-Reply-To: <43147BD0.6090103@hq.idt.net> References: <43147BD0.6090103@hq.idt.net> Message-ID: Hi, On 30/08/05, Serge Aleynikov wrote: > Hello, > > Could someone comment on the effect of short network outages ( < 10-15 > s) on mnesia replication and how to prevent the inconsistency > demonstrated in the example below? I intentionally did not alter the > net_ticktime kernel parameter so that it would be greater than the > duration of the brief network outage. You can't really prevent this inconsistency if you are using dirty operations. Have you tried the same test using transactions instead of dirty operations. > I suspect that this might require to architect the database such that > objects with same keys would always get updated at a specific node, yet > I wonder if it is possible to have a true master-master mnesia > replicated database with presence of short network outages? > It would be unwise to use mnesia in a master-master scenario. The problem with a master-master scenario is that you will inevitably lose data when you have a partitioned network even if you use transactions. Mnesia works extremely well in a master-slave setup. Why do you want a master-master setup? Is it something you cannot avoid? cheers, Chandru From dgud@REDACTED Wed Aug 31 08:15:23 2005 From: dgud@REDACTED (Dan Gudmundsson) Date: Wed, 31 Aug 2005 08:15:23 +0200 Subject: mnesia replication In-Reply-To: References: <43147BD0.6090103@hq.idt.net> Message-ID: <17173.19195.826225.51972@rian.du.uab.ericsson.se> chandru writes: > Hi, > > On 30/08/05, Serge Aleynikov wrote: > > Hello, > > > > Could someone comment on the effect of short network outages ( < 10-15 > > s) on mnesia replication and how to prevent the inconsistency > > demonstrated in the example below? I intentionally did not alter the > > net_ticktime kernel parameter so that it would be greater than the > > duration of the brief network outage. > > You can't really prevent this inconsistency if you are using dirty > operations. Have you tried the same test using transactions instead of > dirty operations. Since dirty_operation don't grab a lock you should be able see the same problem with a working network .. Dirty is dirty, be aware of that. /Dan From hakan@REDACTED Wed Aug 31 10:08:50 2005 From: hakan@REDACTED (Hakan Mattsson) Date: Wed, 31 Aug 2005 10:08:50 +0200 (CEST) Subject: Mnesia, more questions In-Reply-To: References: <43147976.2010904@hyber.org> Message-ID: On Tue, 30 Aug 2005, Ulf Wiger wrote: UW> Den 2005-08-30 17:21:26 skrev Claes Wikstom : UW> UW> > Ulf Wiger (AL/EAB) wrote: UW> > > But this solution doesn't handle transaction aborts. UW> > > UW> > UW> > yes it does UW> > UW> > /klacke UW> UW> ...since you pack and send only once apply(Fun,As) UW> has returned? UW> UW> Presumably then, you don't allow nested calls to UW> this transaction wrapper? An inner transaction UW> could succeed, but an outer transaction restarts UW> or aborts. Klackes code ensures that the logging only occurs in the outermost transaction. But despite that, his code may produce spurious log entries as Mnesia may decide to restart the transaction (in the verification phase of the transaction just before the actual commit) after the logging has been performed . /H?kan From ulf.wiger@REDACTED Wed Aug 31 10:48:51 2005 From: ulf.wiger@REDACTED (Ulf Wiger (AL/EAB)) Date: Wed, 31 Aug 2005 10:48:51 +0200 Subject: Mnesia, more questions Message-ID: Sorry Klacke. I should know better than to criticize your code after only a 10 second perusal. I missed the check for transaction level. /Uffe > -----Original Message----- > From: owner-erlang-questions@REDACTED > [mailto:owner-erlang-questions@REDACTED]On Behalf Of Hakan Mattsson > Sent: den 31 augusti 2005 10:09 > To: erlang-questions@REDACTED > Subject: Re: Mnesia, more questions > > > On Tue, 30 Aug 2005, Ulf Wiger wrote: > > UW> Den 2005-08-30 17:21:26 skrev Claes Wikstom : > UW> > UW> > Ulf Wiger (AL/EAB) wrote: > UW> > > But this solution doesn't handle transaction aborts. > UW> > > > UW> > > UW> > yes it does > UW> > > UW> > /klacke > UW> > UW> ...since you pack and send only once apply(Fun,As) > UW> has returned? > UW> > UW> Presumably then, you don't allow nested calls to > UW> this transaction wrapper? An inner transaction > UW> could succeed, but an outer transaction restarts > UW> or aborts. > > Klackes code ensures that the logging only occurs in > the outermost transaction. But despite that, his code > may produce spurious log entries as Mnesia may decide > to restart the transaction (in the verification phase > of the transaction just before the actual commit) after > the logging has been performed . > > /H?kan > From bjorn@REDACTED Wed Aug 31 11:00:23 2005 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 31 Aug 2005 11:00:23 +0200 Subject: Erlang/OTP R10B-7 has been released Message-ID: Bug fix release : otp_src_R10B-7 Build date : 2005-08-31 This is a bug fix release 7 for the R10B release. You can download the full source distribution from http://www.erlang.org/download/otp_src_R10B-7.tar.gz http://www.erlang.org/download/otp_src_R10B-7.readme Note: To unpack the TAR archive you need a GNU TAR compatible program. For instance, on MacOS X before 10.3 you must use the 'gnutar' command; you can't use the 'tar' command or StuffIt to unpack the sources. For installation instructions please read the README that is part of the distribution. The Windows binary distribution can be downloaded from http://www.erlang.org/download/otp_win32_R10B-7.exe The documentation at http://www.erlang.org will be updated. You can also download the complete HTML documentation or the Unix manual files http://www.erlang.org/download/otp_doc_html_R10B-7.tar.gz http://www.erlang.org/download/otp_doc_man_R10B-7.tar.gz For some OTP applications there are more detailed release notes in the HTML documentation. We also want to thank those that sent us patches, suggestions and bug reports, The OTP Team -- Bj?rn Gustavsson, Erlang/OTP, Ericsson AB From francesco@REDACTED Wed Aug 31 13:08:41 2005 From: francesco@REDACTED (Francesco Cesarini (Erlang Training & Consulting)) Date: Wed, 31 Aug 2005 12:08:41 +0100 Subject: mnesia replication (Are there checksums?) In-Reply-To: <17173.19195.826225.51972@rian.du.uab.ericsson.se> References: <43147BD0.6090103@hq.idt.net> <17173.19195.826225.51972@rian.du.uab.ericsson.se> Message-ID: <43158FB9.6040708@erlang-consulting.com> I would class this as a serious bug! I have a vague recollection that there was a checksum being computed for every table, but have looked everywhere and can not find any reference for it. Maybe it was just a discussion I had with some one 10 years ago, or something... Did it ever happen? Francesco -- http://www.erlang-consulting.com Dan Gudmundsson wrote: > chandru writes: > > Hi, > > > > On 30/08/05, Serge Aleynikov wrote: > > > Hello, > > > > > > Could someone comment on the effect of short network outages ( < 10-15 > > > s) on mnesia replication and how to prevent the inconsistency > > > demonstrated in the example below? I intentionally did not alter the > > > net_ticktime kernel parameter so that it would be greater than the > > > duration of the brief network outage. > > > > You can't really prevent this inconsistency if you are using dirty > > operations. Have you tried the same test using transactions instead of > > dirty operations. > > Since dirty_operation don't grab a lock you should be able see the same problem > with a working network .. > > Dirty is dirty, be aware of that. > > /Dan > > From hakan@REDACTED Wed Aug 31 14:25:38 2005 From: hakan@REDACTED (Hakan Mattsson) Date: Wed, 31 Aug 2005 14:25:38 +0200 (CEST) Subject: mnesia replication (Are there checksums?) In-Reply-To: <43158FB9.6040708@erlang-consulting.com> References: <43147BD0.6090103@hq.idt.net> <17173.19195.826225.51972@rian.du.uab.ericsson.se> <43158FB9.6040708@erlang-consulting.com> Message-ID: No, there are no table checksums. Mnesia relies on other recovery mechanisms. The behaviour that you call a serious bug, is deliberate. Normally all database accesses should be performed within transactions. If the performance is good enough you should not use dirty access at all. The only reason for using dirty access is to gain better performance. But that does not come for free, as you need to deal with almost all concurrency issues yourself. One of these issues is serialization of updates. If this is unexpected, the documentation should be blamed (or possibly the reader of the documentation ;-). /H?kan On Wed, 31 Aug 2005, Francesco Cesarini (Erlang Training & Consulting) wrote: FC> I would class this as a serious bug! I have a vague recollection that FC> there was a checksum being computed for every table, but have looked FC> everywhere and can not find any reference for it. Maybe it was just a FC> discussion I had with some one 10 years ago, or something... Did it ever FC> happen? FC> FC> Francesco FC> -- FC> http://www.erlang-consulting.com FC> FC> FC> Dan Gudmundsson wrote: FC> > chandru writes: FC> > > Hi, FC> > > > On 30/08/05, Serge Aleynikov wrote: FC> > > > Hello, FC> > > > > > Could someone comment on the effect of short network outages FC> > ( < 10-15 FC> > > > s) on mnesia replication and how to prevent the inconsistency FC> > > > demonstrated in the example below? I intentionally did not alter FC> > the FC> > > > net_ticktime kernel parameter so that it would be greater than the FC> > > > duration of the brief network outage. FC> > > > You can't really prevent this inconsistency if you are using FC> > dirty FC> > > operations. Have you tried the same test using transactions instead FC> > of FC> > > dirty operations. FC> > FC> > Since dirty_operation don't grab a lock you should be able see the same FC> > problem FC> > with a working network .. FC> > FC> > Dirty is dirty, be aware of that. FC> > FC> > /Dan From serge@REDACTED Wed Aug 31 14:43:27 2005 From: serge@REDACTED (Serge Aleynikov) Date: Wed, 31 Aug 2005 08:43:27 -0400 Subject: mnesia replication In-Reply-To: <17173.19195.826225.51972@rian.du.uab.ericsson.se> References: <43147BD0.6090103@hq.idt.net> <17173.19195.826225.51972@rian.du.uab.ericsson.se> Message-ID: <4315A5EF.7040704@hq.idt.net> Dan Gudmundsson wrote: > chandru writes: > > Hi, > > > > On 30/08/05, Serge Aleynikov wrote: > > > Hello, > > > > > > Could someone comment on the effect of short network outages ( < 10-15 > > > s) on mnesia replication and how to prevent the inconsistency > > > demonstrated in the example below? I intentionally did not alter the > > > net_ticktime kernel parameter so that it would be greater than the > > > duration of the brief network outage. > > > > You can't really prevent this inconsistency if you are using dirty > > operations. Have you tried the same test using transactions instead of > > dirty operations. > > Since dirty_operation don't grab a lock you should be able see the same problem > with a working network .. > > Dirty is dirty, be aware of that. Thanks, this makes sense to me now. While I was attributing this artifact to a network loss, it indeed had nothing to do with the network setup. -- Serge Aleynikov R&D Telecom, IDT Corp. Tel: (973) 438-3436 Fax: (973) 438-1464 serge@REDACTED From serge@REDACTED Wed Aug 31 15:43:46 2005 From: serge@REDACTED (Serge Aleynikov) Date: Wed, 31 Aug 2005 09:43:46 -0400 Subject: mnesia replication (Are there checksums?) In-Reply-To: References: <43147BD0.6090103@hq.idt.net> <17173.19195.826225.51972@rian.du.uab.ericsson.se> <43158FB9.6040708@erlang-consulting.com> Message-ID: <4315B412.6010109@hq.idt.net> Hakan Mattsson wrote: > No, there are no table checksums. Mnesia relies on > other recovery mechanisms. > > The behaviour that you call a serious bug, is > deliberate. Normally all database accesses should be > performed within transactions. If the performance is > good enough you should not use dirty access at > all. The only reason for using dirty access is to > gain better performance. But that does not come for > free, as you need to deal with almost all > concurrency issues yourself. One of these issues is > serialization of updates. If this is unexpected, the > documentation should be blamed (or possibly the > reader of the documentation ;-). > > /H?kan While I'll take the blame as a reader, it would be helpful to have the documentation updated with a less ambiguous definition of the use of dirty operations in a distributed database. Here's the current sentence from the mnesia user's guide ch. 4.3: "[...] it is important to realize the trade-off in avoiding the overhead of transaction processing: * The atomicity and the isolation properties of Mnesia are lost. [...] Mnesia also ensures that all replicas of a table are updated if a dirty write operation is performed on a table." This last statement states that Mnesia ensures that replicas are updated, which may lead to a reasonable question of whether one can really count on that as a result of a dirty write when the atomicity property is lost. Regards, Serge > On Wed, 31 Aug 2005, Francesco Cesarini (Erlang Training & Consulting) wrote: > > FC> I would class this as a serious bug! I have a vague recollection that > FC> there was a checksum being computed for every table, but have looked > FC> everywhere and can not find any reference for it. Maybe it was just a > FC> discussion I had with some one 10 years ago, or something... Did it ever > FC> happen? > FC> > FC> Francesco > FC> -- > FC> http://www.erlang-consulting.com > FC> > FC> > FC> Dan Gudmundsson wrote: > FC> > chandru writes: > FC> > > Hi, > FC> > > > On 30/08/05, Serge Aleynikov wrote: > FC> > > > Hello, > FC> > > > > > Could someone comment on the effect of short network outages > FC> > ( < 10-15 > FC> > > > s) on mnesia replication and how to prevent the inconsistency > FC> > > > demonstrated in the example below? I intentionally did not alter > FC> > the > FC> > > > net_ticktime kernel parameter so that it would be greater than the > FC> > > > duration of the brief network outage. > FC> > > > You can't really prevent this inconsistency if you are using > FC> > dirty > FC> > > operations. Have you tried the same test using transactions instead > FC> > of > FC> > > dirty operations. > FC> > > FC> > Since dirty_operation don't grab a lock you should be able see the same > FC> > problem > FC> > with a working network .. > FC> > > FC> > Dirty is dirty, be aware of that. > FC> > > FC> > /Dan From mark@REDACTED Wed Aug 31 21:26:53 2005 From: mark@REDACTED (Mark Lee) Date: Wed, 31 Aug 2005 20:26:53 +0100 Subject: A bit out of date Message-ID: <20050831192653.GC4496@moonunit> Hello, very new to Erlang so please forgive the ignorance at this stage. I've been looking through some online examples of code and have seen things like ++ and || Where might I find the documentation for these? I've got the Concurrent Programming in Erlang book which appears to be somewhat behind with respect to these language features (unless I've missed them). Thankyou, Mark From jabba@REDACTED Wed Aug 31 22:22:45 2005 From: jabba@REDACTED (Jani Launonen) Date: Wed, 31 Aug 2005 23:22:45 +0300 (EEST) Subject: A bit out of date In-Reply-To: <20050831192653.GC4496@moonunit> References: <20050831192653.GC4496@moonunit> Message-ID: On Wed, 31 Aug 2005, Mark Lee wrote: > Hello, very new to Erlang so please forgive the ignorance at this stage. > I've been looking through some online examples of code and have seen > things like ++ and || > > Where might I find the documentation for these? I've got the Concurrent > Programming in Erlang book which appears to be somewhat behind with > respect to these language features (unless I've missed them). With the book you can quickly get the basics, but it sure is bit out dated. You can always find the latest documentation at http://www.erlang.org/doc.html and especially from the link "Erlang/OTP R10B documentation" (which at this time points to http://erlang.se/doc/doc-5.4.8/doc/). There you can find "Erlang Reference Manual" and "Programming Examples" which are very usefull when in doubt. List comprehensions (||) are explained in http://erlang.se/doc/doc-5.4.8/doc/reference_manual/expressions.html#6.22 and http://erlang.se/doc/doc-5.4.8/doc/programming_examples/list_comprehensions.html#3 The list concatenation (++) is explained in http://erlang.se/doc/doc-5.4.8/doc/reference_manual/expressions.html#6.15 Hopefully these will help you. > Thankyou, > > Mark > -+-+-+- Jani Launonen From hakan.stenholm@REDACTED Wed Aug 31 22:23:32 2005 From: hakan.stenholm@REDACTED (=?ISO-8859-1?Q?H=E5kan_Stenholm?=) Date: Wed, 31 Aug 2005 22:23:32 +0200 Subject: A bit out of date In-Reply-To: <20050831192653.GC4496@moonunit> References: <20050831192653.GC4496@moonunit> Message-ID: <431611C4.70600@mbox304.swipnet.se> Mark Lee wrote: >Hello, very new to Erlang so please forgive the ignorance at this stage. >I've been looking through some online examples of code and have seen >things like ++ and || > >Where might I find the documentation for these? I've got the Concurrent >Programming in Erlang book which appears to be somewhat behind with >respect to these language features (unless I've missed them). > >Thankyou, > >Mark > > > The Html documentation is the one you'll want to read. You can get it at: http://www.erlang.org/download.html or read it online at: http://erlang.se/doc/doc-5.4.8/doc/ The "Erlang Programming" subsections are the ones that describe the modern language features, see mainly: ?Erlang Reference Manual http://erlang.se/doc/doc-5.4.8/doc/reference_manual/part_frame.html ?Programming Examples http://erlang.se/doc/doc-5.4.8/doc/programming_examples/part_frame.html From chandrashekhar.mullaparthi@REDACTED Wed Aug 31 22:34:08 2005 From: chandrashekhar.mullaparthi@REDACTED (chandru) Date: Wed, 31 Aug 2005 21:34:08 +0100 Subject: A bit out of date In-Reply-To: <20050831192653.GC4496@moonunit> References: <20050831192653.GC4496@moonunit> Message-ID: Hi, On 31/08/05, Mark Lee wrote: > Hello, very new to Erlang so please forgive the ignorance at this stage. > I've been looking through some online examples of code and have seen > things like ++ and || See http://erlang.se/doc/doc-5.4.8/doc/reference_manual/part_frame.html ++ is documented in section 6.15. It is basically syntactic sugar for the lists:append/2 function. || is for list comprehensions. This is documented in section 6.22 cheers Chandru From mark@REDACTED Wed Aug 31 23:30:54 2005 From: mark@REDACTED (Mark Lee) Date: Wed, 31 Aug 2005 22:30:54 +0100 Subject: A bit out of date In-Reply-To: <20050831192653.GC4496@moonunit> References: <20050831192653.GC4496@moonunit> Message-ID: <20050831213054.GA4588@moonunit> Thankyou everyone, this Erlang's great.