From matthias@REDACTED Tue Apr 1 08:22:09 2003 From: matthias@REDACTED (Matthias Lang) Date: Tue, 1 Apr 2003 08:22:09 +0200 Subject: FAQ terminology harmonisation Message-ID: <16009.12305.864364.894513@antilipe.corelatus.se> Hi, Recently, there was some confusion on the list about the meaning of "Defensive Programming" in the context of Erlang. For most programmers, defensive programming is a good thing, yet in the Erlang programming guidelines it is considered a bad thing. Therefore I've renamed it to "micro-managed error handling" to make the author's intent clearer. While doing that, I also tackled a number of similar problems: crash: again, in most languages crashing is bad whereas in Erlang it confusingly enough becomes a good thing. The FAQ now refers to such events as "inter-process exceptions (IPEs)" single-assignment: is a very academic term for what most people would call "const" variables. I have coined the replacement term "auto-consting". tail-recursion: very powerful feature. Ridiculously academic name. Now called stack-unrolling. process: thread. An process is very lightweight. The rest of the world refers to lightweight processes as threads. So does the Erlang FAQ from now on. node: process. An Erlang node is always an OS process. So we may as well call a spade a spade. "process" now means "erlang node". behaviour: interface. In R9B-2, the directive '-public(gen_server).' is a synonym for '-behaviour'. In R10, the -behaviour directive will elicit a warning. By R11 an error. list: array. Everyone knows what an array is. Any further suggestions? Matthias From cpressey@REDACTED Tue Apr 1 08:34:23 2003 From: cpressey@REDACTED (Chris Pressey) Date: Tue, 01 Apr 2003 00:34:23 -0600 Subject: Units of measurement in programming languages (was Re: Complexity Shock Horror II: the Sequel) In-Reply-To: <01C2F7DC.2DF175A0.twanvds@xs4all.nl> References: <01C2F7DC.2DF175A0.twanvds@xs4all.nl> Message-ID: <20030401003423.638d0ced.cpressey@catseye.mb.ca> On Mon, 31 Mar 2003 23:20:54 +0200 Twan van der Schoot wrote: > Hi Chris, Hi. > On Monday, March 31, 2003 9:35 PM, Chris Pressey wrote: > > > > Yet, I don't see *any* scalar values in the world around me. They > > *all* have units of measurement. > > I'm sorry, but quite a number of constants in physical are > dimensionless. > And these have a "scalar" nature. OK, I was a bit hasty in making that statement. However, aside from e and phi, I can't think of any popular constants that are purely scalar in nature. Many scalar constants are more like pi, that is, a ratio between two measurements with the same unit (circumference (distance) / diameter (distance).) In any case, because scalar constants are in the minority, and because it's easier to express a scalar as a measurement without units than it is to express a measurement given only scalars, I do think scalars should be the exception to the rule, rather than the default case. > But in a typical programming context, what about an ordinal number > like an index in an array? And just counting of elements in a list? For both of these, the unit of measurement is 'elements'. > Do you want to count the number of elements, like 23_element, or > 23_list, in case that list is comprised of lists? It depends what you're counting. If you have a function that counts the number of elements of a list, it should return a value with a unit of 'elements.' If you have a function that counts the number of lists in a list, it could return a value with a unit of either 'elements' or 'lists.' All this implies to me is that 'lists' are a subunit of 'elements', and consequently, that the structure of the unit system reflects that of the type system. > Besides, one introduces the requirement for a kind of type-system > (i.c. dimension/unit checking and derivation). Yes. This is a *good* thing, IMO, because it catches errors. > For the usual > arithmatical expressions this may be not a problem. But what unit has > a list of, say, metres? Same deal. If you have a function that counts the number of lists of meters in a list, it could return a value with a unit of any of 'elements' or 'lists' or 'lists of meters.' Just like if you had a function which counts the number of cars in a dealership's showroom, it would return a measurement with 'cars' as the unit; if it counted red cars, it could return either 'X cars' or 'X red cars'; etc. Again, just showing that the unit system mirrors the type system. But because Erlang's type system doesn't distinguish between lists of one thing or another, I don't think it necessarily needs this level of detail. For simplicity, all subunits of 'elements' could be omitted. > And the second question then pops up > immediately. Does one want to base such a measurement system on the > structure of the dimension or should it be a level more concrete and > should one use a concrete unit standard (like SI or BSI or ANSI). Both, converting between the two as necessary. Internally, I imagine measurements would be stored like: {20.7, [{kg,1},{m,2},{sec,-2}]} Whereas in the programming language and its I/O, one could say '20.7 joules' as a shorthand for this. > Eventhough it would make doc-hunting less necessary, it is much too > concrete to be "sufficently" generic for a universal programming > langauge. I think that remains to be seen. > BTW: Are you acquainted with the HP48? That nifty calculator allows > you to enter number extended with units and all arthimatic behaves > nice. Yes. That a calculator can do it, goes to show that it's not technically difficult. Yet we're stuck with spreadsheets and programming languages still in the dark ages of being able to confuse meters and feet, because they're all treated as scalars, because that's how we've always done it, because it's been deemed good enough (not unlike those two-digit years that got us into that y2k kerfuffle.) > So, I guess that leaving scalars in favour of "unit objects" is not a > concept for a universal programming language. But I do think it would > be great to have facilities in a programming language which make it > attractive to have a standard library available which lowers the > threshold to implement /applications/ utilising unit objects as the > main representation of a measurement. What these facilities precisely > should be without unduly interference with the basic clarity of the > programming language, I don't know. > > br > > Twan van der Schoot. While that would help for building a spreadsheet (or similar application) that is unit-aware - why stop there? I still think the greatest benefit will only be seen if there is a tight coupling between measurements and the type system and syntax of the programming language itself. -Chris From cpressey@REDACTED Tue Apr 1 08:52:45 2003 From: cpressey@REDACTED (Chris Pressey) Date: Tue, 01 Apr 2003 00:52:45 -0600 Subject: FAQ terminology harmonisation In-Reply-To: <16009.12305.864364.894513@antilipe.corelatus.se> References: <16009.12305.864364.894513@antilipe.corelatus.se> Message-ID: <20030401005245.21fd0dcf.cpressey@catseye.mb.ca> On Tue, 1 Apr 2003 08:22:09 +0200 Matthias Lang wrote: > Hi, > > Recently, there was some confusion on the list about the meaning of > "Defensive Programming" in the context of Erlang. For most > programmers, defensive programming is a good thing, yet in the Erlang > programming guidelines it is considered a bad thing. Therefore I've > renamed it to "micro-managed error handling" to make the author's > intent clearer. That's probably a better way to put it. Re-reading the programming guidelines - they do put "defensive" in quotes. They also stress making code clearer by seperating the error behaviour out. So you could even use the term "micro-managed, inline error handling" to describe the bad stuff. > While doing that, I also tackled a number of similar > problems: > > crash: again, in most languages crashing is bad whereas in Erlang it > confusingly enough becomes a good thing. The FAQ now refers > to such events as "inter-process exceptions (IPEs)" It's never a good thing. It's just that it's non-fatal here, for a change. I'd say "non-fatal crash" and avoid the TLA. > single-assignment: is a very academic term for what most people > would call "const" variables. I have coined the replacement > term "auto-consting". > > tail-recursion: very powerful feature. Ridiculously academic name. > Now called stack-unrolling. These two terms I had come across before I ever encountered Erlang. I see no reason to change them; even if they are academic, they're an accepted part of the parlance. Google for "single assignment": ~15,000 Google for "auto consting": 0 Google for "tail recursion": ~15,000 Google for "stack unrolling": 22 > process: thread. An process is very lightweight. The rest of the > world refers to lightweight processes as threads. So does the > Erlang FAQ from now on. > > node: process. An Erlang node is always an OS process. So we may as > well call a spade a spade. "process" now means "erlang node". In the context of Erlang running under an operating system, OK. In the context of Erlang running in an Erlang distribution, node is still clearer. > behaviour: interface. In R9B-2, the directive '-public(gen_server).' > is a synonym for '-behaviour'. In R10, the -behaviour > directive will elicit a warning. By R11 an error. 'interface' better describes how it actually acts (but what is the reasoning behind '-public'? To me that says next to nothing.) > list: array. Everyone knows what an array is. And people don't know what [linked] lists are? :) > Any further suggestions? > > Matthias > -Chris From bjorn@REDACTED Tue Apr 1 09:03:03 2003 From: bjorn@REDACTED (Bjorn Gustavsson) Date: 01 Apr 2003 09:03:03 +0200 Subject: FAQ terminology harmonisation In-Reply-To: <16009.12305.864364.894513@antilipe.corelatus.se> References: <16009.12305.864364.894513@antilipe.corelatus.se> Message-ID: Matthias Lang writes: > Hi, > [...] > behaviour: interface. In R9B-2, the directive '-public(gen_server).' > is a synonym for '-behaviour'. In R10, the -behaviour > directive will elicit a warning. By R11 an error. > > list: array. Everyone knows what an array is. > > Any further suggestions? Actually, we think that Erlang being a functional language have scared too many programmers, so we plan some radical changes. The most significant change is that using the thread dictionary (formerly known as the "process dictionary"), will no longer be considered bad style. To make the thread dictionary easier to use, we will add syntactic sugar. Thus var := Expr is syntactic sugar for put(var, Expr) and in any expression *var is syntantic sugar for get(var) Although the ':=' is borrowed from Pascal rather than C, we still think that C programmers will pick it up easily enough. Many C programmers have used Turbo Pascal in the past. put/2 and get/1 (or the syntatic sugar versions) will also be allowed to be used in guards to extend the power of pattern matching. We will of course also change the setelement/3 BIF to do a destructive assignment. The syntactic sugar version will be array@REDACTED := Expr The changes will be implemented in the R9D release, planned to be released April 01, 2004. /Bjorn -- Bj?rn Gustavsson Ericsson Utvecklings AB bjorn@REDACTED ?T2/UAB/F/P BOX 1505 +46 8 727 56 87 125 25 ?lvsj? From raimo.niskanen@REDACTED Tue Apr 1 09:09:21 2003 From: raimo.niskanen@REDACTED (Raimo Niskanen) Date: Tue, 01 Apr 2003 09:09:21 +0200 Subject: odd problem with distributed erlang system References: , , Message-ID: What was annoying in this case was that even though I had: -dumped amd and used aufofs instead -forced rwsize an wsize to 8192 -used NFSv3 -mounted "hard,intr" the kernel or the NFS filesystem screwed up the semantics of a write operation (writev in my opinion i just one write operation despite the write buffer being scattered) by not gathering the write data, doing 1024 synchronous write operations instead. The "sync" mount option is the default and the "safe bet". It works just fine with on Solaris, so I would say NFS on Linux is still sometimes a weak spot. This time it punished the Erlang emulator file driver that just wanted to be efficient. Yes, tcpdump is now a friend of mine :-) / Raimo Niskanen, Erlang/OTP Miguel Barreiro Paz wrote: >>It was on Debian 3.0 (Linux 2.4.18 kernel) with OTP R9B and an >>automounted NFS volume. I had lots of problems to make the automounter >>use the mount options I wanted, partly because the automounter I used >>(amd) seems to not use the mount command, but a library API, so when I >>was done I had changed automounters, written some weird scripts, etc. > > > NFS on Linux has traditionally been a weak spot. It's much much better > today. My experience on nfs on linux: > > - dump amd and use autofs instead > - force rsize and wsize to 8192 if autofs doesn't do it for you > - use NFSv3 (yes, it's marked "experimental", but has been in use here for > a _long_ time without worry. Maybe we just were lucky) > - mount "hard" or "hard,intr" > - NFSv3 over TCP is still a little bit unreliable in my humble experience. > - Async mounts are perfectly OK in a LAN for most purposes. > - use jumbo frames if you're on 1000Base-* and hardware allows (1 ether > frame per 8KB NFS datagram is nice) > - tcpdump is your friend, as you already know :-) > > >>The solution was to not mount the volume synchronously, i.e I added the >>mount options: "async,actimeou=0". The "actimeout=0" flag sets attribute >>caching timeout to 0, which is pretty syncronous, and will do for me. > > > Not quite the same as "sync" but good enough unless someone runs a mail > spool or something similarly insane on that fs. > > > From mikael.karlsson@REDACTED Tue Apr 1 09:18:44 2003 From: mikael.karlsson@REDACTED (Mikael Karlsson) Date: Tue, 1 Apr 2003 09:18:44 +0200 Subject: FAQ terminology harmonisation In-Reply-To: <16009.12305.864364.894513@antilipe.corelatus.se> References: <16009.12305.864364.894513@antilipe.corelatus.se> Message-ID: <200304010918.44448.mikael.karlsson@creado.com> Tue 01 april 2003 Matthias Lang wrote: > Hi, ... > process: thread. An process is very lightweight. The rest of the > world refers to lightweight processes as threads. So does the > Erlang FAQ from now on. > .. > Any further suggestions? To me a thread is lightweight, but also share context/memory with other threads. That is not the case for Erlang processes. /Mikael From erlang@REDACTED Tue Apr 1 09:16:23 2003 From: erlang@REDACTED (Peter-Henry Mander) Date: Tue, 01 Apr 2003 08:16:23 +0100 Subject: FAQ terminology harmonisation References: <16009.12305.864364.894513@antilipe.corelatus.se> Message-ID: <3E893CC7.3080806@manderp.freeserve.co.uk> Oh dear, I only just got used to the existing terminology! (-: Matthias Lang wrote: > Hi, > > Recently, there was some confusion on the list about the meaning of > "Defensive Programming" in the context of Erlang. For most > programmers, defensive programming is a good thing, yet in the Erlang > programming guidelines it is considered a bad thing. Therefore I've > renamed it to "micro-managed error handling" to make the author's > intent clearer. While doing that, I also tackled a number of similar > problems: > > crash: again, in most languages crashing is bad whereas in Erlang it > confusingly enough becomes a good thing. The FAQ now refers > to such events as "inter-process exceptions (IPEs)" ... or just call them exceptions, IPE is just another TLA, and besides, should it not be called "inter-thread exceptions" according to what follows? > single-assignment: is a very academic term for what most people > would call "const" variables. I have coined the replacement > term "auto-consting". ... or just const, C++ programmers can relate to this concept. Single-assignment may be an academic term, but it is an exact description. > tail-recursion: very powerful feature. Ridiculously academic name. > Now called stack-unrolling. I agree, stack unrolling describes what is going on here. If only other languages did this, it would make things a lot more legible. It's not difficult to do or understand after all! > process: thread. An process is very lightweight. The rest of the > world refers to lightweight processes as threads. So does the > Erlang FAQ from now on. See above about "inter-process exceptions (tm)" > node: process. An Erlang node is always an OS process. So we may as > well call a spade a spade. "process" now means "erlang node". Hmm... I feel the term "node" is less generic than "process" which is used/abused everywhere, and reusing an existing term for a different meaning can only be confusing. > behaviour: interface. In R9B-2, the directive '-public(gen_server).' > is a synonym for '-behaviour'. In R10, the -behaviour > directive will elicit a warning. By R11 an error. > > list: array. Everyone knows what an array is. Yes, but a list is not an array. For one, Erlang lists don't encourage the use of indexes. And arrays don't lend themselves to [Head|Tail] manipulation in any other language I know. I would personally stick to "list". > Any further suggestions? > > Matthias From enano@REDACTED Tue Apr 1 10:19:45 2003 From: enano@REDACTED (Miguel Barreiro Paz) Date: Tue, 1 Apr 2003 10:19:45 +0200 (CEST) Subject: FAQ terminology harmonisation In-Reply-To: <16009.12305.864364.894513@antilipe.corelatus.se> References: <16009.12305.864364.894513@antilipe.corelatus.se> Message-ID: Ahm... is there a way to tell the erlang.org majordomo to postpone that post until December 28 for us spanish users? :-) From jonathan@REDACTED Tue Apr 1 11:26:55 2003 From: jonathan@REDACTED (Jonathan Coupe) Date: Tue, 1 Apr 2003 10:26:55 +0100 Subject: FAQ terminology harmonisation References: <16009.12305.864364.894513@antilipe.corelatus.se> Message-ID: <000401c2f831$0ec56a60$890bfea9@mimbi> > tail-recursion: very powerful feature. Ridiculously academic name. > Now called stack-unrolling. > > process: thread. An process is very lightweight. The rest of the > world refers to lightweight processes as threads. So does the > Erlang FAQ from now on. Doesn't the argument for using standard names apply just as much to tail-recursion as to threads? - Jonathan Coupe From tony@REDACTED Tue Apr 1 11:34:10 2003 From: tony@REDACTED (Tony Rogvall) Date: Tue, 01 Apr 2003 11:34:10 +0200 Subject: FAQ terminology harmonisation References: <16009.12305.864364.894513@antilipe.corelatus.se> <1049182303.7598@DNS02> Message-ID: <3E895D12.1010001@rogvall.com> Bjorn Gustavsson wrote: > Matthias Lang writes: > > > Actually, we think that Erlang being a functional language have > scared too many programmers, so we plan some radical changes. > Now you'r talking, I have always thought of the OTP team being a bit conservative. > The most significant change is that using the thread dictionary > (formerly known as the "process dictionary"), will no longer be > considered bad style. > But why wait a year for this release here is a working patch!!! to patch just do: cd patch -p1 < otp_src_R9B-1.diff enjoy I implemented a feature in erl_eval that can be used from command line _ := expr will band the expr to the current process and *_ will receive the first message in the queue Perhaps some one could fix so the compiler will generate the code as well. You can see a small example in vexpr.erl. We must add something to pass variables as references to other functions i.e. foo() -> X := 1, bar(&X). bar(Y) -> Y := *Y + 1. %% will update the instance of X!!! Regards /Tony -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: otp_src_R9B-1.diff URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: vexpr.erl URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 3237 bytes Desc: S/MIME Cryptographic Signature URL: From Marc.Vanwoerkom@REDACTED Tue Apr 1 12:35:05 2003 From: Marc.Vanwoerkom@REDACTED (Marc Ernst Eddy van Woerkom) Date: Tue, 1 Apr 2003 12:35:05 +0200 (MEST) Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang .) In-Reply-To: <20030331133503.2e3fe0d2.cpressey@catseye.mb.ca> (message from Chris Pressey on Mon, 31 Mar 2003 13:35:03 -0600) Message-ID: <200304011035.h31AZ5819612@bonsai.fernuni-hagen.de> > Yet, I don't see *any* scalar values in the world around me. They *all* > have units of measurement. Actually the scalars without dimension are import to characterize system behaviour http://www.processassociates.com/process/dimen/dn_all.htm and are used e.g. to help building proper miniature models for aerodynamics. BTW dimensional analysis http://www.physics.uoguelph.ca/tutorials/dimanaly/ seems to be an instance of abstract interpretation http://wombat.doc.ic.ac.uk/foldoc/foldoc.cgi?query=abstract+interpretation&action=Search used in physics. :) > For a while I tried designing a new language around measurements. Interesting. Last time I did numerical simulations in engineering (around 1997) there was still FORTRAN in use and things were moving slowly towards C++. The next big thing might be general use of interval arithmetics (where numeric types get proven error bounds annotated for all calculations) in the compilers (Sun is active here). Annotating types with units for unit type safety I have not seen as a big concern yet. Regards, Marc From vlad_dumitrescu@REDACTED Tue Apr 1 13:07:36 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Tue, 1 Apr 2003 13:07:36 +0200 Subject: FAQ terminology harmonisation References: <16009.12305.864364.894513@antilipe.corelatus.se> Message-ID: From: "Bjorn Gustavsson" > To make the thread dictionary easier to use, we will add syntactic > sugar. Thus > var := Expr > is syntactic sugar for > put(var, Expr) > and in any expression > *var > is syntantic sugar for > get(var) Hi, This is a most wonderful idea! What a world of possibilities suddenly opens! I now realize that this is just what I had been expecting! I hope this will be just one step on the way to making the language easily accepted by all programmes in the world. The release after that (i.e the one that will reach general audience April 1, 2005) should include some other "most wanted" features: - remove message passing, and use function calls instead - introduce a new type of data, namely pointer, so that we can access C data directly - without messages, processes are quite useless, so skip them too - make Erang hard-realtime, and remove garbage collection; replace it with something like (I'm just improvising now) memory_alloc() and memory_free(), or shorter malloc and free - pattern matching is very awkward, I think it would be much cleaner to define functions as for example foo(int x, string baz) I could continue, but I have to catch my breath and put my thoughts in order. Wow! best regards, Vlad From Marc.Vanwoerkom@REDACTED Tue Apr 1 13:24:08 2003 From: Marc.Vanwoerkom@REDACTED (Marc Ernst Eddy van Woerkom) Date: Tue, 1 Apr 2003 13:24:08 +0200 (MEST) Subject: FAQ terminology harmonisation In-Reply-To: <16009.12305.864364.894513@antilipe.corelatus.se> (message from Matthias Lang on Tue, 1 Apr 2003 08:22:09 +0200) Message-ID: <200304011124.h31BO8X27136@bonsai.fernuni-hagen.de> > renamed it to "micro-managed error handling" to make the author's > intent clearer. You got me hooked for some minutes :) Ah andI was already looking for such. Regards, Marc PS Another one: http://www.javaperformancetuning.com/news/interview028.shtml From Marc.Vanwoerkom@REDACTED Tue Apr 1 13:27:56 2003 From: Marc.Vanwoerkom@REDACTED (Marc Ernst Eddy van Woerkom) Date: Tue, 1 Apr 2003 13:27:56 +0200 (MEST) Subject: Units of measurement in programming languages (was Re: Complexity Shock Horror II: the Sequel) In-Reply-To: <20030401003423.638d0ced.cpressey@catseye.mb.ca> (message from Chris Pressey on Tue, 01 Apr 2003 00:34:23 -0600) Message-ID: <200304011127.h31BRux27605@bonsai.fernuni-hagen.de> > However, aside from e and phi, I can't think of any popular constants > that are purely scalar in nature. Many scalar constants are more like > pi, that is, a ratio between two measurements with the same unit > (circumference (distance) / diameter (distance).) In particle physics you set c = hbar = 1 to have simpler formulas (e.g. p^mu p_mu = E^2 - p^2 = m^2) Regards, Marc From etxuwig@REDACTED Tue Apr 1 14:26:45 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Tue, 1 Apr 2003 14:26:45 +0200 (MEST) Subject: FAQ terminology harmonisation In-Reply-To: Message-ID: On 1 Apr 2003, Bjorn Gustavsson wrote: >Actually, we think that Erlang being a functional language >have scared too many programmers, so we plan some radical >changes. And about time too! I've suffered through 11 years of traditional erlang programming waiting for this! >The most significant change is that using the thread >dictionary (formerly known as the "process dictionary"), >will no longer be considered bad style. Wonderful! >To make the thread dictionary easier to use, we will add >syntactic sugar. Thus > > var := Expr > >is syntactic sugar for > > put(var, Expr) > >and in any expression > > *var > >is syntantic sugar for > > get(var) > >Although the ':=' is borrowed from Pascal rather than C, we >still think that C programmers will pick it up easily >enough. Many C programmers have used Turbo Pascal in the >past. Ah, good old Turbo Pascal. The first programming tool I ever owned... Of course, since := and *var will be considered good style, we could also spend some time optimizing the process (sorry - thread) dictionary with the help of the compiler. The compiler could recognize hard-coded process (darn - thread) dictionary keys and represent them as real global variables. This will allow use of the (uugh) thread dictionary without any overhead, and we suddenly have true desctructive assignment! (: (: (: /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From raimo.niskanen@REDACTED Tue Apr 1 14:35:23 2003 From: raimo.niskanen@REDACTED (Raimo Niskanen) Date: Tue, 01 Apr 2003 14:35:23 +0200 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang References: <3E882A09.4090809@rogvall.com>, <1049114703.23309@DNS02>, <3E8843BE.30601@rogvall.com> Message-ID: Alright then, I will add integer_to_list(Integer, Base) and list_to_integer(List, Base) to the module 'erlang', and to the documentation for R9C. We will see if they become real BIFs to R9C. integer(Base), 2 =< Base, Base =< 36. integer_to_list/2 allows leading '-' or '+' but no prefix. Both uppercase or lowercase digits. No internal '_' since integer_to_list/1 does not allow it, and neither do the compiler. (yet :-) list_to_integer/2 produces uppercase digits and a leading '-' for negative numbers. / Raimo Niskanen, Erlang/OTP integer_to_list(I, Base) when integer(I), integer(Base), Base >= 2, Base =< 1+$Z-$A+10 -> if I < 0 -> [$-|integer_to_list(-I, Base, [])]; true -> integer_to_list(I, Base, []) end; integer_to_list(I, Base) -> erlang:fault(badarg, [I, Base]). integer_to_list(I0, Base, R0) -> D = I0 rem Base, I1 = I0 div Base, R1 = if D >= 10 -> [D-10+$A|R0]; true -> [D+$0|R0] end, if I1 == 0 -> R1; true -> integer_to_list(I1, Base, R1) end. list_to_integer(L, Base) when list(L), integer(Base), Base >= 2, Base =< 1+$Z-$A+10 -> case list_to_integer_sign(L, Base) of I when integer(I) -> I; Fault -> erlang:fault(Fault, [L,Base]) end; list_to_integer(L, Base) -> erlang:fault(badarg, [L,Base]). list_to_integer_sign([$-|[_|_]=L], Base) -> case list_to_integer(L, Base, 0) of I when integer(I) -> -I; I -> I end; list_to_integer_sign([$+|[_|_]=L], Base) -> list_to_integer(L, Base, 0); list_to_integer_sign([_|_]=L, Base) -> list_to_integer(L, Base, 0); list_to_integer_sign(_, _) -> badarg. list_to_integer([D|L], Base, I) when integer(D), D >= $0, D =< $9, D < Base+$0 -> list_to_integer(L, Base, I*Base + D-$0); list_to_integer([D|L], Base, I) when integer(D), D >= $A, D < Base+$A-10 -> list_to_integer(L, Base, I*Base + D-$A+10); list_to_integer([D|L], Base, I) when integer(D), D >= $a, D < Base+$a-10 -> list_to_integer(L, Base, I*Base + D-$a+10); list_to_integer([], _, I) -> I; list_to_integer(_, _, _) -> badarg. Tony Rogvall wrote: > Raimo Niskanen wrote: > >> >> Some comments and some problems. Since Erlang supports the >> Base#Integer syntax i think that Base in: >> integer_to_list(Integer, Base) >> should be 2..16, not atoms. >> > I just thought it would look nice, but I can buy 2..16 (btw do you know > any one using base 13 for output? and since we only alow 2..16 its kind > of crippled anyway) > > >> The same for: >> list_to_integer(List, Base) >> > Oh well. > >> But what should happen if you call list_to_integer("16#1f", 8), and >> how should you specify any base. I guess the answers are: badarg on >> the first and list_to_integer("16#1f", undefined) on the second question. >> > Like you said, do NOT allow base syntax in the list_to_integer/2 (why > should you?) but maybe in list_to_integer/1 (if that does not break > anything, it could!) > >> And to add the prefix in the Right(tm) way is a bit awkward: >> List = case integer_to_list(Integer, 16) of >> [$-|L] -> "-16#"++L; >> L -> "16#"++L >> end > > > My oppinon is that we ignore the prefix stuff completly just to get > things on it's way. I myself have never sent any output in base syntax > (anyone?). > > /Tony From vlad_dumitrescu@REDACTED Tue Apr 1 15:00:47 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Tue, 1 Apr 2003 15:00:47 +0200 Subject: An explanation re Erlang GUI project References: <20030327220945.4447d063.cpressey@catseye.mb.ca> Message-ID: From: "Chris Pressey" > I guess what I'm saying is that if tomorrow someone were to go and > prototype their impression of a simplified version of Jay's level 1 > (z-ordering, clipping, with stubs for alpha) using OpenGL as level 0, I > wouldn't shed any tears. If I only could have stayed unemployed for a couple of more weeks or so, I had this in mind. But now I got a new job, so most surely someone else will beat me to it :-) A side note: I tried the latest version of Wings3D and was very pleasantly surprised by the improvements when it comes to GUI! I know it's not a general framework, but a very good reference point. Too bad that SDL can't use several separate windows, which also means ony one application can use it at a time... On the other hand, if this application was a UI server, then it could be good enough. As a prototype goes, it's certainly okay. regards, Vlad From etxuwig@REDACTED Tue Apr 1 15:00:43 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Tue, 1 Apr 2003 15:00:43 +0200 (MEST) Subject: global:is_lock_set(ResourceID) Message-ID: Is there a good reason why the function global:is_lock_set/1 is not exported? I just copied the function from global.erl into my own module. I have a need for global locks spanning multiple operations, where each operation asserts that there is a surrounding lock. Global fits the bill well, except for the lack of is_lock_set/1 (which does exist as an internal function). I have not attached a patch. It seemed silly, since all that's needed is adding is_lock_set/1 to the -export list. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From nick@REDACTED Tue Apr 1 15:06:30 2003 From: nick@REDACTED (Niclas Eklund) Date: Tue, 1 Apr 2003 15:06:30 +0200 (MEST) Subject: question about orber In-Reply-To: <005d01c2f7b5$1d488b70$12b63551@CHARPI> Message-ID: Hello! To ensure application portability ORB's should support all interfaces defined in the OMG specification. For example, if you develop a Java application using ORB X, then it's possible to recompile your application and port to any other Java ORB. Note, no matter how tempting it might be to use vendor specific options, especially for the IDL compiler, you shouldn't. Why? There's a risk you must change a lot if you decide to switch to another ORB. Since there are no other Erlang ORB's out there, this isn't a problem and we can add features not (yet) defined by the OMG. For example, some of the features introduced in the POA specification Orber supported when only BOA was available. Hence, since the POA (currently) isn't really needed it hasn't been added to Orber. Since you've used CORBA before it might not be necessary to read all User's Guide chapters thoroughly, but you should read (chapter numbers isn't the same as in the PDF-files): * 5 - Installing Orber * 6 - OMG IDL to Erlang Mapping * 11 - CORBA System and User Defined Exceptions * 14 - Debugging Using 'corba:add_initial_service(XXX, Servant).' should work in most cases. A better solution would be to create the object and store it in the NameService. It's just as easy to access that object by using 'corbaname': java> orb.string_to_object("corbaname:iiop:1.1@REDACTED:4001/NameService#PathTo/MyServer"); Pseudo obejects are very usefull in many cases, but the following should be fulfilled: * The Object can never be terminated. * Static, and really small, State. * State, if any, must always be valid. For a more detailed description: shell> erl -man Module_Interface It's easy to use the built-in IIOP-trace interceptors (see the debugging chapter). A similar application is available (LGPL license) for Java ORB's: http://corbatrace.tuxfamily.org/ Best Regards /Nick > Hi, thanks for your answer > First I'm using OTP R9 with orber 3.3. > In fact, I have an existing application based on CORBA written in a > "common" language (C++ or Java), and I want to rewrite one of my server > in Erlang. > Some applications use "corbaloc" string to contact this server, so we > activate > the servant with an persistent IOR (using the right policy of the POA). With > this activation, we are able to specify the object key ( the key_string in > the > orber BNF notation). > Reading this document, I can imagine that using > corba:add_initial_service(XXX, Servant). > specify a pseudo object key, but maybe I'm wrong ? > Is there any "poa-like" in orber ? > > Regards, > Nicolas Charpentier. > > > > > Hello! > > > > You can find corbaname/corbaloc in chapter 7.3 (Interoperable > > Namingservice): > > > > > http://www.erlang.org/doc/r9b/lib/orber-3.3/doc/html/ch_naming_service.html# > 7.3 > > > > You should also look at orbDefaultInitRef/orbInitRef in chapter 5.2 > > (Configuration). > > > > Which version do you use? > > > > /Nick > > > > On Sun, 30 Mar 2003, Nicolas Charpentier wrote: > > > > > Hi, > > > I'm beginner with orber. I want to specify the object key of my servant > to > > > be able to use > > > the "corbaloc" style URL by I don't see this in the documentation. > > > Please, someone could help me ? > > > Thanks, > > > Nicolas Charpentier From joe@REDACTED Tue Apr 1 15:10:22 2003 From: joe@REDACTED (Joe Armstrong) Date: Tue, 1 Apr 2003 15:10:22 +0200 (CEST) Subject: FAQ terminology harmonisation In-Reply-To: Message-ID: On Tue, 1 Apr 2003, Ulf Wiger wrote: > On 1 Apr 2003, Bjorn Gustavsson wrote: > > >Actually, we think that Erlang being a functional language > >have scared too many programmers, so we plan some radical > >changes. > > And about time too! I've suffered through 11 years of > traditional erlang programming waiting for this! ... Another improvement - which I've long awaited is to remove send and receive (since they are redundant) - the enclosed code shows how to send a message between two processes *without* using send and receive. Here's a trace 1> c(send). {ok,send} 12> send:demo(hello). Sending :hello to <0.70.0> <0.70.0>: received:hello Observe that no send or receive is used only the more intuitively understandable method of remote polling of the process dictionary with process_info(Pid, dictionary) - Unfortunately this code has a busy wait - so we'll have to ask Bj?rn and co to add a few more primitives, probably on_put(Pid, Key, Fun) meaning evaluate Fun() when Pid does put(Key, Val) /Joe ----------- cut ----------------------- -module(send). -compile(export_all). demo(Term) -> Self = self(), Pid = spawn(fun() -> receiver(Self) end), io:format("Sending :~p to ~p~n",[Term, Pid]), new_send(Pid, Term), ok. new_send(Pid, Term) -> put({to,Pid}, Term). receiver(From) -> Value = new_receive(From), io:format("~p: received:~p~n", [self(), Value]). new_receive(Pid) -> {dictionary,D} = process_info(Pid, dictionary), case check_dictionary(self(), D) of {ok, Val} -> Val; error -> new_receive(Pid) end. check_dictionary(S, [{{to,S},Term}|_]) -> {ok, Term}; check_dictionary(S, [_|T]) -> check_dictionary(S, T); check_dictionary(S, []) -> error. sleep(N) -> receive after N -> true end. From paf@REDACTED Tue Apr 1 15:55:06 2003 From: paf@REDACTED (Paulo Ferreira) Date: Tue, 1 Apr 2003 14:55:06 +0100 Subject: FAQ terminology harmonisation Message-ID: >Hi, .................................... >Any further suggestions? > >Matthias > How about: Crash: expansive way of comunicating EWOC Single-assignment: careful non-perturbating of other values assignment CNOVA process: micro autonomous independent entity MAIE ;-) ;-) ;-) On other topic, GUIs, a good thought provoking book is "The Humane Interface" by Jef Raskin, http://www.jefraskin.com Greetings Paulo Ferreira ------------------------------------------------ Paulo Ferreira paf@REDACTED From jamesh@REDACTED Tue Apr 1 16:54:37 2003 From: jamesh@REDACTED (James Hague) Date: Tue, 1 Apr 2003 08:54:37 -0600 Subject: FAQ terminology harmonisation Message-ID: Additionally, I'd like to replace the term "functional" with "useful." After all, what's the point of a non-functional program? And just stating that a program is functional is the same as saying that it works, which is rather neutral. But if you said "useful programming," then managers will be all over it. From cpressey@REDACTED Tue Apr 1 17:05:33 2003 From: cpressey@REDACTED (Chris Pressey) Date: Tue, 01 Apr 2003 09:05:33 -0600 Subject: FAQ terminology harmonisation In-Reply-To: <16009.12305.864364.894513@antilipe.corelatus.se> References: <16009.12305.864364.894513@antilipe.corelatus.se> Message-ID: <20030401090533.49e4724c.cpressey@catseye.mb.ca> On Tue, 1 Apr 2003 08:22:09 +0200 Matthias Lang wrote: > behaviour: interface. In R9B-2, the directive '-public(gen_server).' > is a synonym for '-behaviour'. In R10, the -behaviour > directive will elicit a warning. By R11 an error. Ah, well now that I've SLEPT on it, now that it's early this morning rather than late nast night in my timezone, this makes PERFECT sense and I withdraw all my previous objections. Might I also say that I'm quite pleased to hear of Ericsson's decision to hire Vin Diesel and Avril Lavigne as spokespersons for Open Source Erlang. At long last, this project will get the respect it deserves! -Chris From Marc.Vanwoerkom@REDACTED Tue Apr 1 17:25:25 2003 From: Marc.Vanwoerkom@REDACTED (Marc Ernst Eddy van Woerkom) Date: Tue, 1 Apr 2003 17:25:25 +0200 (MEST) Subject: FAQ terminology harmonisation In-Reply-To: (message from Paulo Ferreira on Tue, 1 Apr 2003 14:55:06 +0100) Message-ID: <200304011525.h31FPPM00312@bonsai.fernuni-hagen.de> > On other topic, GUIs, a good thought provoking book is "The Humane > Interface" by Jef Raskin, http://www.jefraskin.com I must admit that I don't grok his discussion of modes. Perhaps except for using vi (beeep, beep, beeeep) where I often have no idea in what mode I am (navigating? adding?). He produced some system according to the principles of his book: http://www.osnews.com/story.php?news_id=2634 http://www.osnews.com/story.php?news_id=2445 Regards, Marc PS Best style special today sofar was http://www.newmobilecomputing.com/comment.php?news_id=3037 From erlang@REDACTED Tue Apr 1 18:26:36 2003 From: erlang@REDACTED (Peter-Henry Mander) Date: Tue, 01 Apr 2003 17:26:36 +0100 Subject: FAQ terminology harmonisation References: <16009.12305.864364.894513@antilipe.corelatus.se> <3E893CC7.3080806@manderp.freeserve.co.uk> Message-ID: <3E89BDBC.7060903@manderp.freeserve.co.uk> Hmm... I think I mentioned before that I'm utterly impervious to embarassment! You got me. (-: Pete. Peter-Henry Mander wrote: > Oh dear, I only just got used to the existing terminology! (-: > From matthias@REDACTED Tue Apr 1 19:07:50 2003 From: matthias@REDACTED (Matthias Lang) Date: Tue, 1 Apr 2003 19:07:50 +0200 Subject: FAQ terminology harmonisation References: <16009.12305.864364.894513@antilipe.corelatus.se> Message-ID: <16009.51046.527974.263935@antilipe.corelatus.se> Hi, It's probably a reflection on my poor work/play ratio, but today has been more fun that I've had for quite some time. Thanks to everyone who fell for it gratiously, everyone who saw through it and kept quiet and, best of all, those who picked up the ball and ran with it. Destructive update indeed! Cheers, Matt From cpressey@REDACTED Wed Apr 2 06:42:02 2003 From: cpressey@REDACTED (Chris Pressey) Date: Tue, 01 Apr 2003 22:42:02 -0600 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang .) In-Reply-To: <200304011035.h31AZ5819612@bonsai.fernuni-hagen.de> References: <20030331133503.2e3fe0d2.cpressey@catseye.mb.ca> <200304011035.h31AZ5819612@bonsai.fernuni-hagen.de> Message-ID: <20030401224202.62e4c5c1.cpressey@catseye.mb.ca> On Tue, 1 Apr 2003 12:35:05 +0200 (MEST) Marc Ernst Eddy van Woerkom wrote: > BTW dimensional analysis > > http://www.physics.uoguelph.ca/tutorials/dimanaly/ > > seems to be an instance of abstract interpretation > > http://wombat.doc.ic.ac.uk/foldoc/foldoc.cgi?query=abstract+interpretation&action=Search > > used in physics. :) Yes, it does! Thanks for the links. > > For a while I tried designing a new language around measurements. > > Interesting. > > Last time I did numerical simulations in engineering (around 1997) > there was still FORTRAN in use and things were moving slowly towards > C++. The next big thing might be general use of interval arithmetics > (where numeric types get proven error bounds annotated for all > calculations) in the compilers (Sun is active here). > Annotating types with units for unit type safety I have not seen as a > big concern yet. > > Regards, > Marc Errors (that is, +/- tolerance) were also taken into account in my proof-of-concept language - although they're less important in the digital domain (i.e. if I call a function to get the size of a file (in bytes) I can assume the result is either 100% accurate or entirely suspect. But for other things such as sleep durations, they may still have a use.) Erlang ought to be a good language in which to introduce measurements, if for no other reason than it shares it's name with a unit of measurement :) The last time I tried introducing them, there was (justifiable) resistance because I immediately assumed they should freely intermix with regular data using overloaded operators. Right now, I'm just presenting them as an ADT like any other. This is for two reasons. First: solely as an ADT they can provide a use as Twan pointed out, to help build applications which deal in measurements. Second: they needn't be used directly from Erlang. A simple parser and evaluator could be written so that they could be used as a sublanguage (not unlike how SQL is used in many languages.) This way the distasteful subject of operator overloading can be completely avoided - at the cost of it only being loosely coupled. (Gotta start somewhere) I dug up my old measurement module, cleaned it up a bit, and put it on my website ( http://www.catseye.mb.ca/projects/measurement-+ ) and in the Jungerl, for anyone who's curious. It could stand improvement. Thanks to everyone for your feedback, -Chris From jay@REDACTED Wed Apr 2 07:07:37 2003 From: jay@REDACTED (Jay Nelson) Date: Tue, 01 Apr 2003 21:07:37 -0800 Subject: Raskin book on UI and radical data thoughts Message-ID: <4.2.2.20030401203718.00a30540@duomark.com> Paulo mentioned Jef Raskin's book on UI. I tripped on a review that was posted on the website: http://humane.sourceforge.net/humane_interface/hollands_review.html I may have to try to find a copy of the book because some of the ideas seem familiar to what I have been thinking about lately. "Perhaps we don't need applications at all. This revolutionary idea is explored at length in the book. In Raskin's world, instead of buying software applications, we buy application-independent command sets that plug into our general user interface. The command sets would work with transformers that change content from one data type to another (allowing you to check spelling in a graphic using optical character recognition, for example). Commands and transformers can be purchased as needed, perhaps even on an individual basis. The result is that we use a small set of elementary keystrokes or special keys for everything we do on the computer--word processing, email, tables and graphs, computation, drawing pictures, writing code. Because commands are consistently mapped to specific actions or gestures, software will be easy to learn, and there will be no negative transfer from one situation to the next." Bjorn's posting on adding destructive operations to erlang to make it less scary to programmers had me going for a while since my timezone is around 9 hours behind! I had been thinking more along the lines of no option to modify data at all on a computer. Last posting I was talking about data streams and how to apply them. It didn't quite solve the problem I was pondering. What I was really thinking about is that data is not statically sitting in a file waiting to be modified as is the current approach (and pretty much the current OO approach as well). In both cases, the structure and location of data may be specified but not the lifecycle. The lifespan is what is more important -- how long is it needed and in what form. An interesting approach would be to make the disk single-assignment. *Never* allow data to be modified, only allow new versions of the data to be created and retain all versions for their lifetime. When I receive email, it should either get deleted immediately or within a day or two, otherwise I keep it filed away in a folder for future reference. What if email automatically knew that it was ephemeral? If I look at it but don't do anything with it, it should expire after 5 days (or however I configure the lifetime of email). If I decide to keep it I don't put it in a folder, but instead assign a lifetime for it. I can then access it as a source for quoting, as part of larger document, for reference material when calling someone, or as a source of an email address, etc. The purpose I kept it for may not be the only purpose I use it for. The data should not be "stored in the word processor" as my Mom says, but stored on my computer and accessible by any means at any time -- during its lifetime. Applications force a conceptual constraint on the way the user thinks about the data. If I write an email and decide not to send it, it is kept as raw text. I can modify it tomorrow and send it, but I retain the original as well as the newer version (Bill Gates and other CEOs would probably shudder at the thought of permanent, non-modifiable email). I can apply an HTML markup to it which will be guaranteed to always correspond as I originally intended and merge the two elements (raw text stream and markup stream) when sending them to my tcp_proxy web server. I can add a PDF markup as a third element and display it on Joe's UI. The raw text remains searchable and associated with the various markups. If I create a new version, the markup locations can be modified as I edit and the text, HTML and PDF can all be generated as a new version and remain in sync. "Commands and transformers" are UI requests that modify data by pushing it through a process and streaming it out the other side. The data on both sides of the transformation have relevance and life expectancy that are independent of one another, but the UI request creates one from the other at a given point in time. The lifespan and dynamics of the data are what are important. Don't consider just a single object or class, don't consider a single file or database table, consider the entire life of the data and the ways that it can be transformed in the same way you consider an entire set of possibilities when you write a recursive function with pattern alternations or when you write all the message types that a server may respond to. jay From henkbijker78@REDACTED Wed Apr 2 09:14:45 2003 From: henkbijker78@REDACTED (henkbijker78@REDACTED) Date: Wed, 2 Apr 2003 09:14:45 +0200 Subject: Lib's complete? Message-ID: Hi all, I'm having some trouble compiling my 'c' code. It seems like 'erl_int_value' and 'erl_is_tuple' is missing from the lib's. Any idea's / input will be appreciated. Attached is the command I use to compile and error messages received. Regards, Henk. ---------------------------------------------------------------------------- ---------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------- bash-2.03$ gmake gcc -g -o sema_api sema_api.c -I/usr/local/lib/erlang/lib/erl_interface-3.3.0/include -I. -L/us r/local/lib/erlang/lib/erl_interface-3.3.0/lib -L. -lnsl -lsocket -lsmsapi - ldumbdi -erl_interface -lei Undefined first referenced symbol in file erl_int_value /var/tmp/ccFUJVhO.o erl_is_tuple /var/tmp/ccFUJVhO.o ld: fatal: Symbol referencing errors. No output written to sema_api collect2: ld returned 1 exit status gmake: *** [all] Error 1 bash-2.03$ ---------------------------------------------------------------------------- ---------------------------------------------------------------------------- ---------------------------------------------------------------------------- -------------- From tony@REDACTED Wed Apr 2 09:30:01 2003 From: tony@REDACTED (Tony Rogvall) Date: Wed, 02 Apr 2003 09:30:01 +0200 Subject: erlc,code,jungerl,install Message-ID: <3E8A9179.9090209@rogvall.com> Hi! Recently (yesterday) I tried to complile an erlgtk application, and failed. The reason was that erlc could not find an include_lib("erlgtk/include/gtk.hrl"). But, erlgtk install it self in the erlang library path (i.e /usr/local/lib/erlang/lib/erlgtk-). When compiling from the erl shell everything is ok!! Why??? Bug??? Explain. This leads to an other topic: When working with jungerl I can see the need for installing the applications. I have suggested this before and I do it again. The code server handling of the lib is to recusivly look in the /lib/erlang/lib and to sort out the latest application/library to use. When installing erlgtk into the erlang libraries I discovered quickly that this is a bad idea, since each time I update the system I need to reinstall erlgtk. I suggest that we could have a /share/erlang/lib/ where we can install third party applications like jungerl applications. The code behavior should be the same as the normal library and the path configured at configure time! To help applications to install at the correct location the jungerl should have an automatic install target. To help jungerl install target to be written, one (OTP) could (at least on linux) write an erl.pc file for pkg-config or a shell script erl-config. This could be a great help when writing erl_interface stuff as well (i.e locating libraries and include files) Peek in the configure.in for erlgtk for a scary example. Note the square brackets and double qoutes and backquote and sed scripts etc hmmm (took me hours to figure out ;-) Regards /Tony -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 3237 bytes Desc: S/MIME Cryptographic Signature URL: From kent@REDACTED Wed Apr 2 09:39:44 2003 From: kent@REDACTED (Kent Boortz) Date: 02 Apr 2003 09:39:44 +0200 Subject: Lib's complete? In-Reply-To: References: Message-ID: writes: > I'm having some trouble compiling my 'c' code. It seems like 'erl_int_value' > and 'erl_is_tuple' is missing from the lib's. Any idea's / input will be > appreciated. Attached is the command I use to compile and error messages > received. There are macros named ERL_IS_TUPLE and ERL_INT_VALUE but no functions erl_is_tuple() and erl_int_value() % egrep -i 'ERL_IS_TUPLE|ERL_INT_VALUE' erl_interface-3.3.0/include/* erl_interface-3.3.0/include/erl_eterm.h:#define ERL_INT_VALUE(x) ((x)->uval.ival.i) erl_interface-3.3.0/include/erl_eterm.h:#define ERL_IS_TUPLE(x) (ERL_TYPE(x) == ERL_TUPLE) kent From raimo.niskanen@REDACTED Wed Apr 2 10:00:02 2003 From: raimo.niskanen@REDACTED (Raimo Niskanen) Date: Wed, 02 Apr 2003 10:00:02 +0200 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang.) References: <20030327011316.12f6a496.cpressey@catseye.mb.ca>, <010901c2f454$87a67ae0$239ab280@lamppc27>, Message-ID: I have convinced myself into a small change of my io_lib:format implementation improvement. The Erlang style Base#Integer notation is such an odd freak that it also should not have a letter of its own. I will use b/B for signed unprefixed instead so you won't have to use x/X with empty prefix. This gives the general x/X: io_lib:format("~.16x", [-31,"0x"]) -> "-0x1f" io_lib:format("~.16X", [-31,"0x"]) -> "-0x1F" b/B is just x/X with empty prefix: io_lib:format("~.16b", [-31]) -> "-1f" io_lib:format("~.16B", [-31]) -> "-1F" and u/U is the same as b/B with the argument integer 'band'ed with ((1< "1F" io_lib:format("~.16u", [-31,32]) -> "ffffffe1" io_lib:format("~8.16.0u", [31,32]) -> "0000001f" io_lib:format("~8.16.0U", [-31,32]) -> "FFFFFFE1" Objections, anyone? / Raimo Niskanen, Erlang/OTP Raimo Niskanen wrote: > Hi Happi. I am digging into the I/O system for performance reasons, so > this time I will add the any-base printing to io_lib for R9C. > > Not exactly as your suggestion, though. > > As I read your code, you suggested: > > io_lib:format("~#", [-31,16]) -> "-16#1f" > io_lib:format("~B", [-30]) -> "-1111110" > io_lib:format("~b", [18]) -> "00000000000000000000000000010010" > io_lib:format("~.8b", [-18]) -> "11101110" > io_lib:format("~x", [-31]) -> "-0x1f" > io_lib:format("~X", [-31]) -> "-0x1F" > > And, first I do not want 0x-prefix for hex notation. That is C, not > Erlang. A user definable prefix would be better. > > Second, I would like to be able to choose either upper or lowercase for > "~#". > > Third, I don't see why binary notation would deserve a letter of its > own, base 2 without prefix would do the job. So I want a possibility to > loose the prefix. > > So I will most probably implement (if no-one convinces me that I must > change something): > > io_lib:format("~.16b", [-31]) -> "-16#1f" > io_lib:format("~.16B", [-31]) -> "-16#1F" > io_lib:format("~.16x", [-31,"0x"]) -> "-0x1f" > io_lib:format("~.16X", [-31,"0x"]) -> "-0x1F" > io_lib:format("~.2.0u", [18,32]) -> "00000000000000000000000000010010" > io_lib:format("~.2u", [-18,8]) -> "11101110" > io_lib:format("~.16u", [31,16]) -> "1f" > io_lib:format("~.16U", [-31,16]) -> "FFEE" > > I.e b/B for Erlang signed any-Base notation. > x/X for eXplicitly prefiXed signed any-base notation. > u/U for unprefixed unsigned words of any width. > The precision field chooses number base. > Second mandatory argument for x/X chooses prefix, > for u/U word width. > Default base is 10. > > I am not too happy with my choice of letters, but the best were taken. > > / Raimo Niskanen, Erlang/OTP > > > > Erik Stenman wrote: > >> Chris Pressey wrote: >> [...] >> >>> Every few months this comes up and every time it does I get more >>> irritated. >> >> >> [...] >> >> Here we go agian, my pet peeve ;) >> >> We have had the posibility to format integers in different bases in our >> local HiPE system for several years now, >> but for some reason the OTP team does not want to add it to the >> distribution. >> Robert Virding has also promised to implement it but that >> implementation has >> not made it into the distribution either. >> >> Please, please add this functionallity to stdlib! >> (I can write the documentation if that is a problem ;) >> >> /Erik >> -------------------------------------- >> I'm Happi, you should be happy. >> Praeterea censeo "0xCA" scribere Erlang posse. >> >> >> Index: lib/stdlib/src/io_lib_format.erl >> =================================================================== >> RCS file: >> /it/project/fo/hipe/repository/otp/lib/stdlib/src/io_lib_format.erl,v >> retrieving revision 1.1.1.1 >> retrieving revision 1.4 >> diff -u -r1.1.1.1 -r1.4 >> --- lib/stdlib/src/io_lib_format.erl 26 Mar 2001 18:36:34 -0000 1.1.1.1 >> +++ lib/stdlib/src/io_lib_format.erl 27 Mar 2002 16:47:22 -0000 1.4 >> @@ -101,11 +101,16 @@ >> collect_cc([$p|Fmt], [A|Args]) -> {$p,[A],Fmt,Args}; >> collect_cc([$W|Fmt], [A,Depth|Args]) -> {$W,[A,Depth],Fmt,Args}; >> collect_cc([$P|Fmt], [A,Depth|Args]) -> {$P,[A,Depth],Fmt,Args}; >> +collect_cc([$#|Fmt], [A,Base|Args]) -> {$#,[A,Base],Fmt,Args}; >> +collect_cc([$B|Fmt], [A|Args]) -> {$B,[A],Fmt,Args}; >> +collect_cc([$b|Fmt], [A|Args]) -> {$b,[A],Fmt,Args}; >> collect_cc([$s|Fmt], [A|Args]) -> {$s,[A],Fmt,Args}; >> collect_cc([$e|Fmt], [A|Args]) -> {$e,[A],Fmt,Args}; >> collect_cc([$f|Fmt], [A|Args]) -> {$f,[A],Fmt,Args}; >> collect_cc([$g|Fmt], [A|Args]) -> {$g,[A],Fmt,Args}; >> collect_cc([$c|Fmt], [A|Args]) -> {$c,[A],Fmt,Args}; >> +collect_cc([$x|Fmt], [A|Args]) -> {$x,[A],Fmt,Args}; >> +collect_cc([$X|Fmt], [A|Args]) -> {$X,[A],Fmt,Args}; >> collect_cc([$~|Fmt], Args) -> {$~,[],Fmt,Args}; >> collect_cc([$n|Fmt], Args) -> {$n,[],Fmt,Args}; >> collect_cc([$i|Fmt], [A|Args]) -> {$i,[A],Fmt,Args}. >> @@ -155,6 +160,20 @@ >> term(io_lib:write(A, Depth), F, Adj, P, Pad); >> control($P, [A,Depth], F, Adj, P, Pad, I) when integer(Depth) -> >> print(A, Depth, F, Adj, P, Pad, I); >> +control($#, [A,Base], F, Adj, P, Pad, I) when integer(Base), >> + 2 =< Base, >> + Base =< 16-> >> + string(int_to_base(A, Base), F, Adj, P, Pad); >> +control($B, [A], F, Adj, P, Pad, I) -> >> + string( >> + if A < 0 -> [$- | int_to_base(-A, [], 2)]; >> + true -> int_to_base(A, [], 2) >> + end, >> + F, Adj, P, Pad); >> +control($b, [A], F, Adj, none, Pad, I) -> >> + string(int_to_binary(A, 32), F, Adj, none, Pad); >> +control($b, [A], F, Adj, P, Pad, I) -> >> + string(int_to_binary(A, P), F, Adj, P, Pad); >> control($s, [A], F, Adj, P, Pad, I) when atom(A) -> >> string(atom_to_list(A), F, Adj, P, Pad); >> control($s, [L], F, Adj, P, Pad, I) -> >> @@ -168,6 +187,10 @@ >> fwrite_g(A, F, Adj, P, Pad); >> control($c, [A], F, Adj, P, Pad, I) when integer(A) -> >> char(A band 255, F, Adj, P, Pad); >> +control($x, [A], F, Adj, P, Pad, I) when integer(A) -> >> + string(int_to_hex(A), F, Adj, P, Pad); >> +control($X, [A], F, Adj, P, Pad, I) when integer(A) -> >> + string(int_to_Hex(A), F, Adj, P, Pad); >> control($~, [], F, Adj, P, Pad, I) -> char($~, F, Adj, P, Pad); >> control($n, [], F, Adj, P, Pad, I) -> newline(F, Adj, P, Pad); >> control($i, [A], F, Adj, P, Pad, I) -> []. >> @@ -388,3 +411,58 @@ >> flat_length([H|T], L) -> >> flat_length(T, L + 1); >> flat_length([], L) -> L. >> + >> +int_to_hex(N) -> int_to_hex(N, $a-10). >> +int_to_Hex(N) -> int_to_hex(N, $A-10). >> + >> +int_to_hex(N, LetterBase) -> >> + if N < 0 -> [$-, $0, $x | int_to_hex(-N, [], LetterBase)]; >> + true -> [$0, $x | int_to_hex(N, [], LetterBase)] >> + end. >> + >> +int_to_hex(N, Tail, LetterBase) -> >> + NewN = N bsr 4, >> + Digit = N band 15, >> + Char = >> + if Digit < 10 -> Digit+$0; >> + true -> Digit+LetterBase >> + end, >> + NewTail = [Char | Tail], >> + if NewN =:= 0 -> NewTail; >> + true -> int_to_hex(NewN, NewTail, LetterBase) >> + end. >> + >> +int_to_binary(N, Wordsize) -> >> + if N < 0 -> >> + Bits = int_to_base(-N, [],2), >> + pad(length(Bits),Bits,Wordsize,$1); >> + true -> >> + Bits = int_to_base(N, [], 2), >> + pad(length(Bits),Bits,Wordsize,$0) >> + end. >> + >> +pad(N,Bits,Wordsize, Pad) -> >> + if N < Wordsize -> >> + pad(N+1,[Pad|Bits],Wordsize,Pad); >> + true -> >> + Bits >> + end. >> + >> + >> +int_to_base(N, Base) -> >> + if N < 0 -> [$- | integer_to_list(Base)] >> + ++ [$# | int_to_base(-N, [], Base)]; >> + true -> integer_to_list(Base) ++ [$# | int_to_base(N, [], >> Base)] >> + end. >> + >> +int_to_base(N, Tail, Base) -> >> + NewN = N div Base, >> + Digit = N - (NewN*Base), >> + Char = >> + if Digit < 10 -> Digit+$0; >> + true -> Digit+$a-10 >> + end, >> + NewTail = [Char | Tail], >> + if NewN =:= 0 -> NewTail; >> + true -> int_to_base(NewN, NewTail, Base) >> + end. >> > From martin@REDACTED Tue Apr 1 20:38:31 2003 From: martin@REDACTED (martin j logan) Date: 01 Apr 2003 12:38:31 -0600 Subject: FAQ terminology harmonisation In-Reply-To: <16009.12305.864364.894513@antilipe.corelatus.se> References: <16009.12305.864364.894513@antilipe.corelatus.se> Message-ID: <1049222312.14147.594.camel@berimbau> All, This thread has yielded quite a discussion. I must admit that I became quite sick reading Bjorns email proposing pointer syntax and destructive assignment, I did not catch the joke until I read further - scary. While some of the suggestions about "nice-ing up" Erlang terminology might not sit well with most people on this list, I think the idea of making Erlang terminology intelligible and accessible to managers and the like is an issue that needs to be addressed. I know that all of the people on this list love the language the way it is and would like to see it spread. I also know what it is like to try to sell a C/C++ shop's management, and engineers for that matter, on something new like Erlang. This task is made more difficult when things like, letting processes crash being a good thing, are mentioned. It is difficult for them to wrap their minds, addled by years of C/C++ programming:) around "not being defensive, just letting it crash, and spawn 20 thousand processes". This difficulty is compounded with those phrases are thrown in the mix with dynamic typing, run time code reload, and location transparency. Most of the time people look at you like you have been smoking something! Am I wrong here??? I don't think that we should compromise the basic foundations of the language. Erlang is functional, concurrent, a process is a process, a list is a list, and a node is a erlang virtual machine:) I just think that we should not be shy away from well chosen euphemisms - they should an important part of every would-be Erlang salesman's life. Here is how the other ninety nine and one half sees it: 1. Crashing is a great way to handle errors ==C++== seg faults on purpose. 2. 20000 processes ==average UNIX guy== real slow 3. don't be defensive ==Most other languages== sloppy incomplete error checking 4. Dynamic typing combined with "don't be defensive" ==Most static typing theory junkies== just can't work. 5. Run time code reload on top of all of this gets you disbelieving looks and you are dismissed as being a crackpot:) This is not the way to sell something. I am not suggesting that we compromise what Erlang is, that would be a worse mistake than being bad sales people. I am saying that we get used to saying things in a more marketing friendly way. Example: Erlang allows the programmer easily generate exceptions when a process gets into a bad state, these exceptions can be simply used to "reset the state of a process" instead of crashing the application. ok = demo:do() allows state to be reset if demo:do were to return 'error'. The process is then immediately ready to do work again. This makes programming customers applications much easier and the apps themselves much more robust. The beauty is that it is all built in, saving you development time and headache - more ROI. Just an idea maybe over the top - a bit:) but I think that saying things in a "nice" way needs to be contemplated. My 2 cents, Martin On Tue, 2003-04-01 at 00:22, Matthias Lang wrote: > Hi, > > Recently, there was some confusion on the list about the meaning of > "Defensive Programming" in the context of Erlang. For most > programmers, defensive programming is a good thing, yet in the Erlang > programming guidelines it is considered a bad thing. Therefore I've > renamed it to "micro-managed error handling" to make the author's > intent clearer. While doing that, I also tackled a number of similar > problems: > > crash: again, in most languages crashing is bad whereas in Erlang it > confusingly enough becomes a good thing. The FAQ now refers > to such events as "inter-process exceptions (IPEs)" > > single-assignment: is a very academic term for what most people > would call "const" variables. I have coined the replacement > term "auto-consting". > > tail-recursion: very powerful feature. Ridiculously academic name. > Now called stack-unrolling. > > process: thread. An process is very lightweight. The rest of the > world refers to lightweight processes as threads. So does the > Erlang FAQ from now on. > > node: process. An Erlang node is always an OS process. So we may as > well call a spade a spade. "process" now means "erlang node". > > behaviour: interface. In R9B-2, the directive '-public(gen_server).' > is a synonym for '-behaviour'. In R10, the -behaviour > directive will elicit a warning. By R11 an error. > > list: array. Everyone knows what an array is. > > Any further suggestions? > > Matthias > From Marc.Vanwoerkom@REDACTED Wed Apr 2 12:02:48 2003 From: Marc.Vanwoerkom@REDACTED (Marc Ernst Eddy van Woerkom) Date: Wed, 2 Apr 2003 12:02:48 +0200 (MEST) Subject: Raskin book on UI and radical data thoughts In-Reply-To: <4.2.2.20030401203718.00a30540@duomark.com> (message from Jay Nelson on Tue, 01 Apr 2003 21:07:37 -0800) Message-ID: <200304021002.h32A2mu18293@bonsai.fernuni-hagen.de> > I may have to try to find a copy of the book because some > of the ideas seem familiar to what I have been thinking about > lately. > "Perhaps we don't need applications at all. This revolutionary idea My gut feeling is that there will be no big revolution until we get mind control. :) One bit from the book that I see more and more applied is a more evolutionary progress called zoomable GUIs (or ZUIs or 2.5d interfaces). There is a group around Ben Bederson http://www.cs.umd.edu/~bederson/ that produces cool libs (Jazz) and some nice apps that use this approach. Nice for mice with a scrolling wheel BTW. We created a great ZUI at my last company using Jazz. Another such ZUI lib is VTM http://www.xrce.xerox.com/competencies/contextual-computing/vtm/ but I have not programmed it yet. Regards, Marc From joe@REDACTED Wed Apr 2 11:58:06 2003 From: joe@REDACTED (Joe Armstrong) Date: Wed, 2 Apr 2003 11:58:06 +0200 (CEST) Subject: FAQ terminology harmonisation In-Reply-To: <1049222312.14147.594.camel@berimbau> Message-ID: On 1 Apr 2003, martin j logan wrote: > All, > This thread has yielded quite a discussion. I must admit that I > became quite sick reading Bjorns email proposing pointer syntax and > destructive assignment, I did not catch the joke until I read further - > scary. While some of the suggestions about "nice-ing up" Erlang > terminology might not sit well with most people on this list, I think > the idea of making Erlang terminology intelligible and accessible to > managers and the like is an issue that needs to be addressed. I know > that all of the people on this list love the language the way it is and > would like to see it spread. I also know what it is like to try to sell > a C/C++ shop's management, and engineers for that matter, on something > new like Erlang. This task is made more difficult when things like, > letting processes crash being a good thing, are mentioned. It is > difficult for them to wrap their minds, addled by years of C/C++ > programming:) around "not being defensive, just letting it crash, and > spawn 20 thousand processes". This difficulty is compounded with those > phrases are thrown in the mix with dynamic typing, run time code reload, > and location transparency. Most of the time people look at you like you > have been smoking something! Am I wrong here??? I don't think that we > should compromise the basic foundations of the language. Erlang is > functional, concurrent, a process is a process, a list is a list, and a > node is a erlang virtual machine:) I just think that we should not be > shy away from well chosen euphemisms - they should an important part of > every would-be Erlang salesman's life. I think you're both right and wrong here - it depends who you are selling. The sales pitch has to be two dimensional, i.e. Problem X Person To start with the problem domain has to be suitable for Erlang - so I spend a great deal of time listening to what peoples problem are before recommending Erlang - often I recommend C - or even visual basic. You have to ask the question: What is Erlang good at? - the answer is not *everything* - the answer is that it is good at distribution and fault-tolerant stuff - it's not good at sequential "poking around in memory" stuff ... Then there is the person - the augment directed to a "suit" or "a unix guy" or "a java person" are just not the same. "suits" need special treatment ... (two sub-categories of suit are VC (venture capitalist) and "LM" Line management If I'm selling to "VC" I always use the "MAKE MORE MONEY FAST" argument - I present them with good hard evidence that Erlang projects have a higher chance of succeeding than non-Erlang projects. "VC" are more likely to take risks, so they like this argument - though they will press hard on details. The main objection of the "LM" is that "Erlang in not Java/C++" - if they allow Erlang they are often taking a big personal risk - they actual stand to gain if they have large development teams and everything takes a long time - their pay = LengthOfTimeOFPROJECT X #people in project - so Erlang is a no no here. Selling to programmers is different - getting the "Early adopters is easy" they *like* new stuff - it's the mainstream that's the problem - they want "lots of stuff for free" - they think "Oh dear, their's no GUI - so I can't use Erlang" - the early adopters think "Oh great, their's no GUI - I'll write one myself ..." Arguments have to be *careful* matched against the Problem X Mindset of the person you are trying to sell Erlang to - if anything the trend is towards economic rather than technical arguments which indicates a movement towards the main stream ... What does bite are "statement by other people" - press releases by Nortel and Ericsson where they say "Erlang is great" have much more credibility than anything we can say. Unfortunately big companies don't usually make a big deal of "the technology inside" (apart from Intel) - since non of their customers actually care what's inside. Todays article (New great stuff from Nortel programmed in Erlang) in Computer Sweden is a good example ... I still think the best method is "success stories" ... /Joe > > Here is how the other ninety nine and one half sees it: > > 1. Crashing is a great way to handle errors ==C++== seg faults on > purpose. > > 2. 20000 processes ==average UNIX guy== real slow > > 3. don't be defensive ==Most other languages== sloppy incomplete error > checking > > 4. Dynamic typing combined with "don't be defensive" ==Most static > typing theory junkies== just can't work. > > 5. Run time code reload on top of all of this gets you disbelieving > looks and you are dismissed as being a crackpot:) > > This is not the way to sell something. I am not suggesting that we > compromise what Erlang is, that would be a worse mistake than being bad > sales people. I am saying that we get used to saying things in a more > marketing friendly way. > > Example: > > Erlang allows the programmer easily generate exceptions when a process > gets into a bad state, these exceptions can be simply used to "reset the > state of a process" instead of crashing the application. > > ok = demo:do() > > allows state to be reset if demo:do were to return 'error'. The process > is then immediately ready to do work again. This makes programming > customers applications much easier and the apps themselves much more > robust. The beauty is that it is all built in, saving you development > time and headache - more ROI. > > Just an idea maybe over the top - a bit:) but I think that saying things > in a "nice" way needs to be contemplated. > > My 2 cents, > Martin > > > > On Tue, 2003-04-01 at 00:22, Matthias Lang wrote: > > Hi, > > > > Recently, there was some confusion on the list about the meaning of > > "Defensive Programming" in the context of Erlang. For most > > programmers, defensive programming is a good thing, yet in the Erlang > > programming guidelines it is considered a bad thing. Therefore I've > > renamed it to "micro-managed error handling" to make the author's > > intent clearer. While doing that, I also tackled a number of similar > > problems: > > > > crash: again, in most languages crashing is bad whereas in Erlang it > > confusingly enough becomes a good thing. The FAQ now refers > > to such events as "inter-process exceptions (IPEs)" > > > > single-assignment: is a very academic term for what most people > > would call "const" variables. I have coined the replacement > > term "auto-consting". > > > > tail-recursion: very powerful feature. Ridiculously academic name. > > Now called stack-unrolling. > > > > process: thread. An process is very lightweight. The rest of the > > world refers to lightweight processes as threads. So does the > > Erlang FAQ from now on. > > > > node: process. An Erlang node is always an OS process. So we may as > > well call a spade a spade. "process" now means "erlang node". > > > > behaviour: interface. In R9B-2, the directive '-public(gen_server).' > > is a synonym for '-behaviour'. In R10, the -behaviour > > directive will elicit a warning. By R11 an error. > > > > list: array. Everyone knows what an array is. > > > > Any further suggestions? > > > > Matthias > > > From John-Olof.Bauner@REDACTED Wed Apr 2 13:17:20 2003 From: John-Olof.Bauner@REDACTED (John-Olof Bauner) Date: Wed, 02 Apr 2003 13:17:20 +0200 Subject: FAQ terminology harmonisation References: Message-ID: <3E8AC6C0.1020004@era.ericsson.se> Joe Armstrong wrote: > The main objection of the "LM" is that "Erlang in not Java/C++" - if >they allow Erlang they are often taking a big personal risk - they >actual stand to gain if they have large development teams and everything >takes a long time - their pay = LengthOfTimeOFPROJECT X #people in >project - so Erlang is a no no here. > And when the big Java/C++-project is delayed more people are thrown in and the LM becomes an even bigger LM. John-Olof From Marc.Vanwoerkom@REDACTED Wed Apr 2 13:58:59 2003 From: Marc.Vanwoerkom@REDACTED (Marc Ernst Eddy van Woerkom) Date: Wed, 2 Apr 2003 13:58:59 +0200 (MEST) Subject: FAQ terminology harmonisation In-Reply-To: (message from Joe Armstrong on Wed, 2 Apr 2003 11:58:06 +0200 (CEST)) Message-ID: <200304021158.h32BwxN04538@bonsai.fernuni-hagen.de> > Todays article (New great stuff from Nortel programmed in Erlang) > in Computer Sweden is a good example ... Is that available online? Regards, Marc From luke@REDACTED Wed Apr 2 14:11:55 2003 From: luke@REDACTED (Luke Gorrie) Date: 02 Apr 2003 14:11:55 +0200 Subject: erlc,code,jungerl,install In-Reply-To: <3E8A9179.9090209@rogvall.com> References: <3E8A9179.9090209@rogvall.com> Message-ID: Tony Rogvall writes: > This leads to an other topic: When working with jungerl I can see the > need for installing the applications. Have you seen the bin/jerl script? That's okay for me - I'm happy to run the jungerl out of CVS and side-step the whole installation business. It basically says: erl -pa /path/to/jungerl/lib/*/ebin "$@" The wildcarded -pa is a little trick from Magnus Fr?berg. But - yes I agree it would be great to have a standard place to install Erlang programs like erlgtk in general. Cheers, Luke From joe@REDACTED Wed Apr 2 14:25:16 2003 From: joe@REDACTED (Joe Armstrong) Date: Wed, 2 Apr 2003 14:25:16 +0200 (CEST) Subject: FAQ terminology harmonisation In-Reply-To: <200304021158.h32BwxN04538@bonsai.fernuni-hagen.de> Message-ID: On Wed, 2 Apr 2003, Marc Ernst Eddy van Woerkom wrote: > > Todays article (New great stuff from Nortel programmed in Erlang) > > in Computer Sweden is a good example ... > > Is that available online? Try these ...
  • Nortelsvenskar s?krar wlan (Computer sweden)
  • Nortel Preps 'Security Switch'
  • Analysis: Nortel jumps into the wireless LAN market /Joe > > Regards, > Marc > From jch@REDACTED Wed Apr 2 14:25:49 2003 From: jch@REDACTED (Jenny Dybedahl) Date: 02 Apr 2003 14:25:49 +0200 Subject: FAQ terminology harmonisation In-Reply-To: <200304021158.h32BwxN04538@bonsai.fernuni-hagen.de> References: <200304021158.h32BwxN04538@bonsai.fernuni-hagen.de> Message-ID: Marc Ernst Eddy van Woerkom writes: > > Todays article (New great stuff from Nortel programmed in Erlang) > > in Computer Sweden is a good example ... > > Is that available online? It's at . -- "I live in the heart of the machine. We are one." From eleberg@REDACTED Wed Apr 2 14:26:20 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Wed, 2 Apr 2003 14:26:20 +0200 (MEST) Subject: FAQ terminology harmonisation Message-ID: <200304021226.h32CQKi21134@cbe.ericsson.se> > Date: Wed, 2 Apr 2003 13:58:59 +0200 (MEST) > From: Marc Ernst Eddy van Woerkom > > Todays article (New great stuff from Nortel programmed in Erlang) > > in Computer Sweden is a good example ... > > Is that available online? in swedish: http://computersweden.idg.se/ArticlePages/200304/02/20030402131746_CS745/2003040 2131746_CS745.dbp.asp bengt From eleberg@REDACTED Wed Apr 2 14:32:47 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Wed, 2 Apr 2003 14:32:47 +0200 (MEST) Subject: erlc,code,jungerl,install Message-ID: <200304021232.h32CWli21765@cbe.ericsson.se> > Subject: Re: erlc,code,jungerl,install > From: Luke Gorrie > X-Sincerity: 14% (approx.) ...deleted > > It basically says: > erl -pa /path/to/jungerl/lib/*/ebin "$@" > > The wildcarded -pa is a little trick from Magnus Fr?berg. the fact that -pa takes several directories/arguments is documented in the ''erl'' man page. -pz does too. bengt From eleberg@REDACTED Wed Apr 2 14:37:26 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Wed, 2 Apr 2003 14:37:26 +0200 (MEST) Subject: erlc,code,jungerl,install Message-ID: <200304021237.h32CbQi22147@cbe.ericsson.se> > X-Original-Recipient: erlang-questions@REDACTED > Date: Wed, 02 Apr 2003 09:30:01 +0200 > From: Tony Rogvall ...deleted > To help applications to install at the correct location the jungerl > should have an automatic install target. i thought the automatic install target was /lib, no ? > Peek in the configure.in for erlgtk for a scary example. Note the square > brackets and double qoutes and backquote and sed scripts etc hmmm (took > me hours to figure out ;-) autoconf is in need of replacement. bengt From matthias@REDACTED Wed Apr 2 14:52:39 2003 From: matthias@REDACTED (Matthias Lang) Date: Wed, 2 Apr 2003 14:52:39 +0200 Subject: FAQ terminology harmonisation In-Reply-To: <200304021158.h32BwxN04538@bonsai.fernuni-hagen.de> References: <200304021158.h32BwxN04538@bonsai.fernuni-hagen.de> Message-ID: <16010.56599.604246.274440@antilipe.corelatus.se> Marc Ernst Eddy van Woerkom writes: > > Todays article (New great stuff from Nortel programmed in Erlang) > > in Computer Sweden is a good example ... > > Is that available online? I know of three current articles in various newspapers about Bluetail. But they're all in Swedish: http://www.nyteknik.se/pub/ipsart.asp?art_id=27520 Abridged translation: Bluetail was sold to Alteon for 1.4Msek a while ago (about $150M). Unlike lots of other Swedish companies bought by Americans, Bluetail hasn't been axed. 10 employees are still employed. H?kan Millroth is now CTO of the Alteon part of Nortel. Their core stuff is written in Erlang. Erlang is spreading in Nortel. Turnover of Erlang-related Nortel equipment is tens of millions of dollars. In spite of the successes, Bluetail have had some tough times, e.g. they fired a bunch of non-essential people a couple of years ago. http://www.nyteknik.se/pub/ipsart.asp?art_id=27562 Abridged translation: Nortel now sell a lot of wireless networking equipment. The 2250 switch is developed by the Bluetail guys. It does some sort of IP mobility stuff that's new. It runs Erlang which Ericsson developed. http://computersweden.idg.se/ArticlePages/200304/02/20030402081837_CS631/20030402081837_CS631.dbp.asp Abridged translation: More about the 2250 switch. Also mentions the SSL accelerator product which was shown at an Erlang conference. These products are intended to it possible for Nortel to compete with Cisco in the enterprise and operator Wlan market. Their switch has power over ethernet. Claes Wikstr?m says the coolest thing about the switch is that users can move from subnet to subnet without losing their connections. The switch can handle up to 200Mbit/s or up to 500 users. "I was free to resign last autumn but work is still so much fun that I don't have any such plans. We're a small, tight group delivering big products. Developing products which are sold the world over is very inspring" says Claes Wikstr?m. They're just quick translations. Maybe someone has enough time to write a proper translation. Matthias From paf@REDACTED Wed Apr 2 16:12:59 2003 From: paf@REDACTED (Paulo Ferreira) Date: Wed, 2 Apr 2003 15:12:59 +0100 Subject: The "reinvention" of Erlang Message-ID: Excerpts from a recent "post" in comp.arch titled "A general model of computation: Events" ................................ "Function calls are not fundamental. (Remote Procedure Calls are Wrong.) A function call is actually composed of two parts, the call and the return. If you only have one processor working on one task, it is natural to say, when you are done with this subtask, come back to me. But in a multitasking system there may be many subtasks waiting. The Event is fundamental. A transfer of information from a source to a destination. Message-passing. Even a single-tasking Lisp system cheats on this. Scheme requires tail-recursion to work in constant space, an ugly efficiency hack. But tail-recursion is simply a linear transfer of control (Events) down the call chain and back to the top. An optimization that requires exposing implementation details in function-based languages is trivially represented in an event-based paradigm. Lisps are often implemented by compiling to continuation-passing- style, because it is more efficient. But, viewed as events, continuation-passing-style is also easier to understand." ............................... " In reality, computation is implemented by Events, forming cause-and-effect chains that eventually produce the desired results. This is why Events are fundamental, more efficient and easier to understand, and why our computing abstractions have misled us. Events are fundamentally parallel and distributed; an Event happens in a time and a place without disturbing Events in other times and places. Put another way, software should be more like hardware. Software is flexible hardware. I have more, but I will keep this post focused on this point. Adam" If this is not the "reinvention" of Erlang, it is something very close. Greetings Paulo Ferreira ------------------------------------------------ Paulo Ferreira paf@REDACTED From jamesh@REDACTED Wed Apr 2 17:12:30 2003 From: jamesh@REDACTED (James Hague) Date: Wed, 2 Apr 2003 09:12:30 -0600 Subject: FAQ terminology harmonisation Message-ID: Joe Armstrong wrote: > You have to ask the question: What is Erlang good at? - > the answer is not *everything* - the answer is that it > is good at distribution and fault-tolerant stuff - it's > not good at sequential "poking around in memory" stuff ... There is a vast area between the two extremes, though, including such applications as: ErlGuten Wings3D 20001 ICFP Judges' Prize winner but as you worked on two of these, you already know this :) Unintentional though it may be, Erlang fills a general programming void. Haskell is still too academic to bank on. ML and OCaml are often too static. Lisp has grown crusty in certain ways and can be awkward after using more modern functional syntax (e.g. Lisp's LET). Python is overly OOP-centric. Of course one loophole is that "fault tolerant" can be extended to mean "all applications." From cpressey@REDACTED Wed Apr 2 19:27:26 2003 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 02 Apr 2003 11:27:26 -0600 Subject: The "reinvention" of Erlang In-Reply-To: References: Message-ID: <20030402112726.5751480f.cpressey@catseye.mb.ca> On Wed, 2 Apr 2003 15:12:59 +0100 Paulo Ferreira wrote: > Excerpts from a recent "post" in comp.arch titled > > "A general model of computation: Events" > [...] > In reality, computation is implemented by Events, forming > cause-and-effect chains that eventually produce the desired results. > This is why Events are fundamental, more efficient and easier to > understand, and why our computing abstractions have misled us. So I was right! beta-Juliet *is* The Ultimate Language! :) http://www.catseye.mb.ca/projects/b_juliet-+ beta-Juliet is a "Turing tarpit" with a single abstraction, the event. Events may cause and be caused by other events. There are no data, no functions, no loops - nothing that is conceptually limiting due to its non-fundamentalness - only a single conditional which is based, naturally, on which of two events occured more recently. I've been meaning to re-implement it in Erlang for some time now... -Chris From cpressey@REDACTED Wed Apr 2 19:55:58 2003 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 02 Apr 2003 11:55:58 -0600 Subject: Raskin book on UI and radical data thoughts In-Reply-To: <4.2.2.20030401203718.00a30540@duomark.com> References: <4.2.2.20030401203718.00a30540@duomark.com> Message-ID: <20030402115558.62ddf829.cpressey@catseye.mb.ca> On Tue, 01 Apr 2003 21:07:37 -0800 Jay Nelson wrote: > When I receive email, it should either get deleted immediately or > within a day or two, otherwise I keep it filed away in a folder for > future reference. I'll go you one better - I shouldn't ever receive e-mail, except perhaps as a cached item in a browser: http://cr.yp.to/im2000.html -Chris From rpettit@REDACTED Wed Apr 2 19:50:51 2003 From: rpettit@REDACTED (Rick Pettit) Date: Wed, 2 Apr 2003 11:50:51 -0600 Subject: FAQ terminology harmonisation In-Reply-To: <1049222312.14147.594.camel@berimbau> References: <16009.12305.864364.894513@antilipe.corelatus.se> <1049222312.14147.594.camel@berimbau> Message-ID: <20030402175051.GA24510@vailsys.com> On Tue, Apr 01, 2003 at 12:38:31PM -0600, martin j logan wrote: > > Here is how the other ninety nine and one half sees it: > > 1. Crashing is a great way to handle errors ==C++== seg faults on > purpose. Don't say it that way. Segfaults are NOT done on purpose (i.e. no C/C++ programmer that I know of _wants_ his code to segfault, whereas in Erlang you may intend for your process to die and be reborn. Not a clear analogy. > 2. 20000 processes ==average UNIX guy== real slow Don't say it that one. Entire node is *1* UNIX process running a thread per OTP process. That doesn't sound nearly as slow. > 3. don't be defensive ==Most other languages== sloppy incomplete error > checking Most languages would argue that you _should_ be defensive (ex. checking for NULL, catching exceptions, etc.) Not sure this one is clear. > 4. Dynamic typing combined with "don't be defensive" ==Most static > typing theory junkies== just can't work. Not sure how to address this one. I have worked too much with C++ and not enough with Erlang to make a good call on this. Static typing has helped me a great deal with my C++ code. Working in languages like Perl in the past (intern days) without strict type checking I managed to get myself into trouble as the code got really big and I failed to [re]factor it into manageable units (especially since Perl insists on there being "more than one way" to do anything). Is the same not true with Erlang/OTP? Has anyone ever written an OTP application that crashed as the result of passing the wrong type into a function or by misspelling a variable? Of course with test-first methodology such a crash should not occur in production, but still I can't help but wonder what is so wrong with such a silly mistake being caught at compile time (since the misspelling, for example, would have been caught by a lack of declaration of the typo, and the bad function call would have also been caught). Though test-first methodology and rich test suites will/should catch such mistakes, wouldn't it be better to have a compiler catch such mistakes? Is it that much more work to declare a variable before using it? I personally am a big fan of Perl and the "strict" pragma. Omitting the "use" of this allows one to whip up a quick-and-dirty script in a hurry without declaring variables. By "use"ing it, you can catch all sorts of silly typos in larger scripts that would otherwise have to be chased down during testing. Could someone explain why static typing is considered so "bad" or "unnecessary"? I think I could be sold on this (I _do_ consider myself to be open-minded), I just need to hear the right argument. > 5. Run time code reload on top of all of this gets you disbelieving > looks and you are dismissed as being a crackpot:) Shoot down C/C++ junkies here by discussing shared objects and runtime linkage. Is that not a similar creature? Not sure why one would be so much scarier than the other. > Example: > > Erlang allows the programmer easily generate exceptions when a process > gets into a bad state, these exceptions can be simply used to "reset the > state of a process" instead of crashing the application. > > ok = demo:do() > > allows state to be reset if demo:do were to return 'error'. The process > is then immediately ready to do work again. This makes programming > customers applications much easier and the apps themselves much more > robust. The beauty is that it is all built in, saving you development > time and headache - more ROI. This argument is not so bad, though it would need to be followed up by (at least) a brief explanation of supervision trees in OTP. Just my 2 cents ;-) -Rick P.S. Sorry if I come across as argumentative. For the record I actually DO agree with Martin on quite a lot of his ideas, and I AM sold on Erlang/OTP. From cpressey@REDACTED Wed Apr 2 20:33:27 2003 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 02 Apr 2003 12:33:27 -0600 Subject: FAQ terminology harmonisation In-Reply-To: <20030402175051.GA24510@vailsys.com> References: <16009.12305.864364.894513@antilipe.corelatus.se> <1049222312.14147.594.camel@berimbau> <20030402175051.GA24510@vailsys.com> Message-ID: <20030402123327.7be6b56b.cpressey@catseye.mb.ca> On Wed, 2 Apr 2003 11:50:51 -0600 Rick Pettit wrote: > On Tue, Apr 01, 2003 at 12:38:31PM -0600, martin j logan wrote: > > > > Here is how the other ninety nine and one half sees it: > > > > 1. Crashing is a great way to handle errors ==C++== seg faults on > > purpose. > > Don't say it that way. Segfaults are NOT done on purpose (i.e. no > C/C++ programmer that I know of _wants_ his code to segfault, whereas > in Erlang you may intend for your process to die and be reborn. Not a > clear analogy. I think what Martin was trying to say is that when you say that crashing is a great way to handle errors, what the average C++ guy hears is 'Seg fault on purpose? That makes no sense. These Erlang people are crazy. Etc.' > [...] > Not sure how to address this one. I have worked too much with C++ and > not enough with Erlang to make a good call on this. Static typing has > helped me a great deal with my C++ code. Working in languages like > Perl in the past (intern days) without strict type checking I managed > to get myself into trouble as the code got really big and I failed to > [re]factor it into manageable units (especially since Perl insists on > there being "more than one way" to do anything). Is the same not true > with Erlang/OTP? Yes. But IMO Perl's problems go way beyond just having dynamic typing, as well. > Has anyone ever written an OTP application that crashed as the result > of passing the wrong type into a function or by misspelling a > variable? Crashed, no. Failed, yes. And that, I think, is an important point. To most people, "crash" is a dirty word because *they associate it with loss of data*. But (even before I encountered Erlang) I realized that a crash is, at least, a clear indication that something has gone wrong. What is worse is the insiduous failure... the semantic error in the system that you don't consciously notice for a long time because it *doesn't* make anything crash outright. It just bungs up the works and leaves you with the feeling that your system is inhabited by gremlins. > Of course > with test-first methodology such a crash should not occur in > production, but still I can't help but wonder what is so wrong with > such a silly mistake being caught at compile time (since the > misspelling, for example, would have been caught by a lack of > declaration of the typo, and the bad function call would have also > been caught). Catching errors as soon as possible is a good thing (and can help avoid gremlins too). I think there's something of a false dilemma here, too - the dynamic typing advocates usually take the position that strong typing is stifling (which it is,) while the strong typing advocates usually take the position that once you have strong typing, you don't need dynamic typing (which is a very systems-construction-ish approach that doesn't lend itself well to ad-hoc networks and hot code reloading.) My thought is that the best system would have both compile-time and run-time checks. > > 5. Run time code reload on top of all of this gets you disbelieving > > looks and you are dismissed as being a crackpot:) > > Shoot down C/C++ junkies here by discussing shared objects and runtime > linkage. Is that not a similar creature? Not sure why one would be so > much scarier than the other. Because runtime linkage typically only happens once during a run of a program, whereas hot code swapping can happen any number of times with any number of changes the to code in the interim. -Chris From rpettit@REDACTED Wed Apr 2 21:18:15 2003 From: rpettit@REDACTED (Rick Pettit) Date: Wed, 2 Apr 2003 13:18:15 -0600 Subject: FAQ terminology harmonisation In-Reply-To: <20030402123327.7be6b56b.cpressey@catseye.mb.ca> References: <16009.12305.864364.894513@antilipe.corelatus.se> <1049222312.14147.594.camel@berimbau> <20030402175051.GA24510@vailsys.com> <20030402123327.7be6b56b.cpressey@catseye.mb.ca> Message-ID: <20030402191815.GE24510@vailsys.com> On Wed, Apr 02, 2003 at 12:33:27PM -0600, Chris Pressey wrote: > I think what Martin was trying to say is that when you say that crashing > is a great way to handle errors, what the average C++ guy hears is 'Seg > fault on purpose? That makes no sense. These Erlang people are crazy. > Etc.' Ah, that makes more sense. Though I know loss of data is a concern when anything crashes. > Yes. But IMO Perl's problems go way beyond just having dynamic typing, > as well. Agreed. Bad example. I try to stay away from Perl for everything but the quick-and-dirty scripts these days. > > Has anyone ever written an OTP application that crashed as the result > > of passing the wrong type into a function or by misspelling a > > variable? > > Crashed, no. Failed, yes. > > And that, I think, is an important point. To most people, "crash" is a > dirty word because *they associate it with loss of data*. Agreed. > But (even before I encountered Erlang) I realized that a crash is, at > least, a clear indication that something has gone wrong. What is worse > is the insiduous failure... the semantic error in the system that you > don't consciously notice for a long time because it *doesn't* make > anything crash outright. It just bungs up the works and leaves you with > the feeling that your system is inhabited by gremlins. Agreed. Assertions can be made in these cases to prevent this very dilemma. Design by contract seems to address this. > Catching errors as soon as possible is a good thing (and can help avoid > gremlins too). > > I think there's something of a false dilemma here, too - the dynamic > typing advocates usually take the position that strong typing is > stifling (which it is,) while the strong typing advocates usually take > the position that once you have strong typing, you don't need dynamic > typing (which is a very systems-construction-ish approach that doesn't > lend itself well to ad-hoc networks and hot code reloading.) I think I follow... > My thought is that the best system would have both compile-time and > run-time checks. I fully agree. > Because runtime linkage typically only happens once during a run of a > program, whereas hot code swapping can happen any number of times with > any number of changes the to code in the interim. Well yes, unless the C/C++ application loading the shared object (which in turn requires runtime linkage) does so over and over again (i.e. loads .so, then later unloads and reloads NEW .so, and so on). In this case I don't see the difference. Unless I am missing something here, regardless of type checking the interface to the [shared object|hot code being loaded] MUST remain the same in BOTH cases. Of course the code behind the interface can change as much as it wants to, also in both cases. In this sense I see no difference between Erlang hot code load and loading/unloading of shared objects. Am I missing something? -Rick From cpressey@REDACTED Wed Apr 2 22:12:44 2003 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 02 Apr 2003 14:12:44 -0600 Subject: Raskin book on UI and radical data thoughts In-Reply-To: <4.2.2.20030401203718.00a30540@duomark.com> References: <4.2.2.20030401203718.00a30540@duomark.com> Message-ID: <20030402141244.2556d527.cpressey@catseye.mb.ca> On Tue, 01 Apr 2003 21:07:37 -0800 Jay Nelson wrote: > Paulo mentioned Jef Raskin's book on UI. I'm not sure what to make of Raskin's claims. >From http://humane.sourceforge.net/the/not_an_editor.html : "Commands never become invisibly hidden deep in a menu structure, and can be invoked at any time, just as in command-line systems" What I take from this is that commands do indeed stay invisibly hidden - in a man page or help file. Not exactly a great leap forward. "but you never get locked into modes" This seems to go against the idea of THE's "LEAP mode" as described in http://www.businessweek.com/technology/content/jan2003/tc20030122_7027.htm So I guess the operative word is "locked" rather than "mode". Is his position that modes, once entered, ought to be immediately canceled by any user action that isn't addressed by the mode? Hard to tell. More from the BusinessWeek review: "At its heart, THE is a command-line system, but it adds a key element: visibility. The user should see information only when needed." I don't see how this conflicts with drop-down menus, in fact this seems to be the very idea behind why menus drop down or pop up. "Raskin accomplishes this simply. The cursor is represented by a flashing blue block. Within the blue block sits a single letter or text command such as space (indicated by a black dot) or a tab (indicated by an arrow). Why is this useful? Think of all the times you've chased phantom paragraph commands with the backspace key in an effort to realign sentences and eliminate shortened lines. There's also the havoc wrought by a forgotten tab. In THE, you see the tab by mousing over the space without having to flip back and forth between viewing modes." I'm tempted to say, "big deal" - even ol' CygnusEd on my Amiga 500 allowed you to make tabs visible (and IIRC spaces too.) The only innovation here is that it now happens on mouseover. Whee. I'm also tempted to go one step further - it's tabs themselves that are flawed. Tabs *as part of the text* are a huge mistake. Tabs should be part of the layout, which ideally should be seperate from the text. Personally I never use tabs except where I absolutely have to (<> Makefiles.) So, while I'll give him due credit for the terms he's coined, and while he seems to have the best of intentions, I think I'm a bit nonplussed by Mr. Raskin's actual ideas. Of course, my reaction isn't based on working with THE; I don't have a Mac handy. But even that's a little suspect - if *all* modern GUI's are "fundamentally flawed" then certainly there's no good reason for him to base his prototype on one particular system or another... ? > I may have to try to find a copy of the book because some > of the ideas seem familiar to what I have been thinking about > lately. > > "Perhaps we don't need applications at all. This revolutionary idea > is explored at length in the book. In Raskin's world, instead of > buying software applications, we buy application-independent command > sets that plug into our general user interface. The command sets > would work with transformers that change content from one data type > to another (allowing you to check spelling in a graphic using > optical character recognition, for example). > [...] I'm still hedging on this, for two reasons. One is, to me, application = command set. This isn't a very radical change. It's not like applications will disappear, only that they might be packaged more loosely. Erlang's definition of an application (e.g. stdlib is an application) is a very good example of this. Two is that I see the problem as inherently being one of data interchange (protocol). If two command set vendors can't describe the same kinds of data objects in the same way, they can't work together, and any advantage gotten from discarding the application as container, is lost. There are basically two reasons for why data interchange is in such a sorry state. One (the bad reason) is that companies are often far too paranoid about their stuff. If other companies can build things which access their data, that means that their customers are no longer solely dependent upon them for their business. My corner of the industry is extremely bad for this, to the point where two software systems can be said to "interface" if one captures the already-formatted and post-driver (i.e. encoded for a particular printer) output of the other, parses it, and imports it. This sort of thing makes my teeth ache. The other reason is the justifiable reason - that one vendor has developed a product that actually encompasses something new, different, non-gratuitous, and useful, as a means of acquiring market share by giving their customers something superior. When the data for that product is exported to another product, it will lose that specialization - and there's no simple way to recover it when it's imported back into the original product. There are lots of ways to work around the problem, but there's no way to actually solve it - true interchange can only take place when the capabilities of the two things doing the interchanging actually match. You could break down all data in day-to-day use, codify and standardize it, but you run the risk of saying "This is the defining essence of a spreadsheet and a spreadsheet shall never be anything more than this" - and consequently penalizing innovation. On the other topic: > An interesting > approach would be to make the disk single-assignment. *Never* > allow data to be modified, only allow new versions of the > data to be created and retain all versions for their lifetime. I think we already have these: journalling file systems? -Chris From cpressey@REDACTED Wed Apr 2 22:27:34 2003 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 02 Apr 2003 14:27:34 -0600 Subject: FAQ terminology harmonisation In-Reply-To: <20030402191815.GE24510@vailsys.com> References: <16009.12305.864364.894513@antilipe.corelatus.se> <1049222312.14147.594.camel@berimbau> <20030402175051.GA24510@vailsys.com> <20030402123327.7be6b56b.cpressey@catseye.mb.ca> <20030402191815.GE24510@vailsys.com> Message-ID: <20030402142734.405cd5e8.cpressey@catseye.mb.ca> On Wed, 2 Apr 2003 13:18:15 -0600 Rick Pettit wrote: > On Wed, Apr 02, 2003 at 12:33:27PM -0600, Chris Pressey wrote: > [...] > > Because runtime linkage typically only happens once during a run of > > a program, whereas hot code swapping can happen any number of times > > with any number of changes the to code in the interim. > > Well yes, unless the C/C++ application loading the shared object > (which in turn requires runtime linkage) does so over and over again > (i.e. loads .so, then later unloads and reloads NEW .so, and so on). > In this case I don't see the difference. But how often does this happen in practice? My impression is that .so's are employed almost exclusively so that an application doesn't use up memory for code until it knows it needs it. i.e. for many (most? all?) programs that are built with .so's I've also seen options to build them with statically linked-in libraries. (Sometimes this is done to make it easier for the user, so that they don't have to download .so's and/or so the system won't accidentally try to load old .so's.) > Unless I am missing something here, regardless of type checking the > interface to the [shared object|hot code being loaded] MUST remain the > same in BOTH cases. Of course the code behind the interface can change > as much as it wants to, also in both cases. In this sense I see no > difference between Erlang hot code load and loading/unloading of > shared objects. > > Am I missing something? Not really - it's not as much a question of capability, as it is of how they're commonly used. Perhaps the issue is that compiled programs using .so's generally aren't fault-tolerant in the same way Erlang is, so using them for hot-swapping is that much scarier. At least with a well written Erlang program, if you swap in something that's up to no good, you can swap it out again and put in the old thing. With a C program, the seg fault would have already happened, and there would be nothing more you could do. Either way, the interface can't change... well, yes and no. The interface between functions can't change. But the interface within the data passed to the functions might. A new option {foo, bar} might be added to a list of configuration options, or an old one might be deprecated. Not sure if this is what you were thinking of, though. > -Rick -Chris From rpettit@REDACTED Wed Apr 2 23:16:42 2003 From: rpettit@REDACTED (Rick Pettit) Date: Wed, 2 Apr 2003 15:16:42 -0600 Subject: FAQ terminology harmonisation In-Reply-To: <20030402142734.405cd5e8.cpressey@catseye.mb.ca> References: <16009.12305.864364.894513@antilipe.corelatus.se> <1049222312.14147.594.camel@berimbau> <20030402175051.GA24510@vailsys.com> <20030402123327.7be6b56b.cpressey@catseye.mb.ca> <20030402191815.GE24510@vailsys.com> <20030402142734.405cd5e8.cpressey@catseye.mb.ca> Message-ID: <20030402211642.GJ24510@vailsys.com> On Wed, Apr 02, 2003 at 02:27:34PM -0600, Chris Pressey wrote: > > Well yes, unless the C/C++ application loading the shared object > > (which in turn requires runtime linkage) does so over and over again > > (i.e. loads .so, then later unloads and reloads NEW .so, and so on). > > In this case I don't see the difference. > > But how often does this happen in practice? Perhaps not often in other companies, but I have personnally written shared object libraries that are meant to be loaded/unloaded/reloaded as the implementation behind the interface evolves. Works really well, too, in that C/C++ clients talk to Erlang servers via these shared objects, and as long as the API from C/C++ app to shared object stays the same all sorts of neat changes can take place both on server side (hot code load) and on client side (shared library swap), with NO DOWNTIME! > My impression is that .so's are employed almost exclusively so that an > application doesn't use up memory for code until it knows it needs it. This is perhaps most common use. > i.e. for many (most? all?) programs that are built with .so's I've also > seen options to build them with statically linked-in libraries. > (Sometimes this is done to make it easier for the user, so that they > don't have to download .so's and/or so the system won't accidentally try > to load old .so's.) Agreed. I think that is the case. Also, applications with statically compiled shared objects do not need to make libdl calls to load/unload explicitly, IIRC. Of course this means such binaries can NOT reload shared objects on the fly. > Perhaps the issue is that compiled programs using .so's generally aren't > fault-tolerant in the same way Erlang is, so using them for hot-swapping > is that much scarier. At least with a well written Erlang program, if > you swap in something that's up to no good, you can swap it out again > and put in the old thing. With a C program, the seg fault would have > already happened, and there would be nothing more you could do. Agreed, though segfaults normally occur in software that is not defensive and has not been coded under a test-first methodology. Not sure there is a big difference between loading a shared object that core's the application and hot-loading Erlang code that keeps killing the process it was loaded into. Only difference is that supervisor would probably restart OTP process, as would inittab entry on Solaris or daemontools, etc. In both cases the new code has to be taken back out and the good version put back in. In both cases the new code caused a problem. Though the entire application may not have gone down in the OTP realm, that may not mean that it can function normally (or at all). My point is that there is NOT a big difference between the two, and that is how Martin should approach the sales pitch with C/C++ guys who argue against hot-code load but are all for shared objects. > Either way, the interface can't change... well, yes and no. The > interface between functions can't change. But the interface within the > data passed to the functions might. A new option {foo, bar} might be > added to a list of configuration options, or an old one might be > deprecated. Not sure if this is what you were thinking of, though. Well, yes and no. That is no different than putting an extra node into a data structure passed in C/C++ IMO. The basic interface MUST remain the same in both cases, but can be modified via the actual data passed in, also in both cases. Again, my point being that there is no real difference between Erlang/OTP hot code load and C/C++ shared object loading, so Martin's sales pitch can include this fact. Under this light, the idea of hot code load is NOT all that crazy. -Rick From jay@REDACTED Thu Apr 3 05:02:02 2003 From: jay@REDACTED (Jay Nelson) Date: Wed, 02 Apr 2003 19:02:02 -0800 Subject: Raskin book on UI and radical data thoughts In-Reply-To: <20030402141244.2556d527.cpressey@catseye.mb.ca> References: <4.2.2.20030401203718.00a30540@duomark.com> <4.2.2.20030401203718.00a30540@duomark.com> Message-ID: <4.2.2.20030402185156.00d37100@duomark.com> Chris Pressey wrote: >I'm not sure what to make of Raskin's claims. >So I guess the operative word is "locked" rather than "mode". Is his >position that modes, once entered, ought to be immediately canceled by >any user action that isn't addressed by the mode? Hard to tell. I took it that he didn't like modes at all, but for some reason decide to allow LEAP to violate that approach. >So, while I'll give him due credit for the terms he's coined, and while >he seems to have the best of intentions, I think I'm a bit nonplussed by >Mr. Raskin's actual ideas. I would agree, but might still want to read to hear his arguments. Often they spur other ideas. I'm not willing to pay $40 or whatever seems to be the going textbook rate now. I just reacted to the paragraph because it hit some of the topics I've been thinking about. >There are basically two reasons for why data interchange is in such a >sorry state. Agreed. There is no incentive on the part of software *sellers* to make this easy. Open source software should want compatibility however. Isn't XML supposed to fix all this anyway? ;-) >I think we already have these: journalling file systems? The user never sees it and the versioning isn't available. Or rather, I know my Linux recovers faster now but I have no idea how it works. Maybe I need to read up on the file system and see how to expose the timestamps and versioning. jay From cpressey@REDACTED Thu Apr 3 05:40:37 2003 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 02 Apr 2003 21:40:37 -0600 Subject: FAQ terminology harmonisation In-Reply-To: <20030402211642.GJ24510@vailsys.com> References: <16009.12305.864364.894513@antilipe.corelatus.se> <1049222312.14147.594.camel@berimbau> <20030402175051.GA24510@vailsys.com> <20030402123327.7be6b56b.cpressey@catseye.mb.ca> <20030402191815.GE24510@vailsys.com> <20030402142734.405cd5e8.cpressey@catseye.mb.ca> <20030402211642.GJ24510@vailsys.com> Message-ID: <20030402214037.3b920ca8.cpressey@catseye.mb.ca> On Wed, 2 Apr 2003 15:16:42 -0600 Rick Pettit wrote: > On Wed, Apr 02, 2003 at 02:27:34PM -0600, Chris Pressey wrote: > > > Well yes, unless the C/C++ application loading the shared object > > > (which in turn requires runtime linkage) does so over and over > > > again(i.e. loads .so, then later unloads and reloads NEW .so, and > > > so on). In this case I don't see the difference. > > > > But how often does this happen in practice? > > Perhaps not often in other companies, but I have personnally written > shared object libraries that are meant to be loaded/unloaded/reloaded > as the implementation behind the interface evolves. Works really > well, too, in that C/C++ clients talk to Erlang servers via these > shared objects, and as long as the API from C/C++ app to shared object > stays the same all sorts of neat changes can take place both on server > side (hot code load) and on client side (shared library swap), with NO > DOWNTIME! Hey, if it works, more power to you. I'm still in a position where I'm working on projects where a couple of minutes of downtime is acceptable, so my experience with hot swapped code comes mostly from playing with it - and I don't think I've ever written a .so - so I'm out of my element here. > [...] > My point is that there is NOT a big difference between the two, and > that is how Martin should approach the sales pitch with C/C++ guys who > argue against hot-code load but are all for shared objects. In light of your success with it - yes indeed. -Chris From vlad_dumitrescu@REDACTED Thu Apr 3 08:45:16 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Thu, 3 Apr 2003 08:45:16 +0200 Subject: adding generic functionality Message-ID: Hi everyone, I have been trying to implement a model-view pattern, using a process group to hold together the views and have some thoughts about some issues. - the model sends a change notification before returning from handle_xxx or from the state function (if a gen_fsm). Since this is generic functionality, I started thinking if it could be abstracted as such and reused. The simplest way is to modify gen_server/gen_fsm, but it seems awkward: we might end with an endless flora of behaviours, handling every combination of features. It would be nice if it were possible to plug in such "mix-in" functionality, but I couldn't find a nice way. - using process groups is cool, but I started thinking about them as "channels of communicatio": a bus where processes can connect and send/receive notifications. It would be nice, I thought, if Joe's idea from UBF, of using a middle-man to type-check the communication protocols. The channel is such a middle-man and could be extended to allow this (and maybe other) addition. Would it be useful? Any feedback will be very appreciated. Thanks in advance. Regards, Vlad From martin@REDACTED Wed Apr 2 22:47:40 2003 From: martin@REDACTED (martin j logan) Date: 02 Apr 2003 14:47:40 -0600 Subject: FAQ terminology harmonisation In-Reply-To: <20030402175051.GA24510@vailsys.com> References: <16009.12305.864364.894513@antilipe.corelatus.se> <1049222312.14147.594.camel@berimbau> <20030402175051.GA24510@vailsys.com> Message-ID: <1049316460.14093.717.camel@berimbau> On Wed, 2003-04-02 at 11:50, Rick Pettit wrote: > On Tue, Apr 01, 2003 at 12:38:31PM -0600, martin j logan wrote: > > > > Here is how the other ninety nine and one half sees it: > > > > 1. Crashing is a great way to handle errors ==C++== seg faults on > > purpose. > > Don't say it that way. Segfaults are NOT done on purpose (i.e. no C/C++ > programmer that I know of _wants_ his code to segfault, whereas in Erlang you > may intend for your process to die and be reborn. Not a clear analogy. Perhaps I can clarify my little ==== bit here. When explaining how things are done in Erlang is is often said that "you should not explicitly handle errors just let the process crash". When a person used to programming in C or C++ hears that they often think crash/segfault that can't ever be good. Stating that "letting a process crash in lieu of handling an error explicitly" is a good thing is not the best way to present the supervision feature of OTP/Erlang to non-erlangers. > > > 2. 20000 processes ==average UNIX guy== real slow > > Don't say it that one. Entire node is *1* UNIX process running a thread per > OTP process. That doesn't sound nearly as slow. > We talk about spawning processes very casually when explaining Erlang. I know the look that I get when I say "This app is comprised of thousands of processes". To most people familiar with concurrency at the UNIX OS level or any number of threading schemes this sounds preposterous. Even after explanation most don't believe it until they have worked with it. Most will not get that opportunity as they will right you off after hearing about your 20000 processes:) > > 3. don't be defensive ==Most other languages== sloppy incomplete error > > checking > > Most languages would argue that you _should_ be defensive (ex. checking for > NULL, catching exceptions, etc.) Not sure this one is clear. It is common in Erlang code to explicitly handle errors only on untrusted interfaces. This is not the case in most other languages and sounds rather radical/unrealistic to the uninitiated. > > 4. Dynamic typing combined with "don't be defensive" ==Most static > > typing theory junkies== just can't work. After saying that you should not be defensive your labeled a radical if you then follow it with "...and its all dynamically typed" you will be walked to the door and asked never to come back. We know after programming Erlang that judicious coding practice and all of Erlangs pluses allow very correct fault tolerant code to be written. Most people do not believe this until they see it. I hope this is more clear now. Cheers, Martin From rpettit@REDACTED Wed Apr 2 23:51:08 2003 From: rpettit@REDACTED (Rick Pettit) Date: Wed, 2 Apr 2003 15:51:08 -0600 Subject: FAQ terminology harmonisation In-Reply-To: <1049316460.14093.717.camel@berimbau> References: <16009.12305.864364.894513@antilipe.corelatus.se> <1049222312.14147.594.camel@berimbau> <20030402175051.GA24510@vailsys.com> <1049316460.14093.717.camel@berimbau> Message-ID: <20030402215108.GK24510@vailsys.com> On Wed, Apr 02, 2003 at 02:47:40PM -0600, martin j logan wrote: > > Perhaps I can clarify my little ==== bit here. > > When explaining how things are done in Erlang is is often said that "you > should not explicitly handle errors just let the process crash". When a > person used to programming in C or C++ hears that they often think > crash/segfault that can't ever be good. Stating that "letting a process > crash in lieu of handling an error explicitly" is a good thing is not > the best way to present the supervision feature of OTP/Erlang to > non-erlangers. Agreed. Chris cleared this silly misunderstanding up for me. > We talk about spawning processes very casually when explaining Erlang. I > know the look that I get when I say "This app is comprised of thousands > of processes". To most people familiar with concurrency at the UNIX OS > level or any number of threading schemes this sounds preposterous. Even > after explanation most don't believe it until they have worked with it. > Most will not get that opportunity as they will right you off after > hearing about your 20000 processes:) Right, but again there is only *1* OS process, with many threads of execution within it. 20000 UNIX processes DOES sound preposterous! > > Most languages would argue that you _should_ be defensive (ex. checking for > > NULL, catching exceptions, etc.) Not sure this one is clear. > > It is common in Erlang code to explicitly handle errors only on > untrusted interfaces. This is not the case in most other languages and > sounds rather radical/unrealistic to the uninitiated. Agreed. I suppose it is interesting to point out that if a C/C++ application was _also_ comprised of individual processes which _could_ crash then a similar approach could be taken. That is, checking for NULL and catching exceptions would NOT have to happen on internal code, only at the border. The difference here is that of restarting a light-weight thread within the OTP node vs. an entire UNIX process. Don't see any other big differences between letting an OTP process (not on the border) to blow up vs. letting a C/C++ application referencing NULL pointer blow up. In both cases, if the overall system is coded to cope with such process deaths than it doesn't really matter, aside from the performance hit restarting a UNIX process vs. a very light-weight Erlang one. > > > 4. Dynamic typing combined with "don't be defensive" ==Most static > > > typing theory junkies== just can't work. > > After saying that you should not be defensive your labeled a radical if > you then follow it with "...and its all dynamically typed" you will be > walked to the door and asked never to come back. We know after > programming Erlang that judicious coding practice and all of Erlangs > pluses allow very correct fault tolerant code to be written. Most people > do not believe this until they see it. Though I do not disagree that judicious coding practice coupled with the many wonderful features of Erlang can lead to a large body of correct/fault-tolerant code, I have my doubts about that codes reusability. I can hear the anti-OO guys out there are already, and I agree that such OO concepts as inheritance are not all they are cracked up to be in practice (i.e. usually a good inheritance tree comes about as the result of refactoring an existing system, since it may not have been clear at design time how the tree should be layed out). A big difference is reusing functions/objects internally that ARE defensively coded. Put another way, most all my objects ARE defensive, and might as well be placed "on the border". Since this is true, I can reuse an internal object on the border without worrying about crashes. I can make calls to it from anywhere and know that it is well behaved. The same is NOT true with an Erlang module that is coded to crash on bad data since it is not meant for border use. It would be a big mistake to use such a module in a border case, and thus it is important as an Erlang/OTP developer to make crystal clear the distinction. Of course the code is much smaller when it is not defensively coded throughout the application, no argument there. But when both sides (i.e. C/C++ and Erlang OTP) are coded that way, what is the difference? I suppose defensively coding EVERYTHING is a bit silly and unnecessary, but this is not a strengh/weakness of Erlang/OTP, merely a coding practice that can be (or not be) applied to any language. > I hope this is more clear now. Much. Thank you. -Rick From martin@REDACTED Thu Apr 3 01:16:57 2003 From: martin@REDACTED (martin j logan) Date: 02 Apr 2003 17:16:57 -0600 Subject: FAQ terminology harmonisation In-Reply-To: References: Message-ID: <1049325417.14147.737.camel@berimbau> On Wed, 2003-04-02 at 03:58, Joe Armstrong wrote: > > > > > On 1 Apr 2003, martin j logan wrote: > > > All, > > This thread has yielded quite a discussion. I must admit that I > > became quite sick reading Bjorns email proposing pointer syntax and > > destructive assignment, I did not catch the joke until I read further - > > scary. While some of the suggestions about "nice-ing up" Erlang > > terminology might not sit well with most people on this list, I think > > the idea of making Erlang terminology intelligible and accessible to > > managers and the like is an issue that needs to be addressed. I know > > that all of the people on this list love the language the way it is and > > would like to see it spread. I also know what it is like to try to sell > > a C/C++ shop's management, and engineers for that matter, on something > > new like Erlang. This task is made more difficult when things like, > > letting processes crash being a good thing, are mentioned. It is > > difficult for them to wrap their minds, addled by years of C/C++ > > programming:) around "not being defensive, just letting it crash, and > > spawn 20 thousand processes". This difficulty is compounded with those > > phrases are thrown in the mix with dynamic typing, run time code reload, > > and location transparency. Most of the time people look at you like you > > have been smoking something! Am I wrong here??? I don't think that we > > should compromise the basic foundations of the language. Erlang is > > functional, concurrent, a process is a process, a list is a list, and a > > node is a erlang virtual machine:) I just think that we should not be > > shy away from well chosen euphemisms - they should an important part of > > every would-be Erlang salesman's life. > > I think you're both right and wrong here - it depends who you are > selling. > > The sales pitch has to be two dimensional, i.e. > > Problem X Person > > To start with the problem domain has to be suitable for Erlang - so > I spend a great deal of time listening to what peoples problem are > before recommending Erlang - often I recommend C - or even visual basic. > > You have to ask the question: What is Erlang good at? - the answer > is not *everything* - the answer is that it is good at distribution > and fault-tolerant stuff - it's not good at sequential "poking around > in memory" stuff ... > > Then there is the person - the augment directed to a "suit" or "a > unix guy" or "a java person" are just not the same. > I agree. > "suits" need special treatment ... (two sub-categories of suit are > VC (venture capitalist) and "LM" Line management > > If I'm selling to "VC" I always use the "MAKE MORE MONEY FAST" > argument - I present them with good hard evidence that Erlang projects > have a higher chance of succeeding than non-Erlang projects. > > "VC" are more likely to take risks, so they like this argument - > though they will press hard on details. > > The main objection of the "LM" is that "Erlang in not Java/C++" - if > they allow Erlang they are often taking a big personal risk - they > actual stand to gain if they have large development teams and everything > takes a long time - their pay = LengthOfTimeOFPROJECT X #people in > project - so Erlang is a no no here. This is the place we need to sell the hardest. Erlang needs to shine here. > > Selling to programmers is different - getting the "Early adopters is > easy" they *like* new stuff - it's the mainstream that's the problem - > they want "lots of stuff for free" - they think "Oh dear, their's no > GUI - so I can't use Erlang" - the early adopters think "Oh great, > their's no GUI - I'll write one myself ..." > > Arguments have to be *careful* matched against the Problem X > Mindset of the person you are trying to sell Erlang to - if anything > the trend is towards economic rather than technical arguments which > indicates a movement towards the main stream ... > The thing is, erlang is a wonderful tool for capitalizing on economic opportunities. Rapid Development, high ROI, low maintenance... The list goes on. How do we position ourselves/Erlang?? How does Erlang capitalize?? > What does bite are "statement by other people" - press releases by > Nortel and Ericsson where they say "Erlang is great" have much more > credibility than anything we can say. Unfortunately big companies > don't usually make a big deal of "the technology inside" (apart from > Intel) - since non of their customers actually care what's inside. > > Todays article (New great stuff from Nortel programmed in Erlang) > in Computer Sweden is a good example ... > > I still think the best method is "success stories" ... Joe, I fully agree with you on this one. I think that one way to have more of these would be to sell the "LM". > Cheers, Martin > /Joe > > > > > > Here is how the other ninety nine and one half sees it: > > > > 1. Crashing is a great way to handle errors ==C++== seg faults on > > purpose. > > > > 2. 20000 processes ==average UNIX guy== real slow > > > > 3. don't be defensive ==Most other languages== sloppy incomplete error > > checking > > > > 4. Dynamic typing combined with "don't be defensive" ==Most static > > typing theory junkies== just can't work. > > > > 5. Run time code reload on top of all of this gets you disbelieving > > looks and you are dismissed as being a crackpot:) > > > > This is not the way to sell something. I am not suggesting that we > > compromise what Erlang is, that would be a worse mistake than being bad > > sales people. I am saying that we get used to saying things in a more > > marketing friendly way. > > > > Example: > > > > Erlang allows the programmer easily generate exceptions when a process > > gets into a bad state, these exceptions can be simply used to "reset the > > state of a process" instead of crashing the application. > > > > ok = demo:do() > > > > allows state to be reset if demo:do were to return 'error'. The process > > is then immediately ready to do work again. This makes programming > > customers applications much easier and the apps themselves much more > > robust. The beauty is that it is all built in, saving you development > > time and headache - more ROI. > > > > Just an idea maybe over the top - a bit:) but I think that saying things > > in a "nice" way needs to be contemplated. > > > > My 2 cents, > > Martin > > > > > > > > On Tue, 2003-04-01 at 00:22, Matthias Lang wrote: > > > Hi, > > > > > > Recently, there was some confusion on the list about the meaning of > > > "Defensive Programming" in the context of Erlang. For most > > > programmers, defensive programming is a good thing, yet in the Erlang > > > programming guidelines it is considered a bad thing. Therefore I've > > > renamed it to "micro-managed error handling" to make the author's > > > intent clearer. While doing that, I also tackled a number of similar > > > problems: > > > > > > crash: again, in most languages crashing is bad whereas in Erlang it > > > confusingly enough becomes a good thing. The FAQ now refers > > > to such events as "inter-process exceptions (IPEs)" > > > > > > single-assignment: is a very academic term for what most people > > > would call "const" variables. I have coined the replacement > > > term "auto-consting". > > > > > > tail-recursion: very powerful feature. Ridiculously academic name. > > > Now called stack-unrolling. > > > > > > process: thread. An process is very lightweight. The rest of the > > > world refers to lightweight processes as threads. So does the > > > Erlang FAQ from now on. > > > > > > node: process. An Erlang node is always an OS process. So we may as > > > well call a spade a spade. "process" now means "erlang node". > > > > > > behaviour: interface. In R9B-2, the directive '-public(gen_server).' > > > is a synonym for '-behaviour'. In R10, the -behaviour > > > directive will elicit a warning. By R11 an error. > > > > > > list: array. Everyone knows what an array is. > > > > > > Any further suggestions? > > > > > > Matthias > > > > > > From eleberg@REDACTED Thu Apr 3 08:50:17 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Thu, 3 Apr 2003 08:50:17 +0200 (MEST) Subject: FAQ terminology harmonisation Message-ID: <200304030650.h336oHi06796@cbe.ericsson.se> > From: James Hague > Lisp has grown crusty in certain ways and can be awkward after > using more modern functional syntax the major problem i have with erlang vs lisp is erlangs syntax. it is not sufficiently symetric, i suppose (i prefer matching start-stop markers). and i have a terrible time remembering if i should use ;/, or not, in case statements. bengt From erlang@REDACTED Thu Apr 3 09:05:26 2003 From: erlang@REDACTED (Peter-Henry Mander) Date: Thu, 03 Apr 2003 08:05:26 +0100 Subject: FAQ terminology harmonisation References: <16009.12305.864364.894513@antilipe.corelatus.se> <1049222312.14147.594.camel@berimbau> <20030402175051.GA24510@vailsys.com> <20030402123327.7be6b56b.cpressey@catseye.mb.ca> <20030402191815.GE24510@vailsys.com> <20030402142734.405cd5e8.cpressey@catseye.mb.ca> <20030402211642.GJ24510@vailsys.com> <20030402214037.3b920ca8.cpressey@catseye.mb.ca> Message-ID: <3E8BDD36.7040600@manderp.freeserve.co.uk> May I join in? The hot-swap in Erlang operates differently to shared library reloading in one aspect which I think you overlooked: *both* the old and new versions of a hot-loaded module will run in a live system *until* all the code relying on the module have come to a suitable switching point. I'll try to explain with an example, a very simple server process that runs in a loop receiving and acting on messages (which I didn't compile or run, so it may not even work, so spank me :-) -module(simple_server). server() -> receive {tagA,Data} -> %% do A ... server(); % <<<<<<<<<<<<<<<< case A {tagB,Data} -> %% do B ... simple_server:server(); %<<< case B end. The difference between cases A and B is that in case B the server code will be swapped with a new version if one was loaded at that time *without stopping*, whereas case A would continue to use the old version regardless. I believe that reloading shared libraries will require a fair amount of runtime code management programmed by hand, and I'm not sure that loops like this one can be swapped without stopping the server momentarily. The Erlang version simply never stops, never loses any server state. I think that the hot-swapping in Erlang is almost (not quite) implicitly supported, whereas C/C++ the extra work involved in implementing and debugging such a feature just gets in the way of solving more interesting problems. Pete. Chris Pressey wrote: > On Wed, 2 Apr 2003 15:16:42 -0600 > Rick Pettit wrote: > > >>On Wed, Apr 02, 2003 at 02:27:34PM -0600, Chris Pressey wrote: >> >>>>Well yes, unless the C/C++ application loading the shared object >>>>(which in turn requires runtime linkage) does so over and over >>>>again(i.e. loads .so, then later unloads and reloads NEW .so, and >>>>so on). In this case I don't see the difference. >>> >>>But how often does this happen in practice? >> >>Perhaps not often in other companies, but I have personnally written >>shared object libraries that are meant to be loaded/unloaded/reloaded >>as the implementation behind the interface evolves. Works really >>well, too, in that C/C++ clients talk to Erlang servers via these >>shared objects, and as long as the API from C/C++ app to shared object >>stays the same all sorts of neat changes can take place both on server >>side (hot code load) and on client side (shared library swap), with NO >>DOWNTIME! > > > Hey, if it works, more power to you. I'm still in a position where I'm > working on projects where a couple of minutes of downtime is acceptable, > so my experience with hot swapped code comes mostly from playing with it > - and I don't think I've ever written a .so - so I'm out of my element > here. > > >>[...] >>My point is that there is NOT a big difference between the two, and >>that is how Martin should approach the sales pitch with C/C++ guys who >>argue against hot-code load but are all for shared objects. > > > In light of your success with it - yes indeed. > > -Chris > > From jay@REDACTED Thu Apr 3 09:13:22 2003 From: jay@REDACTED (Jay Nelson) Date: Wed, 02 Apr 2003 23:13:22 -0800 Subject: FAQ terminology harmonisation Message-ID: <4.2.2.20030402230851.00d61140@duomark.com> Rick Pettit wrote: > Put another way, most all my objects ARE defensive, and > might as well be placed "on the border". Since this is true, > I can reuse an internal object on the border without worrying > about crashes. I can make calls to it from anywhere and know > that it is well behaved. > >The same is NOT true with an Erlang > module that is coded to crash on bad data since it is not meant > for border use. It would be a big mistake to use such a module > in a border case, and thus it is important as an Erlang/OTP > developer to make crystal clear the distinction. I have been promoting the use of processes as an interface mechanism. Precisely because of reuse issues, it is an important method of integration. Make all your code non-defensive and use a process at the border to do any data filtering to ensure that the reusable code doesn't get bad data. You can also use the filter process to alter the data to match the reusable code's interface if necessary. jay From jay@REDACTED Thu Apr 3 09:25:15 2003 From: jay@REDACTED (Jay Nelson) Date: Wed, 02 Apr 2003 23:25:15 -0800 Subject: Hotswap Message-ID: <4.2.2.20030402232138.00a23cd0@duomark.com> Peter wrote: > -module(simple_server). > server() -> > receive > {tagA,Data} -> %% do A ... > server(); % <<<<<<<<<<<<<<<< case A > {tagB,Data} -> %% do B ... > simple_server:server(); %<<< case B > end. Does the entire module simple_server get loaded? If not, what about new functions that server() might call in the new version? If so, why does Chris say that the interface must stay the same -- wouldn't loading the whole module introduce a potentially new interface? jay From erlang@REDACTED Thu Apr 3 10:59:55 2003 From: erlang@REDACTED (Peter-Henry Mander) Date: Thu, 03 Apr 2003 09:59:55 +0100 Subject: Hotswap References: <4.2.2.20030402232138.00a23cd0@duomark.com> Message-ID: <3E8BF80B.30404@manderp.freeserve.co.uk> You reminded me I need to add the -export([server/0]) and a number of other things, oops! And I think there lies the answer to your question: internally the module may change radically, but if you inconsiderately change the exported function signatures, you can expect the server to throw an exception, which hopefully the program writer will catch with another linked supervisor process, which may potentially diagnose the error and revert to a previous version. I'm speculating here, I haven't actually done this before, but the explanation on error handling and robust applications in the Concurrent Programming in Erlang book is quite easy to grasp. I highly recommend this (rare) book! This doesn't prevent the new version from *enhancing* the exported interface, or adding new exported functions, which highlights another strength of Erlang as a prototyping tool. You could potentially write the code to enable the change from one module design to a totally different one, by proceeding in stages to switch the server loop from one tail recursive function to another in the new module. I'm going to attempt a functioning example of switching code within a running server process in the next hour (work permitting) and hopefully follow this up on the mailing list. It's a good toy project and will solidify my understanding too. Pete. Jay Nelson wrote: > Peter wrote: > > -module(simple_server). > > > server() -> > > receive > > {tagA,Data} -> %% do A ... > > server(); % <<<<<<<<<<<<<<<< case A > > {tagB,Data} -> %% do B ... > > simple_server:server(); %<<< case B > > end. > > Does the entire module simple_server get loaded? > > If not, what about new functions that server() might call > in the new version? > > If so, why does Chris say that > the interface must stay the same -- wouldn't loading > the whole module introduce a potentially new interface? > > jay > > > From etxuwig@REDACTED Thu Apr 3 11:07:34 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Thu, 3 Apr 2003 11:07:34 +0200 (MEST) Subject: FAQ terminology harmonisation In-Reply-To: <20030402215108.GK24510@vailsys.com> Message-ID: On Wed, 2 Apr 2003, Rick Pettit wrote: >Put another way, most all my objects ARE defensive, and >might as well be placed "on the border". Since this is >true, I can reuse an internal object on the border without >worrying about crashes. I can make calls to it from >anywhere and know that it is well behaved. > >The same is NOT true with an Erlang module that is coded to >crash on bad data since it is not meant for border use. It >would be a big mistake to use such a module in a border >case, and thus it is important as an Erlang/OTP developer >to make crystal clear the distinction. Remember that Erlang was designed for environments where "resetting" is probably a more correct description than "crashing" -- the program always has to bounce back, preferrably without the external users noticing. I think the idea of having defensive interfaces wherever human (or otherwise external) input is involved is a good thing, but internal components should assume that the users of the interface have RTFM and use the component properly. In any event, misuse of the component should lead to distinct failures, not mystical semi-correct behaviour. Thus, the main difference between a component at the external border and an internal component is not primarily that one is safe and the other is not, but that one produces an error message intended for mere mortals, while the other fails in a way that gives the programmer as much useful debugging info as possible. I think it's a mistake to confuse the two, but also always try to write my code in the same way in both cases. Error handling in the external interface is taken care of by catching exceptions at the top and interpreting the exception information into a human-readable error message. This top layer will have different semantics depending on the nature of the interface (window-based GUI, command line, HTML pages, ...). I reuse code quite a lot, and I think most Erlang programmers do (I know one who doesn't believe in reusing code, since it's so easy to write working erlang programs from scratch...) >Of course the code is much smaller when it is not >defensively coded throughout the application, no argument >there. But when both sides (i.e. C/C++ and Erlang OTP) are >coded that way, what is the difference? > >I suppose defensively coding EVERYTHING is a bit silly and >unnecessary, but this is not a strengh/weakness of >Erlang/OTP, merely a coding practice that can be (or not >be) applied to any language. I recently dusted off the book "Writing solid code" by Steve Maguire, and browsed through it. Very good book, but it struck me that among the countless good advice on how to write robust C code, the most of it was not relevant to Erlang programmers. The book contains lots of sage advice that's surely relevant regardless of language, but as good as the book is, it's hardly worth it to plow through 200 pages of C-specific coding advice in order to get to those pearls. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From thomasl_erlang@REDACTED Thu Apr 3 11:28:43 2003 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Thu, 3 Apr 2003 01:28:43 -0800 (PST) Subject: FAQ terminology harmonisation In-Reply-To: <20030402175051.GA24510@vailsys.com> Message-ID: <20030403092843.10634.qmail@web13310.mail.yahoo.com> --- Rick Pettit wrote: (First, I agree that the word 'crash' is possibly unfortunate for getting exceptions.) > > 4. Dynamic typing combined with "don't be > defensive" ==Most static > > typing theory junkies== just can't work. > > Not sure how to address this one. I have worked too > much with C++ and not enough > with Erlang to make a good call on this. Static > typing has helped me a great > deal with my C++ code. Working in languages like > Perl in the past (intern days) > without strict type checking I managed to get myself > into trouble as the code > got really big and I failed to [re]factor it into > manageable units (especially > since Perl insists on there being "more than one > way" to do anything). Is the > same not true with Erlang/OTP? > > Has anyone ever written an OTP application that > crashed as the result of > passing the wrong type into a function or by > misspelling a variable? Misspelled variables are caught by the compiler. (Esp. if you use warn_unused_vars.) /.../ > Could someone explain why static typing is > considered so "bad" or "unnecessary"? > I think I could be sold on this (I _do_ consider > myself to be open-minded), I > just need to hear the right argument. Here's my opinion at least. My basic train of thought is this: * The main benefit of Erlang, Lisp, Prolog, SML and so on is _type_safeness_: there is no way that you can accidentally confuse one value's type with another. This (along with GC and pureness) gets rid of the majority of errors. (This is also known as 'strong typing', not to be confused with 'static typing'.) * Static typing a la Hindley-Milner (SML, Haskell, etc) probably helps most when you use higher-order functions aggressively. Erlang programs typically do not employ combinators and suchlike, so the need for such checking is less here. Furthermore, static typing does not check concurrency properties that might be of greater interest to our sort of applications. (Model checking etc. seems to be waiting in the wings for checking that sort of thing.) * Finally, static typing in the sense above is prescriptive: it will reject programs that are okay because it can't prove they are (e.g., heterogenous lists were rejected for a long time; not sure about whether it's handled well these days). This may mean you have to 'code around' the problem, though a static typing guy might say you are removing a latent bug. Also, the programming language designers will have to restrict programs to enable checking (e.g., receive ... end is hard to check in its current form, since any process can potentially send to any process, as is hot code loading, for obvious reasons). Basically, prescriptive typing means you have to sacrifice some convenience and slow down language evolution, so that the type checker can keep up. (Some may think this is a good thing, of course.) The other, less common, approach is descriptive typing: permit any program but flag any strangeness. A sort of "lint-like" approach. This is harder to do (since the checker has to *follow* difficult code rather than reject it, and since there is a problem with false positives due to inaccuracy). Still, I think it's an interesting approach. There have been at least four attempts to do this for Erlang that I know of, but none has really gotten 'out of the gates'. * An aside: an interesting difference between Erlang and SML (say) seems to be that SML programmers appear to talk more about types and how they should be designed before coding. This is something I seldom encounter in writing Erlang programs :-) I haven't seen a good summary of the differences, though. (This thinking seems to be more recent than last time I really looked at FP.) Maybe it's a "Smalltalk-Java" difference. To summarize: Personally, I find that static typing in its current form adds little value to my Erlang programming. Errors due to type mistakes do appear, but not so frequently as to make it a major problem. The consequences are exceptions, not core dumps or quiet madness, so debugging is easier than in the C++ case. (An opinion: Making Erlang even easier to test would probably be more pragmatically beneficial than adding static typing.) Best, Thomas __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - File online, calculators, forms, and more http://tax.yahoo.com From erlang@REDACTED Thu Apr 3 12:02:09 2003 From: erlang@REDACTED (Peter-Henry Mander) Date: Thu, 03 Apr 2003 11:02:09 +0100 Subject: Hotswap References: <4.2.2.20030402232138.00a23cd0@duomark.com> <3E8BF80B.30404@manderp.freeserve.co.uk> Message-ID: <3E8C06A1.6050902@manderp.freeserve.co.uk> Okay, here's my example: I do the following in the shell: 8> c(counter). {ok,counter} 9> counter:start(100). {ok,100} 10> counter:test(). incr decr decr decr reset (previous value=98) get_value => 10 ok All is well. Without issuing counter:stop() I modify the code by uncommenting the new code and commenting out the old. I recompile and run counter:test again: 11> c(counter). {ok,counter} 12> counter:test(). incr **** switching NOW! **** decr decr decr reset (previous value=8) get_value => {10,new_parameter} ok 13> counter:stop(). 10 Et voila! I've modified the loop by litterally switching from one tail recursive function to another (and modified the API for the sake of the demo) with very little effort and without stopping anything. Stuff that into your C/C++ pipe and smoke it! (-: Pete. P.s. I'm an experienced C++ programmer, and I've _never_ found it as easy as *this* to hot swap code, neither as quick to implement! Yay Erlang! Peter-Henry Mander wrote: > You reminded me I need to add the -export([server/0]) and a number of > other things, oops! > > And I think there lies the answer to your question: internally the > module may change radically, but if you inconsiderately change the > exported function signatures, you can expect the server to throw an > exception, which hopefully the program writer will catch with another > linked supervisor process, which may potentially diagnose the error and > revert to a previous version. I'm speculating here, I haven't actually > done this before, but the explanation on error handling and robust > applications in the Concurrent Programming in Erlang book is quite easy > to grasp. I highly recommend this (rare) book! > > This doesn't prevent the new version from *enhancing* the exported > interface, or adding new exported functions, which highlights another > strength of Erlang as a prototyping tool. You could potentially write > the code to enable the change from one module design to a totally > different one, by proceeding in stages to switch the server loop from > one tail recursive function to another in the new module. > > I'm going to attempt a functioning example of switching code within a > running server process in the next hour (work permitting) and hopefully > follow this up on the mailing list. It's a good toy project and will > solidify my understanding too. > > Pete. > > > Jay Nelson wrote: > >> Peter wrote: >> > -module(simple_server). >> >> > server() -> >> > receive >> > {tagA,Data} -> %% do A ... >> > server(); % <<<<<<<<<<<<<<<< case A >> > {tagB,Data} -> %% do B ... >> > simple_server:server(); %<<< case B >> > end. >> >> Does the entire module simple_server get loaded? >> >> If not, what about new functions that server() might call >> in the new version? >> >> If so, why does Chris say that >> the interface must stay the same -- wouldn't loading >> the whole module introduce a potentially new interface? >> >> jay >> >> >> > > > > > -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: counter.erl URL: From erlang@REDACTED Thu Apr 3 12:27:58 2003 From: erlang@REDACTED (Peter-Henry Mander) Date: Thu, 03 Apr 2003 11:27:58 +0100 Subject: Transient "Beowulf" cluster of Erlang nodes. Message-ID: <3E8C0CAE.6010204@manderp.freeserve.co.uk> Hi y'all, I have a small project in mind, and would like to know whether someone has done it before, and if so, how? I intend to harness the redundant processing power of our office PCs as a pool of Erlang nodes while everyone is out (overnight or over the weekend, hence "transient Beowulf cluster") and carry out some stress tests on our product using the office PC cluster to share the processing load. The scheme is to create a Knoppix (http://www.knoppix.net) style boot CD-ROM containing R9B that is inserted into the appropriated PCs, which are rebooted or turned on and left to boot up without any further intervention. The main question is how to get the central controlling node, or all the nodes to automagically discover which PCs have been assimilated into the Erlang cluster without any user intervention, and produce a list of available nodes? Are there any other aspects I have to be aware of? Pete. From thomas.arts@REDACTED Thu Apr 3 13:08:19 2003 From: thomas.arts@REDACTED (Thomas Arts) Date: Thu, 3 Apr 2003 13:08:19 +0200 Subject: Transient "Beowulf" cluster of Erlang nodes. References: <3E8C0CAE.6010204@manderp.freeserve.co.uk> Message-ID: <003801c2f9d1$5580ca20$a22d1081@ituniv398> That sounds like a very good application of the leader election behaviour that Ulf Wiger and I wrote two weeks ago. The leader election behaviour let you select a set of nodes from which one leader has to be selected. These nodes are your PC's. If more than 50% of the PC's is started, a leader is chosen (well, it has some way to choose among a smaller subset, but that is rather dubious). The leader will be known by all involved processes and can be taken as the central node, since the leader knows all participating processes (even those that come in later). Ask Ulf whether you can have the source code. It is produced insite Ericsson, thus I cannot disctribute the code. You would be a beta tester of the code :0). /Thomas --- ACM Sigplan Erlang Workshop Call for papers: http://www.erlang.se/workshop/2003/ Dr Thomas Arts Program Manager Software Engineering and Management IT-university in Gothenburg Box 8718, 402 75 Gothenburg, Sweden http://www.ituniv.se/ Tel +46 31 772 6031 Fax +46 31 772 4899 ----- Original Message ----- From: "Peter-Henry Mander" To: Sent: Thursday, April 03, 2003 12:27 PM Subject: Transient "Beowulf" cluster of Erlang nodes. > Hi y'all, > > I have a small project in mind, and would like to know whether someone > has done it before, and if so, how? > > I intend to harness the redundant processing power of our office PCs as > a pool of Erlang nodes while everyone is out (overnight or over the > weekend, hence "transient Beowulf cluster") and carry out some stress > tests on our product using the office PC cluster to share the processing > load. The scheme is to create a Knoppix (http://www.knoppix.net) style > boot CD-ROM containing R9B that is inserted into the appropriated PCs, > which are rebooted or turned on and left to boot up without any further > intervention. > > The main question is how to get the central controlling node, or all the > nodes to automagically discover which PCs have been assimilated into the > Erlang cluster without any user intervention, and produce a list of > available nodes? > > Are there any other aspects I have to be aware of? > > Pete. > > > > From etxuwig@REDACTED Thu Apr 3 13:55:09 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Thu, 3 Apr 2003 13:55:09 +0200 (MEST) Subject: Hotswap In-Reply-To: <4.2.2.20030402232138.00a23cd0@duomark.com> Message-ID: On Wed, 2 Apr 2003, Jay Nelson wrote: >Peter wrote: > > -module(simple_server). > > > server() -> > > receive > > {tagA,Data} -> %% do A ... > > server(); % <<<<<<<<<<<<<<<< case A > > {tagB,Data} -> %% do B ... > > simple_server:server(); %<<< case B > > end. > >Does the entire module simple_server get loaded? Yes. >If not, what about new functions that server() might call >in the new version? server() might call other functions in the same module, and as long as they are not fully qualified (Module:Function(...)), it will be a "local" call in the same version of the module. If it's a fully qualified call, the function has to be part of the module interface. This is still OK, if that function acts only on the provided arguments (is side-effect free) and it's semantics haven't changed in the upgrade. >If so, why does Chris say that the interface must stay the >same -- wouldn't loading the whole module introduce a >potentially new interface? The interface needs to be backward compatible in the areas that matter (the functions that can be called by old code during or after the upgrade). A way around this is to rely on the OTP code change mechanisms, which allow you to specify dependencies between processes and modules; this way, you can suspend processes that might call incompatible functions or otherwise mess up the upgrade. OTP allows you to perform a fully synchronized, orderly upgrade of a complex, multi-node system -- provided you can figure out how from the documentation, which is no small feat. (: /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From erlang@REDACTED Thu Apr 3 15:18:40 2003 From: erlang@REDACTED (Peter-Henry Mander) Date: Thu, 03 Apr 2003 14:18:40 +0100 Subject: Transient "Beowulf" cluster of Erlang nodes. References: <3E8C0CAE.6010204@manderp.freeserve.co.uk> <003801c2f9d1$5580ca20$a22d1081@ituniv398> Message-ID: <3E8C34B0.5080405@manderp.freeserve.co.uk> oooOOOoooh (o:* Thanks for the lead Thomas, this does sound interesting. May I know a bit more please? I'd be happy to be a tester. Now I need to get Knoppix to work, modify it, and launch Erlang on bootup as a service, perhaps. Unless there's a way of running a "pure" Erlang node on a PC? Pete. Thomas Arts wrote: > That sounds like a very good application of the > leader election behaviour that Ulf Wiger and I wrote two > weeks ago. > > The leader election behaviour let you select a set of > nodes from which one leader has to be selected. > These nodes are your PC's. > If more than 50% of the PC's is started, a leader is > chosen (well, it has some way to choose among a > smaller subset, but that is rather dubious). > > The leader will be known by all involved processes > and can be taken as the central node, since the > leader knows all participating processes (even those > that come in later). > > Ask Ulf whether you can have the source code. It is > produced insite Ericsson, thus I cannot disctribute the code. > > You would be a beta tester of the code :0). > > /Thomas > > --- > ACM Sigplan Erlang Workshop > Call for papers: http://www.erlang.se/workshop/2003/ > > > Dr Thomas Arts > Program Manager > Software Engineering and Management > IT-university in Gothenburg > Box 8718, 402 75 Gothenburg, Sweden > http://www.ituniv.se/ > > Tel +46 31 772 6031 > Fax +46 31 772 4899 > > > ----- Original Message ----- > From: "Peter-Henry Mander" > To: > Sent: Thursday, April 03, 2003 12:27 PM > Subject: Transient "Beowulf" cluster of Erlang nodes. > > > >>Hi y'all, >> >>I have a small project in mind, and would like to know whether someone >>has done it before, and if so, how? >> >>I intend to harness the redundant processing power of our office PCs as >>a pool of Erlang nodes while everyone is out (overnight or over the >>weekend, hence "transient Beowulf cluster") and carry out some stress >>tests on our product using the office PC cluster to share the processing >>load. The scheme is to create a Knoppix (http://www.knoppix.net) style >>boot CD-ROM containing R9B that is inserted into the appropriated PCs, >>which are rebooted or turned on and left to boot up without any further >>intervention. >> >>The main question is how to get the central controlling node, or all the >>nodes to automagically discover which PCs have been assimilated into the >>Erlang cluster without any user intervention, and produce a list of >>available nodes? >> >>Are there any other aspects I have to be aware of? >> >>Pete. >> >> >> >> > > > > From mickael.remond@REDACTED Thu Apr 3 15:54:17 2003 From: mickael.remond@REDACTED (Mickael Remond) Date: Thu, 03 Apr 2003 15:54:17 +0200 Subject: Transient "Beowulf" cluster of Erlang nodes. In-Reply-To: <3E8C0CAE.6010204@manderp.freeserve.co.uk> (Peter-Henry Mander's message of "Thu, 03 Apr 2003 11:27:58 +0100") References: <3E8C0CAE.6010204@manderp.freeserve.co.uk> Message-ID: Peter-Henry Mander writes: > Hi y'all, > > I have a small project in mind, and would like to know whether someone > has done it before, and if so, how? > > I intend to harness the redundant processing power of our office PCs > as a pool of Erlang nodes while everyone is out (overnight or over the > weekend, hence "transient Beowulf cluster") and carry out some stress > tests on our product using the office PC cluster to share the > processing load. The scheme is to create a Knoppix > (http://www.knoppix.net) style boot CD-ROM containing R9B that is > inserted into the appropriated PCs, which are rebooted or turned on > and left to boot up without any further intervention. I had such a project regarding this topics that was called Erwolf. This was basically the same idea + everything needed as a complete Erlang development environnement. The idea was: 1. Being able to build an Erlang set of node quickly and automatically on a rather large number of machines. 2. To have everything Erlang on the go: you can boot the CD everywhere and have a complete and working development environment. I can find my CD image and put it back online. It was difficult to maintain has it was based on Linux from Scratch. Updating the CD with new software was a pain. Now there is Knoppix and I think this is the way to go. If you want to lead the initiative I will help you. If you feel confortable with it, I propose to open a dedicated area on Erlang project, for this Erlang/Linux based distribution. -- Micka?l R?mond http://www.erlang-projects.org/ From mickael.remond@REDACTED Thu Apr 3 16:17:48 2003 From: mickael.remond@REDACTED (Mickael Remond) Date: Thu, 03 Apr 2003 16:17:48 +0200 Subject: Transient "Beowulf" cluster of Erlang nodes. In-Reply-To: <3E8C34B0.5080405@manderp.freeserve.co.uk> (Peter-Henry Mander's message of "Thu, 03 Apr 2003 14:18:40 +0100") References: <3E8C0CAE.6010204@manderp.freeserve.co.uk> <003801c2f9d1$5580ca20$a22d1081@ituniv398> <3E8C34B0.5080405@manderp.freeserve.co.uk> Message-ID: Peter-Henry Mander writes: > oooOOOoooh (o:* > > Thanks for the lead Thomas, this does sound interesting. May I know a > bit more please? I'd be happy to be a tester. > > Now I need to get Knoppix to work, modify it, and launch Erlang on > bootup as a service, perhaps. Unless there's a way of running a "pure" > Erlang node on a PC? Basically that is the idea. The hardest question in this approach is how to make it maintenable. If we want the tools too live, it should be nearly automatic to build new version of the distribution, including new tools, tools upgrade and so on. Otherwise, you will soon get pissed of if you have to manually rebuild the modified ISO (by dumping the content on your hard drives, apt-geting the software you want to indlude and regenerate the ISO as described on Knoppix website). Do you know if the Knoppix script for creation of the ISO are easy to use ? -- Micka?l R?mond From jamesh@REDACTED Thu Apr 3 17:02:59 2003 From: jamesh@REDACTED (James Hague) Date: Thu, 3 Apr 2003 09:02:59 -0600 Subject: FAQ terminology harmonisation Message-ID: >> Lisp has grown crusty in certain ways and can be awkward >> after using more modern functional syntax > >the major problem i have with erlang vs lisp is erlangs >syntax. it is not sufficiently symetric, i suppose >(i prefer matching start-stop markers). and i have a >terrible time remembering if i should use ;/, or >not, in case statements. Yes, I agree with that. I've wondered how Erlang would be with Python and Haskell's "significant whitespace" as an alternative to all the commas and semicolons (ah, the endless debates that would start). Writing a preprocessor to do the conversion to proper Erlang would be an easy project. My quibble with Lisp's syntax is less about delimiters and more about the lack of shortcuts that I've gotten used to: * Being able to introduce a local without explicitly declaring it and starting a new indentation level. * Pattern matching to destructure data into components. * Tuples, especially using tuples to return multiple values (as opposed to multiple-value-bind). James From rpettit@REDACTED Thu Apr 3 18:24:46 2003 From: rpettit@REDACTED (Rick Pettit) Date: Thu, 3 Apr 2003 10:24:46 -0600 Subject: FAQ terminology harmonisation In-Reply-To: <20030402214037.3b920ca8.cpressey@catseye.mb.ca> References: <16009.12305.864364.894513@antilipe.corelatus.se> <1049222312.14147.594.camel@berimbau> <20030402175051.GA24510@vailsys.com> <20030402123327.7be6b56b.cpressey@catseye.mb.ca> <20030402191815.GE24510@vailsys.com> <20030402142734.405cd5e8.cpressey@catseye.mb.ca> <20030402211642.GJ24510@vailsys.com> <20030402214037.3b920ca8.cpressey@catseye.mb.ca> Message-ID: <20030403162446.GB13323@vailsys.com> On Wed, Apr 02, 2003 at 09:40:37PM -0600, Chris Pressey wrote: > Hey, if it works, more power to you. I'm still in a position where I'm > working on projects where a couple of minutes of downtime is acceptable, > so my experience with hot swapped code comes mostly from playing with it > - and I don't think I've ever written a .so - so I'm out of my element > here. Please don't get me wrong here, I am not arguing in favor of C/C++ over Erlang. I was merely trying to help Martin clarify his argument. To say Erlang allows code load on the fly and C/C++ does not, or to say that you _have_ to program defensively in C/C++ everywhere whereas you only need to do so in border cases with Erlang is just not true in my opinion. > > My point is that there is NOT a big difference between the two, and > > that is how Martin should approach the sales pitch with C/C++ guys who > > argue against hot-code load but are all for shared objects. > > In light of your success with it - yes indeed. Again, I am just playing devil's advocate here. I would like to see Erlang succeed...I am sold. My only intent was to _strengthen_ his argument by playing the other side. -Rick P.S. Writing applications which load/unload shared objects on the fly without crashing or corrupting data in some way is tricky business, particularly in a multi-threaded environment. I have somehow managed to be successful in doing so, but with Erlang/OTP I clearly see the light ;-) From rpettit@REDACTED Thu Apr 3 18:31:20 2003 From: rpettit@REDACTED (Rick Pettit) Date: Thu, 3 Apr 2003 10:31:20 -0600 Subject: FAQ terminology harmonisation In-Reply-To: <3E8BDD36.7040600@manderp.freeserve.co.uk> References: <16009.12305.864364.894513@antilipe.corelatus.se> <1049222312.14147.594.camel@berimbau> <20030402175051.GA24510@vailsys.com> <20030402123327.7be6b56b.cpressey@catseye.mb.ca> <20030402191815.GE24510@vailsys.com> <20030402142734.405cd5e8.cpressey@catseye.mb.ca> <20030402211642.GJ24510@vailsys.com> <20030402214037.3b920ca8.cpressey@catseye.mb.ca> <3E8BDD36.7040600@manderp.freeserve.co.uk> Message-ID: <20030403163120.GC13323@vailsys.com> On Thu, Apr 03, 2003 at 08:05:26AM +0100, Peter-Henry Mander wrote: > May I join in? Of course you may ;-) > The hot-swap in Erlang operates differently to shared library reloading > in one aspect which I think you overlooked: *both* the old and new > versions of a hot-loaded module will run in a live system *until* all > the code relying on the module have come to a suitable switching point. Agreed. I realized this after my post. In either case, as I mentioned to Chris in a previous mailing, my intent was to strengthen Martin's argument by playing the other side. > or run, so it may not even work, so spank me :-) Would you settle for me "excusing you" :-) > The difference between cases A and B is that in case B the server code > will be swapped with a new version if one was loaded at that time > *without stopping*, whereas case A would continue to use the old version > regardless. Agreed. In my (pthread) applications I would need to synchronize the load/unload via mutex locking, and would NOT be able to easily use a new shared object while finishing up with the old one. I can almost invision an insane way to try to do so, but it would involve terrible obfuscation as the two modules could NOT share the same symbols and still exist in the same process at the same time, AFAIK. This certainly is a limitation (you getting this, Martin?) > I believe that reloading shared libraries will require a fair amount of > runtime code management programmed by hand, and I'm not sure that loops > like this one can be swapped without stopping the server momentarily. > The Erlang version simply never stops, never loses any server state. Agreed. A familiarity with libdl and the dynamic loader is a must to even get off the ground. Erlangers never need to know about such gory details. > I think that the hot-swapping in Erlang is almost (not quite) implicitly > supported, whereas C/C++ the extra work involved in implementing and > debugging such a feature just gets in the way of solving more > interesting problems. Once again, I am in agreement. I must say I am quite happy with the results of my posting, as this discussion has both cleared a few things up for me and given Martin more ammo for his argument with the "LM". -Rick From rpettit@REDACTED Thu Apr 3 18:34:58 2003 From: rpettit@REDACTED (Rick Pettit) Date: Thu, 3 Apr 2003 10:34:58 -0600 Subject: FAQ terminology harmonisation In-Reply-To: <4.2.2.20030402230851.00d61140@duomark.com> References: <4.2.2.20030402230851.00d61140@duomark.com> Message-ID: <20030403163458.GD13323@vailsys.com> On Wed, Apr 02, 2003 at 11:13:22PM -0800, Jay Nelson wrote: > I have been promoting the use of processes as an interface > mechanism. Precisely because of reuse issues, it is an important > method of integration. Make all your code non-defensive and > use a process at the border to do any data filtering to ensure > that the reusable code doesn't get bad data. You can also use > the filter process to alter the data to match the reusable code's > interface if necessary. This sounds pretty interesting, though I must sadly admit that I not an experienced enough Erlang/OTP developer to know if it is the "right thing to do" or not. It does sound like such an architecture could aid in code reusability. Since simplicity seems to be a big concern with the Erlang guys (and rightly so), I would be interested to see what their thoughts are on that. -Rick From rpettit@REDACTED Thu Apr 3 18:44:37 2003 From: rpettit@REDACTED (Rick Pettit) Date: Thu, 3 Apr 2003 10:44:37 -0600 Subject: FAQ terminology harmonisation In-Reply-To: References: <20030402215108.GK24510@vailsys.com> Message-ID: <20030403164437.GE13323@vailsys.com> On Thu, Apr 03, 2003 at 11:07:34AM +0200, Ulf Wiger wrote: > Remember that Erlang was designed for environments where > "resetting" is probably a more correct description than > "crashing" -- the program always has to bounce back, > preferrably without the external users noticing. Of course. Though C/C++ processes which are started out of inittab (Solaris) or started via daemontools do "bounce back", it can hardly be argued that the external user wouldn't notice :-). > I think the idea of having defensive interfaces wherever > human (or otherwise external) input is involved is a good > thing, but internal components should assume that the users > of the interface have RTFM and use the component properly. > In any event, misuse of the component should lead to > distinct failures, not mystical semi-correct behaviour. Agreed. Out of curiousity, if you were to write a C/C++ application (I know, it's too gruesome to think about), would you follow the same strategy? That is, would you NOT check for NULL, etc, in cases where you just should not be passed NULL? How about in an application comprised of distinct processes in a chain which could die and be reborn without the entire application crashing? Of course such a system is far _inferior_ to the OTP equivalent, I am just curious. And I think it goes without saying that referencing a NULL pointer in code that is not defensive will not lead to semi-correct behaviour, but rather a very distinct failure. Of course referencing a non-NULL pointer which points at a region of memory the author was not aware of is another story altogether, so perhaps this whole argument is mute (another win for Martin's argument with "LM"). > I think it's a mistake to confuse the two, but also always > try to write my code in the same way in both cases. Error > handling in the external interface is taken care of by > catching exceptions at the top and interpreting the > exception information into a human-readable error message. > This top layer will have different semantics depending on > the nature of the interface (window-based GUI, command line, > HTML pages, ...). Agreed. Though I think a similar strategy could be taken with C++ and exceptions. Of course being completely non-defensive in the core of the application could lead to segfaults (though I believe even these exceptions can be caught, though the process is doomed after the exception handler returns, IIRC). -Rick From enano@REDACTED Thu Apr 3 19:22:27 2003 From: enano@REDACTED (Miguel Barreiro Paz) Date: Thu, 3 Apr 2003 19:22:27 +0200 (CEST) Subject: Transient "Beowulf" cluster of Erlang nodes. In-Reply-To: <3E8C34B0.5080405@manderp.freeserve.co.uk> References: <3E8C0CAE.6010204@manderp.freeserve.co.uk> <003801c2f9d1$5580ca20$a22d1081@ituniv398> <3E8C34B0.5080405@manderp.freeserve.co.uk> Message-ID: > Now I need to get Knoppix to work, modify it, and launch Erlang on > bootup as a service, perhaps. Unless there's a way of running a "pure" > Erlang node on a PC? #message{offtopic=almost, size=toolong, contents=" Modifying Knoppix is easy: - install the cloop module (compressed loop filesystem) and utilities (apt-get install cloop-src cloop-utils) - compile the cloop.o module ('make' in /usr/src/modules/cloop) - copy the whole CD to your disk (say, /home/pmander/knoppix/cdroot) - mount the large compressed filesystem image and copy it: # insmod cloop.o file=/home/pmander/knoppix/cdroot/KNOPPIX/KNOPPIX # mount -o ro /dev/cloop /mnt/knoppix - copy (keeping owners and permissions) the whole compressed image to your disk, say to ~pmander/knoppix/cloop. chroot to that directory. - configure your network by hand, add debian mirrors to /etc/apt/sources.list and install or remove packages at will (apt-get update ; apt-get install erlang ; dpkg --purge gnome-base ). Edit and configure everything at will (respecting the autoconfig scripts). - exit the chroot, and create a new KNOPPIX compressed image. #!/bin/sh # make-compressed-image - Makes a compressed KNOPPIX image mkisofs -R -l -V "KNOPPIX" -hide-rr-moved -v \ ../cloop | create_compressed_fs - 65536 > /home/pmander/knoppix/KNOPPIX/KNOPPIX - Create an ISO CD-ROM image: #!/bin/sh # make-bootable-cd - Makes a bootable KNOPPIX ISO image mkisofs -l -r -J -V "KNOPPIX" -hide-rr-moved -v \ -b KNOPPIX/boot.img -c KNOPPIX/boot.cat -o \ /home/pmander/knoppix/knoppix.iso /home/pmander/knoppix/cdroot (untested scripts but should work - similar enough to my setup) -Burn your knoppix.iso image into a CD (...preferably a rewritable ;-)) and enjoy ("cdrecord -pad speed=24 dev=0,0,0 blank=fast" or something like this adapted to your system will blank the rewritable quickly). Disclaimer: been a few months since I did it, so things may have changed a bit. You will have to rebuild the compressed image and then the ISO every time you change a single file, and it hurts, so make few mistakes. You will need 512-1024MB RAM for this procedure to take a reasonable time if the compressed image is large. I'm not responsible when/if your computer catches fire. It will. A more interesting setup would be a PXE boot environment that boots directly into an erlang system, with remote I/O. Regards, Miguel "}. From C.Reinke@REDACTED Thu Apr 3 20:44:41 2003 From: C.Reinke@REDACTED (C.Reinke) Date: Thu, 03 Apr 2003 19:44:41 +0100 Subject: typing again (was: FAQ terminology harmonisation) In-Reply-To: Message from Thomas Lindgren of "Thu, 03 Apr 2003 01:28:43 -0800." <20030403092843.10634.qmail@web13310.mail.yahoo.com> Message-ID: > > Could someone explain why static typing is considered so "bad" > > or "unnecessary"? I think I could be sold on this (I _do_ > > consider myself to be open-minded), I just need to hear the > > right argument. static typing isn't at all bad, IMHO (I started functional programming in a dynamically and implicitly typed language, similar to Erlang in that respect, then moved to Haskell, a statically typed language where types are mostly implicit thanks to type inference; the problems involved in that process were not nearly as hard as expected and, while limitations remain, I do not encounter them as often as I feared; although I no longer enjoy those cases where I have to work at the bleeding edge of type system innovation..). And modern type systems do bring a whole lot of good things. I think Ulf brought the problem to a point in a recent c.l.f discussion: as long as you have to choose between advanced type systems and all the goodies Erlang provides, your choice will depend on your applications. And for typical Erlang applications, Erlang goodies are so indispensible that the choice is easy. Unfortunately, his correspondents didn't quite get it, but next time some self-appointed evangelist asks how you can do any safety-critical applications without static typing, the proper answer is "I'd love to have a better type system, but how can you do any safety-critical applications without cheap concurrency, distribution, fault-tolerance, ..."!-) Of course, be prepared to be surprised - some day, Haskell or something like it will catch up, we all hope (for myself, distribution is the main missing bit in Concurrent Haskell, because adding that would need quite a few non-trivial additions - such as Dynamics, and possibly some design changes as well). In this sense, I'd like to throw a couple of references into the discussion (would be interested to hear opinions..): a) Clean - similar to Haskell, yet always different: http://www.cs.kun.nl/~clean/ is currently being extended with support for Dynamics (a way to get the best of both dynamic and static typing, with a clean interface between the two worlds), one motivation being typed communication (between processes, or with the file system). There are several papers on this, not to mention the theory behind it, but perhaps most interesting to this list would be a little concurrency experiment built on top of Dynamics: Arjen van Weelden and Rinus Plasmeijer. Towards a Strongly Typed Functional Operating System. To appear in Selected Papers Proceedings 14th International Workshop on the Implementation of Functional Languages, IFL 2002, Madrid, Spain, September 16-18, 2002. ftp://ftp.cs.kun.nl/pub/Clean/papers/2003/vWeA2003-Famke.ps.gz b) something I haven't read yet (still on my stack), but which seems directly relevant to the discussion: S. J. Gay, V. Vasconcelos and A. Ravara. Session Types for Inter-Process Communication. Technical report TR-2003-133, Department of Computing Science, University of Glasgow, March 2003. http://www.dcs.gla.ac.uk/~simon/publications/TR-2003-133.pdf [idea: just as you can type functions to describe their call-return interface, say + :: Int -> Int -> Int, you can try to type processes to describe their communication interface, say plusServer :: ?Int?Int!Int.End for a server that receives two numbers, then returns their sum and terminates] Cheers, Claus From matthias@REDACTED Thu Apr 3 21:18:46 2003 From: matthias@REDACTED (Matthias Lang) Date: Thu, 3 Apr 2003 21:18:46 +0200 Subject: FAQ terminology harmonisation In-Reply-To: <20030403164437.GE13323@vailsys.com> References: <20030402215108.GK24510@vailsys.com> <20030403164437.GE13323@vailsys.com> Message-ID: <16012.35094.671823.981815@antilipe.corelatus.se> Rick Pettit writes: > Agreed. Out of curiousity, if you were to write a C/C++ application > (I know, it's too gruesome to think about), would you follow the > same strategy? That is, would you NOT check for NULL, etc, in cases > where you just should not be passed NULL? How about in an > application comprised of distinct processes in a chain which > could die and be reborn without the entire application crashing? not checking for "NULL" isn't quite the same as the usual erlang approach. The usual erlang approach is to use pattern matching to force an abort in many cases where something unexpected happens, e.g. {ok, S} = gen_tcp:connect(Host, Port, Options), ... you can't really write that naturally in C, I find myself forever writing sock = connect(...); assert(sock); Is that defensive programming? Not really, IMO. PERL has an idiom which is somewhat like Erlang, btw: f() || die Matthias From vances@REDACTED Thu Apr 3 21:39:11 2003 From: vances@REDACTED (Vance Shipley) Date: Thu, 3 Apr 2003 14:39:11 -0500 Subject: Hotswap In-Reply-To: <3E8C06A1.6050902@manderp.freeserve.co.uk> References: <4.2.2.20030402232138.00a23cd0@duomark.com> <3E8BF80B.30404@manderp.freeserve.co.uk> <3E8C06A1.6050902@manderp.freeserve.co.uk> Message-ID: <20030403193911.GA308@frogman.motivity.ca> Hot swap is useful for more than constant uptime production systems. When you are doing development on a system involving more than a few modules/processes the startup time can be significant. Just starting an erlang node takes a while. I generally edit code in one window and then in another I am running an erlang shell on the system under test in which I run c(module) which compiles and loads the new module. You then test, edit, test, etc. This iteration is really fast compared to a cold boot of the erlang node and starting the processes. -Vance From rpettit@REDACTED Thu Apr 3 21:44:25 2003 From: rpettit@REDACTED (Rick Pettit) Date: Thu, 3 Apr 2003 13:44:25 -0600 Subject: FAQ terminology harmonisation In-Reply-To: <20030403092843.10634.qmail@web13310.mail.yahoo.com> References: <20030402175051.GA24510@vailsys.com> <20030403092843.10634.qmail@web13310.mail.yahoo.com> Message-ID: <20030403194425.GH13323@vailsys.com> On Thu, Apr 03, 2003 at 01:28:43AM -0800, Thomas Lindgren wrote: > Misspelled variables are caught by the compiler. (Esp. > if you use warn_unused_vars.) Ok. Can't remember the details on what was misspelled (i.e. variable or function), so please excuse that remark. > * The main benefit of Erlang, Lisp, Prolog, SML and so > on is _type_safeness_: there is no way that you can > accidentally confuse one value's type with another. > This (along with GC and pureness) gets rid of the > majority of errors. > > (This is also known as 'strong typing', not to be > confused with 'static typing'.) Ah, thank you for clarifying. > * Finally, static typing in the sense above is > prescriptive: it will reject programs that are okay > because it can't prove they are (e.g., heterogenous > lists were rejected for a long time; not sure about > whether it's handled well these days). This may mean > you have to 'code around' the problem, though a static > typing guy might say you are removing a latent bug. > > Also, the programming language designers will have to > restrict programs to enable checking (e.g., receive > ... end is hard to check in its current form, since > any process can potentially send to any process, as is > hot code loading, for obvious reasons). Agreed. > To summarize: > > Personally, I find that static typing in its current > form adds little value to my Erlang programming. > Errors due to type mistakes do appear, but not so > frequently as to make it a major problem. The > consequences are exceptions, not core dumps or quiet > madness, so debugging is easier than in the C++ case. Quiet madness is certianly no good. As for core dumps, I personally find them pretty easy to make use of. If you know how to run a backtrace and work with thread info, etc, you can pretty quickly find out what went wrong and in what thread. I will not argue though that this is easier than debugging Erlang code (in fact I cannot, since as I have said before I am no Erlang/OTP HaXoR ;-) > (An opinion: Making Erlang even easier to test would > probably be more pragmatically beneficial than adding > static typing.) Seems to make sense. Thank you for clearing some of this up for me. -Rick From vances@REDACTED Thu Apr 3 21:56:36 2003 From: vances@REDACTED (Vance Shipley) Date: Thu, 3 Apr 2003 14:56:36 -0500 Subject: FAQ terminology harmonisation In-Reply-To: <16012.35094.671823.981815@antilipe.corelatus.se> References: <20030402215108.GK24510@vailsys.com> <20030403164437.GE13323@vailsys.com> <16012.35094.671823.981815@antilipe.corelatus.se> Message-ID: <20030403195636.GD308@frogman.motivity.ca> There are good reasons for writing defensive C code. You need to check for memory bounds mainly. If you didn't you'd have plenty of the sort of flaws which make for CERT advisories. I don't extend the Erlang "let it fail" philosophy to my C driver code. Personally I consider this interface to be external and code the C node to validate the input. -Vance From rpettit@REDACTED Thu Apr 3 21:49:48 2003 From: rpettit@REDACTED (Rick Pettit) Date: Thu, 3 Apr 2003 13:49:48 -0600 Subject: typing again (was: FAQ terminology harmonisation) In-Reply-To: References: <20030403092843.10634.qmail@web13310.mail.yahoo.com> Message-ID: <20030403194948.GI13323@vailsys.com> On Thu, Apr 03, 2003 at 07:44:41PM +0100, C.Reinke wrote: > static typing isn't at all bad, IMHO (I started functional > programming in a dynamically and implicitly typed language, similar > to Erlang in that respect, then moved to Haskell, a statically typed > language where types are mostly implicit thanks to type inference; > the problems involved in that process were not nearly as hard as > expected and, while limitations remain, I do not encounter them as > often as I feared; although I no longer enjoy those cases where I > have to work at the bleeding edge of type system innovation..). > And modern type systems do bring a whole lot of good things. > > I think Ulf brought the problem to a point in a recent c.l.f > discussion: as long as you have to choose between advanced type > systems and all the goodies Erlang provides, your choice will > depend on your applications. And for typical Erlang applications, > Erlang goodies are so indispensible that the choice is easy. I completely agree. Where we have used Erlang/OTP it was indeed indispensible. > Of course, be prepared to be surprised - some day, Haskell or > something like it will catch up, we all hope (for myself, > distribution is the main missing bit in Concurrent Haskell, because > adding that would need quite a few non-trivial additions - such as > Dynamics, and possibly some design changes as well). Have never looked at Haskell though I am told I need to check it out if I want to grok FP. > b) something I haven't read yet (still on my stack), but which seems > directly relevant to the discussion: > > S. J. Gay, V. Vasconcelos and A. Ravara. Session Types for > Inter-Process Communication. Technical report TR-2003-133, > Department of Computing Science, University of Glasgow, March 2003. > > http://www.dcs.gla.ac.uk/~simon/publications/TR-2003-133.pdf > > [idea: just as you can type functions to describe their > call-return interface, say + :: Int -> Int -> Int, you can > try to type processes to describe their communication interface, > say plusServer :: ?Int?Int!Int.End for a server that receives > two numbers, then returns their sum and terminates] This one sounds like an interesting read...thanks! -Rick From cpressey@REDACTED Thu Apr 3 22:03:27 2003 From: cpressey@REDACTED (Chris Pressey) Date: Thu, 03 Apr 2003 14:03:27 -0600 Subject: type safety (was Re: FAQ terminology harmonisation) In-Reply-To: <20030403092843.10634.qmail@web13310.mail.yahoo.com> References: <20030402175051.GA24510@vailsys.com> <20030403092843.10634.qmail@web13310.mail.yahoo.com> Message-ID: <20030403140327.36ec505c.cpressey@catseye.mb.ca> On Thu, 3 Apr 2003 01:28:43 -0800 (PST) Thomas Lindgren wrote: > * The main benefit of Erlang, Lisp, Prolog, SML and so > on is _type_safeness_: there is no way that you can > accidentally confuse one value's type with another. Not in Erlang. Not if you consider tuples and records two different types. Which they should be. But aren't. We won't have type safety until we have truly opaque types. We have a warning not to let type information leak out of a module. But we currently *have* to implement types on top of existing types: usually tuples, or lists, or binaries could be used, or even refs or pids or atoms... but all of these can be confused with others of the same type, used in a different role. If someone writes a case statement which matches on tuples or lists, they could match on my custom type, quite by accident. Because no matter how well I try to make it opaque, I can't. I can only try to follow a format regime ("always tag tuples" etc) But if other people don't follow the same regime, it's all for naught. This regime *has* to be part of the language in order for Erlang to honestly make the claim of type safety. -Chris From rpettit@REDACTED Thu Apr 3 21:52:53 2003 From: rpettit@REDACTED (Rick Pettit) Date: Thu, 3 Apr 2003 13:52:53 -0600 Subject: Hotswap In-Reply-To: <20030403193911.GA308@frogman.motivity.ca> References: <4.2.2.20030402232138.00a23cd0@duomark.com> <3E8BF80B.30404@manderp.freeserve.co.uk> <3E8C06A1.6050902@manderp.freeserve.co.uk> <20030403193911.GA308@frogman.motivity.ca> Message-ID: <20030403195253.GJ13323@vailsys.com> On Thu, Apr 03, 2003 at 02:39:11PM -0500, Vance Shipley wrote: > Hot swap is useful for more than constant uptime production > systems. When you are doing development on a system involving > more than a few modules/processes the startup time can be > significant. Just starting an erlang node takes a while. I > generally edit code in one window and then in another I am > running an erlang shell on the system under test in which I > run c(module) which compiles and loads the new module. You > then test, edit, test, etc. This iteration is really fast > compared to a cold boot of the erlang node and starting the > processes. Wow, somehow I hadn't thought of that. This truly is an exciting feature, and an excellent use of hot swap. Thanks. -Rick From rpettit@REDACTED Thu Apr 3 22:07:26 2003 From: rpettit@REDACTED (Rick Pettit) Date: Thu, 3 Apr 2003 14:07:26 -0600 Subject: FAQ terminology harmonisation In-Reply-To: <16012.35094.671823.981815@antilipe.corelatus.se> References: <20030402215108.GK24510@vailsys.com> <20030403164437.GE13323@vailsys.com> <16012.35094.671823.981815@antilipe.corelatus.se> Message-ID: <20030403200725.GK13323@vailsys.com> On Thu, Apr 03, 2003 at 09:18:46PM +0200, Matthias Lang wrote: > not checking for "NULL" isn't quite the same as the usual erlang > approach. The usual erlang approach is to use pattern matching to > force an abort in many cases where something unexpected happens, e.g. > > {ok, S} = gen_tcp:connect(Host, Port, Options), > ... > > you can't really write that naturally in C, I find myself forever > writing > > sock = connect(...); > assert(sock); > > Is that defensive programming? Not really, IMO. PERL has an idiom > which is somewhat like Erlang, btw: f() || die Not sure I completely agree here. Checking for NULL _IS_ checking for the unexpected (you just do it more often in C/C++). In both cases you expect the connection to be established, and in both examples you assert that it is. Pattern matching to force an abort (at least in this case) is just syntactical sugar for aborting on failed assertion. If aborting when something unexpected happens is not defensive programming, then perhaps I have a more fundamental misunderstanding. -Rick From fritchie@REDACTED Thu Apr 3 22:22:21 2003 From: fritchie@REDACTED (Scott Lystig Fritchie) Date: Thu, 03 Apr 2003 14:22:21 -0600 Subject: OT: Single-assignment, was Re: Raskin book on UI and radical data thoughts In-Reply-To: Message of "Wed, 02 Apr 2003 14:12:44 CST." <20030402141244.2556d527.cpressey@catseye.mb.ca> Message-ID: <200304032022.h33KMLIq014580@snookles.snookles.com> I'm sorry, I just couldn't keep silent, even though this is off-topic. Maybe it will be interesting to somebody in the same manner that Marc Ernst Eddy van Woerkom's message about the "Judy tree" interested me. {shrug} >>>>> "cp" == Chris Pressey writes: >> An interesting approach would be to make the disk >> single-assignment. *Never* allow data to be modified, only allow >> new versions of the data to be created and retain all versions for >> their lifetime. cp> I think we already have these: journalling file systems? There is at least one write-once file system that I'm aware of: Venti. There's a USENIX paper at http://www.usenix.org/events/fast02/quinlan.htm that describes it. At USENIX 2002 I heard Rob Pike talk a little bit about it. IIRC, during early development, they'd make "backup" snapshots of the entire file system by writing the SHA1 hash (20 bytes) of the root directory on a whiteboard ... that was all the information they needed to find everything else in the file system. -Scott --- snip --- snip --- snip --- snip --- snip --- snip --- snip --- FAST 2002 Abstract Venti: a new approach to archival storage Sean Quinlan and Sean Dorward, Bell Labs, Lucent Technologies Abstract This paper describes a network storage system, called Venti, intended for archival data. In this system, a unique hash of a block's contents acts as the block identifier for read and write operations. This approach enforces a write-once policy, preventing accidental or malicious destruction of data. In addition, duplicate copies of a block can be coalesced, reducing the consumption of storage and simplifying the implementation of clients. Venti is a building block for constructing a variety of storage applications such as logical backup, physical backup, and snapshot file systems. We have built a prototype of the system and present some preliminary performance results. The system uses magnetic disks as the storage technology, resulting in an access time for archival data that is comparable to non-archival data. The feasibility of the write-once model for storage is demonstrated using data from over a decade's use of two Plan 9 file systems. From rpettit@REDACTED Thu Apr 3 22:11:37 2003 From: rpettit@REDACTED (Rick Pettit) Date: Thu, 3 Apr 2003 14:11:37 -0600 Subject: type safety (was Re: FAQ terminology harmonisation) In-Reply-To: <20030403140327.36ec505c.cpressey@catseye.mb.ca> References: <20030402175051.GA24510@vailsys.com> <20030403092843.10634.qmail@web13310.mail.yahoo.com> <20030403140327.36ec505c.cpressey@catseye.mb.ca> Message-ID: <20030403201137.GL13323@vailsys.com> On Thu, Apr 03, 2003 at 02:03:27PM -0600, Chris Pressey wrote: > On Thu, 3 Apr 2003 01:28:43 -0800 (PST) > Thomas Lindgren wrote: > > > * The main benefit of Erlang, Lisp, Prolog, SML and so > > on is _type_safeness_: there is no way that you can > > accidentally confuse one value's type with another. > > Not in Erlang. > Not if you consider tuples and records two different types. > Which they should be. > But aren't. > We won't have type safety until we have truly opaque types. > We have a warning not to let type information leak out of a module. > But we currently *have* to implement types on top of existing types: > usually tuples, or lists, or binaries could be used, or even refs or > pids or atoms... but all of these can be confused with others of the > same type, used in a different role. > If someone writes a case statement which matches on tuples or lists, > they could match on my custom type, quite by accident. > Because no matter how well I try to make it opaque, I can't. > I can only try to follow a format regime ("always tag tuples" etc) > But if other people don't follow the same regime, it's all for naught. > This regime *has* to be part of the language in order for Erlang to > honestly make the claim of type safety. I must say this whole discussion has been rather educational and quite exciting for me. I just hope people on the list don't hold it against me for lighting the fuse on this one :-) -Rick From matthias@REDACTED Thu Apr 3 23:18:15 2003 From: matthias@REDACTED (Matthias Lang) Date: Thu, 3 Apr 2003 23:18:15 +0200 Subject: FAQ terminology harmonisation In-Reply-To: <20030403200725.GK13323@vailsys.com> References: <20030402215108.GK24510@vailsys.com> <20030403164437.GE13323@vailsys.com> <16012.35094.671823.981815@antilipe.corelatus.se> <20030403200725.GK13323@vailsys.com> Message-ID: <16012.42263.471626.414021@antilipe.corelatus.se> Rick Pettit writes: > On Thu, Apr 03, 2003 at 09:18:46PM +0200, Matthias Lang wrote: > > not checking for "NULL" isn't quite the same as the usual erlang > > approach. The usual erlang approach is to use pattern matching to > > force an abort in many cases where something unexpected happens, e.g. > > > > {ok, S} = gen_tcp:connect(Host, Port, Options), > > ... > > > > you can't really write that naturally in C, I find myself forever > > writing > > > > sock = connect(...); > > assert(sock); > > > > Is that defensive programming? Not really, IMO. PERL has an idiom > > which is somewhat like Erlang, btw: f() || die > Not sure I completely agree here. Checking for NULL _IS_ checking for the > unexpected (you just do it more often in C/C++). In both cases you > expect the connection to be established, and in both examples you > assert that it is. I do not think the explanation of how to approach error handling in the programming recommendations is a good one*. Neither do I think "defensive programming" is a good term for it. I ripped off Joe's improved explanation in the FAQ (question 10.15) http://www.erlang.org/faq/ The key is separating error detection and error handling. The talk about "defensive" is a distraction. (Aside: I can't find a good definition of the term. The first 10 links googles gives me all lead to useless essays calling everything from descriptive variable names to exceptions "defensive programming". Is it one of those things everyone feels is a good idea and nobody knows exactly what it is?) There are two problems with the above style in C. One is that it makes the code longer. The other is that error handling becomes all or nothing. If the socket does not connect, the entire program will die, unless the program is structured into several unix processes. Some long-running C programs could actually work reasonably well with such a model, one example is a web server which fork()s for each new connection. In Erlang, there are two main ways to handle errors non-locally. Exceptions and supervision. I think of the difference as being a matter of where you draw your boundary. Exceptions draw the boundary through a certain level of the stack. Supervision draws it around a process. I use both approaches in our systems, they're useful in different situations. But the situations where supervision is useful seem to outnumber the situations where exceptions are useful 20 to 1. Matt * Why did an april fools post contain real criticism? I figured the hoax would work best if started plausibly and then ramped up the implausibility. From C.Reinke@REDACTED Fri Apr 4 01:28:09 2003 From: C.Reinke@REDACTED (C.Reinke) Date: Fri, 04 Apr 2003 00:28:09 +0100 Subject: type safety (was Re: FAQ terminology harmonisation) In-Reply-To: Your message of "Thu, 03 Apr 2003 14:03:27 MDT." <20030403140327.36ec505c.cpressey@catseye.mb.ca> Message-ID: > We won't have type safety until we have truly opaque types. > We have a warning not to let type information leak out of a module. > But we currently *have* to implement types on top of existing types: > usually tuples, or lists, or binaries could be used, or even refs or > pids or atoms... but all of these can be confused with others of the > same type, used in a different role. .. > Because no matter how well I try to make it opaque, I can't. While I don't disagree with the general message, you may be overly pessimistic about data abstraction. In fact, I thought this was handled in the programming rules, but re-reading those after your message shows it isn't. There are some fairly old tricks (sorry, don't have the references here right now - Reynolds, and Morris, I think) that allow us to do slightly better than the queue example in the programming rules - if our language supports first-class functions or procedures. The basic idea is that if there is one abstract type in the language, we might be able to build other abstractions on top of that. Functions fit that bill wonderfully (the only thing you can do with a function is to apply it). In particular, there is no need for a module implementing an abstract type to expose anything but the API functions. Cheers, Claus % here's the queue from the erlang programming rules, % 3.11 Don't allow private data structures % to "leak" out of a module % note that this module exports accessor functions % for the "abstract" queue type, but _also_ externalises % and thus exposes the "hidden" list representation: % it is passed unprotected in and out of the API functions! %% -module(queue). %% -export([new/0, add/2, fetch/1]). %% %% new() -> %% []. %% %% add(Item, Q) -> %% lists:append(Q, [Item]). %% %% fetch([H|T]) -> %% {ok, H, T}; %% fetch([]) -> %% empty. % choosing a functional representation instead, % the only thing exported and passed around are % the API functions, whereas the internal list % representation is hidden in partial applications % of the internal functions: -module(queue). -export([new/0, add/2, fetch/1]). % internal API mk_queue(Q) -> { add_fct(Q), fetch_fct(Q) }. add_fct(Q) -> fun(Item) -> NewQ = lists:append(Q, [Item]), mk_queue(NewQ) end. % sigh.. lazy evaluation would help here fetch_fct([H|T]) -> fun(Delay) -> {ok, H, mk_queue(T) } end; fetch_fct([]) -> fun(Delay) -> empty end. % the old API, for convenience. % hides both the internal list and the Delay/force handling.. new() -> mk_queue([]). add({Add,Fetch}, Item) -> Add(Item). fetch({Add,Fetch}) -> Fetch(force). From cpressey@REDACTED Fri Apr 4 02:38:18 2003 From: cpressey@REDACTED (Chris Pressey) Date: Thu, 03 Apr 2003 18:38:18 -0600 Subject: type safety (was Re: FAQ terminology harmonisation) In-Reply-To: References: <20030403140327.36ec505c.cpressey@catseye.mb.ca> Message-ID: <20030403183818.5c895f0d.cpressey@catseye.mb.ca> On Fri, 04 Apr 2003 00:28:09 +0100 "C.Reinke" wrote: > [me] > > Because no matter how well I try to make it opaque, I can't. Sorry if my tone came across as a bit curt, I was in a rush. > While I don't disagree with the general message, you may be > overly pessimistic about data abstraction. Probably more pedantic than pessimistic. I'd like to be able to call Erlang typesafe, but it's not quite there. > In fact, I thought > this was handled in the programming rules, but re-reading > those after your message shows it isn't. Half-way - it suggests all messages be sent as tagged tuples - I would add that that should be extended to user-defined types as well. (If we can't be opaque, we should at least be consistent.) > [...] > The basic idea is that if there is one abstract type in the > language, we might be able to build other abstractions on top > of that. Functions fit that bill wonderfully (the only thing > you can do with a function is to apply it). In particular, > there is no need for a module implementing an abstract type > to expose anything but the API functions. I'm not sure that solves the problem - it just moves it from one existing type to another (or, I don't follow you and you'll have to give me an example.) I think the problem is more with the pattern matching than the types. In order to achieve type safety, I need to be able to construct a value that does NOT match in any of the following assertions: is_tuple(X) is_record(X, R) is_list(X) is_binary(X) is_pid(X) is_function(X) etc... For this to be, I would need a facility to create an opaque type which is not merely a subtype of one of those. The *only* assertion that ought to be able to match it in a case (or other) statement would be: is_type(X, T) where T is the name of my type. THEN Erlang will be typesafe. Of course, if structs were added *as a unique type*, i.e. NOT just implemented as dicts or tuples, then is_struct(X, S) would work too. Or, if it would not break existing code, the 3rd option would be to make records opaque, i.e.: (is_record(X, R) and is_tuple(X)) == false -Chris From erlang@REDACTED Fri Apr 4 08:35:23 2003 From: erlang@REDACTED (Peter-Henry Mander) Date: Fri, 04 Apr 2003 07:35:23 +0100 Subject: Hotswap References: <4.2.2.20030402232138.00a23cd0@duomark.com> <3E8BF80B.30404@manderp.freeserve.co.uk> <3E8C06A1.6050902@manderp.freeserve.co.uk> <20030403193911.GA308@frogman.motivity.ca> Message-ID: <3E8D27AB.1050000@manderp.freeserve.co.uk> Thanks for emphasising a point that I only hinted at. Yes, prototyping _is_ much faster this way. Only once before I was able to work on a project that was developed in a similar manner in a Smalltalk-ish language, and the productivity of the tiny software team was absolutely blistering! I'm really happy I can work this way again with Erlang. I can't imagine how you would do prototyping in C/C++, the code-compile-load-execute-debug cycle is sooooooooo long! Pete. Vance Shipley wrote: > Hot swap is useful for more than constant uptime production > systems. When you are doing development on a system involving > more than a few modules/processes the startup time can be > significant. Just starting an erlang node takes a while. I > generally edit code in one window and then in another I am > running an erlang shell on the system under test in which I > run c(module) which compiles and loads the new module. You > then test, edit, test, etc. This iteration is really fast > compared to a cold boot of the erlang node and starting the > processes. > > -Vance > > From erlang@REDACTED Fri Apr 4 09:03:49 2003 From: erlang@REDACTED (Peter-Henry Mander) Date: Fri, 04 Apr 2003 08:03:49 +0100 Subject: type safety (was Re: FAQ terminology harmonisation) References: <20030403140327.36ec505c.cpressey@catseye.mb.ca> <20030403183818.5c895f0d.cpressey@catseye.mb.ca> Message-ID: <3E8D2E55.2080403@manderp.freeserve.co.uk> Hmm... This emphasis on exact matching on type would potentially break an aspect of Erlang I have learnt to appreciate: pattern matching. I can make a function match exactly or match with increasing degrees of generality. A special case function first, followed by general case. If none match, an exception occurs. I can work with a bit of dicipline and tag my tuples, and enforce that functions only acccept tagged tuples. Pete. Chris Pressey wrote: > On Fri, 04 Apr 2003 00:28:09 +0100 > "C.Reinke" wrote: > > ----- snip ----- From enano@REDACTED Fri Apr 4 09:28:15 2003 From: enano@REDACTED (Miguel Barreiro Paz) Date: Fri, 4 Apr 2003 09:28:15 +0200 (CEST) Subject: typing again (was: FAQ terminology harmonisation) In-Reply-To: References: Message-ID: > Of course, be prepared to be surprised - some day, Haskell or > something like it will catch up, we all hope (for myself, Oh sure - someone will come up with a 3-liner Haskell fun (*) that adds distribution and fault tolerance and an ASN.1 compiler. I probably won't understand it anyway :-) (*) 3-liner with the Standard Functional Linewidth (TM) of 200 chars, but still. From henkbijker78@REDACTED Fri Apr 4 10:02:53 2003 From: henkbijker78@REDACTED (henkbijker78@REDACTED) Date: Fri, 4 Apr 2003 10:02:53 +0200 Subject: polling problem Message-ID: Hi all, I've written a c Node to communicate between erlang and another server, which I need to poll in intervals of 500ms. Now the problem I have if when you call the "erl_receive_msg", it takes about 15 seconds for a 'ERL_TICK' to occur, so I thought about spawning a process to cause the ticks in 500ms intervals. In my loop() -> I have the following. after 500 -> io:format("~nOk"), {ok, c1@REDACTED}!{self()} , loop() if I call "{ok, c1@REDACTED}!{self()} ." from BEAM emulator, it executes and I can see the response in my c code, but it doesn't execute within the loop functions, although I do see the 'Ok'. Any idea why? From vlad_dumitrescu@REDACTED Fri Apr 4 10:12:18 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Fri, 4 Apr 2003 10:12:18 +0200 Subject: esdl help! Message-ID: Hi, I am trying to get started with esdl, but get a strange behaviour: trying anything from a regular Erlang shell works fine, but when trying from the shell I get in Emacs, then the whole thing locks when running "sdl_video:setVideoMode(640, 480, 16, Flags)"... Sometimes it works, but not often enough to be able to see any pattern. Any ideas as for why this happens? Thanks in advance. regards, Vlad From tab@REDACTED Fri Apr 4 10:30:32 2003 From: tab@REDACTED (Tomas Abrahamsson) Date: Fri, 4 Apr 2003 10:30:32 +0200 (MEST) Subject: Hotswap In-Reply-To: <20030403193911.GA308@frogman.motivity.ca> (message from Vance Shipley on Thu, 3 Apr 2003 14:39:11 -0500) Message-ID: <200304040830.h348UWrF016845@fafner.lysator.liu.se> > Hot swap is useful for more than constant uptime production > systems. When you are doing development on a system involving > more than a few modules/processes the startup time can be > significant. Just starting an erlang node takes a while. I > generally edit code in one window and then in another I am > running an erlang shell on the system under test in which I > run c(module) which compiles and loads the new module. You > then test, edit, test, etc. This iteration is really fast > compared to a cold boot of the erlang node and starting the > processes. We've built a nifty little tool on top of reshd[*], that enables us to connect to a running system, compile and load code directly into all nodes from Emacs by typing C-c k (instead of the usual C-c C-k). One hacker here got so addicted to it that he desperately wants something similar for Java, now that he has to hack Java for a while :-) The turn around time from edit to test is really short. /Tomas ________ [*] See http://www.erlang.org/user.html#reshd-1.2 From thomasl_erlang@REDACTED Fri Apr 4 10:36:45 2003 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Fri, 4 Apr 2003 00:36:45 -0800 (PST) Subject: typing again (was: FAQ terminology harmonisation) In-Reply-To: Message-ID: <20030404083645.94652.qmail@web13304.mail.yahoo.com> --- "C.Reinke" wrote: > S. J. Gay, V. Vasconcelos and A. Ravara. Session > Types for > Inter-Process Communication. Technical report > TR-2003-133, > Department of Computing Science, University of > Glasgow, March 2003. > > > http://www.dcs.gla.ac.uk/~simon/publications/TR-2003-133.pdf > > [idea: just as you can type functions to > describe their > call-return interface, say + :: Int -> Int -> > Int, you can > try to type processes to describe their > communication interface, > say plusServer :: ?Int?Int!Int.End for a > server that receives > two numbers, then returns their sum and > terminates] The Ptolemy II people at Berkeley have proposed "interface automata" as a sort of typing as well. It sounds somewhat similar. Interesting idea; in one paper they could type dining philosophers for instance. Best, Thomas __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - File online, calculators, forms, and more http://tax.yahoo.com From dgud@REDACTED Fri Apr 4 10:40:28 2003 From: dgud@REDACTED (Dan Gudmundsson) Date: Fri, 4 Apr 2003 10:40:28 +0200 Subject: esdl help! In-Reply-To: References: Message-ID: <16013.17660.71589.991430@rian.du.uab.ericsson.se> Sorry no idea.. /Dan Vlad Dumitrescu writes: > Hi, > > I am trying to get started with esdl, but get a strange behaviour: trying > anything from a regular Erlang shell works fine, but when trying from the > shell I get in Emacs, then the whole thing locks when running > "sdl_video:setVideoMode(640, 480, 16, Flags)"... Sometimes it works, but not > often enough to be able to see any pattern. > > Any ideas as for why this happens? Thanks in advance. > regards, > Vlad > From etxuwig@REDACTED Fri Apr 4 11:22:27 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Fri, 4 Apr 2003 11:22:27 +0200 (MEST) Subject: Hotswap In-Reply-To: <20030403193911.GA308@frogman.motivity.ca> Message-ID: On Thu, 3 Apr 2003, Vance Shipley wrote: >Hot swap is useful for more than constant uptime production >systems. When you are doing development on a system >involving more than a few modules/processes the startup >time can be significant. Just starting an erlang node >takes a while. I generally edit code in one window and >then in another I am running an erlang shell on the system >under test in which I run c(module) which compiles and >loads the new module. You then test, edit, test, etc. >This iteration is really fast compared to a cold boot of >the erlang node and starting the processes. Oh, and this feature is a jaw dropper at Interops. I've heard several accounts where people have brought erlang-based systems to interops (Megaco, MPLS, etc.), and have debugged and fixed interoperability problems in minutes without restarting the system -- sometimes without even dropping the session! I also seem to recall occasions where the erlang guys have helped their competitors debugging _their_ system simply by being able to follow the communication so much better on the erlang side. Finally, I've heard accounts of the erlang guys implementing workarounds to other people's bugs simply because it was so much easier to do it that way than to wait for them to get a fix from their design teams. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From thomasl_erlang@REDACTED Fri Apr 4 11:29:53 2003 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Fri, 4 Apr 2003 01:29:53 -0800 (PST) Subject: type safety (was Re: FAQ terminology harmonisation) In-Reply-To: <20030403140327.36ec505c.cpressey@catseye.mb.ca> Message-ID: <20030404092954.17488.qmail@web13302.mail.yahoo.com> Good points, both of them. --- Chris Pressey wrote: > On Thu, 3 Apr 2003 01:28:43 -0800 (PST) > Thomas Lindgren wrote: > > > * The main benefit of Erlang, Lisp, Prolog, SML > and so > > on is _type_safeness_: there is no way that you > can > > accidentally confuse one value's type with > another. > > Not in Erlang. > Not if you consider tuples and records two different > types. > Which they should be. > But aren't. There are two problems with records IMO: - Records of different record type can be confused with each other (breaks type safeness in my eyes, but I consider it a bug in the implementation rather than something fundamental) - The underlying tuples show through the record implementation. Unfortunate choice, but here the argument (not mine :-) seems to be that "records really are just syntactic sugar for tuples". (Oh yeah, a third, related problem is the dependence on include files for record definitions.) > We won't have type safety until we have truly opaque > types. > We have a warning not to let type information leak > out of a module. > But we currently *have* to implement types on top of > existing types: > usually tuples, or lists, or binaries could be used, > or even refs or > pids or atoms... but all of these can be confused > with others of the > same type, used in a different role. It depends a bit on what you mean by type, I'd say -- you can have exactly the same problem in SML. But I think you have a good point that it would sometimes be useful to have support for user-defined data types guaranteed to be distinct from all other types. Also, SML:s abstypes are an admirable use of typing to handle abstract data types; I should have mentioned that in the original message. Best, Thomas __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - File online, calculators, forms, and more http://tax.yahoo.com From pete@REDACTED Thu Apr 3 16:57:54 2003 From: pete@REDACTED (Peter-Henry Mander) Date: Thu, 03 Apr 2003 15:57:54 +0100 Subject: Transient "Beowulf" cluster of Erlang nodes. References: <3E8C0CAE.6010204@manderp.freeserve.co.uk> Message-ID: <3E8C4BF2.5010009@manderp.freeserve.co.uk> Thanks Mickael, I had a hunch that I wasn't doing anything radically new here, and with two leads in a matter of hours I feel confident that I've got moral support at the very least. (-: I hope to create a small ISO image with a basic Linux install and RB9-1 preinstalled, configured to run as a service at bootup. The development environment isn't a requirement, but if it comes for free, why not? Your help is gleefully accepted, and I'd be happy to take on the project. Following up on your second message, I don't know how easy Knoppix is to customise yet. I'm working on it, and I'll eventually post a diary about how easy/hard it is. Since the purpose of this project is to demonstrate the scalability of our Erlang product testing tool I'm quite eager to see it succeed. Pete. Mickael Remond wrote: > Peter-Henry Mander writes: > > >>Hi y'all, >> >>I have a small project in mind, and would like to know whether someone >>has done it before, and if so, how? >> >>I intend to harness the redundant processing power of our office PCs >>as a pool of Erlang nodes while everyone is out (overnight or over the >>weekend, hence "transient Beowulf cluster") and carry out some stress >>tests on our product using the office PC cluster to share the >>processing load. The scheme is to create a Knoppix >>(http://www.knoppix.net) style boot CD-ROM containing R9B that is >>inserted into the appropriated PCs, which are rebooted or turned on >>and left to boot up without any further intervention. > > > I had such a project regarding this topics that was called Erwolf. > This was basically the same idea + everything needed as a complete > Erlang development environnement. The idea was: > 1. Being able to build an Erlang set of node quickly and automatically > on a rather large number of machines. > 2. To have everything Erlang on the go: you can boot the CD everywhere > and have a complete and working development environment. > I can find my CD image and put it back online. > > It was difficult to maintain has it was based on Linux from > Scratch. Updating the CD with new software was a pain. > > Now there is Knoppix and I think this is the way to go. > If you want to lead the initiative I will help you. > > If you feel confortable with it, I propose to open a dedicated area on > Erlang project, for this Erlang/Linux based distribution. > Mickael Remond wrote: > Peter-Henry Mander writes: > > >>oooOOOoooh (o:* >> >>Thanks for the lead Thomas, this does sound interesting. May I know a >>bit more please? I'd be happy to be a tester. >> >>Now I need to get Knoppix to work, modify it, and launch Erlang on >>bootup as a service, perhaps. Unless there's a way of running a "pure" >>Erlang node on a PC? > > > Basically that is the idea. The hardest question in this approach is how > to make it maintenable. If we want the tools too live, it should be > nearly automatic to build new version of the distribution, including > new tools, tools upgrade and so on. > > Otherwise, you will soon get pissed of if you have to manually rebuild > the modified ISO (by dumping the content on your hard drives, > apt-geting the software you want to indlude and regenerate the ISO as > described on Knoppix website). > > Do you know if the Knoppix script for creation of the ISO are easy to > use ? > From hp@REDACTED Fri Apr 4 06:44:02 2003 From: hp@REDACTED (HP Wei) Date: Thu, 3 Apr 2003 23:44:02 -0500 (EST) Subject: help with installation Message-ID: I built and installed Erlang on a Sun (Solaris 5.8 with gcc) in my office. Everything run ok after I invoke it with 'erl' -- I can do 'toolbar:start().' However, after I copied the whole directory of ~/erlang/... onto the Sun machine (Solaris 5.8) at home, I had the following problem. Invoking erl is ok. I can get into the interpreter and run 'string:tokens(...).'. But 'toolbar:start().' give me the error message: ** exited: {startup_timeout,toolbar} ** Perhaps, some setting is not right. Or some libraries are missing. Could someone tell me what is missing on my home machine ?? Thanks, HP From erlang@REDACTED Fri Apr 4 12:05:37 2003 From: erlang@REDACTED (Peter-Henry Mander) Date: Fri, 04 Apr 2003 11:05:37 +0100 Subject: Hotswap References: Message-ID: <3E8D58F1.50609@manderp.freeserve.co.uk> I couldn't let this pass me by without complementing the guys who wrote the MeGaCo stack. I use Erlang/MeGaCo to test for interop with 3rd party stacks and the in-house C/C++ implementation. We performed an acceptance test using it, and pinpointed about a dozen issues with the software we commisioned from XXX (no names given, but they are stack specialists). We couldn't do acceptance against our actual product because the C/C++ MeGaCo stack was nowhere near ready. No comment! I think we embarassed the guy who came over to aid the integration! And our own MeGaCo team! The current Erlang version of the MeGaCo stack is a very solid product, it's value is priceless. I can vouch for it. Pete. Ulf Wiger wrote: > On Thu, 3 Apr 2003, Vance Shipley wrote: > > >>Hot swap is useful for more than constant uptime production >>systems. When you are doing development on a system >>involving more than a few modules/processes the startup >>time can be significant. Just starting an erlang node >>takes a while. I generally edit code in one window and >>then in another I am running an erlang shell on the system >>under test in which I run c(module) which compiles and >>loads the new module. You then test, edit, test, etc. >>This iteration is really fast compared to a cold boot of >>the erlang node and starting the processes. > > > Oh, and this feature is a jaw dropper at Interops. I've > heard several accounts where people have brought > erlang-based systems to interops (Megaco, MPLS, etc.), and > have debugged and fixed interoperability problems in minutes > without restarting the system -- sometimes without even > dropping the session! > > I also seem to recall occasions where the erlang guys have > helped their competitors debugging _their_ system simply by > being able to follow the communication so much better on the > erlang side. Finally, I've heard accounts of the erlang guys > implementing workarounds to other people's bugs simply > because it was so much easier to do it that way than to wait > for them to get a fix from their design teams. > > /Uffe From eleberg@REDACTED Fri Apr 4 13:59:22 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Fri, 4 Apr 2003 13:59:22 +0200 (MEST) Subject: FAQ terminology harmonisation Message-ID: <200304041159.h34BxMi22199@cbe.ericsson.se> > On Wed, 2 Apr 2003 13:18:15 -0600 > Rick Pettit wrote: > (hope this is the correct person getting the attribution) > > Well yes, unless the C/C++ application loading the shared object > > (which in turn requires runtime linkage) does so over and over again > > (i.e. loads .so, then later unloads and reloads NEW .so, and so on). i used shared libraries like this to hot swap code for a network server: 1 install the new lib. 2 send SIGINIT to the process. when the main thread received SIGINIT it would come out of the listen() and do a fork(). the parent would wait for all worker threads connections to close. then it would exit. the child would re-read the config file and then start a new listen(). should i explain more, or is this (including any oversights) sufficient? bengt From mickael.remond@REDACTED Fri Apr 4 15:22:21 2003 From: mickael.remond@REDACTED (Mickael Remond) Date: Fri, 04 Apr 2003 15:22:21 +0200 Subject: help with installation In-Reply-To: (HP Wei's message of "Thu, 3 Apr 2003 23:44:02 -0500 (EST)") References: Message-ID: HP Wei writes: > I built and installed Erlang on a > Sun (Solaris 5.8 with gcc) in my office. > Everything run ok after I invoke it with 'erl' > -- I can do 'toolbar:start().' > > However, after I copied the whole directory of ~/erlang/... > onto the Sun machine (Solaris 5.8) at home, I had the following > problem. > > Invoking erl is ok. I can get into the interpreter and > run 'string:tokens(...).'. > But 'toolbar:start().' give me the error message: > ** exited: {startup_timeout,toolbar} ** > > Perhaps, some setting is not right. Or some libraries are missing. > Could someone tell me what is missing on my home machine ?? If I guess well, you might not have the proper TCL/TK library on your target machine. The toolbar depends on the GS application that depends on TK. This might be the cause of your problem. However, it is ofter safer to do a clean install of the Erlang environment. The 'configure' will warn you in case of missing libraries. -- Micka?l R?mond http://www.erlang-projects.org/ From kent@REDACTED Fri Apr 4 14:28:49 2003 From: kent@REDACTED (Kent Boortz) Date: 04 Apr 2003 14:28:49 +0200 Subject: help with installation In-Reply-To: References: Message-ID: HP Wei writes: > But 'toolbar:start().' give me the error message: > ** exited: {startup_timeout,toolbar} ** I think this is because you don't have the program wish8.X in your path. The graphical tools uses the wish program from Tcl/Tk 8, kent From cpressey@REDACTED Fri Apr 4 17:27:58 2003 From: cpressey@REDACTED (Chris Pressey) Date: Fri, 04 Apr 2003 09:27:58 -0600 Subject: type safety (was Re: FAQ terminology harmonisation) In-Reply-To: <3E8D2E55.2080403@manderp.freeserve.co.uk> References: <20030403140327.36ec505c.cpressey@catseye.mb.ca> <20030403183818.5c895f0d.cpressey@catseye.mb.ca> <3E8D2E55.2080403@manderp.freeserve.co.uk> Message-ID: <20030404092758.4ffcb64a.cpressey@catseye.mb.ca> On Fri, 04 Apr 2003 08:03:49 +0100 Peter-Henry Mander wrote: > Hmm... This emphasis on exact matching on type would potentially break > > an aspect of Erlang I have learnt to appreciate: pattern matching. I > can make a function match exactly or match with increasing degrees of > generality. A special case function first, followed by general case. > If none match, an exception occurs. I can work with a bit of dicipline > and tag my tuples, and enforce that functions only acccept tagged > tuples. > > Pete. Do you mean you write functions like this? case Value of Tuple when is_tuple(Tuple) -> case Tuple of Record when is_record(Record, my_record) -> do_stuff(Record) end end That seems silly. You probably mean like this: case Value of Record when is_record(Record, my_record) -> do_stuff(Record); Tuple when is_tuple(Tuple) -> do_other_stuff(Tuple) end But if records were opaque, that sort of match wouldn't break, either. -Chris From C.Reinke@REDACTED Fri Apr 4 17:43:38 2003 From: C.Reinke@REDACTED (C.Reinke) Date: Fri, 04 Apr 2003 16:43:38 +0100 Subject: type safety (was Re: FAQ terminology harmonisation) In-Reply-To: Message from Chris Pressey of "Thu, 03 Apr 2003 18:38:18 MDT." <20030403183818.5c895f0d.cpressey@catseye.mb.ca> Message-ID: > > [...] > > The basic idea is that if there is one abstract type in the > > language, we might be able to build other abstractions on top > > of that. Functions fit that bill wonderfully (the only thing > > you can do with a function is to apply it). In particular, > > there is no need for a module implementing an abstract type > > to expose anything but the API functions. > > I'm not sure that solves the problem - it just moves it from one > existing type to another It doesn't protect you from trying to misuse a data abstraction, but it severely limits the kinds of misuse you can try, and it makes it nearly impossible to discover the internal representation. That is good enough for most purposes, and a big improvement in the case of the queue example (no disagreement that Erlang's typing could be improved, though;). > (or, I don't follow you and you'll have to give me an example.) oh, but I did!-) After the commented example quoted from the programming rules, I added a variant of the queue based on this idea. Obviously too well hidden, sorry. If that example doesn't clarify the idea, please let me know.. > [..pattern matching and is_sometype(X) expose internal structure ..] Yes, procedural data structures as used in the example would still visibly give you tuples of functions, but they would do so for _all_ data abstractions. The _only_ meaningful way to distinguish between such abstractions (short of reflecting the erlang functions into some other representation) is by their API functions, which is the way it should be. In particular, the internal representation of queues as lists, trees or whatever is no longer visible. Cheers, Claus PS While the idea is nice and understandable without historic context, I'd still like to point to some references to indicate how those tricks relate to "proper" abstract data types, and how long they have been around, even though they depend on the ability to pass functions around (often, this is combined with local references, only accessible from the API functions). 1 Procedural encapsulation: A linguistic protection technique Stephen N. Zilles, 1973 , Proceeding of ACM SIGPLAN - SIGOPS interface meeting on Programming languages - operating systems http://doi.acm.org/10.1145/800021.808305 (text not online:-( 2 Protection in programming languages James H. Morris, Jr. Univ. of California, Berkeley Communications of the ACM, Volume 16 , Issue 1 (January 1973) http://doi.acm.org/10.1145/361932.361937 (don't let the erroneous abstract there fool you..) 3 User-Defined Types and Procedural Data Structures as Complementary Approaches to Data Abstraction, John C.~Reynolds, reprinted in: Theoretical Aspects of Object-Oriented Programming, The MIT Press, 1994, ed. Carl A.Gunter and John C.Mitchell, (first appeared in 1975) preprint at ftp://ftp.cs.cmu.edu/user/jcr/compdataabstr.pdf The relation between procedural data structures and modern abstract data types is explored in 4 On understanding types, data abstraction, and polymorphism. Luca Cardelli and Peter Wegner. Computing Surveys, 17(4):471-522, 1985. http://research.microsoft.com/Users/luca/Papers/OnUnderstanding.A4.pdf (see section 5) 5 Mitchell, J.C. and Plotkin, G.D., Abstract types have existential type, ACM Trans. Programming Languages and Systems, 10, 3 (1988) 470--502. http://doi.acm.org/10.1145/44501.45065 The main difference being that, since the representation type is hidden by the type system, the representation no longer has to be hidden, because clients of the data abstraction can't do anything with the representation but apply API functions to it. From cpressey@REDACTED Fri Apr 4 17:51:32 2003 From: cpressey@REDACTED (Chris Pressey) Date: Fri, 04 Apr 2003 09:51:32 -0600 Subject: type safety (was Re: FAQ terminology harmonisation) In-Reply-To: <20030404092954.17488.qmail@web13302.mail.yahoo.com> References: <20030403140327.36ec505c.cpressey@catseye.mb.ca> <20030404092954.17488.qmail@web13302.mail.yahoo.com> Message-ID: <20030404095132.00cdc469.cpressey@catseye.mb.ca> On Fri, 4 Apr 2003 01:29:53 -0800 (PST) Thomas Lindgren wrote: > There are two problems with records IMO: > > - Records of different record type can be confused > with each other (breaks type safeness in my eyes, but > I consider it a bug in the implementation rather than > something fundamental) > > - The underlying tuples show through the record > implementation. Unfortunate choice, but here the > argument (not mine :-) seems to be that "records > really are just syntactic sugar for tuples". Exactly the things that keep records from being opaque. > (Oh yeah, a third, related problem is the dependence > on include files for record definitions.) > > > We won't have type safety until we have truly opaque > > types. > > We have a warning not to let type information leak > > out of a module. > > But we currently *have* to implement types on top of > > existing types: > > usually tuples, or lists, or binaries could be used, > > or even refs or > > pids or atoms... but all of these can be confused > > with others of the > > same type, used in a different role. > > It depends a bit on what you mean by type, I'd say -- > you can have exactly the same problem in SML. But I > think you have a good point that it would sometimes be > useful to have support for user-defined data types > guaranteed to be distinct from all other types. Not just useful, but required in order to honestly say that Erlang is typesafe. Perhaps there's some confusion between the concepts of a subtype and an implementation type. If I write a module that implements a subtype of some existing type, say lists, then I'm implicitly guaranteeing that my type can be treated as a list type - so there should be no problem when using is_list on it. (You can then further check that it is my subtype of list, or use it as a regular list with no danger of conflict, etc.) If I write a module that implements an ADT and I say "The representation of this type is not defined," like the programming rules recommend, and like the dict module actually does, then the user *can't* safely distinguish it from *any* other types in a case statement, because they don't know what the implementation type is, so is_list or is_tuple or even is_atom (etc) might accidentally succeed on it. Of course - given that we already have the "counter-intuitive" tenet of "crashing is good", if someone can come up with a compelling argument for the equally counter-intuitive idea of "type safety is bad," that would work too. But I am yet to be convinced. -Chris From cpressey@REDACTED Fri Apr 4 18:02:03 2003 From: cpressey@REDACTED (Chris Pressey) Date: Fri, 04 Apr 2003 10:02:03 -0600 Subject: type safety (was Re: FAQ terminology harmonisation) In-Reply-To: References: <20030403183818.5c895f0d.cpressey@catseye.mb.ca> Message-ID: <20030404100203.3a5f4cb8.cpressey@catseye.mb.ca> On Fri, 04 Apr 2003 16:43:38 +0100 "C.Reinke" wrote: > > (or, I don't follow you and you'll have to give me an example.) > > oh, but I did!-) After the commented example quoted from the > programming rules, I added a variant of the queue based on this > idea. Obviously too well hidden, sorry. If that example doesn't > clarify the idea, please let me know.. Oops. I mistook it for part of the programming rules. And yes, what you mean is clearer to me now. > > [..pattern matching and is_sometype(X) expose internal structure ..] > > Yes, procedural data structures as used in the example would still > visibly give you tuples of functions, but they would do so for _all_ > data abstractions. As long as everyone used this method :) That's the real problem - no matter which way you do it, it's currently handled only by discipline and convention, rather than by the language. So maybe our convention is typesafe - but our language isn't. And since not everyone uses the same convention (though I'm certain any deviations come solely from innocent oversight :), the convention isn't much typesafe either... -Chris From C.Reinke@REDACTED Fri Apr 4 18:15:10 2003 From: C.Reinke@REDACTED (C.Reinke) Date: Fri, 04 Apr 2003 17:15:10 +0100 Subject: type safety (was Re: FAQ terminology harmonisation) In-Reply-To: Message from Peter-Henry Mander of "Fri, 04 Apr 2003 08:03:49 BST." <3E8D2E55.2080403@manderp.freeserve.co.uk> Message-ID: > Hmm... This emphasis on exact matching on type would potentially break > an aspect of Erlang I have learnt to appreciate: pattern matching. I can > make a function match exactly or match with increasing degrees of > generality. A special case function first, followed by general case. If > none match, an exception occurs. I can work with a bit of dicipline and > tag my tuples, and enforce that functions only acccept tagged tuples. yes, pattern matching and data abstraction do not usually go well together, as the former tries to expose internal structure whereas the latter tries to hide it. The problem is usually with pattern matching coupling too closely (you change the implementation in one module and suddenly have to adapt patterns all over your code base). There have been various attempts to address that, reconciling pm and adts, but you seem to refer to a different problem? You can still do case selection on a special case/general case basis, you just need to make sure that this doesn't depend on the implementation type but only on the API. Or, perhaps you mean that you sometimes want to be able to treat different things as if they were the same? You can still do that, but no longer by accident (because the different things just happen to be implemented using the same representation right now). The different things would have to support the same API (a kind of interface subtyping). That also means that your case selection code will still work when someone changes one of the internal representations. Cheers, Claus From Sean.Hinde@REDACTED Fri Apr 4 18:53:25 2003 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Fri, 4 Apr 2003 17:53:25 +0100 Subject: type safety (was Re: FAQ terminology harmonisation) Message-ID: Claus, > The problem is usually with pattern matching coupling too closely > (you change the implementation in one module and suddenly have to > adapt patterns all over your code base). Just out of interest what problem domain are you using Erlang for? In several years of using Erlang in relatively complex internet and telecoms type applications I've not found this to be a real problem at all. Major components of the systems exist as separate OTP applications and do not share any common patterns, and within subsystems, tagged tuples seem to do fine. Sean NOTICE AND DISCLAIMER: This email (including attachments) is confidential. If you have received this email in error please notify the sender immediately and delete this email from your system without copying or disseminating it or placing any reliance upon its contents. We cannot accept liability for any breaches of confidence arising through use of email. Any opinions expressed in this email (including attachments) are those of the author and do not necessarily reflect our opinions. We will not accept responsibility for any commitments made by our employees outside the scope of our business. We do not warrant the accuracy or completeness of such information. From erlang@REDACTED Fri Apr 4 19:12:23 2003 From: erlang@REDACTED (Peter-Henry Mander) Date: Fri, 04 Apr 2003 18:12:23 +0100 Subject: type safety (was Re: FAQ terminology harmonisation) References: <20030403140327.36ec505c.cpressey@catseye.mb.ca> <20030403183818.5c895f0d.cpressey@catseye.mb.ca> <3E8D2E55.2080403@manderp.freeserve.co.uk> <20030404092758.4ffcb64a.cpressey@catseye.mb.ca> Message-ID: <3E8DBCF7.6020904@manderp.freeserve.co.uk> I was thinking of something like this (not compiled or tested, sorry) which I find kinda useful sometimes. fn(#a_record{field=an_atom}) -> %% do stuff specific to a record with field=an_atom... fn(Record=#a_record{field=Field}) -> %% do stuff for other values of field... fn(Anything) -> %% do anything... Probably shouldn't! But I have a feeling we may be thinking of different purposes. Sorry I can't elaborate right now, I've gotta scoot, family needs me. Pete. Chris Pressey wrote: > On Fri, 04 Apr 2003 08:03:49 +0100 > Peter-Henry Mander wrote: > > >>Hmm... This emphasis on exact matching on type would potentially break >> >>an aspect of Erlang I have learnt to appreciate: pattern matching. I >>can make a function match exactly or match with increasing degrees of >>generality. A special case function first, followed by general case. >>If none match, an exception occurs. I can work with a bit of dicipline >>and tag my tuples, and enforce that functions only acccept tagged >>tuples. >> >>Pete. > > > Do you mean you write functions like this? > > case Value of > Tuple when is_tuple(Tuple) -> > case Tuple of > Record when is_record(Record, my_record) -> > do_stuff(Record) > end > end > > That seems silly. You probably mean like this: > > case Value of > Record when is_record(Record, my_record) -> > do_stuff(Record); > Tuple when is_tuple(Tuple) -> > do_other_stuff(Tuple) > end > > But if records were opaque, that sort of match wouldn't break, either. > > -Chris > > > From cpressey@REDACTED Fri Apr 4 19:27:07 2003 From: cpressey@REDACTED (Chris Pressey) Date: Fri, 04 Apr 2003 11:27:07 -0600 Subject: type safety (was Re: FAQ terminology harmonisation) In-Reply-To: <3E8DBCF7.6020904@manderp.freeserve.co.uk> References: <20030403140327.36ec505c.cpressey@catseye.mb.ca> <20030403183818.5c895f0d.cpressey@catseye.mb.ca> <3E8D2E55.2080403@manderp.freeserve.co.uk> <20030404092758.4ffcb64a.cpressey@catseye.mb.ca> <3E8DBCF7.6020904@manderp.freeserve.co.uk> Message-ID: <20030404112707.6c4e1ed3.cpressey@catseye.mb.ca> On Fri, 04 Apr 2003 18:12:23 +0100 Peter-Henry Mander wrote: > > I was thinking of something like this (not compiled or tested, sorry) > which I find kinda useful sometimes. > > fn(#a_record{field=an_atom}) -> > %% do stuff specific to a record with field=an_atom... > fn(Record=#a_record{field=Field}) -> > %% do stuff for other values of field... > fn(Anything) -> > %% do anything... Probably shouldn't! > > But I have a feeling we may be thinking of different purposes. Yeah, I think it's more to do with the general feeling that pattern matching and data abstraction are mutually opposed, as Claus pointed out. Which they are. But they can be made to live together too. To summarize: It's obviously not a practical problem, more of a technicality. If/when structs are added to Erlang, to address the shortcomings of records, hopefully, they'll be opaque - they won't be confusable with any other type, not even other structs. We should be able to happily match on them in case statements without wondering if they'll accidentally trigger is_list. And they'll still allow the coding style you demonstrate, above. Then, the programming rules should be amended to recommend that all ADT's be represented, on the surface, as structs. The internal structure of the struct still shouldn't be visible outside the module implementing the ADT, of course. Then, we can call Erlang typesafe, without any guilt :) -Chris From thomasl_erlang@REDACTED Fri Apr 4 19:50:12 2003 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Fri, 4 Apr 2003 09:50:12 -0800 (PST) Subject: type safety (was Re: FAQ terminology harmonisation) In-Reply-To: <20030404095132.00cdc469.cpressey@catseye.mb.ca> Message-ID: <20030404175012.22290.qmail@web13310.mail.yahoo.com> --- Chris Pressey wrote: > > It depends a bit on what you mean by type, I'd say > -- > > you can have exactly the same problem in SML. But > I > > think you have a good point that it would > sometimes be > > useful to have support for user-defined data types > > guaranteed to be distinct from all other types. > > Not just useful, but required in order to honestly > say that Erlang is > typesafe. In that case, I think we have different definitions of type safeness. To clarify, what I mean by type safeness is roughly that integers cannot be mistaken for atoms, conses can't be cast to tuples, etc, in contrast with languages such as C or C++. "Strong" as opposed to "weak" types, as it once was known. User-defined types and ADTs are above and beyond that, using this definition. Anyway, my main point previously was not to define type safeness, but to indicate a nice property which some languages have and some do not, so I think I'll leave it at that. Best, Thomas __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - File online, calculators, forms, and more http://tax.yahoo.com From cpressey@REDACTED Fri Apr 4 20:21:11 2003 From: cpressey@REDACTED (Chris Pressey) Date: Fri, 04 Apr 2003 12:21:11 -0600 Subject: type safety (was Re: FAQ terminology harmonisation) In-Reply-To: <20030404175012.22290.qmail@web13310.mail.yahoo.com> References: <20030404095132.00cdc469.cpressey@catseye.mb.ca> <20030404175012.22290.qmail@web13310.mail.yahoo.com> Message-ID: <20030404122111.01e7f915.cpressey@catseye.mb.ca> On Fri, 4 Apr 2003 09:50:12 -0800 (PST) Thomas Lindgren wrote: > > --- Chris Pressey wrote: > > > It depends a bit on what you mean by type, I'd say > > -- > > > you can have exactly the same problem in SML. But > > I > > > think you have a good point that it would > > sometimes be > > > useful to have support for user-defined data types > > > guaranteed to be distinct from all other types. > > > > Not just useful, but required in order to honestly > > say that Erlang is > > typesafe. > > In that case, I think we have different definitions of > type safeness. > > To clarify, what I mean by type safeness is roughly > that integers cannot be mistaken for atoms, conses > can't be cast to tuples, etc, in contrast with > languages such as C or C++. "Strong" as opposed to > "weak" types, as it once was known. User-defined types > and ADTs are above and beyond that, using this > definition. > > Anyway, my main point previously was not to define > type safeness, but to indicate a nice property which > some languages have and some do not, so I think I'll > leave it at that. > > Best, > Thomas OK. Yeah, my definition is probably a bit different. One thought I just had was - if you try hard enough you can subvert the type safety in any language. I guess my definition of typesafe would have to follow from that - that the shortest, most obvious route should be the one which results in the least confusion between (all) types. In that sense, C's typing is pretty safe (since casting is not the shortest route.) Does coercion figure into it? I'd say probably, since it's an intentional confusion of types - in that sense, both C and Erlang lose points (because coercion IS the shortest route, unfortunately.) So, it's not as simple as I maybe thought it was, going into it. The tuple/record thing is still a bummer though. And until something better comes along, the best I can suggest is that all ADT's be put in the form of records/tagged tuples (simply because this is probably the most common implementation type currently in use.) -Chris From Marc.Vanwoerkom@REDACTED Fri Apr 4 20:40:11 2003 From: Marc.Vanwoerkom@REDACTED (Marc Ernst Eddy van Woerkom) Date: Fri, 4 Apr 2003 20:40:11 +0200 (MEST) Subject: OOP for QC Message-ID: <200304041840.h34IeBJ02920@bonsai.fernuni-hagen.de> It is Friday evening here, so forgive me this Warp drive posting.. :) Alas this list is not particulary fond of OOP, e.g. http://www.bluetail.com/~joe/vol1/v1_oo.html and I had some "OOP vs other Paradigms (LP, FP)" discussion this week where I argumented, that OOP is too much based on analogies to (macroscopic) physical objects and computer science might have some useful organizational patterns that have no physical analogons. So I was quite surprised to read this article http://www.economist.com/printedition/displayStory.cfm?Story_ID=1682086 that some guy used OOP for his QC programming language. And I just thought that the unitary operations of QC are inherent reversibe and thus make even introducing destructive assignments a hard thing. So why is that beast not functional instead of OOP? :) A happy Weekend, Marc From rpettit@REDACTED Fri Apr 4 20:34:51 2003 From: rpettit@REDACTED (Rick Pettit) Date: Fri, 4 Apr 2003 12:34:51 -0600 Subject: Thanks for keeping me in the loop but... Message-ID: <20030404183451.GE20064@vailsys.com> Thanks to everyone for keeping me in the loop as the discussion continues, but just so you all know I am on the erlang-questions mailing list now so you no longer need to cc me when posting to the list. Thanks. -Rick From garry@REDACTED Fri Apr 4 21:06:35 2003 From: garry@REDACTED (Garry Hodgson) Date: Fri, 4 Apr 2003 14:06:35 -0500 (EST) Subject: FAQ terminology harmonisation Message-ID: <200304041906.OAA29622@sprache.sage.att.com> James Hague wrote: > Yes, I agree with that. I've wondered how Erlang would be with Python and > Haskell's "significant whitespace" as an alternative to all the commas and > semicolons (ah, the endless debates that would start). that would be a thing of beauty. ---- Garry Hodgson, Senior Hacker, AT&T Labs "You've been telling lies so long Some believe they're true So they close their eyes to things You have no right to do" --- Steppenwolf From kostis@REDACTED Fri Apr 4 21:58:12 2003 From: kostis@REDACTED (Kostis Sagonas) Date: Fri, 4 Apr 2003 21:58:12 +0200 (MEST) Subject: typing again In-Reply-To: Mail from '"C.Reinke" ' dated: Thu, 03 Apr 2003 19:44:41 +0100 Message-ID: <200304041958.h34JwCdm011807@harpo.it.uu.se> Claus Reinke wrote: > > Could someone explain why static typing is considered so "bad" > > or "unnecessary"? I think I could be sold on this (I _do_ > > consider myself to be open-minded), I just need to hear the > > right argument. > > static typing isn't at all bad > .... > as long as you have to choose between advanced type > systems and all the goodies Erlang provides, your choice will > depend on your applications. And for typical Erlang applications, > Erlang goodies are so indispensible that the choice is easy. > > Unfortunately, his correspondents didn't quite get it, but next > time some self-appointed evangelist asks how you can do any > safety-critical applications without static typing, the proper > answer is "I'd love to have a better type system, but how can you > do any safety-critical applications without cheap concurrency, > distribution, fault-tolerance, ..."!-) With the risk of embarking on a perennial discussion and opening up Pandora's box, I personally think that the proper answer to this is: "I'd love to have a type system that once I've developed my application I can optionally employ to catch possible type errors that may exist in my code, and to use as documentation about my data structures which is compiler-verified. However, I do not necessarily want the type system to stand on my way while I am experimenting, developing prototypes, or when I simply feel like writing programs that I know are OK but the type system somehow does not share my view on the subject..." Cheers, Kostis From cpressey@REDACTED Sat Apr 5 21:17:44 2003 From: cpressey@REDACTED (Chris Pressey) Date: Sat, 05 Apr 2003 13:17:44 -0600 Subject: typing again In-Reply-To: <200304041958.h34JwCdm011807@harpo.it.uu.se> References: <200304041958.h34JwCdm011807@harpo.it.uu.se> Message-ID: <20030405131744.327009cc.cpressey@catseye.mb.ca> On Fri, 4 Apr 2003 21:58:12 +0200 (MEST) Kostis Sagonas wrote: > With the risk of embarking on a perennial discussion and opening > up Pandora's box, I personally think that the proper answer to > this is: > > "I'd love to have a type system that once I've developed > my application I can optionally employ to catch possible > type errors that may exist in my code, and to use as > documentation about my data structures which is > compiler-verified. > > However, I do not necessarily want the type system > to stand on my way while I am experimenting, developing > prototypes, or when I simply feel like writing programs > that I know are OK but the type system somehow does not > share my view on the subject..." > > Cheers, > Kostis No holy war here; that _exactly_ how I feel. -Chris From cpressey@REDACTED Sat Apr 5 23:35:53 2003 From: cpressey@REDACTED (Chris Pressey) Date: Sat, 05 Apr 2003 15:35:53 -0600 Subject: Raskin book on UI and radical data thoughts In-Reply-To: <4.2.2.20030402185156.00d37100@duomark.com> References: <4.2.2.20030401203718.00a30540@duomark.com> <4.2.2.20030401203718.00a30540@duomark.com> <4.2.2.20030402185156.00d37100@duomark.com> Message-ID: <20030405153553.1c5bec36.cpressey@catseye.mb.ca> On Wed, 02 Apr 2003 19:02:02 -0800 Jay Nelson wrote: > Chris Pressey wrote: > >So, while I'll give him due credit for the terms he's coined, and > >while he seems to have the best of intentions, I think I'm a bit > >nonplussed by Mr. Raskin's actual ideas. > > I would agree, but might still want to read to hear his > arguments. Often they spur other ideas. Yes. Guru-types do tend to write enthralling books, even if you don't agree with everything (or even anything) they have to say... > >There are basically two reasons for why data interchange is in such a > >sorry state. > > Agreed. There is no incentive on the part of software *sellers* > to make this easy. Open source software should want compatibility > however. Isn't XML supposed to fix all this anyway? ;-) I expressed a similar sentiment about 6 months ago re: format of source code :) The last time XML came up on this list, some of the posts were very illuminating - for instance, that programmers tend to use XML as a transport layer only - they underuse the data structuring/typing facilities (I forget what they're called...) Could be the feeling that there'll always be "just one more field" that could be added, so no document type is ever "completely complete." Same sort of dilemma I've been trying to put into words for a while... standards are something you have to settle on, and a lot of people rightly don't want to settle! :) > >I think we already have these: journalling file systems? > > The user never sees it and the versioning isn't available. Or rather, > I know my Linux recovers faster now but I have no idea how it > works. Maybe I need to read up on the file system and see how > to expose the timestamps and versioning. > > jay Researching the topic a tiny bit with Google, it seems to have a lot to do with the definition of the word "journalling" in the minds of the people who design the journalling file system. It would be neat to see something a bit more explicit (a bit like CVS or a wiki, perhaps,) where you could select an object and select "revert to" and pick a date. -Chris From jay@REDACTED Sun Apr 6 00:25:05 2003 From: jay@REDACTED (Jay Nelson) Date: Sat, 05 Apr 2003 14:25:05 -0800 Subject: Read only filesystems Message-ID: <4.2.2.20030405141818.00d4e7a0@duomark.com> Chris Pressey wrote: > Researching the topic a tiny bit with Google, it seems to > have a lot to do with the definition of the word "journalling" > in the minds of the people who design the journalling file > system. I read a bit about XFS and then a lot about ReiserFS. Apparently the goal of the latter is database query capability on the filesystem itself. Interesting approach. I was thinking of using mnesia, but I might consider a filesystem if the meta data for versions and dates can be applied. > It would be neat to see something a bit more explicit > (a bit like CVS or a wiki, perhaps,) where you could select > an object and select "revert to" and pick a date. I don't want to view a file as a static current version. I want all versions always available (until I explicitly destroy them or they age off). "reverting" shouldn't be a needed concept. There are multiple read-only files, one of which is currently "published" if you are sharing with others and want a snapshot view. You can change which version a published view contains, but you can always open any file or "modify" (i.e. create a new copy with different details) any version. Semantically the same as what you said probably, but the concept of thinking of "revert" puts one in the single modifiable file mindset. I want to think more along the lines of infinite undo even after I have turned my computer off and come back after a week. jay From C.Reinke@REDACTED Sun Apr 6 14:08:42 2003 From: C.Reinke@REDACTED (C.Reinke) Date: Sun, 06 Apr 2003 13:08:42 +0100 Subject: type safety (was Re: FAQ terminology harmonisation) In-Reply-To: Your message of "Fri, 04 Apr 2003 17:53:25 BST." Message-ID: Sean, > > The problem is usually with pattern matching coupling too closely > > (you change the implementation in one module and suddenly have to > > adapt patterns all over your code base). > > Just out of interest what problem domain are you using Erlang for? In > several years of using Erlang in relatively complex internet and telecoms > type applications I've not found this to be a real problem at all. Major > components of the systems exist as separate OTP applications and do not > share any common patterns, and within subsystems, tagged tuples seem to do > fine. I'm not using Erlang much, certainly not for anything useful (yet;), but I've been working with several functional languages (including Lisp, KiR, Clean, ML, Haskell, and Erlang), and for the last years, Haskell has been my main development language. I've encountered the problem I described in all languages that support pattern matching, even within subsystems, so I'm slightly surprised by your statement (what happens to your receive statements when you've got to extend one of your tagged tuples?). The reason why I still use Haskell instead of Erlang is that (a) my applications focus more on computation than on communication, and (b) due to my work in language design, I like to prototype domain-specific languages by embedding them into a general purpose host language. In both of these areas, Haskell simply offers more expressiveness and more concise specifications, and Concurrent Haskell goes a long way when concurrency is needed. So while I think Haskell is incomplete in several respects, and Erlang covers some of those areas better, Erlang has its own blind spots and Haskell is overall a better match for my problems. Current problem domains include a domain-specific embedded language for dynamic 3d scenes and a refactoring tool for Haskell (as mentioned before, we'd love to find someone to extend the latter project to cover Erlang as well;-). In both domains, there are lots of non-trivial data types (e.g., some mimicking the grammars of the DSEL or of Haskell) with lots of constructors. If those can be seen in modules all over the project, it is tempting to use the powers of pattern matching. But then you've got yourself a task whenever the types change (which is admittedly more likely in the kind of research & prototyping environment I'm working in). That's not difficult to get right (in fact, this is one of the areas where the type system will tell you precisely where type providers and type clients disagree over their common interface), but it is annoying and tiresome (by the end of our functional refactoring project, that task may be automated:), so when large numbers of modules are involved, types have a tendency to get frozen. Cheers, Claus http://www.cs.kent.ac.uk/people/staff/cr3/ From hp@REDACTED Sun Apr 6 19:01:16 2003 From: hp@REDACTED (HP Wei) Date: Sun, 6 Apr 2003 13:01:16 -0400 (EDT) Subject: How to make a term synced on all nodes? Message-ID: <200304061701.h36H1GET015647@wren.rentec.com> Let's say I have an ets table (or some other term (object) in erlang) I want to keep a copy of it on all active nodes. Each of these nodes will update some part of this table. After an update, I want all copies on different nodes to be synced. (The purpose of keeping a copy on all nodes is to keep the info in this table alive all the time even when some nodes go down.) I figure that this is what people in the Erlang world are doing with ease all the time. However, as a beginner, I want to get some references (or example, fragment of codes) as to how to this. (1) how to make this table globally visible, (a name refering to one copy of this table) (2) how to keep it synced. Thanks, HP From ulf.wiger@REDACTED Sun Apr 6 20:24:36 2003 From: ulf.wiger@REDACTED (Wiger Ulf) Date: Sun, 6 Apr 2003 20:24:36 +0200 Subject: How to make a term synced on all nodes? References: <200304061701.h36H1GET015647@wren.rentec.com> Message-ID: <000701c2fc69$c7fb5c60$fd7a40d5@telia.com> You could certainly use mnesia for that. Read the mnesia User's Guide to get started. Mnesia allows you to create a table that is replicated on as many nodes as you want. You can make each table RAM-only, or persistent, depending on your needs. If you really want to use ets, and you want a very simple solution, then rpc:multicall(ets, insert, [TableName, Object]) is the easiest way to replicate. Note that it does not cover all the error cases, so you'd have to complement it with checking for errors, and synchronizing the tables at node restarts. Mnesia is definitely the safest way to go. /Uffe ----- Original Message ----- From: "HP Wei" To: Sent: den 6 april 2003 19:01 Subject: How to make a term synced on all nodes? > Let's say I have an ets table (or some other term (object) in erlang) > I want to keep a copy of it on all active nodes. > Each of these nodes will update some part of this table. > After an update, I want all copies on different nodes to be synced. > > (The purpose of keeping a copy on all nodes is to keep the info > in this table alive all the time even when some nodes go down.) > > I figure that this is what people in the Erlang world are doing > with ease all the time. > However, as a beginner, I want to get some references (or example, > fragment of codes) as to how to this. > (1) how to make this table globally visible, (a name refering to > one copy of this table) > (2) how to keep it synced. > > Thanks, > HP > From vlad_dumitrescu@REDACTED Mon Apr 7 06:17:17 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Mon, 7 Apr 2003 06:17:17 +0200 Subject: Read only filesystems References: <4.2.2.20030405141818.00d4e7a0@duomark.com> Message-ID: Hi, > I don't want to view a file as a static current version. I > want all versions always available (until I explicitly destroy > them or they age off). "reverting" shouldn't be a needed > concept. There are multiple read-only files, one of which > is currently "published" if you are sharing with others and > want a snapshot view. You can change which version a > published view contains, but you can always open any file > or "modify" (i.e. create a new copy with different details) > any version. This description brought one image in my head: the ClearCase filesystem (I'm not sure it is a true FS), where all versions coexist and one uses views to select any particular version to be the current one. Editing non-current versions is still possible, but those changes are very difficult to use in a view where they are not default. regards, Vlad From eleberg@REDACTED Mon Apr 7 09:19:43 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Mon, 7 Apr 2003 09:19:43 +0200 (MEST) Subject: typing again Message-ID: <200304070719.h377Jhi07328@cbe.ericsson.se> > On Fri, 4 Apr 2003 21:58:12 +0200 (MEST) > Kostis Sagonas wrote: > > > With the risk of embarking on a perennial discussion and opening > > up Pandora's box, I personally think that the proper answer to > > this is: > > > > "I'd love to have a type system that once I've developed > > my application I can optionally employ to catch possible > > type errors that may exist in my code, and to use as > > documentation about my data structures which is > > compiler-verified. > > > > However, I do not necessarily want the type system > > to stand on my way while I am experimenting, developing > > prototypes, or when I simply feel like writing programs > > that I know are OK but the type system somehow does not > > share my view on the subject..." > > common lisp? bengt From jay@REDACTED Mon Apr 7 10:03:01 2003 From: jay@REDACTED (Jay Nelson) Date: Mon, 07 Apr 2003 01:03:01 -0700 Subject: Read only filesystems In-Reply-To: References: <4.2.2.20030405141818.00d4e7a0@duomark.com> Message-ID: <4.2.2.20030407005335.00d54100@duomark.com> Vlad wrote: >This description brought one image in my head: the ClearCase filesystem (I'm >not sure it is a true FS), where all versions coexist and one uses views to >select any particular version to be the current one. Editing non-current >versions is still possible, but those changes are very difficult to use in a >view where they are not default. Thanks, I think you are right, but this is *definitely* not what I had in mind. I've used ClearCase (in fact I am using it at work now) and it is too difficult and cumbersome, requiring a staff to keep it running. I want something for a single person or a dynamic, collaborative group that requires little in the way of administration. The Plan9 stuff is interesting, I remember having read about it a year or two ago. They have a single inode for the root of the file system so you can switch from one version to another instantly. I've been thinking more along the lines of having no file names, just contents. mnesia may be the best way to go, although I may need to do something tricky to have multiple indices. One thing at a time, though. I've been swamped at work and haven't had a chance to switch from my Java webserver to my erlang webserver (nor even to complete the 2nd installment of the tutorial on tcp_proxy). jay From bernardp@REDACTED Mon Apr 7 10:12:01 2003 From: bernardp@REDACTED (Pierpaolo BERNARDI) Date: Mon, 7 Apr 2003 10:12:01 +0200 Subject: typing again References: <200304070719.h377Jhi07328@cbe.ericsson.se> Message-ID: <024c01c2fcdd$847f4360$e3f36850@c1p4e3> From: "Bengt Kleberg" > > > "I'd love to have a type system that once I've developed > > > my application I can optionally employ to catch possible > > > type errors that may exist in my code, > common lisp? Type declaration in Common Lisp are only for speed, they don't catch type errors. If you declare a variable to be of a certain type, and the variable gets assigned a value of a different type, the implementation is free to crash (and it usually does in implementations compiling to native code). So, CL is not an answer to Kostis' wish. P. From luke@REDACTED Mon Apr 7 15:49:37 2003 From: luke@REDACTED (Luke Gorrie) Date: 07 Apr 2003 15:49:37 +0200 Subject: CSP book, online in PDF Message-ID: Ahoy, The "Communicating Sequential Processes" book has been nicely PDF'ified, and you can download it from http://www.usingcsp.com/ if you like. (Sorry Scott :-)) Cheers, Luke From luke@REDACTED Mon Apr 7 16:13:45 2003 From: luke@REDACTED (Luke Gorrie) Date: 07 Apr 2003 16:13:45 +0200 Subject: typing again In-Reply-To: <024c01c2fcdd$847f4360$e3f36850@c1p4e3> References: <200304070719.h377Jhi07328@cbe.ericsson.se> <024c01c2fcdd$847f4360$e3f36850@c1p4e3> Message-ID: "Pierpaolo BERNARDI" writes: > From: "Bengt Kleberg" > > > > > "I'd love to have a type system that once I've developed > > > > my application I can optionally employ to catch possible > > > > type errors that may exist in my code, > > > common lisp? > > Type declaration in Common Lisp are only for > speed, they don't catch type errors. I don't know what the standard mandates, but in practice Common Lisps can catch type errors both at compile time and at runtime. CMUCL will generate runtime type checks for types you specify, and also do fancy type-inferencing with what information it has at compile-time and give compiler warnings for type errors it finds. Here is an example program that catches a runtime type error: (defvar n 0) (proclaim '(type (satisfies evenp) n)) (format t "~&Setting N to even number") (setq n 2) (format t "~&Setting N to odd number") (setq n 3) The "proclaim" assigns a type to the variable `n'. The type is (satisfies evenp), meaning that it includes all values for which the function `evenp' returns true. You can use any function, aswell as a vast collection of builtin types. If you run the program, this happens: Setting N to even number Setting N to odd number Type-error in C::BYTE-TYPE-CHECK-XOP: 3 is not of type (OR NULL (SATISFIES EVENP)) And you end up in the Lisp debugger, asking you how to continue. Here's a compile-time example, with a function that tries to use its argument as both a symbol and a number: (defun impossible-list (x) (list (symbol-name x) (1+ x))) The compiler says: ;;; Compiling defun impossible-list In: DEFUN IMPOSSIBLE-LIST (1+ X) --> + ==> X Warning: Result is a SYMBOL, not a (VALUES &OPTIONAL NUMBER &REST T). It all seems very impressive to me. I haven't done enough CL to know if it's actually blissful to work with. Cheers, Luke From mikpe@REDACTED Mon Apr 7 16:56:34 2003 From: mikpe@REDACTED (mikpe@REDACTED) Date: Mon, 7 Apr 2003 16:56:34 +0200 (MEST) Subject: otp SO_BSDCOMPAT problems with recent Linux development kernels Message-ID: <200304071456.h37EuYo2002982@harpo.it.uu.se> Running OTP on a recent Linux development kernel results in the kernel log quickly filling up with messages like: process `beam' is using obsolete setsockopt SO_BSDCOMPAT erts/emulator/drivers/common/inet_drv.c sets this option. However, it is a no-op in the current stable Linux kernels (2.4) and the development kernel recently obsoleted it. The inet_drv.c code setting this option should either be removed, since the option has no effect in non-ancient kernels, or it should be restricted to 2.2 and older kernels. I'll leave it to the OTP networking people to decide what to do about this. I can contribute code for the kernel version test needed at runtime, if you want to continue using the option for older kernels, /Mikael The HiPE team From Marc.Vanwoerkom@REDACTED Mon Apr 7 17:30:18 2003 From: Marc.Vanwoerkom@REDACTED (Marc Ernst Eddy van Woerkom) Date: Mon, 7 Apr 2003 17:30:18 +0200 (MEST) Subject: Arbitrary precision calculations in Erlang Message-ID: <200304071530.h37FUIQ10710@bonsai.fernuni-hagen.de> The Erlang introduction features examples where Erlang does arbitrary length integer multiplications. Is there a package somewhere deep in Erlang that does more, similiar to the bc tool? (Divisions with up to k digits after the radix point, different bases..) Regards, Marc From vlad_dumitrescu@REDACTED Mon Apr 7 17:54:39 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Mon, 7 Apr 2003 17:54:39 +0200 Subject: Read only filesystems References: <4.2.2.20030405141818.00d4e7a0@duomark.com> <4.2.2.20030407005335.00d54100@duomark.com> Message-ID: > >This description brought one image in my head: the ClearCase filesystem > Thanks, I think you are right, but this is *definitely* not what I had in mind. I didn't think you could want it either, but I used it as an example. Hopefully there are other FS that have the advantages, and lack the disadvantages. regards, Vlad From robert.virding@REDACTED Fri Apr 4 16:08:37 2003 From: robert.virding@REDACTED (Robert Virding) Date: Fri, 4 Apr 2003 16:08:37 +0200 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang .) References: <20030331133503.2e3fe0d2.cpressey@catseye.mb.ca> <200304011035.h31AZ5819612@bonsai.fernuni-hagen.de> <20030401224202.62e4c5c1.cpressey@catseye.mb.ca> Message-ID: <012e01c2fab3$b03330b0$8500000a@Clarke> I see to remember from my physics days that an assistent professor once told of a system where all units were dimensionless and scalars. I can't remember its name though (it was many years ago!). As your message wasn't a 1/4 a small comment: there are so many measures that it would be practically impossible to do it. Also would conversions be automatic? I mean could you match metres with furlongs or seconds with fortnights and it would convert for you. I like furlongs/fortnight. :-) Robert ----- Original Message ----- From: "Chris Pressey" To: "Marc Ernst Eddy van Woerkom" Cc: Sent: Wednesday, April 02, 2003 6:42 AM Subject: Re: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang .) > On Tue, 1 Apr 2003 12:35:05 +0200 (MEST) > Marc Ernst Eddy van Woerkom wrote: > > > BTW dimensional analysis > > > > http://www.physics.uoguelph.ca/tutorials/dimanaly/ > > > > seems to be an instance of abstract interpretation > > > > http://wombat.doc.ic.ac.uk/foldoc/foldoc.cgi?query=abstract+interpretation&a ction=Search > > > > used in physics. :) > > Yes, it does! Thanks for the links. > > > > For a while I tried designing a new language around measurements. > > > > Interesting. > > > > Last time I did numerical simulations in engineering (around 1997) > > there was still FORTRAN in use and things were moving slowly towards > > C++. The next big thing might be general use of interval arithmetics > > (where numeric types get proven error bounds annotated for all > > calculations) in the compilers (Sun is active here). > > Annotating types with units for unit type safety I have not seen as a > > big concern yet. > > > > Regards, > > Marc > > Errors (that is, +/- tolerance) were also taken into account in my > proof-of-concept language - although they're less important in the > digital domain (i.e. if I call a function to get the size of a file (in > bytes) I can assume the result is either 100% accurate or entirely > suspect. But for other things such as sleep durations, they may still > have a use.) > > Erlang ought to be a good language in which to introduce measurements, > if for no other reason than it shares it's name with a unit of > measurement :) > > The last time I tried introducing them, there was (justifiable) > resistance because I immediately assumed they should freely intermix > with regular data using overloaded operators. > > Right now, I'm just presenting them as an ADT like any other. This is > for two reasons. First: solely as an ADT they can provide a use as Twan > pointed out, to help build applications which deal in measurements. > Second: they needn't be used directly from Erlang. A simple parser and > evaluator could be written so that they could be used as a sublanguage > (not unlike how SQL is used in many languages.) This way the > distasteful subject of operator overloading can be completely avoided - > at the cost of it only being loosely coupled. (Gotta start somewhere) > > I dug up my old measurement module, cleaned it up a bit, and put it on > my website ( http://www.catseye.mb.ca/projects/measurement-+ ) and in > the Jungerl, for anyone who's curious. It could stand improvement. > > Thanks to everyone for your feedback, > -Chris > From robert.virding@REDACTED Fri Apr 4 16:26:47 2003 From: robert.virding@REDACTED (Robert Virding) Date: Fri, 4 Apr 2003 16:26:47 +0200 Subject: Error prone behavior of regexp. / Emacs mode. References: <022f01c2f68d$e13406a0$0ef36850@c1p4e3> Message-ID: <01b501c2fab6$39e647a0$8500000a@Clarke> This is a bug of course. It is easy to fix but unfortunately there is no really backwards compatible way of fixing it. If someone has saved an old parsed regexp it will not work with the fix. Is this ok Kenneth? I have a new regexp with some new useful features so I will fix this and the null match bug others have found and release it. Robert ----- Original Message ----- From: "Pierpaolo BERNARDI" To: Sent: Sunday, March 30, 2003 8:23 AM Subject: Error prone behavior of regexp. / Emacs mode. > Several functions in regexp behave like this: > > 22> regexp:match("foo",xxx). > nomatch > > That is, if the r.e. is not a list, it is assumed to be an already > parsed r.e. with no safety check whatsoever. > > I tripped in this doing by mistake: > > RE = regexp:parse([$t,$r,$e,$$]), > lists:map(fun(P)-> ... > {ok,S3,_} = regexp:sub(P,RE,"tr?"), > > Surely my fault, but the module could easily be more helpful. > > ----- > > On another topic, the emacs mode misparses strings ending in $. > In "foo$", $" is parsed as a character, compromising > the indentation of the rest of the file. Before I start digging in the > emacs mode, maybe someone has already fixed this? > > P. > > From robert.virding@REDACTED Fri Apr 4 16:15:46 2003 From: robert.virding@REDACTED (Robert Virding) Date: Fri, 4 Apr 2003 16:15:46 +0200 Subject: Gaga about bifs (Was: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang)) References: <3E882A09.4090809@rogvall.com>, <1049114703.23309@DNS02>, <3E8843BE.30601@rogvall.com> Message-ID: <013e01c2fab4$afb7a2a0$8500000a@Clarke> Why is everyone so completely gaga about adding new bifs to do relatively trivial things? Especially seeing you can already to do it without adding new stuff. Use erl_scan:string and io_lib:fwrite. I have sent a modified io_lib to erlang_questions a couple of times but it hasn't seemed to make it into the distribution. If Bj?rn sends the sgml manpage I can add it. My io_lib contained a ~# to write signed based integers and ~b and ~x for binary and hex bitfields. You usually need these diferent styles of writing a number. If someone wants my io_lib I will post it again. Robert ----- Original Message ----- From: "Raimo Niskanen" To: Sent: Tuesday, April 01, 2003 2:35 PM Subject: Re: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang > Alright then, I will add integer_to_list(Integer, Base) and > list_to_integer(List, Base) to the module 'erlang', and to the > documentation for R9C. We will see if they become real BIFs to R9C. > > integer(Base), 2 =< Base, Base =< 36. > > integer_to_list/2 allows leading '-' or '+' but no prefix. Both > uppercase or lowercase digits. No internal '_' since integer_to_list/1 > does not allow it, and neither do the compiler. (yet :-) > > list_to_integer/2 produces uppercase digits and a leading '-' for > negative numbers. > > / Raimo Niskanen, Erlang/OTP > > > > integer_to_list(I, Base) > when integer(I), integer(Base), Base >= 2, Base =< 1+$Z-$A+10 -> > if I < 0 -> > [$-|integer_to_list(-I, Base, [])]; > true -> > integer_to_list(I, Base, []) > end; > integer_to_list(I, Base) -> > erlang:fault(badarg, [I, Base]). > > integer_to_list(I0, Base, R0) -> > D = I0 rem Base, > I1 = I0 div Base, > R1 = if D >= 10 -> > [D-10+$A|R0]; > true -> > [D+$0|R0] > end, > if I1 == 0 -> > R1; > true -> > integer_to_list(I1, Base, R1) > end. > > > > list_to_integer(L, Base) > when list(L), integer(Base), Base >= 2, Base =< 1+$Z-$A+10 -> > case list_to_integer_sign(L, Base) of > I when integer(I) -> > I; > Fault -> > erlang:fault(Fault, [L,Base]) > end; > list_to_integer(L, Base) -> > erlang:fault(badarg, [L,Base]). > > list_to_integer_sign([$-|[_|_]=L], Base) -> > case list_to_integer(L, Base, 0) of > I when integer(I) -> > -I; > I -> > I > end; > list_to_integer_sign([$+|[_|_]=L], Base) -> > list_to_integer(L, Base, 0); > list_to_integer_sign([_|_]=L, Base) -> > list_to_integer(L, Base, 0); > list_to_integer_sign(_, _) -> > badarg. > > list_to_integer([D|L], Base, I) > when integer(D), D >= $0, D =< $9, D < Base+$0 -> > list_to_integer(L, Base, I*Base + D-$0); > list_to_integer([D|L], Base, I) > when integer(D), D >= $A, D < Base+$A-10 -> > list_to_integer(L, Base, I*Base + D-$A+10); > list_to_integer([D|L], Base, I) > when integer(D), D >= $a, D < Base+$a-10 -> > list_to_integer(L, Base, I*Base + D-$a+10); > list_to_integer([], _, I) -> > I; > list_to_integer(_, _, _) -> > badarg. > > > > Tony Rogvall wrote: > > Raimo Niskanen wrote: > > > >> > >> Some comments and some problems. Since Erlang supports the > >> Base#Integer syntax i think that Base in: > >> integer_to_list(Integer, Base) > >> should be 2..16, not atoms. > >> > > I just thought it would look nice, but I can buy 2..16 (btw do you know > > any one using base 13 for output? and since we only alow 2..16 its kind > > of crippled anyway) > > > > > >> The same for: > >> list_to_integer(List, Base) > >> > > Oh well. > > > >> But what should happen if you call list_to_integer("16#1f", 8), and > >> how should you specify any base. I guess the answers are: badarg on > >> the first and list_to_integer("16#1f", undefined) on the second question. > >> > > Like you said, do NOT allow base syntax in the list_to_integer/2 (why > > should you?) but maybe in list_to_integer/1 (if that does not break > > anything, it could!) > > > >> And to add the prefix in the Right(tm) way is a bit awkward: > >> List = case integer_to_list(Integer, 16) of > >> [$-|L] -> "-16#"++L; > >> L -> "16#"++L > >> end > > > > > > My oppinon is that we ignore the prefix stuff completly just to get > > things on it's way. I myself have never sent any output in base syntax > > (anyone?). > > > > /Tony > > From robert.virding@REDACTED Fri Apr 4 16:19:22 2003 From: robert.virding@REDACTED (Robert Virding) Date: Fri, 4 Apr 2003 16:19:22 +0200 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang References: <1048988965.9852@DNS02> <3E882A09.4090809@rogvall.com> <042101c2f792$e28be4e0$d0f06850@c1p4e3> <047501c2f796$f0df0d20$d0f06850@c1p4e3> Message-ID: <017801c2fab5$3090dd60$8500000a@Clarke> This is a bug in the scanner, probably due to reusing functions in the wrong context. Robert ----- Original Message ----- From: "Pierpaolo BERNARDI" To: Sent: Monday, March 31, 2003 5:04 PM Subject: Re: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang > From: "Pierpaolo BERNARDI" > > > BTW, I find this behaviour of the erlang parser puzzling: > > > > 51> 16#-123. > > -123 > > 52> 16#. > > 0 > > > > Is this intended? what's its rationale? > > I mean, I know the correct syntax, I am wondering why > this doesn't raise an error. > > I was cheking if by chance I had overlooked a bit of syntax > and 16#-123 was valid. > > P. > > From robert.virding@REDACTED Fri Apr 4 16:18:18 2003 From: robert.virding@REDACTED (Robert Virding) Date: Fri, 4 Apr 2003 16:18:18 +0200 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang References: <1048988965.9852@DNS02> <3E882A09.4090809@rogvall.com> <042101c2f792$e28be4e0$d0f06850@c1p4e3> <047501c2f796$f0df0d20$d0f06850@c1p4e3> Message-ID: <017201c2fab5$0b312570$8500000a@Clarke> ----- Original Message ----- From: "Pierpaolo BERNARDI" To: Sent: Monday, March 31, 2003 5:04 PM Subject: Re: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang > From: "Pierpaolo BERNARDI" > > > BTW, I find this behaviour of the erlang parser puzzling: > > > > 51> 16#-123. > > -123 > > 52> 16#. > > 0 > > > > Is this intended? what's its rationale? > > I mean, I know the correct syntax, I am wondering why > this doesn't raise an error. > > I was cheking if by chance I had overlooked a bit of syntax > and 16#-123 was valid. > > P. > > From cpressey@REDACTED Tue Apr 8 00:31:22 2003 From: cpressey@REDACTED (Chris Pressey) Date: Mon, 07 Apr 2003 17:31:22 -0500 Subject: Read only filesystems In-Reply-To: <4.2.2.20030405141818.00d4e7a0@duomark.com> References: <4.2.2.20030405141818.00d4e7a0@duomark.com> Message-ID: <20030407173122.502317e8.cpressey@catseye.mb.ca> On Sat, 05 Apr 2003 14:25:05 -0800 Jay Nelson wrote: > Chris Pressey wrote: > > > Researching the topic a tiny bit with Google, it seems to > > have a lot to do with the definition of the word "journalling" > > in the minds of the people who design the journalling file > > system. > > I read a bit about XFS and then a lot about ReiserFS. > Apparently the goal of the latter is database query capability > on the filesystem itself. Interesting approach. I was thinking > of using mnesia, but I might consider a filesystem if the > meta data for versions and dates can be applied. Depends on exactly what they mean when they say 'database query', but yes, being able to locate objects based on something besides the de-facto standard hierarchical path, would be good. Keywords, for example. Current 'find' utilities for OS'es/filesystems are pretty weak when compared to, say, Google. And hierarchies are pretty suffocating - it matters little if I put a file in chris/erlang/doc or chris/doc/erlang or doc/chris/erlang or doc/erlang/chris. Those should really be keywords rather than hierarchical directory names. > > It would be neat to see something a bit more explicit > > (a bit like CVS or a wiki, perhaps,) where you could select > > an object and select "revert to" and pick a date. > > I don't want to view a file as a static current version. I know you don't want to view a file as static. But do you really have a practical choice not to see *some* kind of current version? > I want all versions always available (until I explicitly destroy them > or they age off). I know. > "reverting" shouldn't be a needed concept. Unfortunately "transverting" is not good English... at least not yet :) I don't actually think "revert" is too far off the mark. As soon as you switch the view of an object to a different version, the version you select becomes the newest version (by virtue of the fact that the chosen version is the one you're going to base your next version on.) Even when you, say, switch to a version from a week ago, the version you were just working on becomes an old version - old, when compared to your current version (which is a new copy of the version from a week ago.) Clear as mud :) > There are multiple read-only files, one of which is currently > "published" That's the current version, as I see it. > if you are sharing with others and want a snapshot view. I think most people *will* want a "snapshot" view, as the default. Actually, I can't really imagine any practical alternatives to having a single current view of all objects -- wouldn't anything else get extremely messy? > You can change which version a > published view contains, but you can always open any file > or "modify" (i.e. create a new copy with different details) > any version. To me, it seems a lot easier to split that into two steps: - switch which version is the current version - open or "modify" the current version (to make the next new version) And, from a usage perspective, if the capability to switch versions is part of (say) the open-file dialog, there's no perceptible difference. At the risk of confusing this even more, I guess I could try an analogy here. You always edit a text file from the cursor position. You can't edit the text in any other location; if you want to edit text in some other location, you have to move the cursor there first. The "current version" or "published view" of an object, is analogous to the cursor in a text editor. > Semantically the same as what you said probably, but the > concept of thinking of "revert" puts one in the single modifiable > file mindset. I don't see this is a problem, as long as it doesn't exclude other mindsets. The "destructive assignment" mindset is, in fact, something humans are very used to (e.g. you can't unburn a candle) so I see no reason to abandon it outright. > I want to think more along the lines of infinite > undo even after I have turned my computer off and come back > after a week. I don't really see how those circumstances make things much different, but I certainly don't want to stop you from thinking in that mindset either. > jay -Chris From cpressey@REDACTED Tue Apr 8 01:09:09 2003 From: cpressey@REDACTED (Chris Pressey) Date: Mon, 07 Apr 2003 18:09:09 -0500 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang .) In-Reply-To: <012e01c2fab3$b03330b0$8500000a@Clarke> References: <20030331133503.2e3fe0d2.cpressey@catseye.mb.ca> <200304011035.h31AZ5819612@bonsai.fernuni-hagen.de> <20030401224202.62e4c5c1.cpressey@catseye.mb.ca> <012e01c2fab3$b03330b0$8500000a@Clarke> Message-ID: <20030407180909.3a65d754.cpressey@catseye.mb.ca> On Fri, 4 Apr 2003 16:08:37 +0200 "Robert Virding" wrote: > I see to remember from my physics days that an assistent professor > once told of a system where all units were dimensionless and scalars. > I can't remember its name though (it was many years ago!). It's called "math class" :) > As your message wasn't a 1/4 a small comment: there are so many > measures that it would be practically impossible to do it. I did do a fairly in-depth analysis of this once, and there are five kinds of units that pose a problem (i.e. in the interests of producing something usable, they'd probably be ignored), listed in the order of increasing difficulty to implement: 1. variations on units (league -> statute? naut international? naut UK?) 2. tropical units (misnomers; 1 foot-pound =/= 1 foot * 1 pound) 3. units with a non-zero "zero point" (Celcius, Fahrenheit) 4. logarithmic units (deciBels, Richter scale) 5. subjective units (Beaufort scale) Of course, there may also be others I missed. But the exceptions do seem to be in the minority. Most units behave quite regularly. > Also would > conversions be automatic? I mean could you match metres with furlongs > or seconds with fortnights and it would convert for you. I like > furlongs/fortnight. :-) I think they'd pretty much have to be automatic for it to be useful. But they could be specified explicitly as well. Just imagine opening up a shell and typing 14.9 parsec/jiffy in furlong/fortnight. :) > Robert -Chris From bernardp@REDACTED Tue Apr 8 01:36:29 2003 From: bernardp@REDACTED (Pierpaolo BERNARDI) Date: Tue, 8 Apr 2003 01:36:29 +0200 Subject: typing again References: <200304070719.h377Jhi07328@cbe.ericsson.se><024c01c2fcdd$847f4360$e3f36850@c1p4e3> Message-ID: <01ee01c2fd69$9db0d380$8ff36850@c1p4e3> From: "Luke Gorrie" > > Type declaration in Common Lisp are only for > > speed, they don't catch type errors. > > I don't know what the standard mandates, according the standard, a type declaration is not an assertion to be checked (either at compile or run time), but a promise from the programmer that that type declaration will hold. > but in practice Common Lisps > can catch type errors both at compile time and at runtime. Well, at compile time usually they don't. At run time they must, unless you supply type declarations. CMUCL is an exception. In native-code systems, usually (i.e. in all systems but CMUCL) type declarations are simply ignored in 'safe code' (code compiled at (safety 3)), and they are trusted blindly in code compiled at lower safety. According to the spec the system could also trust type declarations in safe code, but luckily no system that I know of does this. Clisp and Symbolics CL, as a diametrically opposite example, completely ignore type declarations. These systems are always in safe mode (with some exceptions for symbolics). Both approaches are valid according to the standard. > CMUCL will > generate runtime type checks for types you specify, and also do fancy > type-inferencing with what information it has at compile-time and give > compiler warnings for type errors it finds. CMUCL chooses to check declarations, except when at the lowest safety level. This is excellent, but don't count on this in other implementations. Both your examples compile with no errors or warnings in acl and lispworks (and clisp, of course). In all of these implementations a run-time error is signalled, though. Just like in Erlang. If you were accessing an array with an index out of bounds, a type declaration on the index would not protect you, on the contrary, it may suppress a check that the compiler would have put in otherwise. > It all seems very impressive to me. I haven't done enough CL to know > if it's actually blissful to work with. It is. Just there are a lot of dark corners, and many implementations, each with its own set of idiosyncrasies. Cheers P. From raimo.niskanen@REDACTED Tue Apr 8 09:11:04 2003 From: raimo.niskanen@REDACTED (Raimo Niskanen) Date: Tue, 08 Apr 2003 09:11:04 +0200 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang References: <042101c2f792$e28be4e0$d0f06850@c1p4e3>, <047501c2f796$f0df0d20$d0f06850@c1p4e3>, <017801c2fab5$3090dd60$8500000a@Clarke> Message-ID: I will fix it for R9C. / Raimo Niskanen, Erlang/OTP Robert Virding wrote: > This is a bug in the scanner, probably due to reusing functions in the wrong > context. > > Robert > > ----- Original Message ----- > From: "Pierpaolo BERNARDI" > To: > Sent: Monday, March 31, 2003 5:04 PM > Subject: Re: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang > > > >>From: "Pierpaolo BERNARDI" >> >>>BTW, I find this behaviour of the erlang parser puzzling: >>> >>>51> 16#-123. >>>-123 >>>52> 16#. >>>0 >>> >>>Is this intended? what's its rationale? >> >>I mean, I know the correct syntax, I am wondering why >>this doesn't raise an error. >> >>I was cheking if by chance I had overlooked a bit of syntax >>and 16#-123 was valid. >> >>P. >> >> > > From etxuwig@REDACTED Tue Apr 8 10:50:15 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Tue, 8 Apr 2003 10:50:15 +0200 (MEST) Subject: records generated from UBF Message-ID: Is anybody else out there playing around with UBF? I wrote a small utility yesterday that generates a .hrl file from a UBF specification. It generates a record specification for each type that looks like a tagged tuple, where the tag matches the type name, and all other elements are type references. For example: person() = {person, name(), age(), address(), phone()}; becomes -record(person, {name, age, address, phone}). The UBF contract checker will type check all incoming and outgoing messages, so you can trust that all attributes of a record are type correct. This makes it quite easy to put together external interfaces with a very nice programming style for the back-end. ... I will take the opportunity to extoll the virtues of UBF-oriented programming by providing a "small" example. The server in question handles administrative tasks for a Track & Field competition, and also serves spectators with updates on what is going on (which, as everyone who's been to a Track&Field event knows, is quite a lot). The network is typically WLAN. The client is written in Java, and the server in Erlang. I use UBF, mnesia, rdbms, and will probably later use xmerl, inets and perhaps erlguten. Who knows - maybe we'll throw in sowap as well. ;) This is an Open Source project. The UBF contract specifies some basic types, e.g. club_id() = constant(); location() = string(); club() = {club, club_id(), name(), location(), info()}; Using the utility described above, "compiling" the contract results in, among other things, a .hrl file with record declarations to match: -record(club, {club_id, name, location, info}). The contract also specifies valid messages: qNewClub() = {new_club, club()}; qListClubs() = list_clubs; rListClubs() = club_list() | rError(); qOpenClub() = {open_club, club_id()}; rOpenClub() = club() | rError(); qControlClub() = {control_club, club_id()}; qEndControlClub() = {end_control_club, club_id()}; qUpdateClub() = {update_club, club()}; qDeleteClub() = {delete_club, club_id()}; And two states, 'administrator' and 'viewer', where valid messages are listed: +STATE administrator ... qNewClub() => rReply() & administrator; qControlClub() => rReply() & administrator; qEndControlClub() => rReply() & administrator; qUpdateClub() => rReply() & administrator; qDeleteClub() => rReply() & administrator; ... (actually, messages valid both for 'administrator' and 'viewer' are listed under ANYSTATE:) +ANYSTATE qListClubs() => rListClubs(); qOpenClub() => rOpenClub(); I have one plugin serving both administrators and viewers, since the viewer information is a subset of the administrator information. I start two instances of the plugin, one in 'administrator' state and one in 'viewer' state. After this, the contract checker makes sure that only messages valid for each state are admitted, and I don't have to worry much about checking stuff in my own code. The code in the plugin looks like this: ======== handlerRpc(S, list_clubs, D, Env) -> reply(catch {{club_list, club:list_clubs()}, S, D}, S, D); handlerRpc(S, {open_club, ClubId}, D, Env) -> reply(catch {club:open(ClubId), S, D}, S, D); handlerRpc(S, {new_club, Club}, D, Env) -> reply(catch {club:new(Club), S, D}, S, D); ======== And the code in the different modules (club, athlete, event, etc.) looks sort of like this: ======== -module(cath.server.club). -export([list_clubs/0, new/1, open/1, update/1, delete/1]). -export([schema/1]). -include("cath_plugin.hrl"). % generated .hrl file schema([]) -> [ {club, [{attributes, record_info(fields, club)}, {record_name, club}, {disc_copies, db:writer_nodes()}, {ram_copies, db:reader_nodes()}]} ]. list_clubs() -> db:list_items(club). new(#club{club_id = Id} = Club) -> db:new(club, Id, Club). open(ClubID) -> db:open(club, ClubID). update(#club{club_id = Id} = Club) -> db:update(club, Id, Club). delete(Id) -> db:delete(club, Id). The db.erl module is a database wrapper, which uses rdbms as the activity module. Rdbms makes sure e.g. that one cannot add an athlete to a non-existant club, or that all athletes belonging to a club are deleted if the club is deleted -- basic referential integrity, that is. Error handling is simple. Each user gets a session (a process). UBF will exit and close the session if the protocol is violated, and mnesia/rdbms will abort and exit if anything goes wrong inside a transaction; transaction aborts lead to error messages. If the protocol doesn't allow for an error message in response to a certain query, it will complain, and close the session. Perhaps not the most elegant way to do it, but it works. A more complex module, e.g. athlete, might have to handle dependencies: ======== -module(cath.server.athlete). -export([list_athletes/1, open/2, new/2, update/2, delete/2]). -export([schema/1]). -include("cath_plugin.hrl"). schema(Contest) -> TabName = contest:table_name(athlete, Contest), [ {TabName, %% mnesia options [ {disc_copies, db:writer_nodes()}, {ram_copies, db:reader_nodes()}, {attributes, record_info(fields, athlete)}, {record_name, athlete} ], %% rdbms properties [ %% when deleting a club, also delete its athletes {{attr, {club, club_id}, references}, [{TabName,club,{full,cascade,ignore}}]}, {{attr, {TabName,club}, references}, [{club, club_id, {full,ignore,no_action}}]} ] } ]. list_athletes(Contest) -> lists:map( fun(#athlete{club = Id} = A) -> A#athlete{club = club:open(Id)} end, db:list_items(athlete, Contest)). new(#athlete{athlete_id = Id} = Ath, Contest) -> db:new(athlete, Id, Ath, Contest). ======== That is, the referential integrity checks done by rdbms ensure that the new athlete actually belongs to an existing club, and UBF has already checked that the #athlete{} record contains valid types. Not all functionality has been implemented yet, but the server runs all day during testing, and it never crashes (of course, it's Erlang). Performance? I haven't tested it yet, but I'm sure it's more than sufficient. The application is designed to take advantage of distribution, if I add a load sharing front-end to it (I vaguely recall this having been done before...;) Life is good. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From garry@REDACTED Tue Apr 8 15:07:00 2003 From: garry@REDACTED (Garry Hodgson) Date: Tue, 8 Apr 2003 09:07:00 -0400 (EDT) Subject: Read only filesystems Message-ID: <200304081307.JAA73780@sprache.sage.att.com> Chris Pressey wrote: > > It would be neat to see something a bit more explicit > > (a bit like CVS or a wiki, perhaps,) where you could select > > an object and select "revert to" and pick a date. we used to use a thing called 3dfs back in the early 90's that let you do that. that is, if you wanted an old version of /home/garry/.profile, you'd just go to (something like) /2002-12-21/home/garry/.profile. you could edit it, diff it, etc. very, very, nice. ---- Garry Hodgson, Senior Hacker, AT&T Labs Have you any idea why they're lying to you? To your faces! - Paul Kantner From jamesh@REDACTED Tue Apr 8 20:36:17 2003 From: jamesh@REDACTED (James Hague) Date: Tue, 8 Apr 2003 13:36:17 -0500 Subject: Gaga about bifs Message-ID: Robert Virding wrote: >Why is everyone so completely gaga about adding new bifs >to do relatively trivial things? Especially seeing you >can already to do it without adding new stuff. Use >erl_scan:string and io_lib:fwrite. That's a good point, but I can see two reasons: 1. integer_to_list and list_to_integer are already bifs. It's cleaner to have arity two versions with the same names than it is to have completely different functions in different modules. 2. The currently Erlang implementation is one of the fastest interpreted languages I have seen. It walks all over Python for most things, for example (by factors of 2 to 20 on micro-bencmarks!), even though Erlang is functional and Python imperative. Much of this speed comes from great attention to the low-level details of the interpreter: threaded code, beam "superinstructions," having many core functions coded in C. Certainly integer_to_list/2 is not a time critical function in most cases, but then I guess you could argue the same about integer_to_list/1. If implementation purity were the highest priority, then there's no reason for lists:reverse and lists:length to be bifs, for example. Execution speed for most tasks is not top priority, and that the Erlang system *has* been honed with a focus on speed helps keep this true. >I have sent a >modified io_lib to erlang_questions a couple of times >but it hasn't seemed to make it into the distribution. This brings up an entirely different issue. The OTP team is doing a good job with bug fixes and general maintenance, but general improvements, significant and otherwise, seem to have ground to a halt, or at least be in a state of confusion. This has come up several times now. It may just be that Erlang is good enough for the places it is used, but it would be nice to see some more active development. A number of improvements have come up and never seem to go anywhere. From erikp@REDACTED Tue Apr 8 23:21:42 2003 From: erikp@REDACTED (Erik Pearson) Date: Tue, 08 Apr 2003 14:21:42 -0700 Subject: R9B-1 build notes on RH9 Message-ID: <3E933D66.8080004@attbi.com> Just installed RedHat 9 on a new system; added latest patches as well. So, I thought I'd pass some build notes to the maintainers or anyone else. 1. Always have had troubles with unicode and the perl build scripts. I always change LANG=en_US from the default en_US.UTF-8 before building. 2. Applications ssl now fails. Haven't seen this before, so I'm guessing RH put krb5.h in a new place. gcc -c -o ../priv/obj/i686-pc-linux-gnu/esock_ssleay.o -Wall -g -O2 -I/home/erikp/otp_src_R9B-1/erts/i686-pc-linux-gnu -DHAVE_CONFIG_H -O2 -I/usr/include/openssl -I/usr/include esock_ssleay.c In file included from /usr/include/openssl/ssl.h:179, from esock_ssleay.c:74: /usr/include/openssl/kssl.h:72:18: krb5.h: No such file or directory In file included from /usr/include/openssl/ssl.h:179, from esock_ssleay.c:74: krb5.h is found in /usr/kerberos/include. Adding an appropriate -I/usr/kerberos/include solved it. 3. Ssl_esock didn't get installed, so ssl:start() failed. I manually copied $ERL_TOP/lib/ssl/priv/bin/i686-pc-linux-gnu/ssl_esock to /lib/erlang/lib/ssl-2.3.5/priv/bin/ssl_esock Then 'ssl:start()' worked. Other than that, so far so good. --erikp-- From hp@REDACTED Wed Apr 9 02:47:31 2003 From: hp@REDACTED (HP Wei) Date: Tue, 8 Apr 2003 20:47:31 -0400 (EDT) Subject: How do I find a file on http://url_path/filename Message-ID: <200304090047.h390lVET018657@wren.rentec.com> I am a bit lost in the huge amount of docs. (It will get better when I am exposed to it for a while.) For now, Please tell me where I could find the module for doing: (1) check if a file exists on http://url_path/filename? (2) retrieve that file to a local disk. thanks, HP From cpressey@REDACTED Wed Apr 9 03:46:09 2003 From: cpressey@REDACTED (Chris Pressey) Date: Tue, 08 Apr 2003 20:46:09 -0500 Subject: How do I find a file on http://url_path/filename In-Reply-To: <200304090047.h390lVET018657@wren.rentec.com> References: <200304090047.h390lVET018657@wren.rentec.com> Message-ID: <20030408204609.7162d5d6.cpressey@catseye.mb.ca> On Tue, 8 Apr 2003 20:47:31 -0400 (EDT) HP Wei wrote: > I am a bit lost in the huge amount of docs. > (It will get better when I am exposed to it for a while.) > For now, > Please tell me where I could find the module for doing: > > (1) check if a file exists on http://url_path/filename? > (2) retrieve that file to a local disk. > > thanks, > HP Is this something like what you're looking for? 1> http:request_sync(get,{"http://www.erlang.org/foo",[]}). {404, [{'Transfer-Encoding',"chunked"}, {'Content-Type',"text/html"}, {'Date',"Wed, 09 Apr 2003 01:43:27 GMT"}, {'Server',"Apache/1.3.9 (Unix)"}], "\n\n404 Not Found\n\n

    Not Found

    \nThe requested URL /foo was not found on this server.

    \n


    \n
    Apache/1.3.9 Server at www.erlang.org Port 80
    \n\n"} It doesn't look like the http client module is documented yet. -Chris From hp@REDACTED Wed Apr 9 05:45:26 2003 From: hp@REDACTED (HP Wei) Date: Tue, 8 Apr 2003 23:45:26 -0400 (EDT) Subject: How do I find a file on http://url_path/filename In-Reply-To: <20030408204609.7162d5d6.cpressey@catseye.mb.ca> Message-ID: Yes. That works for what I want to do. Thanks. btw, I was trying to find 'this function' in places in the docs related to opening a file. I always thought that 'opening a file' is a useful 'abstract notion'. i.e. I should be able to say open_file( disk_file_path, options), or open_file( url_file_path, options). Instead of writing two completely different 'forms' like in this case. But anyway, just a thought. As long as I can solve my immediate problem, I can live with this function. Thanks again for the pointer, HP On Tue, 8 Apr 2003, Chris Pressey wrote: > On Tue, 8 Apr 2003 20:47:31 -0400 (EDT) > HP Wei wrote: > > > I am a bit lost in the huge amount of docs. > > (It will get better when I am exposed to it for a while.) > > For now, > > Please tell me where I could find the module for doing: > > > > (1) check if a file exists on http://url_path/filename? > > (2) retrieve that file to a local disk. > > > > thanks, > > Is this something like what you're looking for? > > 1> http:request_sync(get,{"http://www.erlang.org/foo",[]}). > It doesn't look like the http client module is documented yet. > > -Chris > From ulf.wiger@REDACTED Wed Apr 9 09:06:38 2003 From: ulf.wiger@REDACTED (Wiger Ulf) Date: Wed, 9 Apr 2003 09:06:38 +0200 Subject: How do I find a file on http://url_path/filename References: Message-ID: <000d01c2fe66$90cbf480$fd7a40d5@telia.com> From: "HP Wei" > I always thought that 'opening a file' is a useful 'abstract notion'. > i.e. I should be able to say > open_file( disk_file_path, options), > or open_file( url_file_path, options). > Instead of writing two completely different 'forms' like in this case. Then you will perhaps appreciate Joe Armstrongs thoughts on "Conceptual Integrity in Erlang" (http://www.sics.se/~joe/nerl.htmlhttp://www.sics.se/~joe/nerl.html) /Uffe From raimo.niskanen@REDACTED Wed Apr 9 10:59:45 2003 From: raimo.niskanen@REDACTED (Raimo Niskanen) Date: Wed, 09 Apr 2003 10:59:45 +0200 Subject: Gaga about bifs (Was: Complexity Shock Horror II: the Sequel References: <3E8843BE.30601@rogvall.com>, , <013e01c2fab4$afb7a2a0$8500000a@Clarke> Message-ID: I have just added something like that to io_lib:fwrite. I did not have your code available when I did it, but I had an example from Happi that sounds just like your suggestion. This was in the thread "MD5 in erlang.", by the way. Here is how it will be in R9C unless anyone has strong objections: io_lib:format("~.16x", [-31,"0x"]) -> "-0x1f" io_lib:format("~.16X", [-31,"0x"]) -> "-0x1F" ~b/~B is just ~x/~X with empty prefix: io_lib:format("~.16b", [-31]) -> "-1f" io_lib:format("~.16B", [-31]) -> "-1F" and ~u/~U is the same as ~b/~B with the argument integer 'band'ed with ((1< "1F" io_lib:format("~.16u", [-31,32]) -> "ffffffe1" io_lib:format("~8.16.0u", [31,32]) -> "0000001f" io_lib:format("~8.16.0U", [-31,32]) -> "FFFFFFE1" And for io:fread I added: io_lib:fread("~16u", "FFFF") -> {ok,[65535],[]} io_lib:fread("~-~16u", "-FFFF") -> {ok,[-1,65535],[]} ~u scans unsigned integers in specified base. ~- scans an optional sign character, so you can write: io_lib:fread("~-0x~16u", "-0xFFFF") -> {ok,[-1,65535],[]} io_lib:fread("~-0x~16u", "+0xFFFF") -> {ok,[1,65535],[]} io_lib:fread("~-0x~16u", "0xFFFF") -> {ok,[1,65535],[]} Therefore ~- and ~u does not skip leading whitespace. / Raimo Niskanen, Erlang/OTP Robert Virding wrote: > Why is everyone so completely gaga about adding new bifs to do relatively > trivial things? Especially seeing you can already to do it without adding > new stuff. Use erl_scan:string and io_lib:fwrite. I have sent a modified > io_lib to erlang_questions a couple of times but it hasn't seemed to make > it into the distribution. If Bj?rn sends the sgml manpage I can add it. > > My io_lib contained a ~# to write signed based integers and ~b and ~x for > binary and hex bitfields. You usually need these diferent styles of writing > a number. > > If someone wants my io_lib I will post it again. > > Robert > > ----- Original Message ----- > From: "Raimo Niskanen" > To: > Sent: Tuesday, April 01, 2003 2:35 PM > Subject: Re: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang > > > >>Alright then, I will add integer_to_list(Integer, Base) and >>list_to_integer(List, Base) to the module 'erlang', and to the >>documentation for R9C. We will see if they become real BIFs to R9C. >> >>integer(Base), 2 =< Base, Base =< 36. >> >>integer_to_list/2 allows leading '-' or '+' but no prefix. Both >>uppercase or lowercase digits. No internal '_' since integer_to_list/1 >>does not allow it, and neither do the compiler. (yet :-) >> >>list_to_integer/2 produces uppercase digits and a leading '-' for >>negative numbers. >> >>/ Raimo Niskanen, Erlang/OTP >> >> >> >>integer_to_list(I, Base) >> when integer(I), integer(Base), Base >= 2, Base =< 1+$Z-$A+10 -> >> if I < 0 -> >> [$-|integer_to_list(-I, Base, [])]; >> true -> >> integer_to_list(I, Base, []) >> end; >>integer_to_list(I, Base) -> >> erlang:fault(badarg, [I, Base]). >> >>integer_to_list(I0, Base, R0) -> >> D = I0 rem Base, >> I1 = I0 div Base, >> R1 = if D >= 10 -> >>[D-10+$A|R0]; >> true -> >>[D+$0|R0] >>end, >> if I1 == 0 -> >> R1; >> true -> >> integer_to_list(I1, Base, R1) >> end. >> >> >> >>list_to_integer(L, Base) >> when list(L), integer(Base), Base >= 2, Base =< 1+$Z-$A+10 -> >> case list_to_integer_sign(L, Base) of >>I when integer(I) -> >> I; >>Fault -> >> erlang:fault(Fault, [L,Base]) >> end; >>list_to_integer(L, Base) -> >> erlang:fault(badarg, [L,Base]). >> >>list_to_integer_sign([$-|[_|_]=L], Base) -> >> case list_to_integer(L, Base, 0) of >>I when integer(I) -> >> -I; >>I -> >> I >> end; >>list_to_integer_sign([$+|[_|_]=L], Base) -> >> list_to_integer(L, Base, 0); >>list_to_integer_sign([_|_]=L, Base) -> >> list_to_integer(L, Base, 0); >>list_to_integer_sign(_, _) -> >> badarg. >> >>list_to_integer([D|L], Base, I) >> when integer(D), D >= $0, D =< $9, D < Base+$0 -> >> list_to_integer(L, Base, I*Base + D-$0); >>list_to_integer([D|L], Base, I) >> when integer(D), D >= $A, D < Base+$A-10 -> >> list_to_integer(L, Base, I*Base + D-$A+10); >>list_to_integer([D|L], Base, I) >> when integer(D), D >= $a, D < Base+$a-10 -> >> list_to_integer(L, Base, I*Base + D-$a+10); >>list_to_integer([], _, I) -> >> I; >>list_to_integer(_, _, _) -> >> badarg. >> >> >> >>Tony Rogvall wrote: >> >>>Raimo Niskanen wrote: >>> >>> >>>>Some comments and some problems. Since Erlang supports the >>>>Base#Integer syntax i think that Base in: >>>> integer_to_list(Integer, Base) >>>>should be 2..16, not atoms. >>>> >>> >>>I just thought it would look nice, but I can buy 2..16 (btw do you know >>>any one using base 13 for output? and since we only alow 2..16 its kind >>>of crippled anyway) >>> >>> >>> >>>>The same for: >>>> list_to_integer(List, Base) >>>> >>> >>>Oh well. >>> >>> >>>>But what should happen if you call list_to_integer("16#1f", 8), and >>>>how should you specify any base. I guess the answers are: badarg on >>>>the first and list_to_integer("16#1f", undefined) on the second >>> > question. > >>>Like you said, do NOT allow base syntax in the list_to_integer/2 (why >>>should you?) but maybe in list_to_integer/1 (if that does not break >>>anything, it could!) >>> >>> >>>>And to add the prefix in the Right(tm) way is a bit awkward: >>>> List = case integer_to_list(Integer, 16) of >>>> [$-|L] -> "-16#"++L; >>>> L -> "16#"++L >>>> end >>> >>> >>>My oppinon is that we ignore the prefix stuff completly just to get >>>things on it's way. I myself have never sent any output in base syntax >>>(anyone?). >>> >>>/Tony >> >> > From ingela@REDACTED Wed Apr 9 14:38:00 2003 From: ingela@REDACTED (Ingela Anderton) Date: Wed, 9 Apr 2003 14:38:00 +0200 Subject: OTP development, was Re: Gaga about bifs References: Message-ID: <16020.5160.96907.476888@gargle.gargle.HOWL> James Hague wrote: > This brings up an entirely different issue. The OTP team is doing a good > job with bug fixes and general maintenance, but general improvements, > significant and otherwise, seem to have ground to a halt, or at least be in > a state of confusion. This has come up several times now. It may just be > that Erlang is good enough for the places it is used, but it would be nice > to see some more active development. A number of improvements have come up > and never seem to go anywhere. We do a whole lot of new development, but the Erlang/OTP team is a quite small team and we have to priorities. Our development is entirely financed by license fees. So what our paying customers consider most important is generally what we consider most important. New language features are seldom on the top of their list. Erlang/OTP is a commercial product, that happens too also be open source. The requirements on commercial product are high. We always need to think about backward compatibility and robustness. We can never just add contributions without somebody checking what they do and making sure that they get tested. (Adding things also means work maintaining them.) Some of the ideas that emerge on the list are good ideas others are not. The ideas that we think are good we try to fit into our development plan if possible. For example Raimo is now putting some new notation in to io_lib as he was doing other development in io_lib anyway. But some things may have a very big impact and are not things that you just do. We have to make sure that if we do something, like for instance introducing some kind of new "struct", that it is properly thought through, so we do not get stuck with some new hack that we can not get rid off. Also suggested improvements may impact not only the language or the specific module where the change was suggested but also tools and other applications. Also we have to devote some of our time to support, the paying customers generate quite a substantial amount of support work. So I assure you we are constantly making improvements, however time, number of team members and money will always limit what is plausible to accomplish. /Ingela - OTP project manager P.S Considering you usually get what you pay for and open source customers do not pay anything I think they have a fairly good deal ;) From etxuwig@REDACTED Wed Apr 9 15:09:57 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Wed, 9 Apr 2003 15:09:57 +0200 (MEST) Subject: OTP development, was Re: Gaga about bifs In-Reply-To: <16020.5160.96907.476888@gargle.gargle.HOWL> Message-ID: On Wed, 9 Apr 2003, Ingela Anderton wrote: >P.S Considering you usually get what you pay for and open >source customers do not pay anything I think they have a >fairly good deal ;) I don't want to nit-pick too much, but I would argue that many of the people on this list put significant time and effort into finding ways to improve OTP, and sometimes even handing you components *for free* that can be added to OTP with a fairly small effort on your part. So your argument may just as well be reversed. ;) I think much of this boils down to the issue of providing feedback about what is actually going on, which ideas are rejected because they're not good enough (and why!), which ideas are basically accepted, but not implemented due to time and resource constraints (and then how others may help) /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From ingela@REDACTED Wed Apr 9 16:09:30 2003 From: ingela@REDACTED (Ingela Anderton) Date: Wed, 9 Apr 2003 16:09:30 +0200 Subject: OTP development, was Re: Gaga about bifs References: <16020.5160.96907.476888@gargle.gargle.HOWL> Message-ID: <16020.10650.940995.314784@gargle.gargle.HOWL> Ulf Wiger wrote: > On Wed, 9 Apr 2003, Ingela Anderton wrote: > > >P.S Considering you usually get what you pay for and open > >source customers do not pay anything I think they have a > >fairly good deal ;) > > I don't want to nit-pick too much, but I would argue that > many of the people on this list put significant time and > effort into finding ways to improve OTP, and sometimes even > handing you components *for free* that can be added to OTP > with a fairly small effort on your part. > > So your argument may just as well be reversed. ;) We do absolutely appreciate all the time and effort people take to try and improve Erlang/OTP. I am not saying that open source users are unimportant. We think they are important. Part of the open source idea of course is that instead off giving us money for our product we get feedback, code contributions and new ideas, and hence it is a good deal for both us and the open source users. But that does not change the fact that the commercial version is what keeps this project alive. > I think much of this boils down to the issue of providing > feedback about what is actually going on, which ideas are > rejected because they're not good enough (and why!), which > ideas are basically accepted, but not implemented due to > time and resource constraints (and then how others may help) Alas this also takes a lot of time. I do not think that we have found a good solution to handle this yet. It seems to be evident that the open source community would like to have more feedback. It is also quite evident too me, that all suggested solutions so far adds too much overhead for us, at least for our current situation. -- /Ingela - OTP project manager From matthias@REDACTED Wed Apr 9 16:43:29 2003 From: matthias@REDACTED (Matthias Lang) Date: Wed, 9 Apr 2003 16:43:29 +0200 Subject: OTP development, was Re: Gaga about bifs Message-ID: <16020.12689.474007.450992@antilipe.corelatus.se> James Hague wrote: > 1. integer_to_list and list_to_integer are already bifs. It's cleaner to > have arity two versions with the same names than it is to have completely > different functions in different modules. Could just as well argue that making integer_to_list a BIF was a mistake and that adding even more BIFs makes the mess even bigger. > general improvements, significant and otherwise, seem to have > ground to a halt, or at least be in a state of confusion. R9B included native compilation. That's significant by any definition. It has been more than three years since Erlang went open source and the OTP group's efforts are still outclassing everyone else. Quietly. It'd really make my day if someone I've never heard of before turned up on the mailing list and said "I've implemented an SS7 stack using the bit syntax, it's available at ftp.wherever.net". I realise that's unlikely, so I'll settle for falling off my chair the day someone _starts_ a discussion about altering the language (replacing records, adding a type checker, reorganising all the libraries) by providing a prototype implementation of their latest and greatest idea*. Matthias * This does sometimes happen, e.g. Richard Carlsson's hierarchical modules. From Sean.Hinde@REDACTED Wed Apr 9 17:35:18 2003 From: Sean.Hinde@REDACTED (Sean Hinde) Date: Wed, 9 Apr 2003 16:35:18 +0100 Subject: type safety (was Re: FAQ terminology harmonisation) Message-ID: Hi, > > > The problem is usually with pattern matching coupling too closely > > > (you change the implementation in one module and suddenly have to > > > adapt patterns all over your code base). > > > > Just out of interest what problem domain are you using > Erlang for? > > I'm not using Erlang much, certainly not for anything useful (yet;), > but I've been working with several functional languages (including > Lisp, KiR, Clean, ML, Haskell, and Erlang), and for the last years, > Haskell has been my main development language. I've encountered the > problem I described in all languages that support pattern matching, > even within subsystems, so I'm slightly surprised by your statement > (what happens to your receive statements when you've got to extend > one of your tagged tuples?). My point was really to challenge your bold assertion that these patterns would get "everywhere across the code base". In a telecoms type system there would typically be nicely designed small interfaces between major subsystems - thus allowing the internal representations to be managed independently. I don't think any sane person would argue that better tools for checking different aspects of program correctness are a bad thing, but it seems obvious that different domains rely on different tools in different proportions (as you acknowledge). Some other fairly random (but related) observations from my Erlang use: * queue is a pain to use I agree! * Sometimes (!) my brain is not big enough to understand a problem completely enough to write the whole system fully type correct without first trying to run something and watch what it does. You might argue that I should start small and grow, but I like the ability to sketch in new bits of functionality which I know will crash if that condition appears but I just want to watch it happen. * Programs must be tested thoroughly in order to be sure they do the correct thing. This as true of a Haskell program as it is of an Erlang program. The end result of this is that the vast majority of Erlang type errors are found before going live, and that the Erlang paradigm of "let it crash" and the very high quality crash reports means that problems found during test are easily fixed. The result seems to be pretty much good enough in the normal Erlang problem domain. > > The reason why I still use Haskell instead of Erlang is that (a) > my applications focus more on computation than on communication, > and (b) due to my work in language design, I like to prototype > domain-specific languages by embedding them into a general purpose > host language. In both of these areas, Haskell simply offers more > expressiveness and more concise specifications, and Concurrent > Haskell goes a long way when concurrency is needed. So while I > think Haskell is incomplete in several respects, and Erlang covers > some of those areas better, Erlang has its own blind spots and > Haskell is overall a better match for my problems. > > Current problem domains include a domain-specific embedded language > for dynamic 3d scenes and a refactoring tool for Haskell (as > mentioned before, we'd love to find someone to extend the latter > project to cover Erlang as well;-). In both domains, there are lots > of non-trivial data types (e.g., some mimicking the grammars of the > DSEL or of Haskell) with lots of constructors. > > If those can be seen in modules all over the project, it is tempting > to use the powers of pattern matching. But then you've got yourself > a task whenever the types change (which is admittedly more likely in > the kind of research & prototyping environment I'm working in). > That's not difficult to get right (in fact, this is one of the areas > where the type system will tell you precisely where type providers > and type clients disagree over their common interface), but it is > annoying and tiresome (by the end of our functional refactoring > project, that task may be automated:), so when large numbers of > modules are involved, types have a tendency to get frozen. Hence we agree :) Sean NOTICE AND DISCLAIMER: This email (including attachments) is confidential. If you have received this email in error please notify the sender immediately and delete this email from your system without copying or disseminating it or placing any reliance upon its contents. We cannot accept liability for any breaches of confidence arising through use of email. Any opinions expressed in this email (including attachments) are those of the author and do not necessarily reflect our opinions. We will not accept responsibility for any commitments made by our employees outside the scope of our business. We do not warrant the accuracy or completeness of such information. From nick@REDACTED Wed Apr 9 17:43:38 2003 From: nick@REDACTED (Niclas Eklund) Date: Wed, 9 Apr 2003 17:43:38 +0200 (MEST) Subject: OTP development, was Re: Gaga about bifs In-Reply-To: <16020.12689.474007.450992@antilipe.corelatus.se> Message-ID: Hello! > > general improvements, significant and otherwise, seem to have > > ground to a halt, or at least be in a state of confusion. I'd like to add that some new features/improvements may not be visible to all users since they simply don't use "every" application. Still, these changes can be very important for both licensed & open source users. Some improvements are a bit harder to discover (e.g. performance boost, less memory usage etc), unless one read the release notes carefully. It's easier to notice new applications, but they're probably not equally important to all users. For example, since R7B we've introduced: * et * observer * megaco * webtool * CORBA applications (cosEventDomain, cosFileTransfer, cosNotification, cosProperty and cosTime). .. and there are more to come. /Niclas > R9B included native compilation. That's significant by any definition. > > It has been more than three years since Erlang went open source and > the OTP group's efforts are still outclassing everyone else. Quietly. > > It'd really make my day if someone I've never heard of before turned > up on the mailing list and said "I've implemented an SS7 stack using > the bit syntax, it's available at ftp.wherever.net". I realise that's > unlikely, so I'll settle for falling off my chair the day someone > _starts_ a discussion about altering the language (replacing records, > adding a type checker, reorganising all the libraries) by providing a > prototype implementation of their latest and greatest idea*. > > Matthias > > * This does sometimes happen, e.g. Richard Carlsson's hierarchical modules. From luke@REDACTED Wed Apr 9 17:48:33 2003 From: luke@REDACTED (Luke Gorrie) Date: 09 Apr 2003 17:48:33 +0200 Subject: OTP development, was Re: Gaga about bifs In-Reply-To: <16020.10650.940995.314784@gargle.gargle.HOWL> References: <16020.5160.96907.476888@gargle.gargle.HOWL> <16020.10650.940995.314784@gargle.gargle.HOWL> Message-ID: Ingela Anderton writes: > > I think much of this boils down to the issue of providing > > feedback about what is actually going on, which ideas are > > rejected because they're not good enough (and why!), which > > ideas are basically accepted, but not implemented due to > > time and resource constraints (and then how others may help) > > Alas this also takes a lot of time. I do not think that we have > found a good solution to handle this yet. It seems to be evident that > the open source community would like to have more feedback. It is also > quite evident too me, that all suggested solutions so far adds too much > overhead for us, at least for our current situation. Maybe you just need to hire someone with an "internet loudmouth" personality :-) -Luke From cpressey@REDACTED Wed Apr 9 21:46:48 2003 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 09 Apr 2003 14:46:48 -0500 Subject: ErlGuten question Message-ID: <20030409144648.06286ca2.cpressey@catseye.mb.ca> Does anyone know of a way to right-align text with ErlGuten? There doesn't seem to be an option for it in the galley files. Also, there isn't anything like pdf:get_text_width(PDF, String), which is what I'd use if I were trying it on a lower (non-XML) level - I tried adding it but it looks like erlguten_font_server doesn't know anything about the metrics of built-in fonts (but logically this can't be the case, I must be doing something wrong with the font index.) -Chris From ulf.wiger@REDACTED Wed Apr 9 22:07:04 2003 From: ulf.wiger@REDACTED (Wiger Ulf) Date: Wed, 9 Apr 2003 22:07:04 +0200 Subject: OTP development, was Re: Gaga about bifs References: <16020.5160.96907.476888@gargle.gargle.HOWL> <16020.10650.940995.314784@gargle.gargle.HOWL> Message-ID: <001f01c2fed3$972da220$fd7a40d5@telia.com> From: "Ingela Anderton" > > I think much of this boils down to the issue of providing > > feedback about what is actually going on, which ideas are > > rejected because they're not good enough (and why!), which > > ideas are basically accepted, but not implemented due to > > time and resource constraints (and then how others may help) > > Alas this also takes a lot of time. I do not think that we have > found a good solution to handle this yet. It seems to be evident that > the open source community would like to have more feedback. It is also > quite evident too me, that all suggested solutions so far adds too much > overhead for us, at least for our current situation. I have no good solution, alas. I realise that part of the "problem" is that you have to maintain a secure way of handling confidential information about your paying customers. This is impossible at e.g. SourceForge, which is otherwise a very nice environment for an Open Source project. Also, the fact that we, your paying customers, have rather extreme requirements on stability and backward compatibility, means that you have to have very tight control of what changes go into a certain release. I think you need to have a ticket tracker that's capable of separating open and confidential stuff, and simply generate listings of tickets, open and closed. Ideally, paying customers could view their own tickets as well as the public ones. Are you using the Bluetail Ticket Tracker or some other Open Source tool? If so, it would be possible for others to assist in developing this functionality. I'm not aware of that many mission-critical middleware products that are available as Open Source (at least not products that are more open and "interactive" than OTP), so there are few references on how to do this properly. /Uffe From mikael.karlsson@REDACTED Wed Apr 9 22:38:19 2003 From: mikael.karlsson@REDACTED (Mikael Karlsson) Date: Wed, 9 Apr 2003 22:38:19 +0200 Subject: ErlGuten question In-Reply-To: <20030409144648.06286ca2.cpressey@catseye.mb.ca> References: <20030409144648.06286ca2.cpressey@catseye.mb.ca> Message-ID: <200304092238.19142.mikael.karlsson@creado.com> Hi Chris, for the low level; I think this works for erlguten 2.1. /Mikael get_string_width(PID, Fontname, PointSize, Str)-> FontIndex = pdf:get_font_alias(PID, Fontname), trunc(erlguten_line_break:sizeof(FontIndex, Str) * PointSize/1000). %% Example, usage for right alignment --- pageno(PDF)-> pdf:begin_text(PDF), pdf:set_font(PDF,"Times-Roman", 11), A = pdf:get_page_no(PDF), Str = "Page " ++ pdf:n2s(A), Width = pdf:get_string_width(PDF,"Times-Roman", 11, Str), %% io:fwrite("Width is :~p~n", [Width]), case A rem 2 of 0 -> pdf:set_text_pos(PDF, 100, 50); 1 -> pdf:set_text_pos(PDF, 510 - Width, 50) end, pdf:text(PDF, Str), pdf:end_text(PDF). --- onsdag 09 april 2003 21:46 skrev Chris Pressey: > Does anyone know of a way to right-align text with ErlGuten? > > There doesn't seem to be an option for it in the galley files. > > Also, there isn't anything like pdf:get_text_width(PDF, String), which > is what I'd use if I were trying it on a lower (non-XML) level - I tried > adding it but it looks like erlguten_font_server doesn't know anything > about the metrics of built-in fonts (but logically this can't be the > case, I must be doing something wrong with the font index.) > > -Chris From cpressey@REDACTED Wed Apr 9 23:55:25 2003 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 09 Apr 2003 16:55:25 -0500 Subject: ErlGuten question In-Reply-To: <200304092238.19142.mikael.karlsson@creado.com> References: <20030409144648.06286ca2.cpressey@catseye.mb.ca> <200304092238.19142.mikael.karlsson@creado.com> Message-ID: <20030409165525.75a28a77.cpressey@catseye.mb.ca> On Wed, 9 Apr 2003 22:38:19 +0200 Mikael Karlsson wrote: > Hi Chris, > for the low level; > I think this works for erlguten 2.1. > > /Mikael > > get_string_width(PID, Fontname, PointSize, Str)-> > FontIndex = pdf:get_font_alias(PID, Fontname), > trunc(erlguten_line_break:sizeof(FontIndex, Str) * > PointSize/1000). Thanks, that does the trick! There's a little weirdness though. Nothing I can't work around, but I'm curious... I start erl with the equivalent of -pa ~/projects/*/ebin , to add all my local packages to the search path. So I made a subdirectory, erlguten-2.1/ebin , and moved all of its .beam files into it. This seems to work fine for almost everything, except one thing: pdf:get_font_alias/2 hangs. It just never returns. pdf:get_font_alias/2 only works if I don't move the .beam files, and run erl with -pa ~/projects/erlguten-2.1 Any idea why this might be? -Chris From cpressey@REDACTED Thu Apr 10 01:01:33 2003 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 09 Apr 2003 18:01:33 -0500 Subject: ErlGuten question In-Reply-To: <20030409165525.75a28a77.cpressey@catseye.mb.ca> References: <20030409144648.06286ca2.cpressey@catseye.mb.ca> <200304092238.19142.mikael.karlsson@creado.com> <20030409165525.75a28a77.cpressey@catseye.mb.ca> Message-ID: <20030409180133.5721b4a8.cpressey@catseye.mb.ca> On Wed, 09 Apr 2003 16:55:25 -0500 Chris Pressey wrote: > pdf:get_font_alias/2 only works if I don't move the .beam files, and run > erl with -pa ~/projects/erlguten-2.1 > > Any idea why this might be? Ah, I think I see now - the fonts directory has to be in the path... Sorry for the confusion. -Chris From hp@REDACTED Thu Apr 10 05:46:51 2003 From: hp@REDACTED (HP Wei) Date: Wed, 9 Apr 2003 23:46:51 -0400 (EDT) Subject: What is the idiomatic way of doing... In-Reply-To: <000d01c2fe66$90cbf480$fd7a40d5@telia.com> Message-ID: Hi Three newbie questions: Suppose I have a file: % test.txt content {"label1", "v1"}. {"label2", "v2"}. In erl, file:consult(test.txt) will give me a list of tuples [{"label1","v1"},{"label2","v2"}]. Suppose test.txt is very big and it is better to extract one tuple at a time to do something. (1) what is the erlang-way of doing this ??? --------------------------------------- Suppose I have this file: % test1.txt content label1 v1 label2 v2 (2) Is there an idiomatic way of getting the list of tuples as in the previous case ?? (3) What about getting one tuple at a time ??? THanks, HP From ulf.wiger@REDACTED Thu Apr 10 09:14:57 2003 From: ulf.wiger@REDACTED (Wiger Ulf) Date: Thu, 10 Apr 2003 09:14:57 +0200 Subject: What is the idiomatic way of doing... References: Message-ID: <001501c2ff30$e4678da0$fd7a40d5@telia.com> From: "HP Wei" > --------------------------------------- > Suppose I have this file: > % test1.txt content > label1 v1 > label2 v2 > > (2) Is there an idiomatic way of getting the list of tuples as in the > previous case ?? > > (3) What about getting one tuple at a time ??? Here's a suggestion for the non-erlang syntax file: -module(readf). -export([file1/1, file2/1]). %% read the whole file at once file1(F) -> {ok, Binary} = file:read_file(F), Lines = string:tokens(binary_to_list(Binary), "\r\n"), [list_to_tuple(string:tokens(L," \t")) || L <- Lines, length(L) > 0]. %% read one line at a time file2(F) -> {ok, Fd} = file:open(F, [read]), read_terms(Fd). read_terms(Fd) -> read_terms(Fd, io:get_line(Fd, ""), []). read_terms(Fd, eof, Acc) -> lists:reverse(Acc); read_terms(Fd, L, Acc) -> [list_to_tuple(string:tokens(L," \t\n")) | read_terms(Fd, io:get_line(Fd,""), [])]. For the file with erlang tuples, you should perhaps study the implementation of file:consult/1 (you will find it in the 'kernel' application). It actually does take one tuple at a time. The solution is similar to my read_terms/3 above, but it uses io:read/2 instead of io:get_line/2. /Uffe From etxuwig@REDACTED Thu Apr 10 10:31:30 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Thu, 10 Apr 2003 10:31:30 +0200 (MEST) Subject: OTP development, was Re: Gaga about bifs In-Reply-To: Message-ID: On 9 Apr 2003, Luke Gorrie wrote: >Maybe you just need to hire someone with an "internet >loudmouth" personality :-) > >-Luke Why, are you looking for a new job, Luke? ;-) /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From eleberg@REDACTED Thu Apr 10 10:50:10 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Thu, 10 Apr 2003 10:50:10 +0200 (MEST) Subject: OTP development, was Re: Gaga about bifs Message-ID: <200304100850.h3A8oAi02651@cbe.ericsson.se> > X-Authentication-Warning: cbe1066.al.sw.ericsson.se: etxuwig owned process doing -bs > Date: Thu, 10 Apr 2003 10:31:30 +0200 (MEST) > From: Ulf Wiger > X-X-Sender: etxuwig@REDACTED > To: Luke Gorrie > cc: erlang-questions@REDACTED > Subject: Re: OTP development, was Re: Gaga about bifs > MIME-Version: 1.0 > > > On 9 Apr 2003, Luke Gorrie wrote: > > >Maybe you just need to hire someone with an "internet > >loudmouth" personality :-) > > > >-Luke > > > Why, are you looking for a new job, Luke? ;-) and, if so, does bluetail/alteon/nortel need a replacement? bengt From samuel@REDACTED Thu Apr 10 11:04:51 2003 From: samuel@REDACTED (Samuel Rivas) Date: Thu, 10 Apr 2003 11:04:51 +0200 Subject: Problems with mnemosyne Message-ID: <20030410090451.GA17770@crusher.lfcia.pri> Hi, I have a problem with mnemosyne and table indices. I want to do some unions with different mnesia tables and I write a mnemosyne query to do it, but I get the error {aborted,{bad_type,2,'_'}}. Changing some body expressions I also get the error {aborted,{bad_type,2,'$1'}}, so I suppose that mnesia could not understand the compiled query. However if I delete all extra indices, the query works fine. 1> get_shown_movies("en", "samu_stpbx", "Samuel", adventure). {ok,[{{movie,'4',"foo4.avi",adventure,1987,false}, {movie_info,'4',"en","A synopsys ...","The princess bride"}}]} If I crete the index again: 2> mnesia:add_table_index(shown_movie, name). {atomic,ok} 3> get_shown_movies("gl", "samu_stpbx", "Samuel", adventure). {aborted,{database_error,{bad_type,2,'_'}}} My fault?, mnemosyne fault? Thanks -- --------------------- | Samuel | --------------------- From svg@REDACTED Thu Apr 10 12:11:00 2003 From: svg@REDACTED (Vladimir Sekissov) Date: Thu, 10 Apr 2003 16:11:00 +0600 (YEKST) Subject: What is the idiomatic way of doing... In-Reply-To: References: <000d01c2fe66$90cbf480$fd7a40d5@telia.com> Message-ID: <20030410.161100.41629581.svg@surnet.ru> Good day, hp> Suppose test.txt is very big and it is better to extract one tuple at a hp> time to do something. hp> (1) what is the erlang-way of doing this ??? 26> {ok, IO} = file:open("tmp.txt", [read]). {ok,<0.90.0>} 27> io:read(IO, ""). {ok,{"label1","v1"}} 28> io:read(IO, ""). {ok,{"label2","v2"}} 29> io:read(IO, ""). eof 30> file:close(IO). ok hp> Suppose I have this file: hp> % test1.txt content hp> label1 v1 hp> label2 v2 hp> hp> (2) Is there an idiomatic way of getting the list of tuples as in the hp> previous case ?? 39> {ok, IO} = file:open("/home/svg/tmp.txt", [read]). {ok,<0.109.0>} 40> list_to_tuple(string:tokens(io:get_line(IO, ""), " \t\n")). {"label1","v1"} ... Best Regards, Vladimir Sekissov hp> Three newbie questions: hp> hp> Suppose I have a file: hp> % test.txt content hp> {"label1", "v1"}. hp> {"label2", "v2"}. hp> hp> In erl, file:consult(test.txt) will give me a list of hp> tuples [{"label1","v1"},{"label2","v2"}]. hp> hp> Suppose test.txt is very big and it is better to extract one tuple at a hp> time to do something. hp> (1) what is the erlang-way of doing this ??? hp> hp> --------------------------------------- hp> Suppose I have this file: hp> % test1.txt content hp> label1 v1 hp> label2 v2 hp> hp> (2) Is there an idiomatic way of getting the list of tuples as in the hp> previous case ?? hp> hp> (3) What about getting one tuple at a time ??? hp> hp> THanks, hp> HP hp> From luke@REDACTED Thu Apr 10 15:30:03 2003 From: luke@REDACTED (Luke Gorrie) Date: 10 Apr 2003 15:30:03 +0200 Subject: OTP development, was Re: Gaga about bifs In-Reply-To: <200304100850.h3A8oAi02651@cbe.ericsson.se> References: <200304100850.h3A8oAi02651@cbe.ericsson.se> Message-ID: Bengt Kleberg writes: > > On 9 Apr 2003, Luke Gorrie wrote: > > > > >Maybe you just need to hire someone with an "internet > > >loudmouth" personality :-) > > > > Why, are you looking for a new job, Luke? ;-) No, but we loud-mouthes gotta look out for each other :-) > and, if so, does bluetail/alteon/nortel need a replacement? I certainly hope not -- but this is a different question ;-) Cheers, Luke From robert.virding@REDACTED Thu Apr 10 16:36:09 2003 From: robert.virding@REDACTED (Robert Virding) Date: Thu, 10 Apr 2003 16:36:09 +0200 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang.) References: <20030327011316.12f6a496.cpressey@catseye.mb.ca>, <010901c2f454$87a67ae0$239ab280@lamppc27>, Message-ID: <01cc01c2ff6e$8779d830$8500000a@Clarke> I will reply to this mail instead of Raimo's reply to my reply. ----- Original Message ----- From: "Raimo Niskanen" To: Sent: Wednesday, April 02, 2003 10:00 AM Subject: Re: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang.) > The Erlang style Base#Integer notation is such an odd freak that it also > should not have a letter of its own. I will use b/B for signed > unprefixed instead so you won't have to use x/X with empty prefix. It may be odd and slightly freakish but it is part of the language so it should be supported if we are going to output based integers. After all we are adding some thing to the *ERLANG* libraries! That is why there should be a ~#! > This gives the general x/X: > io_lib:format("~.16x", [-31,"0x"]) -> "-0x1f" > io_lib:format("~.16X", [-31,"0x"]) -> "-0x1F" > b/B is just x/X with empty prefix: > io_lib:format("~.16b", [-31]) -> "-1f" > io_lib:format("~.16B", [-31]) -> "-1F" No I defintely don't like it! Two major objections: 1. You are adding a completely new concept with an option to have an included string in the middle of an output, this is not consistent with anything. I am strongly for consistency and simplicity. Otherwise why not go for the complete set of Common Lisp options and we can scrap half of the libraries in one fell swoop. 2. If you are using x/X for hex then b/B definitely suggests _B_inary! 3. I don't really understand why we need to directly support other language formats. This just a grumble! Also if u/U and b/B mean hex why the .16? Or do you mean that they mean bit output and you give the base in the precision? So can you write "~.8b" to get octal? Otherwise it is completely redundant and very confusing. > and u/U is the same as b/B with the argument integer 'band'ed with > ((1< io_lib:format("~.16U", [31,32]) -> "1F" > io_lib:format("~.16u", [-31,32]) -> "ffffffe1" > io_lib:format("~8.16.0u", [31,32]) -> "0000001f" > io_lib:format("~8.16.0U", [-31,32]) -> "FFFFFFE1" Some objections here: 1. I assume the second argument is the "word size". Why add an extra option for something which already exists in the language? Why can't the user just write 31 band 255 and be done with. As people have rightly pointed out there is already too much junk in the libraries without adding more unneccessary stuff! 2. You are using the field width inconsistently! It does not mean the width of the outputed data but the total width of allowed field to output the data. If there is not enough data to fill the field padding is inserted. Using the precision is consistent with intent. Like I did! :-) 3. (Sarcastically) If I do io:format("~8.16u", [31,"0x"]) will that insert "0x" somewhare in the output? > Objections, anyone? Yes, defintely lots of objections! Too many inconsistencies and wrong usage of existing features to be allowed in! Cover the language needs first and let the users handle special cases. Adding this would be Big Lose! I know the io:format options aren't the best but at least they are consistent. You mentioned somewhere else a ~- option, this could be useful for io:fwrite. The io:fread option would be useful but I think the option shouldn't use a generic u. Robert From kostis@REDACTED Thu Apr 10 19:19:56 2003 From: kostis@REDACTED (Kostis Sagonas) Date: Thu, 10 Apr 2003 19:19:56 +0200 (MEST) Subject: OTP development, was Re: Gaga about bifs In-Reply-To: Mail from 'Matthias Lang ' dated: Wed, 9 Apr 2003 16:43:29 +0200 Message-ID: <200304101719.h3AHJuoI019747@harpo.it.uu.se> Matthias Lang wrote: > > James Hague wrote: > > general improvements, significant and otherwise, seem to have > > ground to a halt, or at least be in a state of confusion. > > R9B included native compilation. That's significant by any definition. > > It has been more than three years since Erlang went open source and > the OTP group's efforts are still outclassing everyone else. Quietly. I do not want to argue with the above, but just for the record I guess, I would like to point out that perhaps some other group is mostly responsible for bringing native compilation to Erlang/OTP. We, the HiPE group, of course very much appreciate the support and enjoy the very close collaboration that we have with the OTP group these days. Kostis Sagonas The HiPE group (http://www.csd.uu.se/projects/hipe/) From dgud@REDACTED Fri Apr 11 10:07:58 2003 From: dgud@REDACTED (Dan Gudmundsson) Date: Fri, 11 Apr 2003 10:07:58 +0200 Subject: Problems with mnemosyne In-Reply-To: <20030410090451.GA17770@crusher.lfcia.pri> References: <20030410090451.GA17770@crusher.lfcia.pri> Message-ID: <16022.30686.689386.444338@rian.du.uab.ericsson.se> Can you post the record definitions and the mnemosyne query. /Dan Samuel Rivas writes: > Hi, > > I have a problem with mnemosyne and table indices. I want to do some > unions with different mnesia tables and I write a mnemosyne query to > do it, but I get the error {aborted,{bad_type,2,'_'}}. > Changing some body expressions I also get the error > {aborted,{bad_type,2,'$1'}}, so I suppose that mnesia could not > understand the compiled query. > However if I delete all extra indices, the query works fine. > > 1> get_shown_movies("en", "samu_stpbx", "Samuel", adventure). > {ok,[{{movie,'4',"foo4.avi",adventure,1987,false}, > {movie_info,'4',"en","A synopsys ...","The princess bride"}}]} > > If I crete the index again: > > 2> mnesia:add_table_index(shown_movie, name). > {atomic,ok} > 3> get_shown_movies("gl", "samu_stpbx", "Samuel", adventure). > {aborted,{database_error,{bad_type,2,'_'}}} > > My fault?, mnemosyne fault? > > Thanks > > -- > --------------------- > | Samuel | > --------------------- From raimo.niskanen@REDACTED Fri Apr 11 10:26:11 2003 From: raimo.niskanen@REDACTED (Raimo Niskanen) Date: Fri, 11 Apr 2003 10:26:11 +0200 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang.) References: , , <01cc01c2ff6e$8779d830$8500000a@Clarke> Message-ID: Finally, some feedback!. Too bad it was mostly negative. Discussion inserted below. / Raimo Robert Virding wrote: > I will reply to this mail instead of Raimo's reply to my reply. > > ----- Original Message ----- > From: "Raimo Niskanen" > To: > Sent: Wednesday, April 02, 2003 10:00 AM > Subject: Re: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang.) > > > >>The Erlang style Base#Integer notation is such an odd freak that it also >>should not have a letter of its own. I will use b/B for signed >>unprefixed instead so you won't have to use x/X with empty prefix. > > > It may be odd and slightly freakish but it is part of the language so it > should be supported if we are going to output based integers. After all we > are adding some thing to the *ERLANG* libraries! That is why there should be > a ~#! I thougth a lot about using ~#, but could not decide if it should output uppercase or lowercase letters, and I could not find another similar character for the other case (upper/lower). Therefore I selected x/X. > > >>This gives the general x/X: >>io_lib:format("~.16x", [-31,"0x"]) -> "-0x1f" >>io_lib:format("~.16X", [-31,"0x"]) -> "-0x1F" >>b/B is just x/X with empty prefix: >>io_lib:format("~.16b", [-31]) -> "-1f" >>io_lib:format("~.16B", [-31]) -> "-1F" > > > No I defintely don't like it! Two major objections: > 1. You are adding a completely new concept with an option to have an > included string in the middle of an output, this is not consistent with The problem is that to be able to output "-16#1f" for -31 and "16#1f for +31, something ("16#") has to be inserted between the sign and the number. > anything. I am strongly for consistency and simplicity. Otherwise why not go So am I, but only as long as it also is useful. > for the complete set of Common Lisp options and we can scrap half of the > libraries in one fell swoop. > 2. If you are using x/X for hex then b/B definitely suggests _B_inary! I am not using x/X for hex, it is for prefiXed output, and b/B is for any-Base integer (x/X is also any-base, by the way). The only one necessaryis x/X, since b/B is just x/X with empty prefix string, but I think it would be awkward to have to give an empty prefix string in the farily common cases when you do not want any prefix. > 3. I don't really understand why we need to directly support other language > formats. This just a grumble! > Well, there are lots of applications that needs to write files that are to be read by alien applications, so it should be possible, and fairly simple. > Also if u/U and b/B mean hex why the .16? Or do you mean that they mean bit > output and you give the base in the precision? So can you write "~.8b" to > get octal? Otherwise it is completely redundant and very confusing. > Yes, .16 is the base. Allowed bases are 2 throught 36, with default 10. > >>and u/U is the same as b/B with the argument integer 'band'ed with >>((1<>io_lib:format("~.16U", [31,32]) -> "1F" >>io_lib:format("~.16u", [-31,32]) -> "ffffffe1" >>io_lib:format("~8.16.0u", [31,32]) -> "0000001f" >>io_lib:format("~8.16.0U", [-31,32]) -> "FFFFFFE1" > > > Some objections here: > > 1. I assume the second argument is the "word size". Why add an extra option > for something which already exists in the language? Why can't the user just > write 31 band 255 and be done with. As people have rightly pointed out there > is already too much junk in the libraries without adding more unneccessary > stuff! Convenience! I think it might be fairly common to output an unsigned word. The suggestion from Happi had a binary bit field of this sort, but it was only base 2. > 2. You are using the field width inconsistently! It does not mean the width > of the outputed data but the total width of allowed field to output the > data. If there is not enough data to fill the field padding is inserted. > Using the precision is consistent with intent. Like I did! :-) Sorry, I am to stupid to understand your second sentence. And I have no access to your suggestion so I do not know how you did it. It was Happi's suggestion that got me started. I do not think I use the field width inconsistently. It is the only parameter I have not tampered with - I use the precision field inconsistently! The 3'rd line in the example above outputs a 32 bit wide unsigned word in base 16 in a 8 character wide field, padded with zero characters. It is a trick to get the same width for negative and positive numbers since I did not want to use yet another character for zero padding to word size, which of course is a possibility. And I am not certain I am using the precision field inconsistently, either. It already means different things for different format characters. > 3. (Sarcastically) If I do io:format("~8.16u", [31,"0x"]) will that insert > "0x" somewhare in the output? Unfortunately impossible since ~u must know if it has extra arguments in the argument list. They are mandatory. The only arguments that can be optional are field width, precision and padding character. That is why I put number base in the precision field, since there is a natural default (10). Mandatory arguments can be put in the argument list, and do not have to be numeric. That is why I put the prefix string there. > > >>Objections, anyone? > > > Yes, defintely lots of objections! Too many inconsistencies and wrong usage > of existing features to be allowed in! Cover the language needs first and > let the users handle special cases. Adding this would be Big Lose! It should be easy to handle common "special cases". > > I know the io:format options aren't the best but at least they are > consistent. > > You mentioned somewhere else a ~- option, this could be useful for > io:fwrite. The io:fread option would be useful but I think the option > shouldn't use a generic u. Why not ~u, what do you mean generic? It was supposed to be consistent with my suggestion of u/U for unsigned output. I have not suggested an option for scanning any-base integers i.e ~# could scan both "16#1f" and "8#37", is this what you are looking for? My ~16u would scan "1f", and to scan "-16#1f" you would have to know which base you are expecting and use ~-16#~u to scan it. Not quite satisfactory. ~- for fwrite, that is a thought. Then you could (if ~u now output the absolute value and did not take a wordsize argument) do: U = -31, io:fwrite("~-16#~.16u", [U,U]) -> "-16#1f". This makes it hard to make use of the field width, though. Especially for right adjusted and padded fields. How would you e.g output a "......-16#123abc" field? This also speaks for having a prefix string a s argument to the format character. Or, did you think of another use of ~-? > > Robert > > The demands I have are: 1) It must be possible to output signed Erlang style base prefixed integers "-16#1abc"in at least bases 2..16, but why not 2..36, preferably in both lowercase and uppercase. 2) It should be possible to output 2..36 base integers with other prefixes (also no prefix), even if the numbers are negative, in both lowercase and uppercase. 3) It should be fairly simple to interprete a number as a unsigned word of any width and print it like "0000".."FFFF" or also "0".."FFFF". If you can output unprefixed it is of course easy to do with the band operator and zero pad character. Fortunately, there is still some time left to R9C checkin stop, to decide on an implementation reasonable for everyone. From joe@REDACTED Fri Apr 11 11:10:13 2003 From: joe@REDACTED (Joe Armstrong) Date: Fri, 11 Apr 2003 11:10:13 +0200 (CEST) Subject: Meta-survey Message-ID: I'd like to conduct a survey of Erlang/OTP usage - Before sending out a survey with *my* questions on it I'd like to ask what *your* questions would be. I don't want to bias the discussion by saying what sort of questions I'd like there to be - so I won't (yet) say what sort of questions I think should be in the survey. That's why this is a meta survey :-) So to my questions: 1) - In a survey about OTP/Erlang a number of questions will be asked -- what are the best questions to ask in such a survey? 2) If I were to ask such questions would you reply? 3) What would be the best form to ask the questions in order to get a high response frequency? /Joe From vlad_dumitrescu@REDACTED Fri Apr 11 13:38:40 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Fri, 11 Apr 2003 13:38:40 +0200 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang.) Message-ID: Hi, just a suggestion from someone who didn't yet feel the need to print hex numbers :-) Why not let format handle only some of the simple cases, so that the use of the precision and width fields don't get too hairy, and use some separate library function for the others (like for example prefixed output)? just my 2 ?re. Regards, Vlad _________________________________________________________________ Hitta r?tt k?pare p? MSN K?p & S?lj http://www.msn.se/koposalj From hp@REDACTED Fri Apr 11 13:59:07 2003 From: hp@REDACTED (HP Wei) Date: Fri, 11 Apr 2003 07:59:07 -0400 (EDT) Subject: visibility of a function in a module Message-ID: <200304111159.h3BBx71E003869@ram.rentec.com> In this module, f(N) is a function visible in the entire module of test. % -------------------- -module(test). -export([do/0]). do() -> go(). f(N) -> Base = 10, Base + N. go() -> io:format("~w~n", [f(3)]). % --------------------------- But, I want to construct f() when do() is invoked. Now, I have the following module, in which F_() is not visible in the module. And I need to pass it to go() through the parameter passing. Is this the only alternative ? % ----------------------------- -module(test). -export([do/1]). do(Base) -> F_ = fun(N) -> Base+N end, go(F_). go(F) -> io:format("~w~n", [F(3)]). % -------------------------------------- --HP From fredrik.linder@REDACTED Fri Apr 11 14:17:06 2003 From: fredrik.linder@REDACTED (Fredrik Linder) Date: Fri, 11 Apr 2003 14:17:06 +0200 Subject: visibility of a function in a module In-Reply-To: <200304111159.h3BBx71E003869@ram.rentec.com> Message-ID: You can to it like this also: % -------------------- -module(test). -export([do/0]). do() -> go(fun f/1). f(N) -> Base = 10, Base + N. go(F) -> io:format("~w~n", [F(3)]). -----Original Message----- From: owner-erlang-questions@REDACTED [mailto:owner-erlang-questions@REDACTED]On Behalf Of HP Wei Sent: den 11 april 2003 13:59 To: erlang-questions@REDACTED Subject: visibility of a function in a module In this module, f(N) is a function visible in the entire module of test. % -------------------- -module(test). -export([do/0]). do() -> go(). f(N) -> Base = 10, Base + N. go() -> io:format("~w~n", [f(3)]). % --------------------------- But, I want to construct f() when do() is invoked. Now, I have the following module, in which F_() is not visible in the module. And I need to pass it to go() through the parameter passing. Is this the only alternative ? % ----------------------------- -module(test). -export([do/1]). do(Base) -> F_ = fun(N) -> Base+N end, go(F_). go(F) -> io:format("~w~n", [F(3)]). % -------------------------------------- --HP From joe@REDACTED Fri Apr 11 14:28:20 2003 From: joe@REDACTED (Joe Armstrong) Date: Fri, 11 Apr 2003 14:28:20 +0200 (CEST) Subject: visibility of a function in a module In-Reply-To: <200304111159.h3BBx71E003869@ram.rentec.com> Message-ID: > In this module, f(N) is a function visible in the entire module of test. > % -------------------- > -module(test). > -export([do/0]). > > do() -> > go(). > > f(N) -> > Base = 10, > Base + N. > > go() -> > io:format("~w~n", [f(3)]). > % --------------------------- > But, I want to construct f() when do() is invoked. > Now, I have the following module, in which F_() is not visible in > the module. And I need to pass it to go() through the parameter passing. > Is this the only alternative ? > % ----------------------------- > -module(test). > -export([do/1]). > > do(Base) -> > F_ = fun(N) -> Base+N end, > go(F_). > > go(F) -> > io:format("~w~n", [F(3)]). > % -------------------------------------- > Richard Carlsson made something like this (called Parameterised modules) The idea is that you'd write: -module(test(Base)). -export([do/0]). f(N) -> Base + N. do() -> io:format("~w~n", [f(3)] -------- To use this you'd do like this: M = load (test(Base)), M:do() This can be implemented by some relatively simple code transformations. However you look at it there is no way of statically binding a dynamically created fuction to a name - you have to store it in some variable F and carry it round the computation until you wish to use it and then say F(Args) There are of course many many ways of doing this ... f(Base) -> put(dingo, fun(N) -> N + Base end). do() -> io:format("~w~n", [(get(dingo))(3)]. Does the same as your code in a way that is not "recommended" (TM) by some :-) /Joe From etxuwig@REDACTED Fri Apr 11 14:45:46 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Fri, 11 Apr 2003 14:45:46 +0200 (MEST) Subject: ets:match_spec_run/2 Message-ID: I found this undocumented functionality in ets: 1> MS = ets:match_spec_compile([{{'_',2},[],['$_']}]). <<>> 2> ets:match_spec_run([{a,1},{a,2},{b,2}], MS). [{a,2},{b,2} It's used e.g. when implementing mnesia:select(). What is the status of these two functions? (I realise that you can write an erlang equivalent using for example lists:filter() that's a lot prettier, but the point (one point) of the function is obviously when you have a match spec already and need to apply it to a list.) BTW, what kind of magical empty binary is that? /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From hp@REDACTED Fri Apr 11 15:34:41 2003 From: hp@REDACTED (HP Wei) Date: Fri, 11 Apr 2003 09:34:41 -0400 (EDT) Subject: visibility of a function in a module Message-ID: <200304111334.h3BDYf1E005088@ram.rentec.com> >Richard Carlsson made something like this (called Parameterised modules) > M = load (test(Base)), > M:do() > > This can be implemented by some relatively simple code transformations. I guess this is not an 'official feature' of erlang yet. (?) And I could not find it in User Contribution. Where do I find an implementation of this Parameterised module ? --HP From richardc@REDACTED Fri Apr 11 15:43:08 2003 From: richardc@REDACTED (Richard Carlsson) Date: Fri, 11 Apr 2003 15:43:08 +0200 (MET DST) Subject: visibility of a function in a module In-Reply-To: <200304111334.h3BDYf1E005088@ram.rentec.com> References: <200304111334.h3BDYf1E005088@ram.rentec.com> Message-ID: It is not available. We made a "proof of concept" implementation, which needs more work, but this is probably going to be a future feature of Erlang. /Richard On Fri, 11 Apr 2003, HP Wei wrote: > >Richard Carlsson made something like this (called Parameterised modules) > > > M = load (test(Base)), > > M:do() > > > > This can be implemented by some relatively simple code transformations. > > I guess this is not an 'official feature' of erlang yet. (?) > And I could not find it in User Contribution. > Where do I find an implementation of this Parameterised module ? > > --HP > > > Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) E-mail: Richard.Carlsson@REDACTED WWW: http://user.it.uu.se/~richardc/ "Having users is like optimization: the wise course is to delay it." -- Paul Graham From samuel@REDACTED Fri Apr 11 16:49:14 2003 From: samuel@REDACTED (Samuel Rivas) Date: Fri, 11 Apr 2003 16:49:14 +0200 Subject: Problems with mnemosyne In-Reply-To: <16022.30686.689386.444338@rian.du.uab.ericsson.se>; from dgud@erix.ericsson.se on Fri, Apr 11, 2003 at 10:07:58AM +0200 References: <20030410090451.GA17770@crusher.lfcia.pri> <16022.30686.689386.444338@rian.du.uab.ericsson.se> Message-ID: <20030411164914.A10862@bulma.lfcia.pri> On Fri, 11 Apr 2003, 10:07 +0200, Dan Gudmundsson wrote: > > Can you post the record definitions and the > mnemosyne query. > Of course: The records: ----------- -record(movie, {id, file, genre_id, year, new = true }). -record(movie_info, {movie_id, %% References movie.id lang_id, synopsys, title }). -record(shown_movie, {set_top_box_id, name, %% User name movie_id }). Table creation functions: ------------------------ init_movie() -> {atomic, ok} = mnesia:create_table(movie, [{disc_copies, [node()]}, {attributes, record_info(fields, movie)}]). init_movie_info() -> {atomic, ok} = mnesia:create_table(movie_info, [{disc_copies, [node()]}, {type, bag}, {index, [lang_id]}, {attributes, record_info(fields, movie_info)}]). init_shown_movie() -> {atomic, ok} = mnesia:create_table(shown_movie, [{disc_copies, [node()]}, {type, bag}, {index, [name]}, {attributes, record_info(fields, shown_movie)}]). And the query: ------------- get_shown_movies(LangId, StpbxId, User, GenreId) when list(LangId), list(StpbxId), record(User, user), atom(GenreId) -> Q = query [{M, MI} || M <- table(movie), MI <- table(movie_info), ShownMovie <- table(shown_movie), M.genre_id = GenreId, MI.movie_id = M.id, MI.lang_id = LangId, ShownMovie.set_top_box_id = StpxId, ShownMovie.name = User#user.name, ShownMovie.movie_id = M.id] end, F = fun() -> mnemosyne:eval(Q) end, mnesia:transaction(F). I've solved the problem grouping the table keys on a single tuple, {set_top_box_id, name} and {movie_id, lang_id} for both shown_movie and movie_info tables. This elimates the needed to add extra indices. Regards -- --------------------- | Samuel | --------------------- From Simon.Chappell@REDACTED Fri Apr 11 19:04:23 2003 From: Simon.Chappell@REDACTED (Chappell, Simon P) Date: Fri, 11 Apr 2003 12:04:23 -0500 Subject: Meta-survey (long newbie observations) Message-ID: <1AA6971F96FADB4A96CF73E4729B05F103F29D@USEVS012.leinternal.com> Joe et al., I don't know that I can contribute any questions, but I can comment on my experience to date trying to learn the language. One of the important things, IMNSHO, for a language to attract new users, is for the learning process to be easy. Now, this does not require the language to be easy, just the learning process. I have very little time for learning new languages, so for a language to grab my attention, I need the learning process to be as straight-forward as possible. I first heard of Erlang through the article over at UnixReview.com last year. This brought it onto my watch list and I made my way to erlang.org and started reading some of the introductory writings and downloaded the latest release and compiled it. The fact that it compiled first time on my Linux box gave me a good feeling. The fact that I had trouble getting out of the environment gave me bad feeling. It might be stupid, but not being easily able to figure out how to get out of the language environment caused me to feel hesitant to enter it again. Everyone else uses "exit" or "quit" (well, FTP uses "bye" :-) to get out of a language, but it took me a long time to find and get used to using "halt()." But I was still intrigued by this new (to me) language that promised things that Java kept hinting it could do, but never seemed to actually deliver. So, I subscribed to the email list and have lurked for a while. I have been very impressed with the level of discussion on the list. The erlang list is one of the premium lists of all that I have come across. I was pleased when I saw the tutorials, but then when I tried them they seemed wrongly targeted. They seem to start too simple and then veer of into way more detail on what looks like obscure stuff. The PDF of the "Concurrent Programming in ERLANG" book was my grounding point. This is a very good book. So good that I rushed off to Amazon to buy it, only to discover that it is out of print! Grrrr! Fortunately, I have been able to get hold of a second hand copy in good condition. For a language to get traction, it needs good books. The Struts framework (that I use at my employer) was in this quandary, until some of the developers bit the bullet and worked with publishers to write books. Now, the framework is entering the mainstream and the growth has been phenomenal. Now, you may not wish for Erlang to occupy the mainstream and compete with Java, but I suggest that it needs at least one (preferably two) in-print books ... and if you can get O'Reilly to publish one, then you are home and dry. :-) Now that I have finally gotten to the point where I could recognise a tuple if it leapt out and bit me, I have worked my way through the first of Joe's "Spitting in the Sawdust" tutorials and have found myself impressed with both Joe and the language. Next is to finish working my way through the Erlang book and trying everything out. After that, I will pick a small project and try to write something usable in Erlang to solve a need. I also intend to integrate ErlGuten into my personal website build process, so that I can provide information in both HTML and PDF. So, I hope that this is a useful insight into one Erlang newbies journey. There is much to get excited about and I feel that Erlang will have an exciting future. So, that I don't sound like a whining newbie, I am prepared to put together some tutorials (as time permits) on how to get from zero to one on the Erlang learning curve. (I'm sure that Joe et al go all the way to eleven ... to borrow from "This is Spinal Tap") Thank you for reading all of this and I hope that it sounds as positive as I feel about the language. Simon ----------------------------------------------------------------- Simon P. Chappell simon.chappell@REDACTED Java Programming Specialist www.landsend.com Lands' End, Inc. (608) 935-4526 "Never give in - never, never, never, never, in nothing great or small, large or petty, never give in except to convictions of honor and good sense." - Sir Winston Churchill >-----Original Message----- >From: Joe Armstrong [mailto:joe@REDACTED] >Sent: Friday, April 11, 2003 4:10 AM >To: erlang-questions@REDACTED >Subject: Meta-survey > > > > I'd like to conduct a survey of Erlang/OTP usage - > > Before sending out a survey with *my* questions on it I'd like to >ask what *your* questions would be. > > I don't want to bias the discussion by saying what sort of questions >I'd like there to be - so I won't (yet) say what sort of questions >I think should be in the survey. > > That's why this is a meta survey :-) > > So to my questions: > > 1) - In a survey about OTP/Erlang a number of questions will be >asked -- what are the best questions to ask in such a survey? > > 2) If I were to ask such questions would you reply? > > 3) What would be the best form to ask the questions in order to get a >high response frequency? > > /Joe > > > From garry@REDACTED Fri Apr 11 19:16:31 2003 From: garry@REDACTED (Garry Hodgson) Date: Fri, 11 Apr 2003 13:16:31 -0400 (EDT) Subject: Meta-survey Message-ID: <200304111716.NAA09626@sprache.sage.att.com> Joe Armstrong wrote: > So to my questions: > > 1) - In a survey about OTP/Erlang a number of questions will be > asked -- what are the best questions to ask in such a survey? well, of course it depends on just whay you're trying to find out. however, assuming you're trying to get a sense of the scope/scale/domains of erlang usage, you might try : are you using OTP or rolling your own? what are you using erlang for? - private experimentation/learning - stealth use at work - official use at work what kinds of projects? - distributed, server, infrastucture (erlang-ish kinds of things) - general applications - client/ui applications what barriers to entry do you find for learning erlang, for each of: - initial learning - becoming fluent - "thinking" in erlang what obstacles do you face in gaining acceptance for using it? - among colleagues - among management what kinds of things would make it easier to surmount these obstacles? - support? - publicity? - education? - overthrow of pointy-haired-bosses by enraged techies? > 2) If I were to ask such questions would you reply? yes > 3) What would be the best form to ask the questions in order to get a > high response frequency? a web page, with the link provided in the announcement mail. ---- Garry Hodgson, Senior Hacker, AT&T Labs Have you any idea why they're lying to you? To your faces! - Paul Kantner From garry@REDACTED Sat Apr 12 02:15:58 2003 From: garry@REDACTED (Garry Hodgson) Date: Fri, 11 Apr 2003 20:15:58 -0400 (EDT) Subject: OTP development, was Re: Gaga about bifs Message-ID: <200304120015.UAA13089@sprache.sage.att.com> Matthias Lang wrote: > It'd really make my day if someone I've never heard of before turned > up on the mailing list and said "I've implemented an SS7 stack using > the bit syntax, it's available at ftp.wherever.net". I realise that's > unlikely, so I'll settle for falling off my chair the day someone > _starts_ a discussion about altering the language (replacing records, > adding a type checker, reorganising all the libraries) by providing a > prototype implementation of their latest and greatest idea*. has anyone thought about a process like the PEP process used by python? it is described in detail at http://www.python.org/peps/pep-0001.html , but briefly: What is a PEP? PEP stands for Python Enhancement Proposal. A PEP is a design document providing information to the Python community, or describing a new feature for Python. The PEP should provide a concise technical specification of the feature and a rationale for the feature. We intend PEPs to be the primary mechanisms for proposing new features, for collecting community input on an issue, and for documenting the design decisions that have gone into Python. The PEP author is responsible for building consensus within the community and documenting dissenting opinions. it seems to have worked out pretty well so far. ---- Garry Hodgson, Senior Hacker, AT&T Labs Have you any idea why they're lying to you? To your faces! - Paul Kantner From cpressey@REDACTED Sat Apr 12 06:22:46 2003 From: cpressey@REDACTED (Chris Pressey) Date: Fri, 11 Apr 2003 23:22:46 -0500 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang.) In-Reply-To: References: <01cc01c2ff6e$8779d830$8500000a@Clarke> Message-ID: <20030411232246.0b0a95b9.cpressey@catseye.mb.ca> On Fri, 11 Apr 2003 10:26:11 +0200 Raimo Niskanen wrote: > Robert Virding wrote: > > I am strongly for consistency and simplicity. > > So am I, but only as long as it also is useful. All I (and I assume other people) am looking for is a function which converts integers to strings of digits in base N where 2 =< N =< 36... and which doesn't introduce a dependency between my program and a web server. All this talk about prefixes, minus signs, and case is extraneous - I daresay silly! There are simply too many permutations. If I care about a base-indicating prefix (or a suffix,) I'll add it myself. If I care about a minus sign (quick - name three times in the past when you have had a pressing need for negative hexadecimal numbers,) I'll add it myself (perhaps as a suffix - the guys in accounting prefer it that way (on the days they don't prefer to it to be DB or CR instead.)) If I care about case, I'll throw the resulting string through string:to_upper/1 or string:to_lower/1. (Errr... you *are* going to add to_upper/1 and to_lower/1 to the string module... right? Or are those still going to be officially classified as 'httpd helper functions'? :) As far as I can see... in comparison... integer_to_list/2 would be * consistent * simple * useful It's not wonderful that it'd be a BIF, but I can certainly live with it. -Chris From jocke@REDACTED Sat Apr 12 16:30:03 2003 From: jocke@REDACTED (Joakim G.) Date: Sat, 12 Apr 2003 16:30:03 +0200 Subject: visibility of a function in a module In-Reply-To: References: <200304111334.h3BDYf1E005088@ram.rentec.com> Message-ID: <3E9822EB.9030004@bluetail.com> Richard Carlsson wrote: >It is not available. We made a "proof of concept" implementation, >which needs more work, but this is probably going to be a future >feature of Erlang. > Hmm. Is this really what Erlang misses most of all? I can think of a least 25 (or was it 250) things which should be added/updated/fixed before going for this one. An unofficial top-ten (top-hundred) list of wanted/fixable language features would actually be interesting to have around. We could even make it pollable by people on this list. It could be good input to the OTP team. I suppose that "Parameterised modules" wouldn't even be on a top-250 list. My list that is. I will say no more. /Jocke > > > /Richard > > >On Fri, 11 Apr 2003, HP Wei wrote: > > >>>Richard Carlsson made something like this (called Parameterised modules) >>> >>> M = load (test(Base)), >>> M:do() >>> >>> This can be implemented by some relatively simple code transformations. >>> >> I guess this is not an 'official feature' of erlang yet. (?) >> And I could not find it in User Contribution. >> Where do I find an implementation of this Parameterised module ? >> >> --HP >> >> >> >> > >Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) >E-mail: Richard.Carlsson@REDACTED WWW: http://user.it.uu.se/~richardc/ > "Having users is like optimization: the wise course is to delay it." > -- Paul Graham > From hp@REDACTED Sat Apr 12 18:16:18 2003 From: hp@REDACTED (HP Wei) Date: Sat, 12 Apr 2003 12:16:18 -0400 (EDT) Subject: what is a good way to do 'maintaining data distribution' Message-ID: <200304121616.h3CGGI1E004270@ram.rentec.com> On of my responsibilities is to make sure that all databases generated on a few master machines get distributed to other machines in a timely and reliable fashion. Scale: machine number is around 240. Dependence: intertwining. Currently, I have many python scripts here and there for doing this task. When the machines number increases and interdependence rules get more intertwined, it becomes a headache to keep on top of things. Perhaps I did not make full use of python to deal with the ever changing inter-dependence and inter-machine communication. :) Anyway, I am looking into Erlang's way of doing this task, because of the built-in inter-communication at the languague-level. The goal is to set up one system across the entire LAN network, instead of many isolated codes here and there. Here are two approaches that I can think of. (1) Write down the 'dependence rules' --- in analogous to an erlang makefile. Then, a sync-engine (in analogous to ermake.erl) should gather data and execute functions to maintain rule's integrity. (2) More general way (?). we can have a list of entities, [entity1, entity2, ...] Each entity has its value (representing its state) and has associated with it a rule (one or more functions) which may depend on other entities. ---> sort of like a Spreadsheet model. If the value of one entity gets changed, all other entities that depend on it will be updated too. ------------------------------------------------------------ (1) is straightforward to do since ermake is an example. I don't know Erlang deep enough to know how to express (2) in Erlang. Any suggestions are appreciated. If anyone on this list has already such modules (either ready-to-go (1) or example of (2)) that you don't mind sharing, it would spare me more time to play the game of GO :-) Thanks, HP From svg@REDACTED Sat Apr 12 17:15:00 2003 From: svg@REDACTED (Vladimir Sekissov) Date: Sat, 12 Apr 2003 21:15:00 +0600 (YEKST) Subject: what is a good way to do 'maintaining data distribution' In-Reply-To: <200304121616.h3CGGI1E004270@ram.rentec.com> References: <200304121616.h3CGGI1E004270@ram.rentec.com> Message-ID: <20030412.211500.71085382.svg@surnet.ru> Good day, hp> On of my responsibilities is to make sure that all databases hp> generated on a few master machines get distributed to other machines hp> in a timely and reliable fashion. hp> Scale: machine number is around 240. hp> Dependence: intertwining. There aren't enough information to answer your question correctly but I try. 1) If you could switch to Mnesia it did all work for you. Some sophisticated rules could be solved using Ulf Wiger's `rdbms' package (available at contributions page). 2) If you must use SQL database the simplest solution would be database triggers on insert/update/delete to store key information of changed records in log table with timestamps and periodic update on remote nodes using erlang `odbc' and `rpc' modules. hp> Here are two approaches that I can think of. hp> (1) Write down the 'dependence rules' hp> --- in analogous to an erlang makefile. hp> hp> Then, a sync-engine (in analogous to ermake.erl) hp> should gather data and execute functions to maintain rule's integrity. hp> hp> (2) More general way (?). hp> we can have a list of entities, hp> [entity1, entity2, ...] hp> Each entity has its value (representing its state) hp> and has associated with it a rule (one or more functions) which may hp> depend on other entities. hp> ---> sort of like a Spreadsheet model. hp> If the value of one entity gets changed, all other entities hp> that depend on it will be updated too. Best Regards, Vladimir Sekissov From hp@REDACTED Sat Apr 12 19:43:31 2003 From: hp@REDACTED (HP Wei) Date: Sat, 12 Apr 2003 13:43:31 -0400 (EDT) Subject: what is a good way to do 'maintaining data distribution' Message-ID: <200304121743.h3CHhVET025999@wren.rentec.com> >hp> On of my responsibilities is to make sure that all databases >hp> generated on a few master machines get distributed to other machines >hp> in a timely and reliable fashion. >hp> Scale: machine number is around 240. >hp> Dependence: intertwining. > >There aren't enough information to answer your question correctly but I try. > >1) If you could switch to Mnesia it did all work for you. Some >sophisticated rules could be solved using Ulf Wiger's `rdbms' package >(available at contributions page). > >2) If you must use SQL database the simplest solution would be >database triggers on insert/update/delete to store key information of >changed records in log table with timestamps and periodic update on >remote nodes using erlang `odbc' and `rpc' modules. ------------------------------------------------------------------------- Thank you for your input. Unfortunately, SQL is too slow for our company. And the nice Mnesia in Erlang cannot be used for our purpose. Our company uses proprietary databases developed internally using C++, for speed of accessing and performing complicated compression calculations. (btw, it is very hard to change something existing :-) Our company has recently rejected a proposal of moving into ROOT -- a better C++ data framework developed at CERN for dealing with massive amount of data.) Fortunately, each database is divided into many individual files. As a result, maintaining database synchronization becomes the problem of syncing at the level of individual files. --HP From hp@REDACTED Sat Apr 12 19:56:06 2003 From: hp@REDACTED (HP Wei) Date: Sat, 12 Apr 2003 13:56:06 -0400 (EDT) Subject: what is a good way to do 'maintaining data distribution' Message-ID: <200304121756.h3CHu6ET026121@wren.rentec.com> Regarding synchronization of entities across all nodes in Mnesia (or ets), what is the general model (algorithm) used ? Is it like (1) -- the makefile model or is it like (2) -- the Spreadsheet model ??? [Note: (1) and (2) refers to those in my first email. see below.] (I know the answer is in the source code. I figure it's faster and easier to ask :) --hp ---------------------------------------------------------------- >1) If you could switch to Mnesia it did all work for you. Some >sophisticated rules could be solved using Ulf Wiger's `rdbms' package >(available at contributions page). ------------------------------------------------------------------- >hp> On of my responsibilities is to make sure that all databases >hp> generated on a few master machines get distributed to other machines >hp> in a timely and reliable fashion. >hp> Scale: machine number is around 240. >hp> Dependence: intertwining. >hp> Here are two approaches that I can think of. >hp> (1) Write down the 'dependence rules' >hp> --- in analogous to an erlang makefile. >hp> >hp> Then, a sync-engine (in analogous to ermake.erl) >hp> should gather data and execute functions to maintain rule's integrity. >hp> >hp> (2) More general way (?). >hp> we can have a list of entities, >hp> [entity1, entity2, ...] >hp> Each entity has its value (representing its state) >hp> and has associated with it a rule (one or more functions) which may >hp> depend on other entities. >hp> ---> sort of like a Spreadsheet model. >hp> If the value of one entity gets changed, all other entities >hp> that depend on it will be updated too. From svg@REDACTED Sat Apr 12 18:29:17 2003 From: svg@REDACTED (Vladimir Sekissov) Date: Sat, 12 Apr 2003 22:29:17 +0600 (YEKST) Subject: what is a good way to do 'maintaining data distribution' In-Reply-To: <200304121743.h3CHhVET025999@wren.rentec.com> References: <200304121743.h3CHhVET025999@wren.rentec.com> Message-ID: <20030412.222917.97298610.svg@surnet.ru> hp> Fortunately, each database is divided into many individual files. hp> As a result, maintaining database synchronization becomes the problem hp> of syncing at the level of individual files. hp> Hmm, what about to create fragmented tables in Mnesia related to your database, write to it {Key, Record} information about changed records, Record could be direct binary from C struct: 1. Mnesia distribute this tables. 2. Update on slave node. 2.1 Your slave node reads its local replica and updates database table. 2.3 Because table is fragmented it can safely delete record from Mnesia. Best Regards, Vladimir Sekissov From svg@REDACTED Sat Apr 12 18:51:09 2003 From: svg@REDACTED (Vladimir Sekissov) Date: Sat, 12 Apr 2003 22:51:09 +0600 (YEKST) Subject: what is a good way to do 'maintaining data distribution' In-Reply-To: <200304121756.h3CHu6ET026121@wren.rentec.com> References: <200304121756.h3CHu6ET026121@wren.rentec.com> Message-ID: <20030412.225109.78706916.svg@surnet.ru> In first approximation: 1. At startup Mnesia try to find the node where the freshest version of table is located. If local replica is older table's file is copied to local machine. You can use mnesia:set_master_node([MasterNode]) to force Mnesia to use MasterNode as source. 2. At runtime Mnesia keeps log of records to sync. Details depend from mode you use - transactional or dirty. Best Regards, Vladimir Sekissov hp> Regarding synchronization of entities across all nodes in hp> Mnesia (or ets), hp> what is the general model (algorithm) used ? hp> Is it like (1) -- the makefile model hp> or is it like (2) -- the Spreadsheet model ??? hp> [Note: (1) and (2) refers to those in my first email. see below.] From cpressey@REDACTED Sat Apr 12 22:03:27 2003 From: cpressey@REDACTED (Chris Pressey) Date: Sat, 12 Apr 2003 15:03:27 -0500 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang.) In-Reply-To: <20030411232246.0b0a95b9.cpressey@catseye.mb.ca> References: <01cc01c2ff6e$8779d830$8500000a@Clarke> <20030411232246.0b0a95b9.cpressey@catseye.mb.ca> Message-ID: <20030412150327.33c6a082.cpressey@catseye.mb.ca> On Fri, 11 Apr 2003 23:22:46 -0500 Chris Pressey wrote: > (Errr... you *are* going to add to_upper/1 and to_lower/1 to the > string module... right? Or are those still going to be officially > classified as 'httpd helper functions'? :) In an attempt to dislodge Matthias from his chair, here is a patch against R9B-1 that puts these functions in their place. If this is something the OTP team wants, I can make a better patch in the near future (tail-recursive, fixup the references in httpd_*.erl, etc.) -Chris -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: string.diff URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: otp_internal.diff URL: From cpressey@REDACTED Sat Apr 12 22:40:04 2003 From: cpressey@REDACTED (Chris Pressey) Date: Sat, 12 Apr 2003 15:40:04 -0500 Subject: visibility of a function in a module In-Reply-To: <3E9822EB.9030004@bluetail.com> References: <200304111334.h3BDYf1E005088@ram.rentec.com> <3E9822EB.9030004@bluetail.com> Message-ID: <20030412154004.67970120.cpressey@catseye.mb.ca> On Sat, 12 Apr 2003 16:30:03 +0200 "Joakim G." wrote: > An unofficial top-ten (top-hundred) list of wanted/fixable language > features would actually be interesting to have around. We could even > make it pollable by people on this list. It could be good input to the > OTP team. Here's mine, sorted roughly by decreasing feasability: 1. Put general-purpose base-conversion functions somewhere in stdlib (io, or math, or string) and deprecate those in httpd_util. 2. Move general-purpose string functions from httpd_util to string. 3. Move general-purpose date functions from httpd_util to calendar. 4. Fix regexp module. 5. Document all interfaces, esp. ones in common use (active_once, etc) 6. Document BEAM format. 7. Smaller distribution (split into core distribution + apps) 8. Opaque, guarded structs. 9. Type inference in linter that generates warnings only. 10. Arbitrary expressions in guards. -Chris From tony@REDACTED Sat Apr 12 23:51:54 2003 From: tony@REDACTED (Tony Rogvall) Date: Sat, 12 Apr 2003 23:51:54 +0200 Subject: visibility of a function in a module References: <200304111334.h3BDYf1E005088@ram.rentec.com> <3E9822EB.9030004@bluetail.com> <1050180942.985@DNS02> Message-ID: <3E988A7A.6010802@rogvall.com> Chris Pressey wrote: > On Sat, 12 Apr 2003 16:30:03 +0200 > "Joakim G." wrote: > > >>An unofficial top-ten (top-hundred) list of wanted/fixable language >>features would actually be interesting to have around. We could even >>make it pollable by people on this list. It could be good input to the >>OTP team. > > > Here's mine, sorted roughly by decreasing feasability: > > 1. Put general-purpose base-conversion functions somewhere in stdlib > (io, or math, or string) and deprecate those in httpd_util. > 2. Move general-purpose string functions from httpd_util to string. > 3. Move general-purpose date functions from httpd_util to calendar. > 4. Fix regexp module. > 5. Document all interfaces, esp. ones in common use (active_once, etc) > 6. Document BEAM format. > 7. Smaller distribution (split into core distribution + apps) > 8. Opaque, guarded structs. > 9. Type inference in linter that generates warnings only. > 10. Arbitrary expressions in guards. > > -Chris Here is mine: 1. Put the OTP source code in CVS and make it accessible. 2. Use nice patches that people send :-) 3. Rentrant and thread safe emulator (SMP) 4. binary syntax updates, bitgroups! possible add -list -tuple and -msb|-lsb for bit reversal. One more syntax improvment whould to add record support in bitsyntax, something that I have to do by hand to day: -record(r, { a:16/integer, b:32/float }). << X/#r >>. 5. charactar support UNICODE !!! with ord/chr/upper/lower support 6. module as objects, and in external format. This means that modules on disc should be in extrnal format. Think of the following: {ok,Bin} = file:read_file("somemodule"), Mod = binary_to_term(Bin), apply(Mod, my_func, Args). or register_module(Name, Mod) This was done in as a prototype in multithread erlang and worked very nicely! 7. nodes as objects. Today node name is somed kind of DNS name, this does not work for multi-protocol. The # should be something uniq not coded as an atom. 8. subnodes. (from SafeErlang). With orwith out SafeErlang, subnodes could be a nice way to handle safe environments with own name spaces etc. Possibly restrictions on number of processes and execution time etc could be added. 9. I think that will keep you busy for a while :-) 10. Not ready yet ? Have fun/0. /Tony -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 3237 bytes Desc: S/MIME Cryptographic Signature URL: From vances@REDACTED Sun Apr 13 00:54:23 2003 From: vances@REDACTED (Vance Shipley) Date: Sat, 12 Apr 2003 18:54:23 -0400 Subject: Top Ten Lists Message-ID: <20030412225423.GB30824@frogman.motivity.ca> Most of the things I'd like to see happen seem to be in the pipe. The biggest improvement would be documenting the language in a definitive way. There should be an obvious last word on syntax available in an easily accessable way. This is sorely missing although I'm told on the way. The next general improvement would be an openly discussed development path. The cond & try changes appear to be coming. We know this because the keywords were reserved. There is this: http://www.bluetail.com/~rv/Erlang-spec/index.shtml However I don't believe it is accurate. If it were it would be reachable from www.erlang.org. -Vance From cpressey@REDACTED Sun Apr 13 04:19:08 2003 From: cpressey@REDACTED (Chris Pressey) Date: Sat, 12 Apr 2003 21:19:08 -0500 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang.) In-Reply-To: <20030412150327.33c6a082.cpressey@catseye.mb.ca> References: <01cc01c2ff6e$8779d830$8500000a@Clarke> <20030411232246.0b0a95b9.cpressey@catseye.mb.ca> <20030412150327.33c6a082.cpressey@catseye.mb.ca> Message-ID: <20030412211908.1fa75e48.cpressey@catseye.mb.ca> On Sat, 12 Apr 2003 15:03:27 -0500 Chris Pressey wrote: > If this is something the OTP team wants, I can make a better patch in > the near future (tail-recursive, fixup the references in httpd_*.erl, > etc.) Done this now, see attached patch (also contains my older patch for regexp and a few minor tweaks to other files (e.g. -include to -include_lib so I could recompile it easily) math:base/2 returns the same (goofy) error codes as httpd_util:hexlist_to_integer/1 and httpd_util:integer_to_hexlist/1 It does NOT, however, simulate the what-I'd-consider-broken behaviour of httpd_util:hexlist_to_integer/1: Eshell V5.2.3.3 (abort with ^G) 1> httpd_util:hexlist_to_integer("3G5"). 3 2> httpd_util:hexlist_to_integer("-3F5"). 0 Instead it returns 'error' or 'not_a_num' for negative values, as the httpd_util functions do, on the errors that they do detect. -Chris -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: stdlib+inets.patch URL: From cpressey@REDACTED Sun Apr 13 07:52:04 2003 From: cpressey@REDACTED (Chris Pressey) Date: Sun, 13 Apr 2003 00:52:04 -0500 Subject: Documentation project (was: Re: Top Ten Lists) In-Reply-To: <20030412225423.GB30824@frogman.motivity.ca> References: <20030412225423.GB30824@frogman.motivity.ca> Message-ID: <20030413005204.45772929.cpressey@catseye.mb.ca> On Sat, 12 Apr 2003 18:54:23 -0400 Vance Shipley wrote: > The biggest improvement would be documenting the language in a > definitive way. On this subject - are the documentation HTML files generated from some underlying format? Or is it OK to submit patches on them directly? -Chris From thomasl_erlang@REDACTED Sun Apr 13 13:59:34 2003 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Sun, 13 Apr 2003 04:59:34 -0700 (PDT) Subject: Top Ten Lists In-Reply-To: <20030412225423.GB30824@frogman.motivity.ca> Message-ID: <20030413115934.16013.qmail@web13305.mail.yahoo.com> Some more suggestions. These are more along the lines of cleaning up the existing stuff. * Garbage collection of atom table. * Emulator not dying when it runs out of memory. * Better exceptions (e.g., return {mod, func, arity, line, reason}). Maybe leave a way open to add "structured exceptions" or "exception objects" that can contain even more info. * Record operations should check that they are actually working on the right kind of records. Best, Thomas __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - File online, calculators, forms, and more http://tax.yahoo.com From kent@REDACTED Sun Apr 13 16:44:39 2003 From: kent@REDACTED (Kent Boortz) Date: 13 Apr 2003 16:44:39 +0200 Subject: Documentation project (was: Re: Top Ten Lists) In-Reply-To: <20030413005204.45772929.cpressey@catseye.mb.ca> References: <20030412225423.GB30824@frogman.motivity.ca> <20030413005204.45772929.cpressey@catseye.mb.ca> Message-ID: > On this subject - are the documentation HTML files generated from some > underlying format? Or is it OK to submit patches on them directly? If you mean the normal Erlang documentation, it is written in SGML. Each image is in two formats, GIF and PostScript/EPS. From this we generate Unix manual pages, HTML and LaTeX. From LaTeX we generate PostScript/PDF. The conversion tool is mainly written in Erlang. It uses nsgmls as a parser. I know nsgmls can do XML (I don't know how well) so maybe it is not that hard to convert the tool to use XML as input instead of SGML. The preparation for releasing the SGML tool as OpenSource is unfinished. I may be wrong but I think it is not that much left. A "we want that tool now please" may be enough to get it out the door ;-) kent From blitzfeuer@REDACTED Sun Apr 13 12:51:51 2003 From: blitzfeuer@REDACTED (Walter C. Reel III) Date: Sun, 13 Apr 2003 10:51:51 +0000 Subject: Application structure Message-ID: <200304131051.51677.blitzfeuer@sc.rr.com> I'm trying to learn Erlang and create a 'Proof of Concept' system at the same time. I came across the Application structure in the 'Design Principles' documentation. Would it be better to start from this structure and work upwards? It would seem there is a lot of built in functionality that relates to the application structure. If so, does a node correspond to an application? The mnesia schema would go under 'App/priv' or 'App/priv/schema', right? Thanks, - Walt From robert.virding@REDACTED Sun Apr 13 21:02:50 2003 From: robert.virding@REDACTED (Robert Virding) Date: Sun, 13 Apr 2003 21:02:50 +0200 Subject: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang.) References: <01cc01c2ff6e$8779d830$8500000a@Clarke> <20030411232246.0b0a95b9.cpressey@catseye.mb.ca> <20030412150327.33c6a082.cpressey@catseye.mb.ca> Message-ID: <003a01c301ef$47caf240$8100a8c0@virding.org> Yes, add these! Robert ----- Original Message ----- From: "Chris Pressey" To: Cc: Sent: Saturday, April 12, 2003 10:03 PM Subject: Re: Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang.) > On Fri, 11 Apr 2003 23:22:46 -0500 > Chris Pressey wrote: > > > (Errr... you *are* going to add to_upper/1 and to_lower/1 to the > > string module... right? Or are those still going to be officially > > classified as 'httpd helper functions'? :) > > In an attempt to dislodge Matthias from his chair, here is a patch > against R9B-1 that puts these functions in their place. > > If this is something the OTP team wants, I can make a better patch in > the near future (tail-recursive, fixup the references in httpd_*.erl, > etc.) > > -Chris > From cpressey@REDACTED Mon Apr 14 06:34:38 2003 From: cpressey@REDACTED (Chris Pressey) Date: Sun, 13 Apr 2003 23:34:38 -0500 Subject: Documentation project (was: Re: Top Ten Lists) In-Reply-To: References: <20030412225423.GB30824@frogman.motivity.ca> <20030413005204.45772929.cpressey@catseye.mb.ca> Message-ID: <20030413233438.101002d2.cpressey@catseye.mb.ca> On 13 Apr 2003 16:44:39 +0200 Kent Boortz wrote: > > On this subject - are the documentation HTML files generated from > > some underlying format? Or is it OK to submit patches on them > > directly? > > If you mean the normal Erlang documentation, it is written in > SGML. Each image is in two formats, GIF and PostScript/EPS. From this > we generate Unix manual pages, HTML and LaTeX. From LaTeX we generate > PostScript/PDF. The conversion tool is mainly written in Erlang. It > uses nsgmls as a parser. I know nsgmls can do XML (I don't know how > well) so maybe it is not that hard to convert the tool to use XML as > input instead of SGML. > > The preparation for releasing the SGML tool as OpenSource is > unfinished. I may be wrong but I think it is not that much left. > A "we want that tool now please" may be enough to get it out > the door ;-) > > kent I'm just thinking of the case where an open-source user notices an error in the documentation, and wants to submit a correction. The most painless way to do this is to submit a patch against the doc source. But if they don't have access to the doc source, they can't do that. So, I don't care as much about the SGML->HTML/man/PDF converter as the SGML files themselves. In fact, one could argue that, if they're not publicly available, then the documentation isn't open-source. (All the user gets is the 'compiled' (HTML) version.) (btw - there is a redundant link to otp_html_R9B-1.tar.gz on the download page) -Chris From cpressey@REDACTED Mon Apr 14 07:01:55 2003 From: cpressey@REDACTED (Chris Pressey) Date: Mon, 14 Apr 2003 00:01:55 -0500 Subject: moving general-purpose functions from httpd_util to stdlib In-Reply-To: <003a01c301ef$47caf240$8100a8c0@virding.org> References: <01cc01c2ff6e$8779d830$8500000a@Clarke> <20030411232246.0b0a95b9.cpressey@catseye.mb.ca> <20030412150327.33c6a082.cpressey@catseye.mb.ca> <003a01c301ef$47caf240$8100a8c0@virding.org> Message-ID: <20030414000155.2b025eae.cpressey@catseye.mb.ca> On Sun, 13 Apr 2003 21:02:50 +0200 "Robert Virding" wrote: > Yes, add these! > > Robert I still have some reservations on my final patch. - hex could be done equally well with io:format or erlang:integer_to_list. If one of these is settled on as officially, I'll happily redo my patch to use it instead of math:base. - httpd_util:hexlist_to_integer and integer_to_hexlist return not-very-helpful atoms ('error', 'empty' or 'not_a_num') in the case of an error. In the interests of backwards-compatibility, I made math:base return the same atoms. However, when you consider that: - these error returns aren't documented in the httpd_util manpage - other httpd_* modules don't seem to check explicitly for them ...one wonders whether it would be wiser to improve the error handling, at least to the point where they return {error, Reason} like so many other functions do. This brings up one of those burning questions of our times - that is, what exactly "defensive programming" means in the context of Erlang. Say you have a function foo() that can return either an integer or the atom 'error'. You can write a caller of foo either like this: case foo() of I when is_integer(I) -> bar(I); error -> {error, foo_failed} end or like this: case foo() of I when is_integer(I) -> bar(I); _ -> {error, foo_didnt_return_an_integer} end The first seems to be more in tune with "write for the correct case, otherwise just let it crash." You know the range of foo(), and you write the case to map exactly to that range. The second seems to be more in tune with "defensive programming," at least one definition of it that I've seen mentioned. You're assuming that the range of foo() might be expanded in the future, and you don't want to have to change your foo-caller code. (and/or you didn't read the documentation for foo() too closely and you only know that it can return 'at least' an integer) The question is - which is wiser? The first is clearer (easier to follow by reading,) but the second is less fragile (more resistant to interface evolution.) Presently, I'm quite undecided, and would be interested in hearing other Erlang programmers' thoughts on this. Anyway - in the future, I won't clutter this list with patches, I'll send them to erlang-patches@ only. -Chris From eleberg@REDACTED Mon Apr 14 07:52:25 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Mon, 14 Apr 2003 07:52:25 +0200 (MEST) Subject: OTP development, was Re: Gaga about bifs Message-ID: <200304140552.h3E5qPi00387@cbe.ericsson.se> > Date: Fri, 11 Apr 2003 20:15:58 -0400 (EDT) > MIME-Version: 1.0 > Content-Transfer-Encoding: 7bit > Subject: Re: Re: OTP development, was Re: Gaga about bifs > To: erlang-questions@REDACTED > From: Garry Hodgson ...deleted > has anyone thought about a process like the PEP process > used by python? it is described in detail at > http://www.python.org/peps/pep-0001.html , > but briefly: > > What is a PEP? > > PEP stands for Python Enhancement Proposal. A PEP is a design > document providing information to the Python community, or > describing a new feature for Python. The PEP should provide a > concise technical specification of the feature and a rationale for > the feature. > > We intend PEPs to be the primary mechanisms for proposing new > features, for collecting community input on an issue, and for > documenting the design decisions that have gone into Python. The > PEP author is responsible for building consensus within the > community and documenting dissenting opinions. and then there is http://srfi.schemers.org/ it does the same thing for a community with a very large amount of implementations. sort of opposite of erlang. however, there was a lot of very knowledgable people that designed the srfi process. bengt From eleberg@REDACTED Mon Apr 14 08:08:54 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Mon, 14 Apr 2003 08:08:54 +0200 (MEST) Subject: moving general-purpose functions from httpd_util to stdlib Message-ID: <200304140608.h3E68si01418@cbe.ericsson.se> > Date: Mon, 14 Apr 2003 00:01:55 -0500 > From: Chris Pressey ...deleted > This brings up one of those burning questions of our times - that is, > what exactly "defensive programming" means in the context of Erlang. > > Say you have a function foo() that can return either an integer or the > atom 'error'. an alternative to this problem is described by Richard Carlsson: - A function should *not* return wrapped values like {ok,Value}/{error,Reason} to indicate success or failure. The assumed behaviour should be success, and failures should be signalled by exceptions, as described below. bengt From jay@REDACTED Mon Apr 14 08:37:26 2003 From: jay@REDACTED (Jay Nelson) Date: Sun, 13 Apr 2003 23:37:26 -0700 Subject: Part 2 of tcp_proxy tutorial Message-ID: <4.2.2.20030413233013.00d77e20@duomark.com> I made a few minor changes to Part 1 of the tcp_proxy tutorial. This tutorial demonstrates using gen_server to create a TCP/IP proxy server: http://www.duomark.com/erlang/tutorials/proxy.html Part 2 of the tutorial is now complete as well. It describes the proxy interface and provides three demonstration applications: a simple telnet echo, a browser-based echo and a proxy server that blocks "naughty" sites from being visited. http://www.duomark.com/erlang/tutorials/proxy2.html Let me know of any changes or corrections that are recommended. I will start working on my gameserver again (based on the tutorial code) so it will be a while before I finish up with Part 3: web services by proxy. The code can be downloaded as a tgz file from the link at the top of the page. Some individual text files are provided where the narrative of the text refers to them. jay From etxuwig@REDACTED Mon Apr 14 12:25:47 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Mon, 14 Apr 2003 12:25:47 +0200 (MEST) Subject: moving general-purpose functions from httpd_util to stdlib In-Reply-To: <200304140608.h3E68si01418@cbe.ericsson.se> Message-ID: On Mon, 14 Apr 2003, Bengt Kleberg wrote: >> Date: Mon, 14 Apr 2003 00:01:55 -0500 >> From: Chris Pressey >...deleted > >> This brings up one of those burning questions of our times - that is, >> what exactly "defensive programming" means in the context of Erlang. >> >> Say you have a function foo() that can return either an integer or the >> atom 'error'. > >an alternative to this problem is described by Richard Carlsson: > > - A function should *not* return wrapped values like > {ok,Value}/{error,Reason} to indicate success or > failure. The assumed behaviour should be success, > and failures should be signalled by exceptions, > as described below. This is the behaviour I much prefer. I think one should always try to think about what a user can reasonably do if the requested operation doesn't succeed. If the normal case is to exit, then I think it's best to have the original function exit right away. If the odd caller does not want to exit, there's always catch. I've seen tons of code where the caller checks the return value in the following manner: case foo(X,Y,Z) of {ok, Result} -> ...; {error, Reason} -> {error, Reason} end. If this type of pattern is scattered all over in your programs, then you'd be much better off writing functions that either succeed or fail distinctly. One of my favourite examples has been timer:send_after/3, which returns {ok, TRef} | {error, Reason}. How many times when you've ordered a timer has there been any reasonable alternative action in the event that a timer weren't available? /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From luke@REDACTED Mon Apr 14 15:20:39 2003 From: luke@REDACTED (Luke Gorrie) Date: 14 Apr 2003 15:20:39 +0200 Subject: moving general-purpose functions from httpd_util to stdlib In-Reply-To: References: Message-ID: Ulf Wiger writes: > >an alternative to this problem is described by Richard Carlsson: > > > > - A function should *not* return wrapped values like > > {ok,Value}/{error,Reason} to indicate success or > > failure. The assumed behaviour should be success, > > and failures should be signalled by exceptions, > > as described below. > > This is the behaviour I much prefer. > > I think one should always try to think about what a user can > reasonably do if the requested operation doesn't succeed. If > the normal case is to exit, then I think it's best to have > the original function exit right away. If the odd caller > does not want to exit, there's always catch. I agree, except that I'm not comfortable enough with using 'catch', since it always catches everything and mucks up your backtraces. I would like to have more explicit control over what I actually catch. The proposed 'try-catch' construct could be nice for this. Cheers, Luke From garry@REDACTED Mon Apr 14 16:47:01 2003 From: garry@REDACTED (Garry Hodgson) Date: Mon, 14 Apr 2003 10:47:01 -0400 (EDT) Subject: OTP development processes Message-ID: <200304141447.KAA33157@sprache.sage.att.com> Bengt Kleberg wrote: > > From: Garry Hodgson > > has anyone thought about a process like the PEP process > > used by python? it is described in detail at > > http://www.python.org/peps/pep-0001.html , > and then there is http://srfi.schemers.org/ > it does the same thing for a community with a very large amount of > implementations. sort of opposite of erlang. however, there was a lot > of very knowledgable people that designed the srfi process. yes, that looks like it'd be useful, as well. i think the key thing is to add some rigor to the process, and mostly to relieve the main developers from having to deal with the task of vetting new proposals. they would still have the final word on what gets done and how it gets done, but could restrict their attention to those proposals that have made it through the peer review process. proposals that came along with working code would be nice, too. ---- Garry Hodgson, Senior Hacker, AT&T Labs Have you any idea why they're lying to you? To your faces! - Paul Kantner From robert.virding@REDACTED Tue Apr 15 02:12:39 2003 From: robert.virding@REDACTED (Robert Virding) Date: Tue, 15 Apr 2003 02:12:39 +0200 Subject: moving general-purpose functions from httpd_util to stdlib References: <200304140608.h3E68si01418@cbe.ericsson.se> Message-ID: <003501c302e3$ba33e220$8300a8c0@virding.org> ----- Original Message ----- From: "Bengt Kleberg" To: Sent: Monday, April 14, 2003 8:08 AM Subject: Re: moving general-purpose functions from httpd_util to stdlib > > > Date: Mon, 14 Apr 2003 00:01:55 -0500 > > From: Chris Pressey > ...deleted > > > This brings up one of those burning questions of our times - that is, > > what exactly "defensive programming" means in the context of Erlang. > > > > Say you have a function foo() that can return either an integer or the > > atom 'error'. > > an alternative to this problem is described by Richard Carlsson: > > - A function should *not* return wrapped values like > {ok,Value}/{error,Reason} to indicate success or > failure. The assumed behaviour should be success, > and failures should be signalled by exceptions, > as described below. I think I would try to qualify that a little more. It depends on what type of failure you mean. I would generally say that bad argument type or values should generate an exit so it is quite clear that Chris's hex conversion functions should only return the value and exit on failure. However, there are many cases where the non-success case does not really represent an error and then it should not generate an exit but use qualified return values like {ok,V}/{error,R}. Maybe the convention to use ok/error was badly chosen and we should have used yes/no but I think it would be worse to try and have two, or more, "conventions". Better to have one and try to explain how it is used. This is why most of the original, older libraries at least very rarely check arguments types and values but just assume they are correct and otherwise exit. As do most bifs. You can't do anything sensible if the arguments are all wrong. Another example would be file:open. As I envisaged when I wrote it was that if the arguments were of the wrong type or had illegal values ('creat') then it should exit. However, not being able to open the file I didn't really see as an error so it returned qualified values to indicate this. What it exactly does now I don't know. Not everyone agreed with me. Basically there are errors and errors. Robert From erik@REDACTED Tue Apr 15 09:42:26 2003 From: erik@REDACTED (Erik Pearson) Date: Tue, 15 Apr 2003 00:42:26 -0700 Subject: records generated from UBF In-Reply-To: Message-ID: I'd like to give UBF a try. It looks really great, and thanks for your addition to it. I'm currently need to move from a simple data exchange format that I've used for years (it is a glorified url query string), and have stayed away from XML-RPC and the ilk partly because of the reasons sited at the UBF site (http://www.sics.se/~joe/ubf). UBF just may save the day! What would be great, though, is if someone can share a Java implementation (or any other implementation out there, e.g. Tcl). I need it to glue together a Java servlet to Erlang (or whatever). From the UBF paper, it appears that a Java implementation was largely completed. It would be great to either use that code, or start with it and complete the implementation far enough to get something working. Yeah, call me a moocher :) Thanks, Erik. On Tuesday, April 8, 2003, at 01:50 AM, Ulf Wiger wrote: > > Is anybody else out there playing around with UBF? > > I wrote a small utility yesterday that generates a .hrl file > from a UBF specification. It generates a record > [ all the good stuff snipped... ] > > > Life is good. > > /Uffe > > -- > Ulf Wiger, Senior Specialist, > / / / Architecture & Design of Carrier-Class Software > / / / Strategic Product & System Management > / / / Ericsson AB, Connectivity and Control Nodes > Erik Pearson Adaptations From mickael.remond@REDACTED Tue Apr 15 10:36:28 2003 From: mickael.remond@REDACTED (Mickael Remond) Date: Tue, 15 Apr 2003 10:36:28 +0200 Subject: records generated from UBF In-Reply-To: (Erik Pearson's message of "Tue, 15 Apr 2003 00:42:26 -0700") References: Message-ID: Erik Pearson writes: > What would be great, though, is if someone can share a Java > implementation (or any other implementation out there, e.g. Tcl). I > need it to glue together a Java servlet to Erlang (or whatever). > > From the UBF paper, it appears that a Java implementation was largely > completed. It would be great to either use that code, or start with > it and complete the implementation far enough to get something > working. Yeah, call me a moocher :) UBF Java implementation is available in the latest archive from the downloads area: http://www.sics.se/~joe/ubf/downloads/ubf-1.11.tgz -- Micka?l R?mond http://www.erlang-projects.org/ From etxuwig@REDACTED Tue Apr 15 10:43:11 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Tue, 15 Apr 2003 10:43:11 +0200 (MEST) Subject: records generated from UBF In-Reply-To: Message-ID: On Tue, 15 Apr 2003, Erik Pearson wrote: >I'd like to give UBF a try. It looks really great, and >thanks for your addition to it. Good. (: Joe is, I believe, in Iceland this week, undoubtedly spending quality time trying out all the hot baths there. Let's see how he wants to play it when he gets back. Otherwise, you can certainly download whatever he has made available on his website, and I can send you my modified version, with absolutely no guarantees. ;-) >What would be great, though, is if someone can share a Java >implementation (or any other implementation out there, e.g. >Tcl). I need it to glue together a Java servlet to Erlang >(or whatever). > > From the UBF paper, it appears that a Java implementation >was largely completed. It would be great to either use that >code, or start with it and complete the implementation far >enough to get something working. There are two Java implementations that I know of. Luke's Java client that's included in Joe's care package, and Jon ?kerg?rden's Athletics client prototype. Jon's Java code can be downloaded from http://www.it.kth.se/~e98_jak/ However, Jon is actively working on the code right now, so the downloadable version is almost certainly outdated. >From a quick glance (and be warned: I've yet to write even Hello World in Java), Luke's UBF decoder seems to lack caching support(*), and Jon's decoder lacks support for binaries; I'm also unsure about whether Jon's decoder handlers escaping properly, but Luke's does. If you take the union of the two, you probably have a complete decoder, but they don't seem totally compatible to me. ;) Someone else with more knowledge of Java will perhaps see things differently. /Uffe (*) This is only a problem if the other side uses caching. Joe's Erlang-based UBF encoder will take advantage of caching, so a corresponding decoder will of course have to as soon as there is something cachable in the messages. -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From vlad_dumitrescu@REDACTED Tue Apr 15 11:29:08 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Tue, 15 Apr 2003 11:29:08 +0200 Subject: records generated from UBF Message-ID: Hi, Just a quick and silly question: for me the most interesting part of UBF is the contract checker; it could also be used with normal Erlang messages, not only with UBF - the question is: why not do it like this? I think that it would be very useful (and also super-cool) if such a contract-checker could be introduced between any two processes, transparently. best regards, Vlad _________________________________________________________________ Hitta r?tt k?pare p? MSN K?p & S?lj http://www.msn.se/koposalj From etxuwig@REDACTED Tue Apr 15 12:58:59 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Tue, 15 Apr 2003 12:58:59 +0200 (MEST) Subject: records generated from UBF In-Reply-To: Message-ID: On Tue, 15 Apr 2003, Vlad Dumitrescu wrote: >Hi, > >Just a quick and silly question: for me the most >interesting part of UBF is the contract checker; it could >also be used with normal Erlang messages, not only with UBF >- the question is: why not do it like this? > >I think that it would be very useful (and also super-cool) >if such a contract-checker could be introduced between any >two processes, transparently. The contract checker consists of two parts (I think -- I haven't really studied that part of the code in depth): - A middle-man process that keeps track of the server's state and checks incoming and outgoing messages. This process calls known helper functions in the server's callback module in order to check the message. - A parse transform that reads the contract and inserts said helper functions in the server callback module. The helper functions are: + contract_name() -> string() + contract_states() -> [atom()] + contract_types() -> [atom()] + contract_state(S) -> [{input,type(),type()} | {event,type()}] + contract_anystate() -> [type()] + contract_type(Type) -> type() Thus, the contract checker depends on UBF(B), the type definitions, and UBF(C), the state machine specification, but not on UBF(A), the encode/decode scheme. One could most likely design a UBFish gen_server that implements the UBF contract checking, but skips the encode/decode part. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From vlad_dumitrescu@REDACTED Tue Apr 15 13:16:19 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Tue, 15 Apr 2003 13:16:19 +0200 Subject: records generated from UBF Message-ID: >From: Ulf Wiger > >Thus, the contract checker depends on UBF(B), the type >definitions, and UBF(C), the state machine specification, >but not on UBF(A), the encode/decode scheme. > >One could most likely design a UBFish gen_server that >implements the UBF contract checking, but skips the >encode/decode part. Yes, of course, that's what I meant. I keep thinking of UBF as UBF(A), because (B) and (C) are really very weakly connected to it - any encoding would do. regards, Vlad _________________________________________________________________ Hitta r?tt p? n?tet med MSN S?k http://search.msn.se/ From Marc.Vanwoerkom@REDACTED Tue Apr 15 13:33:24 2003 From: Marc.Vanwoerkom@REDACTED (Marc Ernst Eddy van Woerkom) Date: Tue, 15 Apr 2003 13:33:24 +0200 (MEST) Subject: multi precision arithmetic Message-ID: <200304151133.h3FBXO402935@bonsai.fernuni-hagen.de> Hi list, I have a task which involves writing a small arithmetics lib (+ - * / < = >) that should be able to calculate exact results for a given number of digits behind the radix point and is able to handle digits from different (integer) bases. Correctness is more important than speed or efficient memory usage. To my big surprise I found no existing lib or package so far that meets these requirements. (See references for what I looked at) In some cases I was not really sure, because I had trouble to understand the available docs. The existing software has a strong bias on efficiency or efficent memory usage (to handle as large numbers as possible). Most applications seem to be from cryptology or algorithmic number theory. Another surprise was to find such software included in the web scripting language PHP, obviously I paid no close attention to the term "base64 encoding" :) One of systems I had a quick look at was Erlang, because of the example of calculation n! with obvious more than standard precision in the introduction. The specs http://www.erlang.org/download/erl_spec47.ps.gz tell me that what I look for is a bignum. Where can I find some docs on what is implemented in the present Erlang/OTP releases? Regards, Marc References ---------- [Bernstein] http://cr.yp.to/papers/m3.dvi [BigNum] http://www.mit.edu/afs/athena.mit.edu/contrib/bignum [FreeBSD Ports] http://www.freebsd.org/ports/math.html [GNU MP] http://www.swox.com/gmp [Google] http://www.google.com [Howell] http://www.cis.ksu.edu/~howell/calculator/calc.html [Knuth] Knuth, Vol. 2, Kapitel 4 [LiDIA] http://www.informatik.tu-darmstadt.de/TI/LiDIA [LiDIA 2] http://www.math.psu.edu/local_doc/LiDIA/node25.html [Maple] http://www.maplesoft.com [MuPAD] http://www.mupad.de [Octave] http://www.octave.org [PARI-GP] http://www.math.u-psud.fr/~belabas/pari.html [Zheng] http://www.math.uwaterloo.ca/~wwzheng/62/62.html [Zimmermann] http://www.loria.fr/~zimmerma/bignum/compnew.ps.gz [Zimmermann2] http://www.loria.fr/~zimmerma/bignum From kent@REDACTED Tue Apr 15 15:42:59 2003 From: kent@REDACTED (Kent Boortz) Date: 15 Apr 2003 15:42:59 +0200 Subject: multi precision arithmetic In-Reply-To: <200304151133.h3FBXO402935@bonsai.fernuni-hagen.de> References: <200304151133.h3FBXO402935@bonsai.fernuni-hagen.de> Message-ID: Marc Ernst Eddy van Woerkom writes: > I have a task which involves writing a small arithmetics lib > (+ - * / < = >) that should be able to calculate exact results > for a given number of digits behind the radix point and is > able to handle digits from different (integer) bases. > > Correctness is more important than speed or efficient memory > usage. I'm I correct that you want to calculate things like 0x34FA.FF21 * 100.566 ? And that you can use any programming language? You can probably use the rational numbers in the GMP C library, i.e. first convert your numbers to rational numbers, perform the calculations and convert it back to your format. See http://www.swox.com/gmp/manual/Rational-Number-Functions.html Writing a small package in Erlang to do rational number arithmetics without any demands on speed is probably a fun exercise but I think some operations like '<' and '=' on rational numbers are not as trivial as they may seem as first. The operands need to be canonicalized, kent 0x34FA.FF21 * 100.566 => (0x34FAFF21 / 16**4) * (100566 / 10**3) => (888864545 / 16**4) * (100566 / 10**3) => (888864545 * 100566) / (16**4 * 10**3) . . From vlad_dumitrescu@REDACTED Tue Apr 15 16:25:43 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Tue, 15 Apr 2003 16:25:43 +0200 Subject: records generated from UBF Message-ID: Since the topic came up... :-) I like the programming-by-contract idea very much. I have though some wonderings about UBF(B): - in a real-life environment, there are more than two cooperating instances, and also the 'client' and 'server' roles may be fuzzy. Also a request may not be mapped to a succesion of query-answer message pairs. As far as I can see, UBF(B) can't handle other cases than 1-to-1 strict client-to-server. - trying to solve the issues I mentioned before makes everything very messy, but at the same time it makes a solution more valuable. If I am not confused, the result would be something of a mix between SDL and MSC which I think was tried (at least as a thought experiment) for Erlang, without too good results. One of the big problems of using MSC (and SDL) is that really useful tools are commercial and cost heaps. The free ones I found are okay, up to a point - on the other hand they can be extended. Maybe it would be interesting think about that? best regards, Vlad _________________________________________________________________ L?ttare att hitta dr?mresan med MSN Resor http://www.msn.se/resor/ From luke@REDACTED Tue Apr 15 16:44:01 2003 From: luke@REDACTED (Luke Gorrie) Date: 15 Apr 2003 16:44:01 +0200 Subject: records generated from UBF In-Reply-To: References: Message-ID: Ulf Wiger writes: > There are two Java implementations that I know of. Luke's > Java client that's included in Joe's care package, and Jon > ?kerg?rden's Athletics client prototype. At the last Erlang conference Joe mentioned that somebody in New Zealand had also done a Java implementation. I think he said it included a contract-checker and everything. I don't know if it's available, or if my memory is failing me. I haven't looked at Jon's code, but I guess it's more up-to-date than mine, having been used in a real system. So I'll assume nobody needs any new features in my Java client unless I hear otherwise. Cheers, Luke From Marc.Vanwoerkom@REDACTED Tue Apr 15 16:57:02 2003 From: Marc.Vanwoerkom@REDACTED (Marc Ernst Eddy van Woerkom) Date: Tue, 15 Apr 2003 16:57:02 +0200 (MEST) Subject: multi precision arithmetic In-Reply-To: (message from Kent Boortz on 15 Apr 2003 15:42:59 +0200) Message-ID: <200304151457.h3FEv2t04808@bonsai.fernuni-hagen.de> > 0x34FA.FF21 * 100.566 Yes. > ? And that you can use any programming language? Of course. The final implementation is in a language so outdated I don't dare to mention it here. :) > You can probably use the rational numbers in the GMP C library I would rather go for their integers which are some [sign, a_n, .. , a_0, a_-1, .., a_-k] representation. a_i is the coefficient/digit to b^i. k ist the number of guaranteed digits behind the radix point, in case of non terminating divisions like 1/3. But GNU bc and also GMP (if I am not wrong) seem to do the calculation in decimal base and do base conversions before and after. The problem is precision (k or scale) one tells that software to guarantee is given for decimal rounding: $bc scale=10 ibase=16 AF.F 175.9375000000 obase=10 # note this means hex 10 = dec 16! AF.F AF.F0000000 # 10 digits dec seen to be about 8 digits hex scale=1 AF.F # my input AF.E # output 175.9 because this is 1 digit *decimal* rounding! A workaround is a formula that tells you how many digits precision in the intended base are equivalent to p digits in decimal representation: t = CEIL((p * log(10) / log(base))) + 3 Funny is that I found nothing that does the maths directly in base 29 for example. > Writing a small package in Erlang to do rational number arithmetics > without any demands on speed is probably a fun exercise I just want an independend implementation for testing purposes. But what is curious with Erlang is that it has already some rudimenatary aribitrary precision maths built in. I just don't find the docs and I don't know why it was put in the first place because it seems to feature just a little bit of the usual maths of that kind. Regards, Marc From andrew@REDACTED Tue Apr 15 19:37:09 2003 From: andrew@REDACTED (andrew cooke) Date: Tue, 15 Apr 2003 13:37:09 -0400 (CLT) Subject: multi precision arithmetic In-Reply-To: <200304151457.h3FEv2t04808@bonsai.fernuni-hagen.de> References: <200304151457.h3FEv2t04808@bonsai.fernuni-hagen.de> Message-ID: <1093.200.27.214.82.1050428229.squirrel@127.0.0.1> Marc Ernst Eddy van Woerkom said: [...] > Funny is that I found nothing that does the maths directly in base 29 > for example. [...] But you wouldn't expect that because it means implementing every mathematical function (more or less) to work in arbitrary base. Surely it's much less work to write the functions in a fixed base (2 or 10 or 16 or whatever) and then convert (I guess no-one starts out thinking they will only want addition :o) Or maybe I misunderstood? Andrew -- http://www.acooke.org/andrew From cpressey@REDACTED Tue Apr 15 20:06:08 2003 From: cpressey@REDACTED (Chris Pressey) Date: Tue, 15 Apr 2003 13:06:08 -0500 Subject: moving general-purpose functions from httpd_util to stdlib In-Reply-To: <003501c302e3$ba33e220$8300a8c0@virding.org> References: <200304140608.h3E68si01418@cbe.ericsson.se> <003501c302e3$ba33e220$8300a8c0@virding.org> Message-ID: <20030415130608.6378f6eb.cpressey@catseye.mb.ca> Thanks, everybody. But I have to apologize for that bad example. The 'error' is a red herring that clouds the issue. The question is more about whether it is wiser, in general, to write "open" or "closed" cases. A (possibly) better example: % "open" case case A > B of true -> 41; _ -> 42 end % "closed" case case A > B of true -> 41; false -> 42 end % "let-it-crash" style - seems almost like a different problem case catch begin true = A > B, 41 end of {'EXIT', Reason} -> 42; Result -> Result end -Chris On Tue, 15 Apr 2003 02:12:39 +0200 "Robert Virding" wrote: > ----- Original Message ----- > From: "Bengt Kleberg" > To: > Sent: Monday, April 14, 2003 8:08 AM > Subject: Re: moving general-purpose functions from httpd_util to > stdlib > > > > > > > Date: Mon, 14 Apr 2003 00:01:55 -0500 > > > From: Chris Pressey > > ...deleted > > > > > This brings up one of those burning questions of our times - that > > > is, what exactly "defensive programming" means in the context of > > > Erlang. > > > > > > Say you have a function foo() that can return either an integer or > > > the atom 'error'. > > > > an alternative to this problem is described by Richard Carlsson: > > > > - A function should *not* return wrapped values like > > {ok,Value}/{error,Reason} to indicate success or > > failure. The assumed behaviour should be success, > > and failures should be signalled by exceptions, > > as described below. > > I think I would try to qualify that a little more. It depends on what > type of failure you mean. I would generally say that bad argument type > or values should generate an exit so it is quite clear that Chris's > hex conversion functions should only return the value and exit on > failure. However, there are many cases where the non-success > case does not really represent an error and then it should not > generate an exit but use qualified return values like > {ok,V}/{error,R}. Maybe the convention to use ok/error was badly > chosen and we should have used yes/no but I think it would be > worse to try and have two, or more, "conventions". Better to > have one and try to explain how it is used. > > This is why most of the original, older libraries at least very rarely > check arguments types and values but just assume they are > correct and otherwise exit. As do most bifs. You can't do anything > sensible if the arguments are all wrong. > > Another example would be file:open. As I envisaged when I wrote > it was that if the arguments were of the wrong type or had illegal > values ('creat') then it should exit. However, not being able to > open the file I didn't really see as an error so it returned qualified > values to indicate this. What it exactly does now I don't know. > > Not everyone agreed with me. > > Basically there are errors and errors. > > Robert > From valentin@REDACTED Tue Apr 15 22:43:45 2003 From: valentin@REDACTED (Valentin) Date: Tue, 15 Apr 2003 22:43:45 +0200 Subject: Fw: moving general-purpose functions from httpd_util to stdlib Message-ID: <006901c3038f$b767b6a0$01010d0a@moneymaker> If one has to live in two worlds, i.e. Erlang and C++, is there a better way to integrate these environments (in a consistent way) without using "normalized" returned values, like {true, Value} or {false, ErrMsg}? Valentin. From eleberg@REDACTED Wed Apr 16 06:59:51 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Wed, 16 Apr 2003 06:59:51 +0200 (MEST) Subject: moving general-purpose functions from httpd_util to stdlib Message-ID: <200304160459.h3G4xpi24924@cbe.ericsson.se> > Date: Tue, 15 Apr 2003 13:06:08 -0500 > From: Chris Pressey ...deleted > herring that clouds the issue. The question is more about whether it is > wiser, in general, to write "open" or "closed" cases. > > A (possibly) better example: > > % "open" case > case A > B of > true -> > 41; > _ -> > 42 > end > > % "closed" case > case A > B of > true -> > 41; > false -> > 42 > end i think that your ''closed'' case is the one i use. given a finite (2) set of results i match them all. > % "let-it-crash" style - seems almost like a different problem > case catch begin > true = A > B, > 41 > end of > {'EXIT', Reason} -> > 42; > Result -> > Result > end here you have lost me. i thought the ''closed'' case was the ''let-it-crash'' style. and that one would guard oneself against crashes by doing: case catch (A > B) of true -> 41; false -> 42; _Other -> 42 end i understand this is not what you mean, but fail to understand what it is you do mean. sorry. bengt From james@REDACTED Thu Apr 10 04:51:40 2003 From: james@REDACTED (James Hague) Date: Wed, 9 Apr 2003 21:51:40 -0500 Subject: OTP development, was Re: Gaga about bifs Message-ID: <3E9495EC.2153.1175DD@localhost> Ulf Wiger wrote: >I'm not aware of that many mission-critical middleware products that >are available as Open Source (at least not products that are more >open and "interactive" than OTP), so there are few references on >how to do this properly That's a very good point, one that I hadn't thought about. Erlang is odd in this respect, being so directly connected with commercial products, but that's also maybe it's biggest advantage. I can certain understand being conservative in some ways. At the same time, the floating point improvements that went into R8 didn't follow this rule, at least it doesn't appear that they didn't (someone correct me if I'm wrong). I was under the impression that they were added specifically for the benefit of Wings3D. James From james@REDACTED Wed Apr 16 04:11:01 2003 From: james@REDACTED (James Hague) Date: Tue, 15 Apr 2003 21:11:01 -0500 Subject: Top Ten Lists Message-ID: <3E9C7565.26683.174DC7@localhost> Here's my list, roughly ordered by impact on the current system: 1. Saving of settings (window position & size, toolbar) between werl sessions. 2. BEAM documentation. 3. Smaller, simpler Erlang distribution. 4. SAE for all platforms. 5. Cleaner driver interface. The runtime system should fill-in the dispatch table (by looking for exported functions), not the driver. 6. Truly constant data structures (ver() -> "Version 2.00". should not build a list). 7. Bit-syntax extensions. 8. An alternative to records. 9. Garbage collection of atoms, even if manually activated. Not even ten items! From raimo.niskanen@REDACTED Wed Apr 16 11:59:20 2003 From: raimo.niskanen@REDACTED (Raimo Niskanen) Date: Wed, 16 Apr 2003 11:59:20 +0200 Subject: otp SO_BSDCOMPAT problems with recent Linux development kernels References: <200304071456.h37EuYo2002982@harpo.it.uu.se> Message-ID: Yes, please. Can you give us a runtime test? / Raimo Niskanen, Erlang/OTP, Ericsson AB mikpe@REDACTED wrote: > Running OTP on a recent Linux development kernel results > in the kernel log quickly filling up with messages like: > > process `beam' is using obsolete setsockopt SO_BSDCOMPAT > > erts/emulator/drivers/common/inet_drv.c sets this option. > However, it is a no-op in the current stable Linux kernels > (2.4) and the development kernel recently obsoleted it. > > The inet_drv.c code setting this option should either be > removed, since the option has no effect in non-ancient kernels, > or it should be restricted to 2.2 and older kernels. > > I'll leave it to the OTP networking people to decide what > to do about this. I can contribute code for the kernel > version test needed at runtime, if you want to continue > using the option for older kernels, > > /Mikael > The HiPE team From bernardp@REDACTED Wed Apr 16 13:56:16 2003 From: bernardp@REDACTED (Pierpaolo BERNARDI) Date: Wed, 16 Apr 2003 13:56:16 +0200 Subject: A bug. References: <4.2.2.20030413233013.00d77e20@duomark.com> Message-ID: <02a201c3040f$300106a0$05f06850@c1p4e3> Hello, this looks like a serious bug. I'm using OTP R9B on windows. Given this function: instr_forms() -> [{add, "Add", [il_UISA], if_XO, [field_D,field_A,field_B,field_OE,field_Rc], %% 1111111111222222222233 %%01234567890123456789012345678901 2#01111100000000000000001000010100 }, ... %%% 347 tuples in total, all similar to the first one. ]. The list returned is corrupted. The last 5 items are not there and there are random characters: 59> hd(lists:reverse(risk_bug_0:instr_forms())). 115 The same list, if put in a data file and read from there is read fine, looks like the problem is not in the parser. The source which reproduces this is available here: http://space.virgilio.it/romebern/ppcbug.tgz As a secondary issue, compiling this simple function takes about 10 minutes. Before someone suggests it: yes, putting the list in a file and reading it from there would be better. I have already done this. Cheers P. From etxuwig@REDACTED Wed Apr 16 14:18:24 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Wed, 16 Apr 2003 14:18:24 +0200 (MEST) Subject: Dr Dobb's mention of Erlang Message-ID: http://www.ddjembedded.com/languages/erlang/ The Dr Dobb's Embedded Systems web page lists the following programming languages under the "languages" heading: C/C++, Java, Ada, Erlang, Forth, Eiffel, Pascal (in that order). On Erlang, Dr Dobb writes the following: "The Erlang language started life as a proprietary application development language within Ericsson Telecommunications in Sweden. In 1998, Ericsson decided to release the language, tools and libraries into the Open Source community. This is significant, since despite a quirky syntax, Erlang is a powerful development environment for real time applications. Ericsson's own telephony switches are programmed in the language. There is an active group using Erlang for some very interesting things, indeed. Couple Erlang with XML-RPC (as one project is doing), and you have some very interesting possibilities for distributed embedded systems. The system is a tad large for the smallest embedded applications ? you generally need 16MB and a MTD to run the system." /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From bernardp@REDACTED Wed Apr 16 14:55:08 2003 From: bernardp@REDACTED (Pierpaolo BERNARDI) Date: Wed, 16 Apr 2003 14:55:08 +0200 Subject: Dr Dobb's mention of Erlang References: Message-ID: <031f01c30417$cee244c0$05f06850@c1p4e3> From: "Ulf Wiger" > This is significant, since despite a quirky syntax, Erlang A quirky syntax??? > The system is a tad large for the smallest embedded > applications ? you generally need 16MB and a MTD to run the > system." What is an MTD? P. From daniel.neri@REDACTED Wed Apr 16 16:45:38 2003 From: daniel.neri@REDACTED (Daniel =?iso-8859-1?q?N=E9ri?=) Date: Wed, 16 Apr 2003 14:45:38 +0000 Subject: Dr Dobb's mention of Erlang References: <031f01c30417$cee244c0$05f06850@c1p4e3> Message-ID: <87r882ijql.fsf@fnord.local.sigicom.com> "Pierpaolo BERNARDI" writes: >> The system is a tad large for the smallest embedded applications ? >> you generally need 16MB and a MTD to run the system." > > What is an MTD? Something like this, I assume: http://www.linux-mtd.infradead.org/ Regards, --Daniel From rvg@REDACTED Wed Apr 16 15:57:48 2003 From: rvg@REDACTED (Rudolph van Graan) Date: Wed, 16 Apr 2003 15:57:48 +0200 Subject: String encoding/decoding Message-ID: <630C1976EE416B44A0F38020D67F578816A34A@galileo.ifoni.com> Hi all, A couple of newbie questions here... Hope you can help Suppose you have a string, for which the Hex representation looks something like this: 021234053132333435 In reality the string is coded as this: Byte 1: Length of Word [2 byte unsigned] Bytes 2,3: High Byte, Low Byte of unsigned work Byte 4: Length of string to following Bytes 5-9: A 5 character string So if I want to decode it, I would usually write some code that looks like this [in pseudocode, doesn't imply any language] Len1 = String.GetByte(1) //Returns a single byte Word1 = String.GetWord(Len1) //Returns a word of len vLen1 Len2 = String.GetByte(1) //Returns a single byte String1 = String.GetString(vLen2) //Returns the string "12345" Now, my question is this. If I want to write an elegant module in erlang, that decodes a complex string into its members [members can be any type, being byte, word, string, etc etc] into an erlang structure, how would I do that? We don't use ASN.1, so my question deals specifically with raw strings. You can assume that the string is an erlang list and that the output must be an erlang tuple. Also, I would like to do exactly the reverse as well - generate these strings from tuples. I can imagine needing a function that takes 1/2/4 integers [byte values] from the list and that builds a single 32bit signed/unsigned int and also the reverse. The above example is quite simplistic, my typical strings would contain a number of encoded elements, the structure of which is known. Any ideas or help would be really appreciated! Regards, Rudolph van Graan From per.gustafsson@REDACTED Wed Apr 16 16:25:35 2003 From: per.gustafsson@REDACTED (Per Gustafsson) Date: Wed, 16 Apr 2003 16:25:35 +0200 (MET DST) Subject: String encoding/decoding In-Reply-To: <630C1976EE416B44A0F38020D67F578816A34A@galileo.ifoni.com> References: <630C1976EE416B44A0F38020D67F578816A34A@galileo.ifoni.com> Message-ID: One of the things that you could use is the bit syntax, what you have then is a binary and you can decode that into integer, floats and other binaries like this: <> = Binary, This makes A into an integer consisting of the first 16 bits in the binary, Length becomes an integer consisting of the next 8 bits and NewBinary becomes a binary that contains the rest of the bits in the original binary. The bit syntax is documented in the erlang extensions after 4.4. To turn a list of characters into a binary you can use list_to_binary(List). Per Gustafsson On Wed, 16 Apr 2003, Rudolph van Graan wrote: > Hi all, > > A couple of newbie questions here... Hope you can help > > Suppose you have a string, for which the Hex representation looks > something like this: > > 021234053132333435 > > In reality the string is coded as this: > > Byte 1: Length of Word [2 byte unsigned] > Bytes 2,3: High Byte, Low Byte of unsigned work > Byte 4: Length of string to following > Bytes 5-9: A 5 character string > > So if I want to decode it, I would usually write some code that looks > like this [in pseudocode, doesn't imply any language] > > Len1 = String.GetByte(1) //Returns a single byte > Word1 = String.GetWord(Len1) //Returns a word of len vLen1 > Len2 = String.GetByte(1) //Returns a single byte > String1 = String.GetString(vLen2) //Returns the string "12345" > > Now, my question is this. If I want to write an elegant module in > erlang, that decodes a complex string into its members [members can be > any type, being byte, word, string, etc etc] into an erlang structure, > how would I do that? We don't use ASN.1, so my question deals > specifically with raw strings. You can assume that the string is an > erlang list and that the output must be an erlang tuple. Also, I would > like to do exactly the reverse as well - generate these strings from > tuples. > > I can imagine needing a function that takes 1/2/4 integers [byte values] > from the list and that builds a single 32bit signed/unsigned int and > also the reverse. The above example is quite simplistic, my typical > strings would contain a number of encoded elements, the structure of > which is known. > > Any ideas or help would be really appreciated! > > Regards, > > Rudolph van Graan > From earlyriser@REDACTED Wed Apr 16 16:41:25 2003 From: earlyriser@REDACTED (Sean Hinde) Date: Wed, 16 Apr 2003 15:41:25 +0100 Subject: Inets 3.0.1 and 3.0.3 bug Message-ID: <7FC84BC3-7019-11D7-AAAC-000393A45C3C@mac.com> The following esi callback generates broken HTTP test1(Env, []) -> io:format("Env:~p~n",[Env]), ["", "", "Test1", "", "", "

    Erlang Body

    ", "

    Stuff

    ", "", ""]. The problem is that inets does not add the empty line at the end of the headers. The following patch fixes this case, though I haven't run any other regression tests. Interestingly the only browser I found which actually still managed to load the page was IE on Windows. I can't imagine what algorithm they used to figure this out.. --- httpd_response.erl.orig Mon Apr 14 18:41:28 2003 +++ httpd_response.erl Wed Apr 16 15:38:44 2003 @@ -415,7 +415,7 @@ {ok, Body} -> Header = httpd_util:header(StatusCode,Info#mod.connection) ++ - "Content-Length:" ++ content_length(Body), + "Content-Length:" ++ content_length(Body) ++"\r\n", httpd_socket:deliver(Type, Sock, [Header, Response]); {error, Reason} -> From matthias@REDACTED Wed Apr 16 16:55:24 2003 From: matthias@REDACTED (Matthias Lang) Date: Wed, 16 Apr 2003 16:55:24 +0200 Subject: Dr Dobb's mention of Erlang In-Reply-To: <031f01c30417$cee244c0$05f06850@c1p4e3> References: <031f01c30417$cee244c0$05f06850@c1p4e3> Message-ID: <16029.28380.429190.164618@antilipe.corelatus.se> Pierpaolo BERNARDI writes: > > This is significant, since despite a quirky syntax, Erlang > A quirky syntax??? I'd guess the author was mostly familiar with Java or C++. Java went to some lengths to be syntactically compatible with C++. Many people are lot more comfortable learning a new language if it _appears_ familar. By the time they've figured out that the semantics are different in a few important ways, they've overcome the "shock of the unknown". ;-) Erlang doesn't look like Java or C++, so for someone with that background it looks quirky. > > The system is a tad large for the smallest embedded > > applications ? you generally need 16MB and a MTD to run the > > system." > What is an MTD? Basically flash memory, e.g. a compact flash card. The writeup seems to be a slightly confused version of the FAQ entry, which says that you _can_ squeeze Erlang into 2M of flash. That doesn't mean it's the only way. Just the most common one. Matthias From mickael.remond@REDACTED Wed Apr 16 17:08:47 2003 From: mickael.remond@REDACTED (Mickael Remond) Date: Wed, 16 Apr 2003 17:08:47 +0200 Subject: String encoding/decoding In-Reply-To: <630C1976EE416B44A0F38020D67F578816A34A@galileo.ifoni.com> ("Rudolph van Graan"'s message of "Wed, 16 Apr 2003 15:57:48 +0200") References: <630C1976EE416B44A0F38020D67F578816A34A@galileo.ifoni.com> Message-ID: "Rudolph van Graan" writes: > I can imagine needing a function that takes 1/2/4 integers [byte values] > from the list and that builds a single 32bit signed/unsigned int and > also the reverse. The above example is quite simplistic, my typical > strings would contain a number of encoded elements, the structure of > which is known. > > Any ideas or help would be really appreciated! Did you look at the bit syntax ? This is a pattern matching based encoding/decoding approach to binary management. You can have more details here: http://www.erlang.org/doc/r9b/doc/extensions/bit_syntax.html I hope this does answer to your question. -- Micka?l R?mond http://www.erlang-projects.org/ From erik@REDACTED Wed Apr 16 18:18:15 2003 From: erik@REDACTED (Erik Pearson) Date: Wed, 16 Apr 2003 09:18:15 -0700 Subject: records generated from UBF In-Reply-To: Message-ID: <07357D60-7027-11D7-AC5B-0050E4594D1D@adaptations.com> Thanks Ulf, I hadn't actually looked for the java stuff in the download, since it the java section of the site says that it is not done yet! Well, there it is! It works fine so far. FWIW, this is probably what how I'll attempt to use it first -- What I'm doing is integrating it into my web server scripting language (a very close offshoot of Tcl, from the Jacl tcl implementation, that is, Tcl implemented in Java). I'm starting with just UBF(A), since for my purposes gettting two or more disparate network services (web or other) to exchange information is the first goal. The first bit of work will be to implement a pleasant java/tcl interface so that UBF(A) can be easily scripted on the web server. Since UBF(A) is straightforward, that part should be pretty easy, and is mostly working now. After that, UBF(B)... On the other side of the equation are several other related network services or applications which are variously implemented (currently) in Tcl and CL. Now, the discovery of UBF has prompted me to rethink the usage of Erlang for these same services. (I had been using Erlang, but issues with mnesia caused me to put it aside for a while...) BTW, the very practical and straightforward nature of UBF fits right into why Erlang has always been so appealing (to me.) I'll check back later (after my very short vacation) in if I get some interesting results. Thanks, Erik. On Tuesday, April 15, 2003, at 01:43 AM, Ulf Wiger wrote: > On Tue, 15 Apr 2003, Erik Pearson wrote: > >> I'd like to give UBF a try. It looks really great, and >> thanks for your addition to it. > > Good. (: > > Joe is, I believe, in Iceland this week, undoubtedly > spending quality time trying out all the hot baths there. > Let's see how he wants to play it when he gets back. > Otherwise, you can certainly download whatever he has made > available on his website, and I can send you my modified > version, with absolutely no guarantees. ;-) > > >> What would be great, though, is if someone can share a Java >> implementation (or any other implementation out there, e.g. >> Tcl). I need it to glue together a Java servlet to Erlang >> (or whatever). >> >> From the UBF paper, it appears that a Java implementation >> was largely completed. It would be great to either use that >> code, or start with it and complete the implementation far >> enough to get something working. > > There are two Java implementations that I know of. Luke's > Java client that's included in Joe's care package, and Jon > ?kerg?rden's Athletics client prototype. Jon's Java code can > be downloaded from http://www.it.kth.se/~e98_jak/ > However, Jon is actively working on the code right now, so > the downloadable version is almost certainly outdated. > >> From a quick glance (and be warned: I've yet to write even > Hello World in Java), Luke's UBF decoder seems to lack > caching support(*), and Jon's decoder lacks support for > binaries; I'm also unsure about whether Jon's decoder > handlers escaping properly, but Luke's does. > > If you take the union of the two, you probably have a > complete decoder, but they don't seem totally compatible to > me. ;) Someone else with more knowledge of Java will > perhaps see things differently. > > /Uffe > > (*) This is only a problem if the other side uses caching. > Joe's Erlang-based UBF encoder will take advantage of > caching, so a corresponding decoder will of course have to > as soon as there is something cachable in the messages. > > -- > Ulf Wiger, Senior Specialist, > / / / Architecture & Design of Carrier-Class Software > / / / Strategic Product & System Management > / / / Ericsson AB, Connectivity and Control Nodes > > Erik Pearson Adaptations desk +1 510 527 5437 cell +1 510 517 3122 From hp@REDACTED Wed Apr 16 20:06:01 2003 From: hp@REDACTED (HP Wei) Date: Wed, 16 Apr 2003 14:06:01 -0400 (EDT) Subject: group in regexp ? Message-ID: <200304161806.h3GI61ET018669@wren.rentec.com> > regexp:matches(" first=string second=test end", "first=(.*) second=(.*) end"). {match,[{3,28}]} *** How do I get the matched string in the first group ? first group match = string second group match = test hp From ds.erl@REDACTED Wed Apr 16 21:11:41 2003 From: ds.erl@REDACTED (Daniel Solaz) Date: Wed, 16 Apr 2003 21:11:41 +0200 Subject: trouble with files bigger than 4GB Message-ID: <200304162052.34521@no.siento.las.piennas> hi, anyone out there trying to deal with large files? when given a file that is 4294967297 bytes (4GB + 1 byte) long, file:read_file_info() incorrectly reports a file size of 1 byte file:position(F, {eof, 0}) returns {ok, 1} files bigger than 2GB but smaller than 4GB work fine I'm using R9B-1 on FreeBSD 4.6 for intel on Solaris 8 for intel, R9B-1 refuses to file:read_file_info() or file:open() the file, returning {error, unknown}, and I actually prefer this behavior this difference might (or might not) be due to Solaris requiring fopen64() for large file operations, whereas FreeBSD just uses fopen() is this a known bug? -Daniel From robert.virding@REDACTED Wed Apr 16 23:24:53 2003 From: robert.virding@REDACTED (Robert Virding) Date: Wed, 16 Apr 2003 23:24:53 +0200 Subject: group in regexp ? References: <200304161806.h3GI61ET018669@wren.rentec.com> Message-ID: <006601c3045e$9eb67360$8100a8c0@virding.org> ----- Original Message ----- From: "HP Wei" To: Sent: Wednesday, April 16, 2003 8:06 PM Subject: group in regexp ? > > regexp:matches(" first=string second=test end", > "first=(.*) second=(.*) end"). > {match,[{3,28}]} > > *** How do I get the matched string in the first group ? > > first group match = string > second group match = test You can't do it at the moment, but I am working on an upgrade to the regexp module which includes this. It works but needs some more checking before I release it. Robert From robert.virding@REDACTED Wed Apr 16 23:29:02 2003 From: robert.virding@REDACTED (Robert Virding) Date: Wed, 16 Apr 2003 23:29:02 +0200 Subject: moving general-purpose functions from httpd_util to stdlib References: <200304140608.h3E68si01418@cbe.ericsson.se> <003501c302e3$ba33e220$8300a8c0@virding.org> <20030415130608.6378f6eb.cpressey@catseye.mb.ca> Message-ID: <008401c3045f$34d9d080$8100a8c0@virding.org> Definitely the closed case. The extra cost is negligible and the meaning much clearer, especially if the test is not so obviously a "safe" boolean. Robert ----- Original Message ----- From: "Chris Pressey" To: "Robert Virding" Cc: ; Sent: Tuesday, April 15, 2003 8:06 PM Subject: Re: moving general-purpose functions from httpd_util to stdlib > Thanks, everybody. > > But I have to apologize for that bad example. The 'error' is a red > herring that clouds the issue. The question is more about whether it is > wiser, in general, to write "open" or "closed" cases. > > A (possibly) better example: > > % "open" case > case A > B of > true -> > 41; > _ -> > 42 > end > > % "closed" case > case A > B of > true -> > 41; > false -> > 42 > end > > % "let-it-crash" style - seems almost like a different problem > case catch begin > true = A > B, > 41 > end of > {'EXIT', Reason} -> > 42; > Result -> > Result > end > > -Chris From jay@REDACTED Thu Apr 17 07:30:21 2003 From: jay@REDACTED (Jay Nelson) Date: Wed, 16 Apr 2003 22:30:21 -0700 Subject: Globus Message-ID: <4.2.2.20030416222430.00d82490@duomark.com> Has anyone been talking about Globus? It is the open source approach to grid computing that is backed by IBM and the It seems to me it is an attempt to implement all that erlang already has. I think the big failing is that they are trying to extend the 'familiar languages' to distributed computing. It sounds neat: all the power you can tap into, shared computing etc. But fundamentally you will end up trying to use non- distributed languages to implement distributed code. The infrastructure makes it sound easy, but it doesn't solve the hard problems of distributed algorithms -- just the management aspects of the nodes. See http://www.globus.org/ for info. Are they on to something, way off base, or are they just redoing erlang with some marketing and advertising dollars behind it? jay From vlad_dumitrescu@REDACTED Thu Apr 17 09:18:50 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Thu, 17 Apr 2003 09:18:50 +0200 Subject: Globus Message-ID: IMHO, this is a complementary approach. It is meant to be run over the Internet, which presents challenges that Erlang is also trying to address as an afterthought (most important aspect, I think, is security, but also heterogenity). On the other hand, maybe a good way of solving these problems would be to use an Erlang mesh as the infrastructure, and build a higher-level framework on top of it. Do you happen to know someone that would want to grant a couple of millions for researching this thoroughly? :-) regards, Vlad >From: Jay Nelson >To: erlang-questions@REDACTED >Subject: Globus >Date: Wed, 16 Apr 2003 22:30:21 -0700 > >Has anyone been talking about Globus? It is the open source >approach to grid computing that is backed by IBM and the >It seems to me it is an attempt to implement all that erlang >already has. I think the big failing is that they are trying to >extend the 'familiar languages' to distributed computing. It >sounds neat: all the power you can tap into, shared computing >etc. But fundamentally you will end up trying to use non- >distributed languages to implement distributed code. The >infrastructure makes it sound easy, but it doesn't solve the >hard problems of distributed algorithms -- just the management >aspects of the nodes. > >See http://www.globus.org/ for info. > >Are they on to something, way off base, or are they just >redoing erlang with some marketing and advertising dollars >behind it? > >jay _________________________________________________________________ L?ttare att hitta dr?mresan med MSN Resor http://www.msn.se/resor/ From francesco@REDACTED Thu Apr 17 09:45:09 2003 From: francesco@REDACTED (Francesco Cesarini) Date: Thu, 17 Apr 2003 08:45:09 +0100 Subject: Globus References: <4.2.2.20030416222430.00d82490@duomark.com> Message-ID: <3E9E5B85.8040105@erlang-consulting.com> Distribution was added to Erlang in 1993, a couple of years after the first fast virtual machine was implemented (1991) after the language had stabilized. The successes is due to the transparency with which the new semantics were added and that Klacke got it right with TCP/IP. For scalability, we can obviously thank the fact that concurrency was already there. It will be interesting to see the outcome of this project. (I will not hold my breath). Francesco -- http://www.erlang-consulting.com Jay Nelson wrote: > Has anyone been talking about Globus? It is the open source > approach to grid computing that is backed by IBM and the > It seems to me it is an attempt to implement all that erlang > already has. I think the big failing is that they are trying to > extend the 'familiar languages' to distributed computing. It > sounds neat: all the power you can tap into, shared computing > etc. But fundamentally you will end up trying to use non- > distributed languages to implement distributed code. The > infrastructure makes it sound easy, but it doesn't solve the > hard problems of distributed algorithms -- just the management > aspects of the nodes. > > See http://www.globus.org/ for info. > > Are they on to something, way off base, or are they just > redoing erlang with some marketing and advertising dollars > behind it? > > jay > > From raimo.niskanen@REDACTED Thu Apr 17 10:14:40 2003 From: raimo.niskanen@REDACTED (Raimo Niskanen) Date: Thu, 17 Apr 2003 10:14:40 +0200 Subject: trouble with files bigger than 4GB References: <200304162052.34521@no.siento.las.piennas> Message-ID: Not really a known bug, but I am not surprised. Large file support is fairly new, and not well (if at all :-) tested. There is some way to compile a program for solaris so that fopen() means fopen64(), off_t becomes 64 bit, and so on. If this is done, the code should work. It is perhaps even so that for an Erlang/OTP system built for Solaris8 it works, while not for a system built for Solaris2.5.1. Since the size of off_t is configured when building open source Erlang, on a system with 64 bits off_t - large file operations should work. Have a look in $ERL_TOP/erts/$PLATFORM/config.h for SIZEOF_OFF_T and see if it is 4 (bytes). $PLATFORM is the system name $ERL_TOP/erts/autoconf/config.guess reports when executed. $ERL_TOP is your open source build root. Please try some more file operations on your large file. Try file:open, file:position, file:read, and see if it seems to work on FreeBSD. I am really curious. I have browsed the source and think I see a bug in reading the size field for file:read_file_info - the high word of the size field is ignored, so if other file operations work, it is a small bug fix and can be done for R9C. If no other file operations work, it is a bigger problem and will have to wait. Please let me know. / Raimo Niskanen, Erlang/OTP, Ericsson AB Daniel Solaz wrote: > hi, anyone out there trying to deal with large files? > > when given a file that is 4294967297 bytes (4GB + 1 byte) long, > file:read_file_info() incorrectly reports a file size of 1 byte > > file:position(F, {eof, 0}) returns {ok, 1} > > files bigger than 2GB but smaller than 4GB work fine > > I'm using R9B-1 on FreeBSD 4.6 for intel > > on Solaris 8 for intel, R9B-1 refuses to file:read_file_info() or > file:open() the file, returning {error, unknown}, and I actually prefer > this behavior > > this difference might (or might not) be due to Solaris requiring > fopen64() for large file operations, whereas FreeBSD just uses fopen() > > is this a known bug? > > -Daniel From ermine@REDACTED Thu Apr 17 11:14:47 2003 From: ermine@REDACTED (Anastasia Gornostaeva) Date: Thu, 17 Apr 2003 13:14:47 +0400 Subject: crypto Message-ID: <20030417091447.GA56701@ermine.home> On FreeBSD, we have: bash-2.05b$ erl Erlang (BEAM) emulator version 5.2.3.3 [source] [hipe] [threads:0] Eshell V5.2.3.3 (abort with ^G) 1> crypto:start(). crypto_drv:start : function 9 not initialized {error,{shutdown,{crypto_app,start,[normal,[]]}}} =INFO REPORT==== 17-Apr-2003::13:09:09 === application: crypto exited: {shutdown,{crypto_app,start,[normal,[]]}} type: temporary 2> Why? Please give a good solution. ermine From bernardp@REDACTED Thu Apr 17 11:15:57 2003 From: bernardp@REDACTED (Pierpaolo BERNARDI) Date: Thu, 17 Apr 2003 11:15:57 +0200 Subject: A bug. References: <4.2.2.20030413233013.00d77e20@duomark.com> <02a201c3040f$300106a0$05f06850@c1p4e3> Message-ID: <012e01c304c2$1039dd20$baf06850@c1p4e3> From: "Pierpaolo BERNARDI" > this looks like a serious bug. A followup. The compiled code for my function uses 1034 registers: .... {put_list,{atom,field_A},{x,1033},{x,1033}}. {put_list,{atom,field_D},{x,1033},{x,1033}}. {put_tuple,6,{x,1034}}. {put,{atom,vxor}}. ... while the vm has a hard limit of 1024, from erl_vm.h: #define MAX_REG 1024 /* Max number of x(N) registers used */ If there must be a hard limit on the number of registers, the solution looks simple: the compiler must check that this limit is not violated, and issue an appropriate diagnostic if it is. BTW, it seems to me that the function can be compiled using only a handful of registers, interleaving the creation of the list elements with the creation of the list spine. Alas, I'm not familiar with the compiler and cannot estimate how difficult would be this change. Cheers P. From etxuwig@REDACTED Thu Apr 17 15:21:39 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Thu, 17 Apr 2003 15:21:39 +0200 (MEST) Subject: Application structure In-Reply-To: <200304131051.51677.blitzfeuer@sc.rr.com> Message-ID: My apologies - this reply got stuck in my drafts box for far too long. I see noone else has replied to your question, so I will send what I had written. Sorry if incomplete. /Uffe On Sun, 13 Apr 2003, Walter C. Reel III wrote: >I'm trying to learn Erlang and create a 'Proof of Concept' >system at the same time. I came across the Application >structure in the 'Design Principles' documentation. Would >it be better to start from this structure and work upwards? >It would seem there is a lot of built in functionality that >relates to the application structure. You should probably not try to comply to all of it at once. Some basic initial steps could be taken to ease the transition into more complex stuff later: 1) File structure Organize your code into App/src, App/ebin, etc. Try to keep the organization symmetric, e.g. MyLib/App1 /App2 You do not really have to dive into .app files and boot scripts. If you want ready access to all your code, you can add instructions in a .erlang file in your home directory (assuming you're using UNIX): code:add_paths([".../MyLib/App1/ebin", ...]). 2) Behaviours If you use e.g. gen_server, it will be easier to adapt your code to a supervision structure, and applications, later. 3) Nodes and applications >If so, does a node correspond to an application? The >mnesia schema would go under 'App/priv' or >'App/priv/schema', right? A node is one instance of the Erlang VM. You can run several interconnected VM instances on the same machine, or on different machiens across a network. OTP Applications are a way of grouping modules and processes into a logical entity that can be started, stopped or upgraded together. Each OTP library (stdlib, kernel, inets, etc.) is an application. Some (e.g. stdlib) do not actually start any processes when starting the application (they can still be started and stopped, but mainly for consistency and convenience.) A common setup is to keep the same code on all nodes -- i.e. identical application trees. One very good reason for doing this is to avoid having different versions of the same module in the system. You may also start each node with the same boot script, and rely on the OTP application controller to decide which applications should run where. Given this, naming the mnesia directory e.g. priv/mnesia or priv/schema will work as long as you have only one node. The default name for the mnesia directory is Mnesia.. You can have a similar setup under your priv/ directory, but I would propose instead a habit of creating a ./ directory, and under it, e.g. a mnesia/ directory, logs/, etc. This will allow you to test your system running several nodes on the same machine -- a very nice aspect of Erlang. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From svg@REDACTED Thu Apr 17 15:35:29 2003 From: svg@REDACTED (Vladimir Sekissov) Date: Thu, 17 Apr 2003 19:35:29 +0600 (YEKST) Subject: crypto In-Reply-To: <20030417091447.GA56701@ermine.home> References: <20030417091447.GA56701@ermine.home> Message-ID: <20030417.193529.74756441.svg@surnet.ru> Good day, Try to discover $ERL_TOP/lib/crypto-*.*.*/priv/lib/elibcrypto.so: 1. nm -a elibcrypto.so | grep des_set_key Output must be something like: 00004b80 T des_set_key 2. Look that it can find all libraries it wants: ldd elibcrypto.so 3. If you installed Erlang from ports try to recompile driver manually using patch from http://www.erlang.org/ml-archive/erlang-questions/200303/msg00439.html Best Regards, Vladimir Sekissov ermine> On FreeBSD, we have: ermine> ermine> bash-2.05b$ erl ermine> Erlang (BEAM) emulator version 5.2.3.3 [source] [hipe] [threads:0] ermine> ermine> Eshell V5.2.3.3 (abort with ^G) ermine> 1> crypto:start(). ermine> crypto_drv:start : function 9 not initialized ermine> {error,{shutdown,{crypto_app,start,[normal,[]]}}} ermine> ermine> =INFO REPORT==== 17-Apr-2003::13:09:09 === ermine> application: crypto ermine> exited: {shutdown,{crypto_app,start,[normal,[]]}} ermine> type: temporary ermine> 2> ermine> ermine> Why? Please give a good solution. ermine> ermine> ermine From bparsia@REDACTED Thu Apr 17 19:57:02 2003 From: bparsia@REDACTED (Bijan Parsia) Date: Thu, 17 Apr 2003 13:57:02 -0400 (EDT) Subject: Fwd: forwarded message from Christian Tismer (fwd) Message-ID: Is Erlang up to this challenge? [[[Let me simply end this pamphlete with some simple sentences: Stackless Python is more capable of tasklets switching than any other light-weight threading software package. If anyone disagrees, please give me a runnable counter-example.]]] [Numbers and other details in forwarded message below.] Cheers, Bijan Parsia. Begin forwarded message: [snip] > From: Christian Tismer > Date: Thu Apr 17, 2003 12:40:32 AM US/Eastern > To: stackless@REDACTED, Pythonistas , > python-dev@REDACTED, dev@REDACTED, "Hilmar V. P?tursson" > , Matth?as Gu?mundsson , Mark > Peek , Lonhyn Jasinskyj , > Sam Rushing , Eric Huss , > Arman Bostani , Ingunn J?nsd?ttir > , "Eggert J. Magn?sson" , Hannes > Tismer , Guido van Rossum , Tim > Peters , achtman@REDACTED, Axel Roepke > , Christoph von Stuckrad , > Eric van Riet Paap , Peter Freimuth > , Gerald von Tschirnhaus , Gordon McMillan > , Jean-Claude Wippler , Giorgio > Giacomazzi , Axel Bringenberg berlin.de>, Marita Antony , Laura Lewin > , Laura Creighton , Aaron Watters > , Fredrik Lundh > Subject: Stackless 3.0 alpha 1 at blinding speed > > > Dear community, dear Stackless addicts, dear friends, > > Ich habe Euch wirklich was zu erz?hlen, liebe Freunde, > > I really have to tell you a story! > > During the last four months, I have been struggling with > Stackless Python, and especially with myself and how to > get re-focused on my major project which you know very well. > Some of you might know quite well too how hard this was for me, > especially in the context of my parent's endangeroured health. > This particular problem seems to be solved, > for the moment, so let's celebrate the moment, celebrate the moment! > > Without going into details, I would like to tell you about the > current status of Stackless Python. > For short, like an abstract, Stackless 3.0 is something like an > or-merge of Stackless 1.0 and 2.0 technology. > > Guido, Tim, you both will probably remember my lengthy approaches > to introduce those continuations, years ago, you both convinced > me to drop them, and I did what I was supposed to do. I'm hopefully > a proper citizen, right now. Anyway, you know I'll never really be... > > After a long period of depression, I re-invented Stackless in early > 2002, with a version number of 2.0, denoting that I had dropped all the > 1.0 paradigms (as there are: (1) try to keep compatible, (2) do minimal > changes only, (3) absolutely avoid assembly code at all) > > At the same time, I dismissed all of my Stackless 1.0 code, which was > continuation-based, an absolute no-no in Guido's eyes. I still do think > that TimP wasn't that conformant to this "nono"-statement, after I read > a lot of his comments, especially side-notes on the thread-sig, > but this time Guido's veto was clearly stronger than Tim's arguing, > a thing that doesn't happen so often, but I'm proactively respecting > this, positively. > > Now, after all that rubbish, let's go into facts, which are quite > interesting. > > ------------------------------------------------------------- > > Today, I finished Stackless Python 3.0, alpha 3.0.1! > > First of all, I would like to talk about the new principles. > Yes, no, there are no longer continuations in that sense. > I'm meanwhile convinced that we don't want to support them, > any longer, although I'm happy that Stackless allowed me to > learn *all* any much more about them that that is avalable > on the wor(th|ld) w/h)i(d|l)e net!! > > Q&A: > > Q: What is it about that Stackless 3.0, will this guy never shut up??? > > A: No, he most probably never will, unless he's dead, and this is > another 40 or more years in advance, for heaven's sake. > > Q: So, what is it about that Stackless 3.0 hype around since months? > > A: Simple! Stackless 3.0 has all the hardware switching stuff in it > that Stackless 2.0 had. Stackless 3.0 also incorporates 80% of the > soft switching protocol that Stackless 1.0 had. > But there are a lot of new features: > Stackless has again shown how to marry the impossible with the > imbelievable, and this is the new concept of Stackless 3.0: > There is a maerge between (1.0) soft context switching and (2.0) > hard context switching, which always does the most reasonable thing. > > There are a lot of benefits which stem from this hybrid solution, > which will appear in one of my most recent papers, pretty soon. > > -------------------------------------------------------------- > > BLURB > > Let me simply end this pamphlete with some simple sentences: > Stackless Python is more capable of tasklets switching than any > other light-weight threading software package. > If anyone disagrees, please give me a runnable counter-example. > > Here are some impressive site-specific time measurements, which > especially show, that 20.000.000 cframe tasklet switches per > second are really, really hard to beat. > > Pythonon Win32: > > D:\slpdev\src\2.2\src\Stackless\test>..\..\pcbuild\python taskspeed.py > 10000000 frame switches took 3.83061 seconds, rate = 2610551/s > 10000000 frame softswitches took 2.40112 seconds, rate = 4164718/s > 10000000 cfunction calls took 2.13033 seconds, rate = 4694098/s > 10000000 cframe softswitches took 0.49296 seconds, rate = 20285627/s > 10000000 cframe switches took 1.98907 seconds, rate = 5027486/s > 10000000 cframe 100 words took 3.93737 seconds, rate = 2539768/s > The penalty per stack word is about 0.980 percent of raw switching. > Stack size of initial stub = 14 > Stack size of frame tasklet = 58 > Stack size of cframe tasklet = 35 > > D:\slpdev\src\2.2\src\Stackless\test> > > Python on Debian > > -- Christian Tismer :^) > Mission Impossible 5oftware : Have a break! Take a ride on Python's > Johannes-Niemeyer-Weg 9a : *Starship* http://starship.python.net/ > 14109 Berlin : PGP key -> http://wwwkeys.pgp.net/ > work +49 30 89 09 53 34 home +49 30 802 86 56 pager +49 173 24 18 776 > PGP 0x57F3BF04 9064 F4E1 D754 C2FF 1619 305B C09C 5A3B 57F3 BF04 > whom do you want to sponsor today? http://www.stackless.com/ > > > > -- http://mail.python.org/mailman/listinfo/python-list > > From ermine@REDACTED Thu Apr 17 23:13:13 2003 From: ermine@REDACTED (Anastasia Gornostaeva) Date: Fri, 18 Apr 2003 01:13:13 +0400 Subject: crypto In-Reply-To: <20030417.193529.74756441.svg@surnet.ru> References: <20030417091447.GA56701@ermine.home> <20030417.193529.74756441.svg@surnet.ru> Message-ID: <20030417211313.GA43154@ermine.home> On Thu, Apr 17, 2003 at 07:35:29PM +0600, Vladimir Sekissov wrote: > Good day, These all below is invalid, the problem was -- *new* version of OpenSSL which is in FreeBSD 4.8 (the problem is repeated 100%). My friend help me and made a patch, that works fine. Tomorrow it will be here. ermine > Try to discover $ERL_TOP/lib/crypto-*.*.*/priv/lib/elibcrypto.so: > > 1. nm -a elibcrypto.so | grep des_set_key > > Output must be something like: > > 00004b80 T des_set_key > > 2. Look that it can find all libraries it wants: > > ldd elibcrypto.so > > 3. If you installed Erlang from ports try to recompile driver manually > using patch from > > http://www.erlang.org/ml-archive/erlang-questions/200303/msg00439.html > > > Best Regards, > Vladimir Sekissov > > ermine> On FreeBSD, we have: > ermine> > ermine> bash-2.05b$ erl > ermine> Erlang (BEAM) emulator version 5.2.3.3 [source] [hipe] [threads:0] > ermine> > ermine> Eshell V5.2.3.3 (abort with ^G) > ermine> 1> crypto:start(). > ermine> crypto_drv:start : function 9 not initialized > ermine> {error,{shutdown,{crypto_app,start,[normal,[]]}}} > ermine> > ermine> =INFO REPORT==== 17-Apr-2003::13:09:09 === > ermine> application: crypto > ermine> exited: {shutdown,{crypto_app,start,[normal,[]]}} > ermine> type: temporary > ermine> 2> > ermine> > ermine> Why? Please give a good solution. > ermine> > ermine> ermine From ulf.wiger@REDACTED Fri Apr 18 01:36:18 2003 From: ulf.wiger@REDACTED (Wiger Ulf) Date: Fri, 18 Apr 2003 01:36:18 +0200 Subject: forwarded message from Christian Tismer (fwd) References: Message-ID: <000701c3053a$2579fee0$fd7a40d5@telia.com> Of course, it's always difficult to know exactly what's being tested, and in this case also difficult to know what hardware was used. The erlang processor, ECOMP, could task switch in just a few clock cycles, so it would have been up to it. Regular erlang? Well, on my measly 400 MHz Pentium running Windows 98, I measure about 800,000 context switches/s, which does not compare (even though it probably suffices for most applications). That's two erlang processes yielding to each other in a tight loop. Writing a simple call dispatcher, that calls a function object in each loop (I suspect it's more similar to what Stackless Python does, but don't really know anything about it), I register slightly over 2 million/s. OK, cute, but what is the application? /Uffe From: "Bijan Parsia" > Is Erlang up to this challenge? > > > Let me simply end this pamphlete with some simple sentences: > > Stackless Python is more capable of tasklets switching than any > > other light-weight threading software package. > > If anyone disagrees, please give me a runnable counter-example. > > > > Here are some impressive site-specific time measurements, which > > especially show, that 20.000.000 cframe tasklet switches per > > second are really, really hard to beat. > > > > Pythonon Win32: > > > > D:\slpdev\src\2.2\src\Stackless\test>..\..\pcbuild\python taskspeed.py > > 10000000 frame switches took 3.83061 seconds, rate = 2610551/s > > 10000000 frame softswitches took 2.40112 seconds, rate = 4164718/s > > 10000000 cfunction calls took 2.13033 seconds, rate = 4694098/s > > 10000000 cframe softswitches took 0.49296 seconds, rate = 20285627/s > > 10000000 cframe switches took 1.98907 seconds, rate = 5027486/s > > 10000000 cframe 100 words took 3.93737 seconds, rate = 2539768/s > > The penalty per stack word is about 0.980 percent of raw switching. > > Stack size of initial stub = 14 > > Stack size of frame tasklet = 58 > > Stack size of cframe tasklet = 35 From hp@REDACTED Fri Apr 18 02:17:31 2003 From: hp@REDACTED (HP Wei) Date: Thu, 17 Apr 2003 20:17:31 -0400 (EDT) Subject: forwarded message from Christian Tismer (fwd) Message-ID: <200304180017.h3I0HVL7024987@ram.rentec.com> >From: "Wiger Ulf" >Regular erlang? Well, on my measly 400 MHz Pentium running >Windows 98, I measure about 800,000 context switches/s, For the benefits of those (such as myself) who are not familiar with the term 'context switches', can someone educate us on what this number tells us? (e.g. The larger this number is, the faster the interpreter runs our codes ? ) thanks, --HP From jay@REDACTED Fri Apr 18 03:09:00 2003 From: jay@REDACTED (Jay Nelson) Date: Thu, 17 Apr 2003 18:09:00 -0700 Subject: forwarded message from Christian Tismer (fwd) Message-ID: <4.2.2.20030417180700.00d7a100@duomark.com> Ulf, post your code. I would like to try it on my 500MHz Celeron running RedHat 7.2 and on my 350MHz Mips Cobalt Qube 2. I hope to soon get a mini-ITX with a fanless 500MHz Via Eden. Meaningless benchmarks are always fun to try. jay From blitzfeuer@REDACTED Fri Apr 18 00:50:32 2003 From: blitzfeuer@REDACTED (Walter C. Reel III) Date: Thu, 17 Apr 2003 22:50:32 +0000 Subject: Application structure In-Reply-To: References: Message-ID: <200304172250.32749.blitzfeuer@sc.rr.com> Many thanks. That pointed me in a much better direction. On Thursday 17 April 2003 01:21 pm, Ulf Wiger wrote: > > 1) File structure > > Organize your code into App/src, App/ebin, etc. > Try to keep the organization symmetric, e.g. > MyLib/App1 > /App2 I've noticed (after you mentioned it) that the standard libraries in the OTP distribution adhere to that same type of organization. Although I may be stretching it, would it be safe to say that applications closely resemble the idea of a package in Python or Java? So, just to make sure I understand the terminology, a "system" is a collection of interoperating nodes (which could be running on different machines) and a "node" is an instance of the Erlang VM which could host multiple application/server/etc. processes. Right? (Of course my current place of employment uses those terms but with completely different meanings ;) Cheers, - Walt From spearce@REDACTED Fri Apr 18 07:39:09 2003 From: spearce@REDACTED (Shawn Pearce) Date: Fri, 18 Apr 2003 01:39:09 -0400 Subject: forwarded message from Christian Tismer (fwd) In-Reply-To: <000701c3053a$2579fee0$fd7a40d5@telia.com> References: <000701c3053a$2579fee0$fd7a40d5@telia.com> Message-ID: <20030418053909.GA8182@spearce.org> Wiger Ulf wrote: > Regular erlang? Well, on my measly 400 MHz Pentium running > Windows 98, I measure about 800,000 context switches/s, which > does not compare (even though it probably suffices for most > applications). That's two erlang processes yielding to each other > in a tight loop. Aaaaaah! The world is ending! Erlang has been beat! :-) Move along folks. Nothing to see here. A Python hacker has come up with an even faster way to context switch useless threads. (By useless I have to say: do they support linking? monitors? private heaps? message queues? distributed messaging? floating point context? Doubtful.) Erlang isn't the fastest platform. I think we all know that. We also know that for most high level operations (where Erlang really shines), its very hard to beat the toolkit that comes with Erlang, and the language is actually pretty reasonable to program in (compared to say Java!). > OK, cute, but what is the application? Fast context switching, so Python can implement better threading (but still as useless as ever) then it already has. IMHO, the killer feature to threading is what Erlang already does: no locks, messaging, message queues, linking, monitoring, private heaps. Of course deadlock is still possible, but its a whole heck of a lot easier to write complex threaded code in Erlang and not run into trouble. I really think the POSIX folks (and thus C++ and Java folks, Python, etc) have all got threading wrong from the start. Now I'd be a happy man if I could just find day-time work hacking Erlang code. Seems a tall order here in the states! > From: "Bijan Parsia" > > > Is Erlang up to this challenge? > > > > > Let me simply end this pamphlete with some simple sentences: > > > Stackless Python is more capable of tasklets switching than any > > > other light-weight threading software package. > > > If anyone disagrees, please give me a runnable counter-example. > > > > > > Here are some impressive site-specific time measurements, which > > > especially show, that 20.000.000 cframe tasklet switches per > > > second are really, really hard to beat. > > > > > > Pythonon Win32: > > > > > > D:\slpdev\src\2.2\src\Stackless\test>..\..\pcbuild\python taskspeed.py > > > 10000000 frame switches took 3.83061 seconds, rate = 2610551/s > > > 10000000 frame softswitches took 2.40112 seconds, rate = 4164718/s > > > 10000000 cfunction calls took 2.13033 seconds, rate = 4694098/s > > > 10000000 cframe softswitches took 0.49296 seconds, rate = 20285627/s > > > 10000000 cframe switches took 1.98907 seconds, rate = 5027486/s > > > 10000000 cframe 100 words took 3.93737 seconds, rate = 2539768/s > > > The penalty per stack word is about 0.980 percent of raw switching. > > > Stack size of initial stub = 14 > > > Stack size of frame tasklet = 58 > > > Stack size of cframe tasklet = 35 > -- Shawn. Steinbach's Guideline for Systems Programming: Never test for an error condition you don't know how to handle. From ermine@REDACTED Fri Apr 18 11:43:58 2003 From: ermine@REDACTED (Anastasia Gornostaeva) Date: Fri, 18 Apr 2003 13:43:58 +0400 Subject: crypto In-Reply-To: <20030417091447.GA56701@ermine.home> References: <20030417091447.GA56701@ermine.home> Message-ID: <20030418094358.GA88783@ermine.home> On Thu, Apr 17, 2003 at 01:14:47PM +0400, Anastasia Gornostaeva wrote: > On FreeBSD, we have: > > bash-2.05b$ erl > Erlang (BEAM) emulator version 5.2.3.3 [source] [hipe] [threads:0] > > Eshell V5.2.3.3 (abort with ^G) > 1> crypto:start(). > crypto_drv:start : function 9 not initialized > {error,{shutdown,{crypto_app,start,[normal,[]]}}} > > =INFO REPORT==== 17-Apr-2003::13:09:09 === > application: crypto > exited: {shutdown,{crypto_app,start,[normal,[]]}} > type: temporary > 2> > > Why? Please give a good solution. Patch is for FreeBSD 4.8 and is below. Big thanks to Alexander Timoshenko. ermine diff -ur lib/crypto.old/c_src/Makefile.in lib/crypto/c_src/Makefile.in --- lib/crypto.old/c_src/Makefile.in Fri Apr 18 10:20:27 2003 +++ lib/crypto/c_src/Makefile.in Fri Apr 18 10:20:58 2003 @@ -107,9 +107,9 @@ -u SHA1_Init \ -u SHA1_Update \ -u SHA1_Final \ - -u des_set_key \ - -u des_ncbc_encrypt \ - -u des_ede3_cbc_encrypt + -u DES_set_key \ + -u DES_ncbc_encrypt \ + -u DES_ede3_cbc_encrypt endif # ---------------------------------------------------- diff -ur lib/crypto.old/c_src/crypto_drv.c lib/crypto/c_src/crypto_drv.c --- lib/crypto.old/c_src/crypto_drv.c Fri Apr 18 10:20:27 2003 +++ lib/crypto/c_src/crypto_drv.c Fri Apr 18 10:21:19 2003 @@ -208,9 +208,9 @@ cfs.SHA1_Init = driver_dl_sym(lib_handle, "SHA1_Init"); cfs.SHA1_Update = driver_dl_sym(lib_handle, "SHA1_Update"); cfs.SHA1_Final = driver_dl_sym(lib_handle, "SHA1_Final"); - cfs.des_set_key = driver_dl_sym(lib_handle, "des_set_key"); - cfs.des_ncbc_encrypt = driver_dl_sym(lib_handle, "des_ncbc_encrypt"); - cfs.des_ede3_cbc_encrypt = driver_dl_sym(lib_handle, "des_ede3_cbc_encrypt"); + cfs.des_set_key = driver_dl_sym(lib_handle, "DES_set_key"); + cfs.des_ncbc_encrypt = driver_dl_sym(lib_handle, "DES_ncbc_encrypt"); + cfs.des_ede3_cbc_encrypt = driver_dl_sym(lib_handle, "DES_ede3_cbc_encrypt"); /* Check that all pointer where initialized */ for (i = 0; i < sizeof(crypto_funcs)/sizeof(void*); i++) { From thomasl_erlang@REDACTED Fri Apr 18 13:04:12 2003 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Fri, 18 Apr 2003 04:04:12 -0700 (PDT) Subject: Fwd: forwarded message from Christian Tismer (fwd) In-Reply-To: Message-ID: <20030418110412.97314.qmail@web13304.mail.yahoo.com> --- Bijan Parsia wrote: > Is Erlang up to this challenge? > > [[[Let me simply end this pamphlete with some simple > sentences: > Stackless Python is more capable of tasklets > switching than any > other light-weight threading software package. > If anyone disagrees, please give me a runnable > counter-example.]]] Results at the end. First some comments. 1. The benchmark itself seems kinda meaningless for a claim of being a fast thread package. Where is the IPC cost? The scheduling cost? The process creation cost? etc, etc. (Not to mention realistic conditions ... :-) 2. What was the system being measured? 20 million is sort of a meaningless number without knowing that. 3. What was the benchmarking methodology? Is it an average? A "best of N runs"? What? My system was this: RedHat 8.x Athlon 1300+ with 512 MB of slow memory running out-of-the-box Erlang R9B1. (system cost $400) The program (csw.erl) consists of two processes that yield N times each. The completion time is the difference between earliest start time and latest stop time. Result: csw did AT BEST 6.4 million Erlang context switches per second, and ON AVERAGE 5.8-5.9 million Erlang context switches per second, over a range of parameters (100k-10m context switches per benchmark run). Best, Thomas __________________________________________________ Do you Yahoo!? The New Yahoo! Search - Faster. Easier. Bingo http://search.yahoo.com -------------- next part -------------- A non-text attachment was scrubbed... Name: csw.erl Type: application/octet-stream Size: 2406 bytes Desc: csw.erl URL: From mikael.karlsson@REDACTED Fri Apr 18 13:08:26 2003 From: mikael.karlsson@REDACTED (Mikael Karlsson) Date: Fri, 18 Apr 2003 13:08:26 +0200 Subject: XML database? Message-ID: <200304181308.26906.mikael.karlsson@creado.com> In: http://www.erlang.org/ml-archive/erlang-questions/200208/msg00072.html Ulf Wiger writes: >.. > A short example: I'm working (slowly) on an XML database solution > using fragmented tables. I want all elements in one XML document > to be stored in the same fragment, but all XML documents to be > spread out evenly using a hashing algorithm. The idea is that I > want to control the fragments for one table (xmerldb_obj), and > let the others use the default scheme. > .. Just got curious, is the "plan" to add this to xmerl? /Mikael From alexey@REDACTED Fri Apr 18 14:31:21 2003 From: alexey@REDACTED (Alexey Shchepin) Date: 18 Apr 2003 15:31:21 +0300 Subject: SSL problem Message-ID: <87u1cw56na.fsf@office.sevcom.net> Hi! There is a following problem with SSL module in Erlang. In passive mode you can't send something with ssl:send until another process executes ssl:recv (which not returns until something appears in socket). E.g. in following example you don't receive "123" lines until you send something with 'telnet -z ssl localhost 5555': %%% test_ssl.erl -module(test_ssl). -export([start/0, listen/0]). start() -> ssl:start(), spawn(test_ssl, listen, []). listen() -> {ok, ListenSocket} = ssl:listen(5555, [binary, {packet, 0}, {active, false}, {nodelay, true}, {certfile, "./ssl.pem"}]), {ok, Socket} = ssl:accept(ListenSocket), timer:apply_interval(500, ssl, send, [Socket, "123\n"]), loop(Socket). loop(Socket) -> case ssl:recv(Socket, 0) of {ok, Data} -> loop(Socket) end. From mickael.remond@REDACTED Fri Apr 18 15:05:25 2003 From: mickael.remond@REDACTED (Mickael Remond) Date: Fri, 18 Apr 2003 15:05:25 +0200 Subject: Erlang code reuse model Message-ID: Hello, I am to trying to clarify a little bit the code reuse model in Erlang. There are several approaches that could be emphasized (The classification could probably be refined): - Libraries: You can put together the reuseable part of your code in a set of Erlang modules. - The call backs approach: You create an API that can use any module that respect a given API defined by a set of functions. The reusable parts are put in the API, whereas the specific element of code are defined in a module implementing the API. This approach has been generalized by the introduction of Erlang behaviours. - Applications: You can decide that what you want to implement is a service for other program. You then put the code you want to reuse in a separate application. A good example of this approach is Mnesia. - Anonymous function: This approach can be mixed with the libraries and the call back approach. Anonymous functions can be used to configure a piece of reusable code. This approach allow the developer to create reusable code that are more flexible than reusable code simply using values as parameters. Now, I found difficult to go further in defining the code reuse model of Erlang. I will take an example. Suppose that I want to isolate the piece of code that are commons in every TCP/IP server written in Erlang. The code for that is composed of several Erlang behaviours, under a supervisor. I have at least two approaches to organise the code reuse: - Develop a new behaviour, that can be reuse in OTP project that want to act as a TCP/IP server. - Develop an Application that handle the TCP/IP server part and delegating the processing of the request to specific ad-hoc modules. I would do it as an application, as I think it feels strange to have several processes hidden in a behaviour. What I would like to do is gather your feeling and your best pratices to write a synthesis document on Erlang code reuse. I think this could be helpfull for Erlang newcomers that are used to other languages and try to get into the Erlang way of structuring developments. So, what do you think ? :-) -- Micka?l R?mond http://www.erlang-projects.org/ From hp@REDACTED Fri Apr 18 15:30:41 2003 From: hp@REDACTED (HP Wei) Date: Fri, 18 Apr 2003 09:30:41 -0400 (EDT) Subject: Fwd: forwarded message from Christian Tismer (fwd) Message-ID: <200304181330.h3IDUfL7001748@ram.rentec.com> >> Stackless Python is more capable of tasklets >> switching than any >> other light-weight threading software package. >1. The benchmark itself seems kinda meaningless for a >claim of being a fast thread package. Where is the IPC >cost? The scheduling cost? The process creation cost? >etc, etc. (Not to mention realistic conditions ... :-) >My system was this: RedHat 8.x Athlon 1300+ with 512 >MB of slow memory running out-of-the-box Erlang R9B1. >(system cost $400) >Result: csw did AT BEST 6.4 million Erlang context >switches per second, and ON AVERAGE 5.8-5.9 million >Erlang context switches per second, over a range of >parameters (100k-10m context switches per benchmark >run). I run Thomas's csw.erl on my machine: Sun-Blade-100 1GHz, 512Mb RAM, and SunOS 5.9, Erlang 5.2(R9B1) The result is about 3.1 million CS per second. (A factor two slower than Thomas's result. Perhaps, I have a lot of other stuff running on my machine.) ---------------------------- I myself use python at work instead of perl (the company's standard scripting language) because of its cleaner syntax. I am learning Erlang now because of its simple (reads clear and effective) communication stuff. --HP From ds.erl@REDACTED Fri Apr 18 16:18:07 2003 From: ds.erl@REDACTED (Daniel Solaz) Date: Fri, 18 Apr 2003 16:18:07 +0200 Subject: trouble with files bigger than 4GB In-Reply-To: References: <200304162052.34521@no.siento.las.piennas> Message-ID: <200304181515.42510@no.siento.las.piennas> On Thursday 17 April 2003 10:14 Raimo Niskanen wrote: > There is some way to compile a program for solaris so that fopen() > means fopen64(), off_t becomes 64 bit, and so on. If this is done, > the code should work. It is perhaps even so that for an Erlang/OTP > system built for Solaris8 it works, while not for a system built for > Solaris2.5.1. Yes, this is described in the lfcompile(5) man page. I'll try to hack the appropriate Makefile(s) and recompile so I can check whether this is enough to get the code working, where working means "like in FreeBSD". > Since the size of off_t is configured when building open source > Erlang, on a system with 64 bits off_t - large file operations should > work. Have a look in $ERL_TOP/erts/$PLATFORM/config.h for > SIZEOF_OFF_T and see if it is 4 (bytes). $PLATFORM is the system name > $ERL_TOP/erts/autoconf/config.guess reports when executed. $ERL_TOP > is your open source build root. You're right, off_t is reported to be 4 bytes long. > Please try some more file operations on your large file. Try > file:open, file:position, file:read, and see if it seems to work on > FreeBSD. I am really curious. > I have browsed the source and think I see a bug in reading the size > field for file:read_file_info - the high word of the size field is > ignored, so if other file operations work, it is a small bug fix and > can be done for R9C. If no other file operations work, it is a bigger > problem and will have to wait. Please let me know. Reading the large file buffer by buffer all the way from the beginning works fine; file:position(F, {bof, 4294967296}) returns {ok, 0} BUT the file pointer is actually set to byte 4294967296, as does file:position(F, {eof, 0}) on a 4 GB file. So it seems the problem lies in the code that reports sizes and offsets ignoring the high word of the file size or position. -Daniel From mickael.remond@REDACTED Fri Apr 18 17:28:24 2003 From: mickael.remond@REDACTED (Mickael Remond) Date: Fri, 18 Apr 2003 17:28:24 +0200 Subject: Package support in Erlang: Status ? Message-ID: Hello, I would like to know what is the current status of packages in Erlang ? During the last Erlang User Conference, I had the feeling that the use of package for erlang development was here for feedback from the developers but not yet really approved for industrial project. I do not feel conformtable yet with the package development as it requires to change the syntax for standard module call (You need to use the prefix . to specify that you are refering to the root package). This means that code need to be modified to work with packages. What is the current status ? I have seen that Erik Reitsma was using them successfully in the Erlang SOAP module. Does other developers have adopted it already ? Should the developer use it for new development ? -- Micka?l R?mond http://www.erlang-projects.org/ From hp@REDACTED Sat Apr 19 03:11:09 2003 From: hp@REDACTED (HP Wei) Date: Fri, 18 Apr 2003 21:11:09 -0400 (EDT) Subject: optimization ? Message-ID: <200304190111.h3J1B9tW007274@wren.rentec.com> Hi, I (a newbie in Erlang) am trying to get used to Erlang's way of doing things. I have a small module in the following whose function is to extract a list of subdirectories under the Top directory. It works. But it is a bit slow (5 sec for a specific directory on our machine). Is this the best I can do ?? [In comparision, my old python code generates the list in about 1.8 sec. But that code uses a global variable as the accumulator (Acc), and one recursive function. And that scheme cannot be duplicated in Erlang because of the immutable Variable.] thanks, HP % -----------------test.erl -------------------------- -module(test). -include_lib("kernel/include/file.hrl"). -export([dirs/1]). dirs(Top) -> case file:list_dir(Top) of {ok, Entries} -> dirs(Top, Entries, []); {error, Reason} -> {error, {Top, Reason}} end. dirs(Top, [F|Tail], Acc) -> F2 = Top ++ "/" ++ F, case file:read_link_info(F2) of {ok, FileInfo} when FileInfo#file_info.type == directory -> case dirs(F2) of {error, Reason} -> {error, Reason}; List -> T = [F2|List], dirs(Top, Tail, T ++ Acc) end; Other -> dirs(Top, Tail, Acc) end; dirs(_Top, [], Ack) -> Ack. % ----------------------------------------------- From taj.khattra@REDACTED Sat Apr 19 05:25:00 2003 From: taj.khattra@REDACTED (Taj Khattra) Date: Fri, 18 Apr 2003 20:25:00 -0700 Subject: records generated from UBF In-Reply-To: References: Message-ID: <20030419032500.GA956@localhost.localdomain> On Tue, Apr 15, 2003 at 04:25:43PM +0200, Vlad Dumitrescu wrote: > > One of the big problems of using MSC (and SDL) is that really useful tools > are commercial and cost heaps. The free ones I found are okay, up to a > point - on the other hand they can be extended. Maybe it would be > interesting think about that? > have you tried UBET (available for solaris and windows) ? http://cm.bell-labs.com/cm/cs/what/ubet/index.html -taj From taj.khattra@REDACTED Sat Apr 19 08:03:57 2003 From: taj.khattra@REDACTED (Taj Khattra) Date: Fri, 18 Apr 2003 23:03:57 -0700 Subject: Fwd: forwarded message from Christian Tismer (fwd) In-Reply-To: <200304181330.h3IDUfL7001748@ram.rentec.com> References: <200304181330.h3IDUfL7001748@ram.rentec.com> Message-ID: <20030419060357.GA1777@localhost.localdomain> On Fri, Apr 18, 2003 at 09:30:41AM -0400, HP Wei wrote: > I run Thomas's csw.erl on my machine: > Sun-Blade-100 1GHz, 512Mb RAM, and SunOS 5.9, Erlang 5.2(R9B1) > > The result is about 3.1 million CS per second. > (A factor two slower than Thomas's result. Perhaps, I have a lot of > other stuff running on my machine.) > more likely it's because solaris is slow as molasses ... -taj From richardc@REDACTED Sat Apr 19 12:54:15 2003 From: richardc@REDACTED (Richard Carlsson) Date: Sat, 19 Apr 2003 12:54:15 +0200 Subject: Package support in Erlang: Status ? References: Message-ID: <002101c30662$06d686b0$33bfee82@gnit> ----- Original Message ----- From: "Mickael Remond" To: Sent: Friday, April 18, 2003 5:28 PM Subject: Package support in Erlang: Status ? > I would like to know what is the current status of packages in Erlang > > During the last Erlang User Conference, I had the feeling that the use > of package for erlang development was here for feedback from the > developers but not yet really approved for industrial project. The OTP people have said that the package system is included for evaluation, and if it turns out that people (i.e., you who are reading this) don't like it, it could be removed again. So it's up to you. So far I've had almost no feedback at all from users, so if you read this and have tried using packages, then please do let everybody know what you think! > I do not feel conformtable yet with the package development as it > requires to change the syntax for standard module call (You need to > use the prefix . to specify that you are refering to the root > package). The much preferred method is to simply add an 'import' statement at the top of the module. So e.g, if you want to call the standard library 'lists' module from within a module in a package: -module(com.bigcorp.foo). ... -import(lists). ... f(X) -> ... lists:reverse(...) ... will call 'lists:reverse(...)' instead of the default 'com.bigcorp.lists:reverse(...)'. The prefix form '.lists:reverse(...)' could also be used, as you mention, but this is more of a "final resort" solution (if the imported name is already used), or could be used if you have a one-shot call to some module and don't feel like adding an import statement, but the -import(...) makes it less error prone. So, if you want to move code from the current "flat" namespace into a package namespace, you have to: 1. rename the module, by prefixing a package name 2. add an '-import(Mod)' for each non-package Mod that is being called. and that's it. Note that existing code can call package modules without any changes - for example, you can give a module name as 'com.bigcorp.mycallback' to the good old gen_server, and everything works just as normal. The only real problem I currently know of is the debugger, which has a hard time with the fact that the source file name is not the same as the full module name. I hope I can fix this for the coming R9C release, or just mail a patch to this list. /Richard From ulf.wiger@REDACTED Sat Apr 19 13:42:22 2003 From: ulf.wiger@REDACTED (Wiger Ulf) Date: Sat, 19 Apr 2003 13:42:22 +0200 Subject: forwarded message from Christian Tismer (fwd) References: <4.2.2.20030417180700.00d7a100@duomark.com> Message-ID: <000e01c30668$bdeb8480$fd7a40d5@telia.com> OK, here it is, for what it's worth. tasklets:context(N) will trigger N*2 context switches as two processes run a busy loop each, yielding before each iteration. tasklets:calls(N) will run a dispatch loop, calling a fun() and returning a new fun() for the next iteration. Both functions use timer:tc(). /Uffe ----- Original Message ----- From: "Jay Nelson" To: Sent: den 18 april 2003 03:09 Subject: Re: forwarded message from Christian Tismer (fwd) > Ulf, post your code. I would like to try it on my 500MHz > Celeron running RedHat 7.2 and on my 350MHz Mips > Cobalt Qube 2. I hope to soon get a mini-ITX with a > fanless 500MHz Via Eden. > > Meaningless benchmarks are always fun to try. > > jay > -------------- next part -------------- A non-text attachment was scrubbed... Name: tasklets.erl Type: application/octet-stream Size: 817 bytes Desc: not available URL: From ulf.wiger@REDACTED Sat Apr 19 13:47:01 2003 From: ulf.wiger@REDACTED (Wiger Ulf) Date: Sat, 19 Apr 2003 13:47:01 +0200 Subject: XML database? References: <200304181308.26906.mikael.karlsson@creado.com> Message-ID: <001e01c30669$645c2900$fd7a40d5@telia.com> Well, I wouldn't go so far as to call it a "plan", but I have a hope that this will eventually happen, yes. (: Currently, I'm not working on the XML database at all. I hope to be able to return to it in the foreseeable future. /Uffe ----- Original Message ----- From: "Mikael Karlsson" To: "Ulf Wiger" Cc: Sent: den 18 april 2003 13:08 Subject: XML database? > In: > http://www.erlang.org/ml-archive/erlang-questions/200208/msg00072.html > Ulf Wiger writes: > >.. > > A short example: I'm working (slowly) on an XML database solution > > using fragmented tables. I want all elements in one XML document > > to be stored in the same fragment, but all XML documents to be > > spread out evenly using a hashing algorithm. The idea is that I > > want to control the fragments for one table (xmerldb_obj), and > > let the others use the default scheme. > > .. > > Just got curious, is the "plan" to add this to xmerl? > > /Mikael From ulf.wiger@REDACTED Sat Apr 19 13:58:10 2003 From: ulf.wiger@REDACTED (Wiger Ulf) Date: Sat, 19 Apr 2003 13:58:10 +0200 Subject: Package support in Erlang: Status ? References: <002101c30662$06d686b0$33bfee82@gnit> Message-ID: <001101c3066a$f2e99440$fd7a40d5@telia.com> > -module(com.bigcorp.foo). > ... > -import(lists). > ... > f(X) -> ... lists:reverse(...) ... > > will call 'lists:reverse(...)' instead of the default > 'com.bigcorp.lists:reverse(...)'. I sent a suggestion for a patch to the linter to erlang-patches the other day (no cc to erlang-questions) though. This patch makes the linter issue a warning if it encounters e.g. lists:reverse(...), and there is (a) no '-import(lists).' statement in the module, and (b) there is no lists.beam (presumably comp.bigcorp.lists) in the outdir directory. I've found this to be one of the most common errors related to the the use of packages. With this warning in place, I feel that adding -import clauses does not cause me any problems at all, and the linter will remind me if I've forgotten one. /Uffe ----- Original Message ----- From: "Richard Carlsson" To: ; "Mickael Remond" Sent: den 19 april 2003 12:54 Subject: Re: Package support in Erlang: Status ? > ----- Original Message ----- > From: "Mickael Remond" > To: > Sent: Friday, April 18, 2003 5:28 PM > Subject: Package support in Erlang: Status ? > > > > I would like to know what is the current status of packages in Erlang > > > > During the last Erlang User Conference, I had the feeling that the use > > of package for erlang development was here for feedback from the > > developers but not yet really approved for industrial project. > > The OTP people have said that the package system is included for evaluation, > and if it turns out that people (i.e., you who are reading this) don't like > it, it > could be removed again. So it's up to you. > > So far I've had almost no feedback at all from users, so if you read this > and > have tried using packages, then please do let everybody know what you think! > > > I do not feel conformtable yet with the package development as it > > requires to change the syntax for standard module call (You need to > > use the prefix . to specify that you are refering to the root > > package). > > The much preferred method is to simply add an 'import' statement at the > top of the module. So e.g, if you want to call the standard library 'lists' > module from within a module in a package: > > -module(com.bigcorp.foo). > ... > -import(lists). > ... > f(X) -> ... lists:reverse(...) ... > > will call 'lists:reverse(...)' instead of the default > 'com.bigcorp.lists:reverse(...)'. > The prefix form '.lists:reverse(...)' could also be used, as you mention, > but this > is more of a "final resort" solution (if the imported name is already used), > or > could be used if you have a one-shot call to some module and don't feel like > adding an import statement, but the -import(...) makes it less error prone. > > So, if you want to move code from the current "flat" namespace into a > package namespace, you have to: > > 1. rename the module, by prefixing a package name > 2. add an '-import(Mod)' for each non-package Mod that is being > called. > > and that's it. Note that existing code can call package modules without any > changes - for example, you can give a module name as > 'com.bigcorp.mycallback' > to the good old gen_server, and everything works just as normal. > > The only real problem I currently know of is the debugger, which has a hard > time > with the fact that the source file name is not the same as the full module > name. I hope > I can fix this for the coming R9C release, or just mail a patch to this > list. > > /Richard > From svg@REDACTED Sat Apr 19 13:24:07 2003 From: svg@REDACTED (Vladimir Sekissov) Date: Sat, 19 Apr 2003 17:24:07 +0600 (YEKST) Subject: Package support in Erlang: Status ? In-Reply-To: <002101c30662$06d686b0$33bfee82@gnit> References: <002101c30662$06d686b0$33bfee82@gnit> Message-ID: <20030419.172407.108736967.svg@surnet.ru> Good day, richardc> So far I've had almost no feedback at all from users, so if you read this richardc> and richardc> have tried using packages, then please do let everybody know what you think! I'm using packages and like them a lot so here is my vote for them. Best Regards, Vladimir Sekissov From costel.vrinceanu@REDACTED Sat Apr 19 18:15:31 2003 From: costel.vrinceanu@REDACTED (Costel Vrinceanu) Date: 19 Apr 2003 09:15:31 -0700 Subject: RFC for external term format Message-ID: Has anyone considered putting the external term format into an RFC? From steve@REDACTED Sat Apr 19 18:38:40 2003 From: steve@REDACTED (Steven H. Rogers, PhD.) Date: Sat, 19 Apr 2003 11:38:40 -0500 Subject: Yaws Emacs Mode? In-Reply-To: <001101c3066a$f2e99440$fd7a40d5@telia.com> References: <002101c30662$06d686b0$33bfee82@gnit> <001101c3066a$f2e99440$fd7a40d5@telia.com> Message-ID: <3EA17B90.5070408@shrogers.com> Is there Yaws Emacs mode that highlights both HTML and Erlang? If so, where might I find it? If not, what are other folks doing? Steve -- _ Steven H. Rogers, PhD. <_` email: steve@REDACTED |_> Weblog http://shrogers.com/zope/portal/Members/steve/blog | \ "A language that doesn't affect the way you think about programming is not worth knowing." - Alan Perlis From Chandrashekhar.Mullaparthi@REDACTED Sun Apr 20 04:32:49 2003 From: Chandrashekhar.Mullaparthi@REDACTED (Chandrashekhar Mullaparthi) Date: Sun, 20 Apr 2003 03:32:49 +0100 Subject: Application structure Message-ID: Hi, OTP has it's own Package system similar to what you find in Java - which provides a namespace for your code, so that names of modules don't clash with the names of modules in applications developed by someone else. A crude comparison is that an application is similar to a library when using C, C++ - it's a collection of code which implements certain functionality. You could call a collection of interoperting nodes a "system" - though it is not official :-) You are right about the "node" cheers Chandru -----Original Message----- From: Walter C. Reel III [mailto:blitzfeuer@REDACTED] Sent: 17 April 2003 23:51 To: erlang-questions@REDACTED Cc: Ulf Wiger Subject: Re: Application structure Many thanks. That pointed me in a much better direction. On Thursday 17 April 2003 01:21 pm, Ulf Wiger wrote: > > 1) File structure > > Organize your code into App/src, App/ebin, etc. > Try to keep the organization symmetric, e.g. > MyLib/App1 > /App2 I've noticed (after you mentioned it) that the standard libraries in the OTP distribution adhere to that same type of organization. Although I may be stretching it, would it be safe to say that applications closely resemble the idea of a package in Python or Java? So, just to make sure I understand the terminology, a "system" is a collection of interoperating nodes (which could be running on different machines) and a "node" is an instance of the Erlang VM which could host multiple application/server/etc. processes. Right? (Of course my current place of employment uses those terms but with completely different meanings ;) Cheers, - Walt NOTICE AND DISCLAIMER: This email (including attachments) is confidential. If you have received this email in error please notify the sender immediately and delete this email from your system without copying or disseminating it or placing any reliance upon its contents. We cannot accept liability for any breaches of confidence arising through use of email. Any opinions expressed in this email (including attachments) are those of the author and do not necessarily reflect our opinions. We will not accept responsibility for any commitments made by our employees outside the scope of our business. We do not warrant the accuracy or completeness of such information. From erik@REDACTED Sun Apr 20 05:44:12 2003 From: erik@REDACTED (Erik Pearson) Date: Sat, 19 Apr 2003 20:44:12 -0700 Subject: records generated from UBF In-Reply-To: <07357D60-7027-11D7-AC5B-0050E4594D1D@adaptations.com> Message-ID: <59AEDDDE-72E2-11D7-805D-0050E4594D1D@adaptations.com> After a little more fiddling around, I have a practical question about UBF(A): The representation of a "binary" type is: Int ~blahblah~ Where Int is an integer, and ~ is the delimiter for the binary data, and blahblah is a stream/array of bytes Int long (and the space is 0 or more spaces) In order resolve the ambiguity with regular Int , the otherwise simple parsing becomes more complicated. It seems to me, unnecessarily complex. That is, the parser first determines that there is an int, and then it has to keep going to determine whether it really is an int or whether it will become a binary. What if the binary representation was something like ~ Int ~blahblah~ Then the initial ~ would be a nice and and simple flag for the parser that binary value was coming up. This would be consistent with all of the other simple types, for which the initial byte serves as a flag for the type (" for string, ' for contants, 0-9 or - for number (oops, or binary)...) Finally, just a quick correction to the spec at http://www.sics.se/~joe/ubf/site/ubfa.html I believe the structure should be defined with comma separators rather than just whitespace { Obj1, Obj2, ..., Objn } rather than { Obj1 Obj2 ... Objn } The examples show the comma separators. Thanks, Erik. On Wednesday, April 16, 2003, at 09:18 AM, Erik Pearson wrote: > Thanks Ulf, > > I hadn't actually looked for the java stuff in the download, since it > the java section of the site says that it is not done yet! Well, there > it is! > > It works fine so far. > > FWIW, this is probably what how I'll attempt to use it first -- What > I'm doing is integrating it into my web server scripting language (a > very close offshoot of Tcl, from the Jacl tcl implementation, that is, > Tcl implemented in Java). I'm starting with just UBF(A), since for my > purposes gettting two or more disparate network services (web or > other) to exchange information is the first goal. The first bit of > work will be to implement a pleasant java/tcl interface so that UBF(A) > can be easily scripted on the web server. Since UBF(A) is > straightforward, that part should be pretty easy, and is mostly > working now. After that, UBF(B)... > > On the other side of the equation are several other related network > services or applications which are variously implemented (currently) > in Tcl and CL. Now, the discovery of UBF has prompted me to rethink > the usage of Erlang for these same services. (I had been using Erlang, > but issues with mnesia caused me to put it aside for a while...) > > BTW, the very practical and straightforward nature of UBF fits right > into why Erlang has always been so appealing (to me.) > > I'll check back later (after my very short vacation) in if I get some > interesting results. > > Thanks, > > Erik. > > > On Tuesday, April 15, 2003, at 01:43 AM, Ulf Wiger wrote: > >> On Tue, 15 Apr 2003, Erik Pearson wrote: >> >>> I'd like to give UBF a try. It looks really great, and >>> thanks for your addition to it. >> >> Good. (: >> >> Joe is, I believe, in Iceland this week, undoubtedly >> spending quality time trying out all the hot baths there. >> Let's see how he wants to play it when he gets back. >> Otherwise, you can certainly download whatever he has made >> available on his website, and I can send you my modified >> version, with absolutely no guarantees. ;-) >> >> >>> What would be great, though, is if someone can share a Java >>> implementation (or any other implementation out there, e.g. >>> Tcl). I need it to glue together a Java servlet to Erlang >>> (or whatever). >>> >>> From the UBF paper, it appears that a Java implementation >>> was largely completed. It would be great to either use that >>> code, or start with it and complete the implementation far >>> enough to get something working. >> >> There are two Java implementations that I know of. Luke's >> Java client that's included in Joe's care package, and Jon >> ?kerg?rden's Athletics client prototype. Jon's Java code can >> be downloaded from http://www.it.kth.se/~e98_jak/ >> However, Jon is actively working on the code right now, so >> the downloadable version is almost certainly outdated. >> >>> From a quick glance (and be warned: I've yet to write even >> Hello World in Java), Luke's UBF decoder seems to lack >> caching support(*), and Jon's decoder lacks support for >> binaries; I'm also unsure about whether Jon's decoder >> handlers escaping properly, but Luke's does. >> >> If you take the union of the two, you probably have a >> complete decoder, but they don't seem totally compatible to >> me. ;) Someone else with more knowledge of Java will >> perhaps see things differently. >> >> /Uffe >> >> (*) This is only a problem if the other side uses caching. >> Joe's Erlang-based UBF encoder will take advantage of >> caching, so a corresponding decoder will of course have to >> as soon as there is something cachable in the messages. >> >> -- >> Ulf Wiger, Senior Specialist, >> / / / Architecture & Design of Carrier-Class Software >> / / / Strategic Product & System Management >> / / / Ericsson AB, Connectivity and Control Nodes >> >> > Erik Pearson > Adaptations > desk +1 510 527 5437 > cell +1 510 517 3122 > > Erik Pearson Adaptations desk +1 510 527 5437 cell +1 510 517 3122 From ulf.wiger@REDACTED Sun Apr 20 09:35:37 2003 From: ulf.wiger@REDACTED (Wiger Ulf) Date: Sun, 20 Apr 2003 09:35:37 +0200 Subject: Package support in Erlang: Status ? References: <002101c30662$06d686b0$33bfee82@gnit> Message-ID: <000901c3070f$701787c0$fd7a40d5@telia.com> From: "Richard Carlsson" > So far I've had almost no feedback at all from users, so if you read this > and > have tried using packages, then please do let everybody know what you think! I'm using packages, and am fairly positive so far. I don't think there are many drawbacks, and the package concept does solve the problem of module name space -- I find that a great relief. I have suggested a patch to the release handler (systools_make) that makes it able to build boot scripts even if package names are used. I have noted that embedded mode code loading doesn't work, and that this is due to the fact that erl_prim_loader does not regognize packages. This module is special, in that it's statically linked into the Erlang VM; otherwise, the problem is not difficult to fix. I have also privately suggested that Erlang allow "dotted atoms" (that is, without single quotes) in other places as well, e.g. in registered names, ets tables, etc. This would make package support feel a little less like an afterthought, and more like an integrated part of the language. /Uffe From ulf.wiger@REDACTED Sun Apr 20 09:41:36 2003 From: ulf.wiger@REDACTED (Wiger Ulf) Date: Sun, 20 Apr 2003 09:41:36 +0200 Subject: records generated from UBF References: <59AEDDDE-72E2-11D7-805D-0050E4594D1D@adaptations.com> Message-ID: <001f01c30710$460045c0$fd7a40d5@telia.com> From: "Erik Pearson" > What if the binary representation was something like > > ~ Int ~blahblah~ > > Then the initial ~ would be a nice and and simple flag for the parser > that binary value was coming up. This would be consistent with all of > the other simple types, for which the initial byte serves as a flag for > the type (" for string, ' for contants, 0-9 or - for number (oops, or > binary)...) I'm not the one to either approve or reject your suggestion, but I think you do have a good point. > Finally, just a quick correction to the spec at > > http://www.sics.se/~joe/ubf/site/ubfa.html > > I believe the structure should be defined with comma separators rather > than just whitespace > > { Obj1, Obj2, ..., Objn } > > rather than > > { Obj1 Obj2 ... Objn } > > The examples show the comma separators. I was also confused by the example, but... reading on you will find that Joe has defined comma as whitespace: "For convenience blank, carriage return, line feed tab and comma are treated as white space. Comments can be included in UBF(A) with the syntax %...% the usual quoting convention applies. " That is, the commas are optional. /Uffe From thomasl_erlang@REDACTED Sun Apr 20 12:21:36 2003 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Sun, 20 Apr 2003 03:21:36 -0700 (PDT) Subject: Package support in Erlang: Status ? In-Reply-To: <002101c30662$06d686b0$33bfee82@gnit> Message-ID: <20030420102136.45185.qmail@web13305.mail.yahoo.com> --- Richard Carlsson wrote: > So far I've had almost no feedback at all from > users, so if you read this > and > have tried using packages, then please do let > everybody know what you think! /.../ > So, if you want to move code from the current "flat" > namespace into a > package namespace, you have to: > > 1. rename the module, by prefixing a package > name > 2. add an '-import(Mod)' for each > non-package Mod that is being > called. > > and that's it. Note that existing code can call > package modules without any > changes - for example, you can give a module name as > 'com.bigcorp.mycallback' > to the good old gen_server, and everything works > just as normal. I tried using packages in my optimizer (granted, a somewhat unusual application, but one that tends to encounter these sorts of issues) and ran into a problem with atoms used as module names. In particular, the following two functions are not equivalent in a "packaged" module foo.bar (try erlc -E): -module(foo.bar). -compile(export_all). f1() -> m:f(X). f2() -> Mod = m, Mod:f(X). As I understand your papers, this is intentional. But it also breaks referential transparency: one (compiler or developer) can no longer just replace occurrences of Mod with its value m (or in general, a variable occurrence X with the value of X). That spells needless semantic trouble for all involved, in my experience. So, my suggestion is to fix that undesirable feature interaction. Best, Thomas __________________________________________________ Do you Yahoo!? The New Yahoo! Search - Faster. Easier. Bingo http://search.yahoo.com From lennart.ohman@REDACTED Sun Apr 20 23:22:18 2003 From: lennart.ohman@REDACTED (=?ISO-8859-1?Q?Lennart_=D6hman?=) Date: Sun, 20 Apr 2003 23:22:18 +0200 Subject: Application structure References: <200304172250.32749.blitzfeuer@sc.rr.com> Message-ID: <3EA30F8A.1040500@st.se> Hi, a problem is that many general terms are used to denote (different) specific things in different contexts. In the Erlang/OTP world the following is usually meant by: Applications are collections of resources. Today these are usually code (modules) and processes (or supervision structures (trees) of processes). Applications are the smallest piece which is handled by the release- handler. Hence the smallest piece which can be replaced. The idea is that application shall be idependent in a way that it can be reused in other places. Dependencies among applications are of course allowed. All applications depend on stdlib and kernel for instance. A system, in this context, usually referes to a collection of applications. These applications are usually started through a boot-script file generated by a tool in the sasl application. When you start a "standard Erlang" system, you use a standard boot-script which starts a system with the applications kernel and stdlib. Best Regards, Lennart Walter C. Reel III wrote: > Many thanks. That pointed me in a much better direction. > > On Thursday 17 April 2003 01:21 pm, Ulf Wiger wrote: > >>1) File structure >> >>Organize your code into App/src, App/ebin, etc. >>Try to keep the organization symmetric, e.g. >>MyLib/App1 >> /App2 > > > I've noticed (after you mentioned it) that the standard libraries in the OTP > distribution adhere to that same type of organization. Although I may be > stretching it, would it be safe to say that applications closely resemble the > idea of a package in Python or Java? > > So, just to make sure I understand the terminology, a "system" is a collection > of interoperating nodes (which could be running on different machines) and a > "node" is an instance of the Erlang VM which could host multiple > application/server/etc. processes. Right? > (Of course my current place of employment uses those terms but with completely > different meanings ;) > > Cheers, > - Walt -- ------------------------------------------------------------- Lennart Ohman phone : +46-8-587 623 27 Sjoland & Thyselius Telecom AB cellular: +46-70-552 6735 Sehlstedtsgatan 6 fax : +46-8-667 8230 SE-115 28 STOCKHOLM, SWEDEN email : lennart.ohman@REDACTED From cpressey@REDACTED Mon Apr 21 01:07:28 2003 From: cpressey@REDACTED (Chris Pressey) Date: Sun, 20 Apr 2003 18:07:28 -0500 Subject: "open" vs "closed" cases In-Reply-To: <008401c3045f$34d9d080$8100a8c0@virding.org> References: <200304140608.h3E68si01418@cbe.ericsson.se> <003501c302e3$ba33e220$8300a8c0@virding.org> <20030415130608.6378f6eb.cpressey@catseye.mb.ca> <008401c3045f$34d9d080$8100a8c0@virding.org> Message-ID: <20030420180728.6b0cee71.cpressey@catseye.mb.ca> On Wed, 16 Apr 2003 23:29:02 +0200 "Robert Virding" wrote: > Definitely the closed case. The extra cost is negligible and the > meaning much clearer, especially if the test is not so obviously a > "safe" boolean. > > Robert OK, I've been looking at the way I write code, and I often use "open" cases - partly because I communicate at the user level (or a level where I want to assume certain defaults if input is missing or incorrect), and partly because I'm lazy and I know it's a bad habit but I do it anyway. As penance, I *have* been trying to write stricter interfaces & cases where appropriate lately, for example in the new API for my webserver, I have the following interface (roughly) for modules: start(conf()) -> conf() serve(conf()) -> {not_found, conf()} | {{serve, data()}, conf()} In the first case, crashing if something goes wrong is good; there's nothing sensible that can be done after a module can't be started. In the second case, the error is not really a 'show-stopper' type error - it's more like a condition, so I pass it back as a value. (However, if the serve function does crash, the webserver does generate a 501 internal server error response - which also makes sense.) So, yes - I agree (with Robert) that errors come in a spectrum. I also agree (with Ulf) that it's usually best to write only for the correct case and let everything else crash - and I hope that a future version of Erlang will incorporate 'try', to make that option even more feasible. -Chris From vlad_dumitrescu@REDACTED Mon Apr 21 09:18:14 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Mon, 21 Apr 2003 09:18:14 +0200 Subject: records generated from UBF References: <20030419032500.GA956@localhost.localdomain> Message-ID: Hi, ----- Original Message ----- From: "Taj Khattra" > have you tried UBET (available for solaris and windows) ? Yes, I discovered it right after posting my question, and it's better than most free tools I saw. Thanks for the pointer! regards, Vlad From ulf.wiger@REDACTED Mon Apr 21 10:28:07 2003 From: ulf.wiger@REDACTED (Wiger Ulf) Date: Mon, 21 Apr 2003 10:28:07 +0200 Subject: Application structure References: <200304172250.32749.blitzfeuer@sc.rr.com> <3EA30F8A.1040500@st.se> Message-ID: <000901c307df$efe883c0$fd7a40d5@telia.com> From: "Lennart ?hman" > Applications are the smallest piece which is handled by the release- > handler. Hence the smallest piece which can be replaced. ... by the release handler. ;-) (I know that's what you meant.) The release handler provides ways to upgrade a collection of applications (a system) in an orderly fashion. This includes performing a synchronized upgrade across nodes in a multi-node(*) system. The release handler also supports reversal of an upgrade, so that one can fall back to the last stable version if something goes wrong. An erlang module can of course be replaced by simply loading a new version, but this is only safe under special circumstances (e.g. if the module does not contain a representation of internal process state which changes during the upgrade, and if the interface of the module doesn't change.) This method of replacing code is of course still extremely useful and used extensively during development and testing. /Uffe (*) as in Erlang node. From erik@REDACTED Mon Apr 21 16:56:06 2003 From: erik@REDACTED (Erik Pearson) Date: Mon, 21 Apr 2003 07:56:06 -0700 Subject: records generated from UBF In-Reply-To: <001f01c30710$460045c0$fd7a40d5@telia.com> Message-ID: <61230626-7409-11D7-8682-0050E4594D1D@adaptations.com> Thanks, Ulf ... some comments below > >> Finally, just a quick correction to the spec at >> >> http://www.sics.se/~joe/ubf/site/ubfa.html >> >> I believe the structure should be defined with comma separators rather >> than just whitespace >> >> { Obj1, Obj2, ..., Objn } >> >> rather than >> >> { Obj1 Obj2 ... Objn } >> >> The examples show the comma separators. > > I was also confused by the example, but... reading on you will find > that > Joe has defined comma as whitespace: > > "For convenience blank, carriage return, line feed tab and comma are > treated > as white space. Comments can be included in UBF(A) with the syntax > %...% the > usual quoting convention applies. " > > That is, the commas are optional. Thanks, I didn't notice the comma sneaking in there as whitespace. However, I am still somewhat concerned: - how do you disambiguate {"Hi" 'greeting', "world" 'planet'}? It seems that this could be either {Obj1 Obj2 Obj3 Obj4} or {Obj1 Obj3 Obj4} or {Obj1 Obj2}. I must be missing something crucial here. I have a new concern too -- how to represent null (i.e. missing, blank) values? For strings it would be "" $ for constants '' $ for binary 0 ~~ $ (or ~0~~ $ if the tilde prefix is preferable), but for integers it would be $ .. that is, a blank. But this raises a few issues: 1. How do you carry the type information for a blank integer? 2. Is there a valid concept of typeless null? That is not only is the value blank, but it also carries not type information? 3. It seems impossible to represent a null tagged integer -- it would be indistinguishable from a plain constant. Do you or does anyone else have experience with confronting these issues? I can see that UBF(B) might help with some of these issues, since the usage of values within a particular context would imply their type. However, at this point I'm just concerned with getting plain old UBF(A). Also, one of the things I'm trying to keep an eye on is places where the spec introduces more work for the parser-builder. In my case, I would like to use this with multi-vendor data and message exchange. In these cases, having a clear, easy-to-implement spec is very important. People need to implement this stuff in all sots of weird languages and often in a hurry! Thanks, Erik. > > /Uffe > > Erik Pearson Adaptations desk +1 510 527 5437 cell +1 510 517 3122 From spearce@REDACTED Mon Apr 21 17:52:13 2003 From: spearce@REDACTED (Shawn Pearce) Date: Mon, 21 Apr 2003 11:52:13 -0400 Subject: records generated from UBF In-Reply-To: <61230626-7409-11D7-8682-0050E4594D1D@adaptations.com> References: <001f01c30710$460045c0$fd7a40d5@telia.com> <61230626-7409-11D7-8682-0050E4594D1D@adaptations.com> Message-ID: <20030421155213.GA18415@spearce.org> Erik Pearson wrote: > Thanks, I didn't notice the comma sneaking in there as whitespace. > However, I am still somewhat concerned: > > - how do you disambiguate {"Hi" 'greeting', "world" 'planet'}? It seems > that this could be either {Obj1 Obj2 Obj3 Obj4} or {Obj1 Obj3 Obj4} or > {Obj1 Obj2}. Its clearly {Obj1 Obj2 Obj3 Obj4}. ' ' (space) and ',' (comma) are both whitespace characters to UBF. Thus its {"Hi"'greeting'"world"'planet'}, which is a 4 object tuple. Now UBF(B) may define that the atom 'greeting' represents a type which is called greeting, however a type can only be made of up simple types. Thus in order to create a UBF(B) type of 'greeting' it would be necessary to encode as {"Hi" {'greeting', "world"}, 'planet'} which if you look at Erlang records is exactly how a greeting record would be encoded. (Tuple holding the tuple name as the first term and the values as the rest. So clearly the example you give cannot even be a UBF(B) type. > I must be missing something crucial here. > > I have a new concern too -- how to represent null (i.e. missing, blank) > values? Use an atom. In Erlang (which UBF has borrowed a lot from), null is generally defined (by convention) to be the atom 'undefined'. Thus if you want a null string or a null integer, the UDF(B) must allow either an Int or the atom 'undefined'. Otherwise you cannot define a null Int. (Same for the other types.) > For strings it would be > "" $ > > for constants > '' $ > > for binary > 0 ~~ $ > > (or > ~0~~ $ > if the tilde prefix is preferable), > > but for integers it would be > > $ > > .. that is, a blank. But this raises a few issues: > > 1. How do you carry the type information for a blank integer? > > 2. Is there a valid concept of typeless null? That is not only is the > value blank, but it also carries not type information? Yes, the atom 'undefined' does this by convention, but this of course means you cannot use the atom 'undefined' to mean a non-typless-null value. :) It sounds ugly, but in practice it works better than say the typeless SQL null. > 3. It seems impossible to represent a null tagged integer -- it would > be indistinguishable from a plain constant. Erlang has no concept of a null integer, it uses 'undefined' (by convention). You could define the atom 'null' or 'nullint' or 'nan' to mean the same thing(s), but its your code that must define the meaning of these atoms. I much prefer the Erlang system of doing it by convention, rather than forcing it on you. > Do you or does anyone else have experience with confronting these > issues? > > I can see that UBF(B) might help with some of these issues, since the > usage of values within a particular context would imply their type. > However, at this point I'm just concerned with getting plain old UBF(A). > > Also, one of the things I'm trying to keep an eye on is places where > the spec introduces more work for the parser-builder. In my case, I > would like to use this with multi-vendor data and message exchange. In > these cases, having a clear, easy-to-implement spec is very important. > People need to implement this stuff in all sots of weird languages and > often in a hurry! I'm not quite sure what you mean here. Almost every language/system I have worked in this far has a concept of a linked list, a concept of an array, of a constant (atom), and numerics/strings/binaries. Thus you should be able to quickly read the UBF(A) spec and see the mapping to your language environment, and just map it. Perhaps the UBF(A) spec just isn't clear on how one would handle null values? One thing I like about UBF(A) is that it should only take a few days to write a parser, while XML is estimated to take about 3 weeks. Thus most developers should be able to bring a UBF(A) parser online in a very short time, perhaps about the same amount of effort required to just write a simple SAX or DOM parser (which uses an existing parser). :) -- Shawn. When smashing monuments, save the pedstals -- they always come in handy. -- Stanislaw J. Lem, "Unkempt Thoughts" From erik@REDACTED Mon Apr 21 19:50:30 2003 From: erik@REDACTED (Erik Pearson) Date: Mon, 21 Apr 2003 10:50:30 -0700 Subject: records generated from UBF In-Reply-To: <20030421155213.GA18415@spearce.org> Message-ID: Hi Shawn, Thanks for the explanations! I think we are coming at the problem from different sides, though. I'm trying to see this from the "Erlang talking to the outside world" point of view, which in turn implies "the outside world talking to the outside world". In this approach, Erlang conventions don't really matter. What matters is the internal consistency of UBF, and its ability to convey any type of information. At least that is what _I_ want out of it :) From this point of view, my comments are below: On Monday, April 21, 2003, at 08:52 AM, Shawn Pearce wrote: > Erik Pearson wrote: >> Thanks, I didn't notice the comma sneaking in there as whitespace. >> However, I am still somewhat concerned: >> >> - how do you disambiguate {"Hi" 'greeting', "world" 'planet'}? It >> seems >> that this could be either {Obj1 Obj2 Obj3 Obj4} or {Obj1 Obj3 Obj4} or >> {Obj1 Obj2}. > > Its clearly {Obj1 Obj2 Obj3 Obj4}. ' ' (space) and ',' (comma) are > both > whitespace characters to UBF. Thus its > {"Hi"'greeting'"world"'planet'}, > which is a 4 object tuple. Now UBF(B) may define that the atom > 'greeting' represents a type which is called greeting, however a > type can only be made of up simple types. Thus in order to create > a UBF(B) type of 'greeting' it would be necessary to encode as > > {"Hi" {'greeting', "world"}, 'planet'} > > which if you look at Erlang records is exactly how a greeting record > would be encoded. (Tuple holding the tuple name as the first term > and the values as the rest. So clearly the example you give cannot > even be a UBF(B) type. The problem is that the object "Hi" 'greeting' $ is a perfectly valid UBF value -- a semantically tagged string. I believe that any base object (string, constant, integer, binary) can be extended by adding a semantic tag after it. Thus anywhere that an object can appear, you should be able to add a constant value after it and have it recognized as a semantic tag. My problem is that within a structure this doesn't seem to work unless you have a specific byte-code for separating objects (perhaps better thought of as a way of terminating an object). That was the point of the example. I hope! > >> I must be missing something crucial here. >> >> I have a new concern too -- how to represent null (i.e. missing, >> blank) >> values? > > Use an atom. In Erlang (which UBF has borrowed a lot from), null > is generally defined (by convention) to be the atom 'undefined'. > Thus if you want a null string or a null integer, the UDF(B) must > allow either an Int or the atom 'undefined'. Otherwise you cannot > define a null Int. (Same for the other types.) Yeah, I guess one can say that typeless nulls (ala lisp nil or java null) can be represented, but that typed nulls would be in the realm of UBF(B). Either you'd need to use more structure (e.g. 'undefined' 'int32' $), or complex types in order for UBF(B) to know what you are talking about. I guess that when you need this level of interpretation, you should be dealing with UBF(B) anyway. However, I do think that it is a relatively important distinction that the UBF(A) encoding does not allow for the encoding of a null value into its objects (with type). > >> For strings it would be >> "" $ >> >> for constants >> '' $ >> >> for binary >> 0 ~~ $ >> >> (or >> ~0~~ $ >> if the tilde prefix is preferable), >> >> but for integers it would be >> >> $ >> >> .. that is, a blank. But this raises a few issues: >> >> 1. How do you carry the type information for a blank integer? >> >> 2. Is there a valid concept of typeless null? That is not only is the >> value blank, but it also carries not type information? > > Yes, the atom 'undefined' does this by convention, but this of course > means you cannot use the atom 'undefined' to mean a non-typless-null > value. :) It sounds ugly, but in practice it works better than say > the typeless SQL null. Actually, I think that just an empty object in UBF(A) is a typeless null. UBF(A) doesn't mention it, but it sesms like a reasonable interpretation that an empty object is a null object. $ is a null object -- no data, no type. however, there can't be any tagged null because 'tag' $ would be interpreted as the constant 'tag'. What do the empty structure and list mean? { } $ # & $ > >> 3. It seems impossible to represent a null tagged integer -- it would >> be indistinguishable from a plain constant. > > Erlang has no concept of a null integer, it uses 'undefined' (by > convention). You could define the atom 'null' or 'nullint' or 'nan' > to mean the same thing(s), but its your code that must define the > meaning of these atoms. I much prefer the Erlang system of doing it > by convention, rather than forcing it on you. Again, I'm just grappling with how to encode objects at the A level -- what can and can't be done -- using just the UBF spec as the guideline. > >> Do you or does anyone else have experience with confronting these >> issues? >> >> I can see that UBF(B) might help with some of these issues, since the >> usage of values within a particular context would imply their type. >> However, at this point I'm just concerned with getting plain old >> UBF(A). >> >> Also, one of the things I'm trying to keep an eye on is places where >> the spec introduces more work for the parser-builder. In my case, I >> would like to use this with multi-vendor data and message exchange. In >> these cases, having a clear, easy-to-implement spec is very important. >> People need to implement this stuff in all sots of weird languages and >> often in a hurry! > > I'm not quite sure what you mean here. Almost every language/system > I have worked in this far has a concept of a linked list, a concept > of an array, of a constant (atom), and numerics/strings/binaries. Thus > you should be able to quickly read the UBF(A) spec and see the mapping > to your language environment, and just map it. Perhaps the UBF(A) spec > just isn't clear on how one would handle null values? The problem has more to do with making sure that the mapping is as strightforward as possible. Also, I want as few of these questions as possible coming my way! Some issues that I've come across so far are: - encoding for binaries is made a little more complex than (I think) necessary, since there is no initial bytecode to signal the type. The parser has to keep going past the integer to determine if the object is an integer or a binary. - encoding of structures seems ambiguous with regard to separating objects - encoding of lists is non-intuitive in two senses -- - for those who don't deal with functional languages, the idea of a list in reverse order may not make a lot of sense - there is no explicit list terminator, unlike for structures. (both of these seem to not fare well in the "human readable" goal stated in the spec.) Now, I'm not saying that these are insurmountable problems, perhaps they are just issues that I'd like to understand better. > > One thing I like about UBF(A) is that it should only take a few days > to write a parser, while XML is estimated to take about 3 weeks. Thus > most developers should be able to bring a UBF(A) parser online in a > very > short time, perhaps about the same amount of effort required to just > write a simple SAX or DOM parser (which uses an existing parser). :) Yes, I really love the idea and implementation of UBF(*). I wrote most of a UBF(A) parser as a passenger driving to and from a mini-vacation (I conveniently left my wallet at home and couldn't drive...) I just rewrote the parser last night to try a different approach. Even the harder stuff doesn't take _that_long to do. Erik. > > -- > Shawn. > > When smashing monuments, save the pedstals -- they always come in > handy. > -- Stanislaw J. Lem, "Unkempt Thoughts" > Erik Pearson Adaptations desk +1 510 527 5437 cell +1 510 517 3122 From erik@REDACTED Mon Apr 21 21:08:06 2003 From: erik@REDACTED (Erik Pearson) Date: Mon, 21 Apr 2003 12:08:06 -0700 Subject: records generated from UBF In-Reply-To: Message-ID: <95447654-742C-11D7-8825-0050E4594D1D@adaptations.com> Well, `grimace`, some of the issues go away now that I realize that the semantic tag uses backquote rather than single quote ... [... tons snipped ...] Erik From cpressey@REDACTED Tue Apr 22 00:29:50 2003 From: cpressey@REDACTED (Chris Pressey) Date: Mon, 21 Apr 2003 17:29:50 -0500 Subject: new line Message-ID: <20030421172950.2b408f26.cpressey@catseye.mb.ca> In the io man page, it says "~n Writes a new line." How is a new line defined? Under Windows, when printing to a file, ASCII character 10 is all that prints for a ~n. (to the screen it does display a new line.) This is also the case for a large term passed to ~p that is printed on multiple lines. Is this behaviour intentional or incidental? -Chris From cpressey@REDACTED Tue Apr 22 07:49:17 2003 From: cpressey@REDACTED (Chris Pressey) Date: Tue, 22 Apr 2003 00:49:17 -0500 Subject: catching errors from linked processes: simplest way? Message-ID: <20030422004917.1b90a16c.cpressey@catseye.mb.ca> OK, so, I'm actually trying to write 'aggressively simple' code now, without open cases or inline error handling, and I've come across a case that I can't see a simple way to handle. (I can see a couple of somewhat complicated ways to handle it, but wouldn't that defeat the purpose :) When I run the attached program I get the following output: 1> test3:start(). all OK got "11" ok got "21" got "31" got "51" got "61" got "81" got "91" got "181" Pretty much exactly what I expected. So far, so good. If I change line 7 to case catch client(Pid, [10, 20, 30, 50, 60, atom, 90, 180]) of Then when I run it I get 1> test3:start(). not OK: {'EXIT',{badarith,[{test3,client,2}, {test3,start,0}, {erl_eval,expr,3}, {erl_eval,exprs,4}, {shell,eval_loop,2}]}} got "11" got "21" ok got "31" got "51" got "61" Also what I expected. But if I now change line 17 to Pid ! Head, I get 1> test3:start(). all OK got "10" ok got "20" got "30" got "50" got "60" 2> =ERROR REPORT==== 22-Apr-2003::00:25:16 === Error in process <0.30.0> with exit value: {badarg,[{erlang,integer_to_list,[atom]},{test3,loop,0}]} ** exited: {badarg,[{erlang,integer_to_list,[atom]},{test3,loop,0}]} ** Not exactly what I'd prefer to happen! I guess what I'm thinking is, wouldn't it be great if 'catch' could catch errors from linked processes. I guess I'm also thinking that someone's probably thought of this before, so there's probably a simple way to do it, of which I'm unaware. The complicated ways to do it that I can think of are: - make the client process trap exits and use a receive loop in the client to get them and re-throw them in the client process; - monitor the server from the client process and use a receive loop in the client to throw errors in the client process when the server bombs; - catch errors in the sever and explicitly pass an {error, Reason} value back from the server (exactly what I'm now trying to avoid) All of these would require me putting a 'receive' in the client, which is less than elegantly simple - it goes against the grain of what I'm now trying to do, i.e. eliminate explicit, inline error-handling code from the main logic. If I have to resort to it, I will, but if it turns out I don't have to, that'd be great. Any suggestions would be appreciated. Thanks, -Chris -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: test3.erl URL: From spearce@REDACTED Tue Apr 22 08:08:00 2003 From: spearce@REDACTED (Shawn Pearce) Date: Tue, 22 Apr 2003 02:08:00 -0400 Subject: new line In-Reply-To: <20030421172950.2b408f26.cpressey@catseye.mb.ca> References: <20030421172950.2b408f26.cpressey@catseye.mb.ca> Message-ID: <20030422060800.GA19721@spearce.org> I believe it is intentional. ~n is LF, ~r is CR, and there is no fancy difference between UNIX and Windows when it comes to how ~n is handled. Thus code can be written to be portable, if you really wanted ~r~n for the braindead platforms that still need it, you would have to handle that yourself. At least that's what I think I've read on this list before. :) I happen to like that there isn't a difference between ~n on UNIX and Windows, makes it easy to do everything but read/write Windows text files. And most good (aka not notepad.exe) Windows text editors (even wordpad!) can handle UNIX text files holding just LFs. Thus I don't usually find a need to generate "proper" CRLF Windows text files and "proper" LF-only UNIX text files (when on UNIX) from the same code. Chris Pressey wrote: > In the io man page, it says "~n Writes a new line." > > How is a new line defined? > > Under Windows, when printing to a file, ASCII character 10 is all that > prints for a ~n. (to the screen it does display a new line.) This is > also the case for a large term passed to ~p that is printed on multiple > lines. > > Is this behaviour intentional or incidental? > > -Chris -- Shawn. Pick another fortune cookie. From cpressey@REDACTED Tue Apr 22 08:09:11 2003 From: cpressey@REDACTED (Chris Pressey) Date: Tue, 22 Apr 2003 01:09:11 -0500 Subject: optimization ? In-Reply-To: <200304190111.h3J1B9tW007274@wren.rentec.com> References: <200304190111.h3J1B9tW007274@wren.rentec.com> Message-ID: <20030422010911.58dd89da.cpressey@catseye.mb.ca> Hello, On Fri, 18 Apr 2003 21:11:09 -0400 (EDT) HP Wei wrote: > Hi, I (a newbie in Erlang) > am trying to get used to Erlang's way of doing things. > I have a small module in the following > whose function is to extract a list > of subdirectories under the Top directory. > It works. But it is a bit slow > (5 sec for a specific directory on our machine). > Is this the best I can do ?? > [...] > dirs(Top, [F|Tail], Acc) -> > F2 = Top ++ "/" ++ F, > case file:read_link_info(F2) of > {ok, FileInfo} when FileInfo#file_info.type == directory -> > case dirs(F2) of > {error, Reason} -> > {error, Reason}; > List -> > T = [F2|List], > dirs(Top, Tail, T ++ Acc) ^^^^^^^^ This is probably one reason that it's kind of slow. To perform T ++ Acc, the runtime has to search for the end of the T list, which is expensive compared to a simple cons. You might want to try [T|Acc]... > end; > Other -> > dirs(Top, Tail, Acc) > end; > > dirs(_Top, [], Ack) -> Ack. ...then lists:flatten/1 the result here before you return it, if you wish. Hope that helps, -Chris From svg@REDACTED Tue Apr 22 08:28:34 2003 From: svg@REDACTED (Vladimir Sekissov) Date: Tue, 22 Apr 2003 12:28:34 +0600 (YEKST) Subject: catching errors from linked processes: simplest way? In-Reply-To: <20030422004917.1b90a16c.cpressey@catseye.mb.ca> References: <20030422004917.1b90a16c.cpressey@catseye.mb.ca> Message-ID: <20030422.122834.07647314.svg@surnet.ru> Good day, cpressey> I guess what I'm thinking is, wouldn't it be great if 'catch' could cpressey> catch errors from linked processes. I guess I'm also thinking that cpressey> someone's probably thought of this before, so there's probably a simple You are catching exit message , it is in your mailbox: start() -> Pid = spawn_link(?MODULE, server, []), case catch client(Pid, [10, 20, 30, 50, abba, 80, 90, 180]) of ok -> io:fwrite("all OK~n"), receive {'EXIT', Pid, Reason} -> io:fwrite("not OK: ~p~n", [Reason]) after 0 -> ok end; Else -> io:fwrite("not OK: ~p~n", [Else]) end. 3> test3:start(). not OK: {'EXIT',{badarith,[{test3,client,2}, {test3,start,0}, {erl_eval,expr,3}, {erl_eval,exprs,4}, {shell,eval_loop,2}]}} got "11" ... Best Regards, Vladimir Sekissov From lennart.ohman@REDACTED Tue Apr 22 08:30:14 2003 From: lennart.ohman@REDACTED (=?ISO-8859-1?Q?Lennart_=D6hman?=) Date: Tue, 22 Apr 2003 08:30:14 +0200 Subject: catching errors from linked processes: simplest way? References: <20030422004917.1b90a16c.cpressey@catseye.mb.ca> Message-ID: <3EA4E176.9070106@st.se> Hi Chris Pressey wrote: > OK, so, I'm actually trying to write 'aggressively simple' code now, Good! :-) The "aggressive way" when having several processes is to have one (or possibly several if it is a complicated system) process which supervises the other(s). In this way you move all the error handling, if you need it at all, away from the code implementing the logic. You should then try to write the code in a way that the logic works fine without the supervision (during normal input). The supervision is then only an add-on to provide robustness. /Lennart ------------------------------------------------------------- Lennart Ohman phone : +46-8-587 623 27 Sjoland & Thyselius Telecom AB cellular: +46-70-552 6735 Sehlstedtsgatan 6 fax : +46-8-667 8230 SE-115 28 STOCKHOLM, SWEDEN email : lennart.ohman@REDACTED From svg@REDACTED Tue Apr 22 08:53:49 2003 From: svg@REDACTED (Vladimir Sekissov) Date: Tue, 22 Apr 2003 12:53:49 +0600 (YEKST) Subject: catching errors from linked processes: simplest way? In-Reply-To: <20030422.122834.07647314.svg@surnet.ru> References: <20030422004917.1b90a16c.cpressey@catseye.mb.ca> <20030422.122834.07647314.svg@surnet.ru> Message-ID: <20030422.125349.108741064.svg@surnet.ru> I'm awfully sorry. Please ignore my last post. Not yet fully awaken. Best Regards, Vladimir Sekissov From raimo.niskanen@REDACTED Tue Apr 22 09:34:05 2003 From: raimo.niskanen@REDACTED (Raimo Niskanen) Date: Tue, 22 Apr 2003 09:34:05 +0200 Subject: trouble with files bigger than 4GB References: <200304162052.34521@no.siento.las.piennas>, , <200304181515.42510@no.siento.las.piennas> Message-ID: <3EA4F06D.90703@uab.ericsson.se> Comments inserted below... Daniel Solaz wrote: > On Thursday 17 April 2003 10:14 Raimo Niskanen wrote: > >>There is some way to compile a program for solaris so that fopen() >>means fopen64(), off_t becomes 64 bit, and so on. If this is done, >>the code should work. It is perhaps even so that for an Erlang/OTP >>system built for Solaris8 it works, while not for a system built for >>Solaris2.5.1. > > Yes, this is described in the lfcompile(5) man page. > I'll try to hack the appropriate Makefile(s) and recompile so I can > check whether this is enough to get the code working, where working > means "like in FreeBSD". > > >>Since the size of off_t is configured when building open source >>Erlang, on a system with 64 bits off_t - large file operations should >>work. Have a look in $ERL_TOP/erts/$PLATFORM/config.h for >>SIZEOF_OFF_T and see if it is 4 (bytes). $PLATFORM is the system name >>$ERL_TOP/erts/autoconf/config.guess reports when executed. $ERL_TOP >>is your open source build root. > > You're right, off_t is reported to be 4 bytes long. > > >>Please try some more file operations on your large file. Try >>file:open, file:position, file:read, and see if it seems to work on >>FreeBSD. I am really curious. >>I have browsed the source and think I see a bug in reading the size >>field for file:read_file_info - the high word of the size field is >>ignored, so if other file operations work, it is a small bug fix and >>can be done for R9C. If no other file operations work, it is a bigger >>problem and will have to wait. Please let me know. > > Reading the large file buffer by buffer all the way from the beginning > works fine; file:position(F, {bof, 4294967296}) returns {ok, 0} BUT the > file pointer is actually set to byte 4294967296, as does > file:position(F, {eof, 0}) on a 4 GB file. > So it seems the problem lies in the code that reports sizes and offsets > ignoring the high word of the file size or position. > > -Daniel Well, I will fix the simple bug i mentioned above, but if off_t is 4 bytes, there is not much to do on such a system. There is no high word to make use of. File size (or absolute position) 4294967296 is indistinguishable from 0. Absolute position 4294967295 is the same as error return value -1 from lseek(). So file sizes up to and including 4GByte-2Byte should work, but for larger files you need a system with 8 byte off_t. And the bug fix for file:read_file_info/1 to come in R9C. / Raimo Niskanen, Erlang/OTP, Ericsson AB From svg@REDACTED Tue Apr 22 09:43:30 2003 From: svg@REDACTED (Vladimir Sekissov) Date: Tue, 22 Apr 2003 13:43:30 +0600 (YEKST) Subject: optimization ? In-Reply-To: <20030422010911.58dd89da.cpressey@catseye.mb.ca> References: <200304190111.h3J1B9tW007274@wren.rentec.com> <20030422010911.58dd89da.cpressey@catseye.mb.ca> Message-ID: <20030422.134330.71082413.svg@surnet.ru> Good day, cpressey> > dirs(Top, Tail, T ++ Acc) cpressey> ^^^^^^^^ cpressey> This is probably one reason that it's kind of slow. To perform T ++ cpressey> Acc, the runtime has to search for the end of the T list, which is cpressey> expensive compared to a simple cons. You might want to try [T|Acc]... According to fprof function spends most time in {file,read_link_info}: CNT ACC {test,dirs,3} 1086 2365.887 {file,read_link_info,1} 1010 2152.686 {erlang,'++',2}, 1085 24.044 Best Regards, Vladimir Sekissov From joe@REDACTED Tue Apr 22 10:25:41 2003 From: joe@REDACTED (Joe Armstrong) Date: Tue, 22 Apr 2003 10:25:41 +0200 (CEST) Subject: records generated from UBF In-Reply-To: <59AEDDDE-72E2-11D7-805D-0050E4594D1D@adaptations.com> Message-ID: On Sat, 19 Apr 2003, Erik Pearson wrote: > After a little more fiddling around, I have a practical question about > UBF(A): > > The representation of a "binary" type is: > > Int ~blahblah~ > > Where Int is an integer, and ~ is the delimiter for the binary data, > and blahblah is a stream/array of bytes Int long (and the space is 0 or > more spaces) > > In order resolve the ambiguity with regular Int , the otherwise simple > parsing becomes more complicated. It seems to me, unnecessarily > complex. That is, the parser first determines that there is an int, and > then it has to keep going to determine whether it really is an int or > whether it will become a binary. > > What if the binary representation was something like > > ~ Int ~blahblah~ > > Then the initial ~ would be a nice and and simple flag for the parser > that binary value was coming up. This would be consistent with all of > the other simple types, for which the initial byte serves as a flag for > the type (" for string, ' for contants, 0-9 or - for number (oops, or > binary)...) > IMHO this would be more difficult to parse :-) You should think of UBF(A) as a byte code program designed to be executed by a push down autonoma. As soon as you recognize *anything* you just push it onto the stack. So to parse: 123 ~.....~ The parser proceeds as follows: 1) Recognize that "1" is the start of an integer 2) go get the integer 3) Blank terminates the integer so push the recognized integer "123" onto the stack 4) Recognize ~ - this means "here comes a memory buffer" the length will be on the top of the stack Pop the stack 5) collect 123 bytes into a memory buffer 6) push the memory buffer onto the stack 7) collect a ~ Step 7 is (or course) not necessary. UFB(A) has a few "features" to make it not only easy to parse but easy to read and write - Thus the trailing ~ is just there to make it easier to read. > Finally, just a quick correction to the spec at > > http://www.sics.se/~joe/ubf/site/ubfa.html > > I believe the structure should be defined with comma separators rather > than just whitespace > > { Obj1, Obj2, ..., Objn } > > rather than > > { Obj1 Obj2 ... Objn } > > The examples show the comma separators. Again this is just to make it easier to read - commas and white space mean the same. /Joe > Thanks, > > Erik. > > > On Wednesday, April 16, 2003, at 09:18 AM, Erik Pearson wrote: > > > Thanks Ulf, > > > > I hadn't actually looked for the java stuff in the download, since it > > the java section of the site says that it is not done yet! Well, there > > it is! > > > > It works fine so far. > > > > FWIW, this is probably what how I'll attempt to use it first -- What > > I'm doing is integrating it into my web server scripting language (a > > very close offshoot of Tcl, from the Jacl tcl implementation, that is, > > Tcl implemented in Java). I'm starting with just UBF(A), since for my > > purposes gettting two or more disparate network services (web or > > other) to exchange information is the first goal. The first bit of > > work will be to implement a pleasant java/tcl interface so that UBF(A) > > can be easily scripted on the web server. Since UBF(A) is > > straightforward, that part should be pretty easy, and is mostly > > working now. After that, UBF(B)... > > > > On the other side of the equation are several other related network > > services or applications which are variously implemented (currently) > > in Tcl and CL. Now, the discovery of UBF has prompted me to rethink > > the usage of Erlang for these same services. (I had been using Erlang, > > but issues with mnesia caused me to put it aside for a while...) > > > > BTW, the very practical and straightforward nature of UBF fits right > > into why Erlang has always been so appealing (to me.) > > > > I'll check back later (after my very short vacation) in if I get some > > interesting results. > > > > Thanks, > > > > Erik. > > > > > > On Tuesday, April 15, 2003, at 01:43 AM, Ulf Wiger wrote: > > > >> On Tue, 15 Apr 2003, Erik Pearson wrote: > >> > >>> I'd like to give UBF a try. It looks really great, and > >>> thanks for your addition to it. > >> > >> Good. (: > >> > >> Joe is, I believe, in Iceland this week, undoubtedly > >> spending quality time trying out all the hot baths there. > >> Let's see how he wants to play it when he gets back. > >> Otherwise, you can certainly download whatever he has made > >> available on his website, and I can send you my modified > >> version, with absolutely no guarantees. ;-) > >> > >> > >>> What would be great, though, is if someone can share a Java > >>> implementation (or any other implementation out there, e.g. > >>> Tcl). I need it to glue together a Java servlet to Erlang > >>> (or whatever). > >>> > >>> From the UBF paper, it appears that a Java implementation > >>> was largely completed. It would be great to either use that > >>> code, or start with it and complete the implementation far > >>> enough to get something working. > >> > >> There are two Java implementations that I know of. Luke's > >> Java client that's included in Joe's care package, and Jon > >> ?kerg?rden's Athletics client prototype. Jon's Java code can > >> be downloaded from http://www.it.kth.se/~e98_jak/ > >> However, Jon is actively working on the code right now, so > >> the downloadable version is almost certainly outdated. > >> > >>> From a quick glance (and be warned: I've yet to write even > >> Hello World in Java), Luke's UBF decoder seems to lack > >> caching support(*), and Jon's decoder lacks support for > >> binaries; I'm also unsure about whether Jon's decoder > >> handlers escaping properly, but Luke's does. > >> > >> If you take the union of the two, you probably have a > >> complete decoder, but they don't seem totally compatible to > >> me. ;) Someone else with more knowledge of Java will > >> perhaps see things differently. > >> > >> /Uffe > >> > >> (*) This is only a problem if the other side uses caching. > >> Joe's Erlang-based UBF encoder will take advantage of > >> caching, so a corresponding decoder will of course have to > >> as soon as there is something cachable in the messages. > >> > >> -- > >> Ulf Wiger, Senior Specialist, > >> / / / Architecture & Design of Carrier-Class Software > >> / / / Strategic Product & System Management > >> / / / Ericsson AB, Connectivity and Control Nodes > >> > >> > > Erik Pearson > > Adaptations > > desk +1 510 527 5437 > > cell +1 510 517 3122 > > > > > Erik Pearson > Adaptations > desk +1 510 527 5437 > cell +1 510 517 3122 > From vances@REDACTED Tue Apr 22 10:28:34 2003 From: vances@REDACTED (Vance Shipley) Date: Tue, 22 Apr 2003 04:28:34 -0400 Subject: records generated from UBF Message-ID: <20030422082806.GA59293@frogman.motivity.ca> On Tue, 15 Apr 2003 Vlad Dumitrescu" wrote: } } - in a real-life environment, there are more than two cooperating instances, } and also the 'client' and 'server' roles may be fuzzy. Also a request may } not be mapped to a succesion of query-answer message pairs. As far as I can } see, UBF(B) can't handle other cases than 1-to-1 strict client-to-server. I am having the same problem seeing how I can use UBF. The other problem is that no one has offered up an example implementation in C. :) There seems to be no end to the options one has to interface C with Erlang. OTP provides two versions of a C interface; the original erl_interface and the newer ei version. It used to include IG (Interface Generator) but that is still available elsewhere. It also includes Corba. Then there is Scott's EDTK. Now we have UBF to consider as well. That is if it had a C binding. Of course there is also rpc and xml-rpc from user contributions and I'm sure countless other ways to talk between languages. So many options. Hmmm... -Vance From eleberg@REDACTED Tue Apr 22 10:34:29 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Tue, 22 Apr 2003 10:34:29 +0200 (MEST) Subject: optimization ? Message-ID: <200304220834.h3M8YTi12216@cbe.ericsson.se> > Date: Tue, 22 Apr 2003 01:09:11 -0500 > From: Chris Pressey > Subject: Re: optimization ? ...deleted > expensive compared to a simple cons. You might want to try [T|Acc]... > > > end; > > Other -> > > dirs(Top, Tail, Acc) > > end; > > > > dirs(_Top, [], Ack) -> Ack. > > ...then lists:flatten/1 the result here before you return it, if you are you sure? i tried this (but might have made a mistake) and the result i got was 1 single (long) string. the original result, a list of strings, is much more readable. bengt From joe@REDACTED Tue Apr 22 10:46:06 2003 From: joe@REDACTED (Joe Armstrong) Date: Tue, 22 Apr 2003 10:46:06 +0200 (CEST) Subject: records generated from UBF In-Reply-To: <61230626-7409-11D7-8682-0050E4594D1D@adaptations.com> Message-ID: Good point :-) - I guess there should be one more operator meaning undefined - The obvious choice would be "?" This looks like something for UBF-2 (if there ever is a UBF-2 :-) Otherwise you could use just # which is the nil terminator at the end of a list - but you'd have to change the parser etc. (and the contract checker to do this). I haven't though about it a lot but at first sight using "?" might allow a simplification of the contract rules using "?" instead of ANY - which would make then more readable and possibly more powerful (a la Prolog) /Joe > > I have a new concern too -- how to represent null (i.e. missing, blank) > values? > For strings it would be > "" $ > > for constants > '' $ > > for binary > 0 ~~ $ > > (or > ~0~~ $ > if the tilde prefix is preferable), > > but for integers it would be > > $ > > .. that is, a blank. But this raises a few issues: > > 1. How do you carry the type information for a blank integer? > > 2. Is there a valid concept of typeless null? That is not only is the > value blank, but it also carries not type information? > > 3. It seems impossible to represent a null tagged integer -- it would > be indistinguishable from a plain constant. > > Do you or does anyone else have experience with confronting these > issues? > > I can see that UBF(B) might help with some of these issues, since the > usage of values within a particular context would imply their type. > However, at this point I'm just concerned with getting plain old UBF(A). > > Also, one of the things I'm trying to keep an eye on is places where > the spec introduces more work for the parser-builder. In my case, I > would like to use this with multi-vendor data and message exchange. In > these cases, having a clear, easy-to-implement spec is very important. > People need to implement this stuff in all sots of weird languages and > often in a hurry! > > Thanks, > > Erik. > > > > > > > /Uffe > > > > > Erik Pearson > Adaptations > desk +1 510 527 5437 > cell +1 510 517 3122 > From joe@REDACTED Tue Apr 22 10:50:31 2003 From: joe@REDACTED (Joe Armstrong) Date: Tue, 22 Apr 2003 10:50:31 +0200 (CEST) Subject: Package support in Erlang: Status ? In-Reply-To: <000901c3070f$701787c0$fd7a40d5@telia.com> Message-ID: > > I have also privately suggested that Erlang allow "dotted atoms" (that is, > without single quotes) in other places as well, e.g. in registered names, > ets tables, etc. This would make package support feel a little less like an > afterthought, and more like an integrated part of the language. > There goes the dot - I'd have liked the dot for "proper" structs - (fortunately there is still ^ and ?) /Joe > /Uffe > From ingela@REDACTED Tue Apr 22 11:05:12 2003 From: ingela@REDACTED (Ingela Anderton) Date: Tue, 22 Apr 2003 11:05:12 +0200 Subject: optimization ? References: <200304220834.h3M8YTi12216@cbe.ericsson.se> Message-ID: <16037.1480.457620.444172@gargle.gargle.HOWL> Bengt Kleberg wrote: > > > Date: Tue, 22 Apr 2003 01:09:11 -0500 > > From: Chris Pressey > > Subject: Re: optimization ? > ...deleted > > expensive compared to a simple cons. You might want to try [T|Acc]... > > > > > end; > > > Other -> > > > dirs(Top, Tail, Acc) > > > end; > > > > > > dirs(_Top, [], Ack) -> Ack. > > > > ...then lists:flatten/1 the result here before you return it, if you > > are you sure? > i tried this (but might have made a mistake) and the result i got was 1 > single (long) string. > the original result, a list of strings, is much more readable. >From the efficency guide: When you have a deep list of depth 1 you can flatten it using append/1 [...] NOTE: If your deep list is a list of strings you will not get the wanted result using flatten. Remember that strings are lists. See example below: > lists:append([["foo"], ["bar"]]). ["foo","bar"] > lists:flatten([["foo"], ["bar"]]). "foobar" -- /m.v.h Ingela //The highway of life is always under construction. // |\ _,,,--,,_ ,) /,`.-'`' -, ;-;;' |,4- ) )-,_ ) /\ '---''(_/--' (_/-' Ericsson AB - OTP team Cellular/Mobile: +46 70 636 78 68 From thomasl_erlang@REDACTED Tue Apr 22 12:29:56 2003 From: thomasl_erlang@REDACTED (Thomas Lindgren) Date: Tue, 22 Apr 2003 03:29:56 -0700 (PDT) Subject: records generated from UBF In-Reply-To: <20030422082806.GA59293@frogman.motivity.ca> Message-ID: <20030422102956.42453.qmail@web13304.mail.yahoo.com> --- Vance Shipley wrote: > There seems to be no end to the options one has to > interface C with Erlang. > OTP provides two versions of a C interface; the > original erl_interface and > the newer ei version. It used to include IG > (Interface Generator) but that > is still available elsewhere. It also includes > Corba. Then there is > Scott's EDTK. > > Now we have UBF to consider as well. That is if it > had a C binding. Of > course there is also rpc and xml-rpc from user > contributions and I'm sure > countless other ways to talk between languages. So > many options. Hmmm... As we all know, the good thing with standards is that there are so many to choose from. Though one of Erlang's (or the Erlang community's) strong points is in being fairly agnostic about what you're talking to and how. "The communications hub of 21C", if you will. Best, Thomas __________________________________________________ Do you Yahoo!? The New Yahoo! Search - Faster. Easier. Bingo http://search.yahoo.com From joe@REDACTED Tue Apr 22 12:42:53 2003 From: joe@REDACTED (Joe Armstrong) Date: Tue, 22 Apr 2003 12:42:53 +0200 (CEST) Subject: Fwd: forwarded message from Christian Tismer (fwd) In-Reply-To: <200304181330.h3IDUfL7001748@ram.rentec.com> Message-ID: A Stackless Python context switch may or may not be faster than an Erlang context switch - in any case I fail to see why the question should be interesting. Stackless Python (presumably) allows for an efficient implementation of Python threads - but Python threads themselves seem to suffer from all the usual problems of thread programming - Erlang processes are *independent* (unless you link them) - Python threads share memory - so you need all the usual mess of synchronization primitives to get anything to work and one thread can happily corrupt the memory space of another - IMHO to write fault-tolerant code you need *independent* processes (not shared memory threads) - doing this takes processor power - so I'd expect an Erlang process to have 2-3 times the overhead of a thread (because it does a lot more) - what is surprising is that (say) Java threads are so heavyweight. Light-weight threads are presumably great if you want to convince a Java programmer to use Python - so they can carry on using a difficult to program shared memory thread model - but hardly something that is desirable in its own right - unless, of course, you actually like solving problems in the most difficult way possible :-) /Joe On Fri, 18 Apr 2003, HP Wei wrote: > > >> Stackless Python is more capable of tasklets > >> switching than any > >> other light-weight threading software package. > > >1. The benchmark itself seems kinda meaningless for a > >claim of being a fast thread package. Where is the IPC > >cost? The scheduling cost? The process creation cost? > >etc, etc. (Not to mention realistic conditions ... :-) > > >My system was this: RedHat 8.x Athlon 1300+ with 512 > >MB of slow memory running out-of-the-box Erlang R9B1. > >(system cost $400) > > >Result: csw did AT BEST 6.4 million Erlang context > >switches per second, and ON AVERAGE 5.8-5.9 million > >Erlang context switches per second, over a range of > >parameters (100k-10m context switches per benchmark > >run). > > > I run Thomas's csw.erl on my machine: > Sun-Blade-100 1GHz, 512Mb RAM, and SunOS 5.9, Erlang 5.2(R9B1) > > The result is about 3.1 million CS per second. > (A factor two slower than Thomas's result. Perhaps, I have a lot of > other stuff running on my machine.) > > ---------------------------- > I myself use python at work instead of perl (the company's standard > scripting language) because of its cleaner syntax. > I am learning Erlang now because of its simple (reads clear and effective) > communication stuff. > > --HP > > From richardc@REDACTED Tue Apr 22 13:45:38 2003 From: richardc@REDACTED (Richard Carlsson) Date: Tue, 22 Apr 2003 13:45:38 +0200 (MET DST) Subject: Package support in Erlang: Status ? In-Reply-To: <000901c3070f$701787c0$fd7a40d5@telia.com> References: <002101c30662$06d686b0$33bfee82@gnit> <000901c3070f$701787c0$fd7a40d5@telia.com> Message-ID: On Sun, 20 Apr 2003, Wiger Ulf wrote: > I have also privately suggested that Erlang allow "dotted atoms" (that > is, without single quotes) in other places as well, e.g. in registered > names, ets tables, etc. This would make package support feel a little > less like an afterthought, and more like an integrated part of the > language. You mean like this?: 1> register(self(), fee.fie.foo). ok 2> whereis(fee.fie.foo). <0.31.0> It's already there, if you try it. If you find some example of where it does not work, please report it to me. /Richard Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) E-mail: Richard.Carlsson@REDACTED WWW: http://user.it.uu.se/~richardc/ "Having users is like optimization: the wise course is to delay it." -- Paul Graham From etxuwig@REDACTED Tue Apr 22 14:13:34 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Tue, 22 Apr 2003 14:13:34 +0200 (MEST) Subject: Package support in Erlang: Status ? In-Reply-To: Message-ID: On Tue, 22 Apr 2003, Richard Carlsson wrote: > >On Sun, 20 Apr 2003, Wiger Ulf wrote: > >> I have also privately suggested that Erlang allow >> "dotted atoms" (that is, without single quotes) in other >> places as well, e.g. in registered names, ets tables, >> etc. This would make package support feel a little less >> like an afterthought, and more like an integrated part of >> the language. > >You mean like this?: > > 1> register(self(), fee.fie.foo). > ok > 2> whereis(fee.fie.foo). > <0.31.0> > >It's already there, if you try it. If you find some example >of where it does not work, please report it to me. I admit that I hadn't tried it. Moot point then. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From mickael.remond@REDACTED Tue Apr 22 15:57:05 2003 From: mickael.remond@REDACTED (Mickael Remond) Date: Tue, 22 Apr 2003 15:57:05 +0200 Subject: TIPC: Carrier Grade Cluster Protocol (Slightly Off Topic) Message-ID: Hello, Here is a link to another Ericsson project that has recently been released under an Open Source license. http://tipc.sourceforge.net/ The Telecom Inter Process Communication (TIPC) protocol is specially designed for intra cluster communication, and has been used as a part of Ericsson products for years. It has now been ported to Linux, provided as a portable source code package implementing a loadable kernel module. Cheers, -- Micka?l R?mond http://www.erlang-projects.org/ From erik@REDACTED Tue Apr 22 18:55:08 2003 From: erik@REDACTED (Erik Pearson) Date: Tue, 22 Apr 2003 09:55:08 -0700 Subject: records generated from UBF In-Reply-To: Message-ID: <2C79B35B-74E3-11D7-AA29-0050E4594D1D@adaptations.com> Hi Joe, Thanks for the clarification. I think the reason it was an issue for me was the approach I had taken to write the parser, which was more akin to: - start reading a stream, byte at a time. - feed bytes to whitespacecomsumer() - on the first non-whitespce bytecode , you know what the upcoming object is - now feed bytes to a function which knows how to collect that object, getint(), getstring(), etc. - that function: collects the bytes, when it sees the object termination condition, turns them into native object, returns that object and the next function to use. I've since rewritten the parser to rely on generalized stream-consuming functions which respond to different types of byte collection and detection requests (collect-until, collect-while, etc.). It is now utilizes something of a little stack (actually an associative list to store facts about each object as they are discovered - value, tag, termination bytecode). It is implemented in Common Lisp, so it is a little weird. Anyway, not that you wanted to know all of _that_ ... On Tuesday, April 22, 2003, at 01:25 AM, Joe Armstrong wrote: > On Sat, 19 Apr 2003, Erik Pearson wrote: > >> After a little more fiddling around, I have a practical question about >> UBF(A): >> >> The representation of a "binary" type is: >> >> Int ~blahblah~ >> >> Where Int is an integer, and ~ is the delimiter for the binary data, >> and blahblah is a stream/array of bytes Int long (and the space is 0 >> or >> more spaces) >> >> In order resolve the ambiguity with regular Int , the otherwise simple >> parsing becomes more complicated. It seems to me, unnecessarily >> complex. That is, the parser first determines that there is an int, >> and >> then it has to keep going to determine whether it really is an int or >> whether it will become a binary. >> >> What if the binary representation was something like >> >> ~ Int ~blahblah~ >> >> Then the initial ~ would be a nice and and simple flag for the parser >> that binary value was coming up. This would be consistent with all of >> the other simple types, for which the initial byte serves as a flag >> for >> the type (" for string, ' for contants, 0-9 or - for number (oops, or >> binary)...) >> > > IMHO this would be more difficult to parse :-) I guess simplicity is in the eye of the beholder! Seriously, though, I guess there are multiple issues to be juggled here... - merit of the design (elegance, extensibility, etc.) - efficiency (size of objects, ease of parsing) - simplicity (amount of code to implement, number of words in the spec.) - ease of implementation in various languages (since this is a "glue" between disparate systems, this is important.) Of course, what really grabbed me about UBF was that you (Joe) attacked some of these issues head-on, without the usual XML b.s. (pardon me). I think these issues become less relevant to the end user if they don't have to implement their own clients and servers -- if there are free clients (and possibly servers) for multiple platforms (java, tcl, c, python, perl, vb, c#, com, scheme, lisp :) etc.) as hinted in the UBF materials, then implementation issues are much lower in importance. With free clients on your platform and language of choice, and a free (and free) Erlang server, I guess no-one could complain about anything! Erik. > > You should think of UBF(A) as a byte code program designed to be > executed by a push down autonoma. As soon as you recognize *anything* > you just push it onto the stack. > > So to parse: > > 123 ~.....~ > > The parser proceeds as follows: > > > 1) Recognize that "1" is the start of an integer > 2) go get the integer > 3) Blank terminates the integer so push the recognized integer > "123" onto the stack > 4) Recognize ~ - this means "here comes a memory buffer" > the length will be on the top of the stack > Pop the stack > 5) collect 123 bytes into a memory buffer > 6) push the memory buffer onto the stack > 7) collect a ~ > > Step 7 is (or course) not necessary. > > UFB(A) has a few "features" to make it not only easy to parse > but easy to read and write - Thus the trailing ~ is just there to make > it easier to read. > > > >> Finally, just a quick correction to the spec at >> >> http://www.sics.se/~joe/ubf/site/ubfa.html >> >> I believe the structure should be defined with comma separators rather >> than just whitespace >> >> { Obj1, Obj2, ..., Objn } >> >> rather than >> >> { Obj1 Obj2 ... Objn } >> >> The examples show the comma separators. > > Again this is just to make it easier to read - commas and white space > mean the same. (But above didn't you say that comma is the bytecode for element separation; if it is also the same as whitespace how can it separate. Perhaps I need to enlarge the font on my monitor...) I don't know if you saw my other notes, but the problem I was having is the separation of objects within the structure. At that time I did not realize that the bytecode for delimiting tags was the backquote -- I thought it was single quote and thus the tag was just a constant. In that case, one would have a problem keeping track of objects without an explicit separator. With that confusion removed, that particular issue goes away. Another issue is that without an object separator (or the ? "null" bytecode you suggested) you can't include missing/null objects because it will just look like more whitespace (although you can include blank strings, constants, etc. -- just not untagged integers) Erik. > > /Joe > > > >> Thanks, >> >> Erik. >> >> >> On Wednesday, April 16, 2003, at 09:18 AM, Erik Pearson wrote: >> >>> Thanks Ulf, >>> >>> I hadn't actually looked for the java stuff in the download, since it >>> the java section of the site says that it is not done yet! Well, >>> there >>> it is! >>> >>> It works fine so far. >>> >>> FWIW, this is probably what how I'll attempt to use it first -- What >>> I'm doing is integrating it into my web server scripting language (a >>> very close offshoot of Tcl, from the Jacl tcl implementation, that >>> is, >>> Tcl implemented in Java). I'm starting with just UBF(A), since for my >>> purposes gettting two or more disparate network services (web or >>> other) to exchange information is the first goal. The first bit of >>> work will be to implement a pleasant java/tcl interface so that >>> UBF(A) >>> can be easily scripted on the web server. Since UBF(A) is >>> straightforward, that part should be pretty easy, and is mostly >>> working now. After that, UBF(B)... >>> >>> On the other side of the equation are several other related network >>> services or applications which are variously implemented (currently) >>> in Tcl and CL. Now, the discovery of UBF has prompted me to rethink >>> the usage of Erlang for these same services. (I had been using >>> Erlang, >>> but issues with mnesia caused me to put it aside for a while...) >>> >>> BTW, the very practical and straightforward nature of UBF fits right >>> into why Erlang has always been so appealing (to me.) >>> >>> I'll check back later (after my very short vacation) in if I get some >>> interesting results. >>> >>> Thanks, >>> >>> Erik. >>> >>> >>> On Tuesday, April 15, 2003, at 01:43 AM, Ulf Wiger wrote: >>> >>>> On Tue, 15 Apr 2003, Erik Pearson wrote: >>>> >>>>> I'd like to give UBF a try. It looks really great, and >>>>> thanks for your addition to it. >>>> >>>> Good. (: >>>> >>>> Joe is, I believe, in Iceland this week, undoubtedly >>>> spending quality time trying out all the hot baths there. >>>> Let's see how he wants to play it when he gets back. >>>> Otherwise, you can certainly download whatever he has made >>>> available on his website, and I can send you my modified >>>> version, with absolutely no guarantees. ;-) >>>> >>>> >>>>> What would be great, though, is if someone can share a Java >>>>> implementation (or any other implementation out there, e.g. >>>>> Tcl). I need it to glue together a Java servlet to Erlang >>>>> (or whatever). >>>>> >>>>> From the UBF paper, it appears that a Java implementation >>>>> was largely completed. It would be great to either use that >>>>> code, or start with it and complete the implementation far >>>>> enough to get something working. >>>> >>>> There are two Java implementations that I know of. Luke's >>>> Java client that's included in Joe's care package, and Jon >>>> ?kerg?rden's Athletics client prototype. Jon's Java code can >>>> be downloaded from http://www.it.kth.se/~e98_jak/ >>>> However, Jon is actively working on the code right now, so >>>> the downloadable version is almost certainly outdated. >>>> >>>>> From a quick glance (and be warned: I've yet to write even >>>> Hello World in Java), Luke's UBF decoder seems to lack >>>> caching support(*), and Jon's decoder lacks support for >>>> binaries; I'm also unsure about whether Jon's decoder >>>> handlers escaping properly, but Luke's does. >>>> >>>> If you take the union of the two, you probably have a >>>> complete decoder, but they don't seem totally compatible to >>>> me. ;) Someone else with more knowledge of Java will >>>> perhaps see things differently. >>>> >>>> /Uffe >>>> >>>> (*) This is only a problem if the other side uses caching. >>>> Joe's Erlang-based UBF encoder will take advantage of >>>> caching, so a corresponding decoder will of course have to >>>> as soon as there is something cachable in the messages. >>>> >>>> -- >>>> Ulf Wiger, Senior Specialist, >>>> / / / Architecture & Design of Carrier-Class Software >>>> / / / Strategic Product & System Management >>>> / / / Ericsson AB, Connectivity and Control Nodes >>>> >>>> >>> Erik Pearson >>> Adaptations >>> desk +1 510 527 5437 >>> cell +1 510 517 3122 >>> >>> >> Erik Pearson >> Adaptations >> desk +1 510 527 5437 >> cell +1 510 517 3122 >> > > Erik Pearson Adaptations desk +1 510 527 5437 cell +1 510 517 3122 From erlang@REDACTED Tue Apr 22 16:34:44 2003 From: erlang@REDACTED (Inswitch Solutions - Erlang Evaluation) Date: Tue, 22 Apr 2003 16:34:44 +0200 Subject: Binary parsing Message-ID: <00b701c308dc$51d644d0$1e00a8c0@design> I have a C/C++ port which receives bytes to be parsed for a specific protocol. The parsing could be done in C/C++ or I can forward the bytes to Erlang and make the parsing here. What would be the best choice ? By means of performance how is binary pattern matching in Erlang compared to C/C++ code? Thanks, Eduardo Figoli INSwitch Solutions -------------- next part -------------- An HTML attachment was scrubbed... URL: From vances@REDACTED Tue Apr 22 22:08:46 2003 From: vances@REDACTED (Vance Shipley) Date: Tue, 22 Apr 2003 16:08:46 -0400 Subject: Binary parsing In-Reply-To: <00b701c308dc$51d644d0$1e00a8c0@design> References: <00b701c308dc$51d644d0$1e00a8c0@design> Message-ID: <20030422200846.GO53726@frogman.motivity.ca> Depends on whether you are referring to runtime performance or your own performance in programming it. :) -Vance On Tue, Apr 22, 2003 at 04:34:44PM +0200, Eduardo Figoli wrote: } } By means of performance how is binary pattern matching in Erlang } compared to C/C++ code? From cpressey@REDACTED Tue Apr 22 22:14:12 2003 From: cpressey@REDACTED (Chris Pressey) Date: Tue, 22 Apr 2003 15:14:12 -0500 Subject: optimization ? In-Reply-To: <200304220834.h3M8YTi12216@cbe.ericsson.se> References: <200304220834.h3M8YTi12216@cbe.ericsson.se> Message-ID: <20030422151412.2f646d5c.cpressey@catseye.mb.ca> On Tue, 22 Apr 2003 10:34:29 +0200 (MEST) Bengt Kleberg wrote: > > > Date: Tue, 22 Apr 2003 01:09:11 -0500 > > From: Chris Pressey > > Subject: Re: optimization ? > ...deleted > > expensive compared to a simple cons. You might want to try > > [T|Acc]... > > > > > end; > > > Other -> > > > dirs(Top, Tail, Acc) > > > end; > > > > > > dirs(_Top, [], Ack) -> Ack. > > > > ...then lists:flatten/1 the result here before you return it, if you > > are you sure? Oops. No, you're right, I forgot the list was of strings. Flattening it doesn't make sense, and if you leave it deep it can reflect the directory structure, which might be handy. Anyway, it looks like the real culprit is file:read_link_info/1. > i tried this (but might have made a mistake) and the result i got was > 1 single (long) string. > the original result, a list of strings, is much more readable. > > > bengt -Chris From enewhuis@REDACTED Tue Apr 22 22:32:01 2003 From: enewhuis@REDACTED (Eric Newhuis) Date: Tue, 22 Apr 2003 15:32:01 -0500 Subject: Binary parsing References: <00b701c308dc$51d644d0$1e00a8c0@design> <20030422200846.GO53726@frogman.motivity.ca> Message-ID: <005801c3090e$3ab57af0$34c2cf0a@futuresource.com> In my experience C++ binary pattern matching crashes much faster than Erlang. ;-) From cpressey@REDACTED Tue Apr 22 22:35:16 2003 From: cpressey@REDACTED (Chris Pressey) Date: Tue, 22 Apr 2003 15:35:16 -0500 Subject: catching errors from linked processes: simplest way? In-Reply-To: <3EA4E176.9070106@st.se> References: <20030422004917.1b90a16c.cpressey@catseye.mb.ca> <3EA4E176.9070106@st.se> Message-ID: <20030422153516.0d82b09d.cpressey@catseye.mb.ca> On Tue, 22 Apr 2003 08:30:14 +0200 Lennart ?hman wrote: > Hi > > Chris Pressey wrote: > > OK, so, I'm actually trying to write 'aggressively simple' code now, > > Good! :-) > > The "aggressive way" when having several processes is to have one (or > possibly several if it is a complicated system) process which > supervises the other(s). In this way you move all the error handling, > if you need it at all, away from the code implementing the logic. > > You should then try to write the code in a way that the logic works > fine without the supervision (during normal input). The supervision is > then only an add-on to provide robustness. > > /Lennart OK! I wrote a supervisor process to catch errors from both the client and the server, and it works fairly well. However, I got to another sticking point. I have several functions that only make sense under a certain condition, let's call it A. The functions used to look like this: foo(A, B) -> case A of true -> bar(B); false -> {error, only_applies_under_condition_a} end. Now, they look like this: foo(A, B) -> A = true, bar(B). which is *much* easier to read. :) However, the error message has gone from a nice, informative one, to the generic {badmatch, true}, which is not all that great (I'd like to be able to give the (probably non-Erlang-literate) user a message as to exactly why it crashed.) I can think of two ways to handle this: either translate the error in the client, or translate the error in the supervisor. If I do the translation in the client, I would have: foo(A, B) -> case A of true -> bar(B); false -> throw(only_applies_under_condition_a) end. which is hardly any improvement over the original. If I do the translation in the supervisor, I would have something like: process_flag(trap_exits, true), receive ... {'EXIT', Client, {{badmatch, true}, [{module,foo,2} | Tail]}} -> io:fwrite("Client code violated condition A~n"); ... end. This is worrisome. First, if I change the implementation of the client, say if I move what foo does to another function, then I have to change the supervisor code to reflect it. Second, the supervisor is inferring (guessing!) that condition A was violated because it knows that it's the only one in foo. If there were two or more invariants in foo, it wouldn't know which one was violated. I guess the underlying 'problem' is that there's no way (that I'm aware of) to pass along some state when an error occurs, without causing that error yourself. I think such a thing would be really very handy, especially when I consider things like encountering an error when parsing a text file - you would want the supervisor to know which line, column, and token you choked on. Or is this just 'too aggressive'? It seems there is a time and place for error return values instead of crashing, and this may be it. -Chris From cpressey@REDACTED Tue Apr 22 23:44:32 2003 From: cpressey@REDACTED (Chris Pressey) Date: Tue, 22 Apr 2003 16:44:32 -0500 Subject: catching errors from linked processes: simplest way? In-Reply-To: <20030422153516.0d82b09d.cpressey@catseye.mb.ca> References: <20030422004917.1b90a16c.cpressey@catseye.mb.ca> <3EA4E176.9070106@st.se> <20030422153516.0d82b09d.cpressey@catseye.mb.ca> Message-ID: <20030422164432.299014e4.cpressey@catseye.mb.ca> On Tue, 22 Apr 2003 15:35:16 -0500 Chris Pressey wrote: > If I do the translation in the client, I would have: > > foo(A, B) -> > case A of > true -> > bar(B); > false -> > throw(only_applies_under_condition_a) > end. > > which is hardly any improvement over the original. Ah! I think I see a compromise: notify the supervisor of the nature of any potential upcoming errors. So the code becomes something like: foo(A, B) -> supervisor:potential_error(only_applies_under_condition_a, [A,B]), A = true, bar(B). where supervisor:potential_error/2 sends a message to the supervisor, which stores it in a dictionary using the pid the message came from as the key, and which retrieves it when an error actually does occur. The code is still fairly easy to read, and the supervisor doesn't need to know about the structure of the code it's supervising, yet it can know some details about what state the process was in when it crashed. Sweet! -Chris From vances@REDACTED Wed Apr 23 00:23:39 2003 From: vances@REDACTED (Vance Shipley) Date: Tue, 22 Apr 2003 18:23:39 -0400 Subject: catching errors from linked processes: simplest way? In-Reply-To: <20030422164432.299014e4.cpressey@catseye.mb.ca> References: <20030422004917.1b90a16c.cpressey@catseye.mb.ca> <3EA4E176.9070106@st.se> <20030422153516.0d82b09d.cpressey@catseye.mb.ca> <20030422164432.299014e4.cpressey@catseye.mb.ca> Message-ID: <20030422222339.GU53726@frogman.motivity.ca> It seems like a workable solution however I don't find it elegant. It seems to me that since the problem you are trying to solve is an error handling one it should be solved in the error handler. If the error handler needs to have knowledge of the structure of the code to do the error handling the way you want then so be it. -Vance On Tue, Apr 22, 2003 at 04:44:32PM -0500, Chris Pressey wrote: } } Ah! I think I see a compromise: notify the supervisor of the nature of } any potential upcoming errors. So the code becomes something like: } } foo(A, B) -> } supervisor:potential_error(only_applies_under_condition_a, [A,B]), } A = true, bar(B). } } where supervisor:potential_error/2 sends a message to the supervisor, } which stores it in a dictionary using the pid the message came from as } the key, and which retrieves it when an error actually does occur. } } The code is still fairly easy to read, and the supervisor doesn't need } to know about the structure of the code it's supervising, yet it can } know some details about what state the process was in when it crashed. } } Sweet! } } -Chris From etxuwig@REDACTED Wed Apr 23 00:55:54 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Wed, 23 Apr 2003 00:55:54 +0200 (MEST) Subject: catching errors from linked processes: simplest way? In-Reply-To: <20030422153516.0d82b09d.cpressey@catseye.mb.ca> Message-ID: How about writing a small library function: assert(false, Msg) -> exit(Msg); assert(true, _) -> true. foo(A, B) -> assert(A, only_applies_under_condition_a), bar(B). /Uffe On Tue, 22 Apr 2003, Chris Pressey wrote: >However, I got to another sticking point. I have several functions that >only make sense under a certain condition, let's call it A. The >functions used to look like this: > > foo(A, B) -> > case A of > true -> > bar(B); > false -> > {error, only_applies_under_condition_a} > end. > >Now, they look like this: > > foo(A, B) -> > A = true, bar(B). > >which is *much* easier to read. :) > >However, the error message has gone from a nice, >informative one, to the generic {badmatch, true}, which is >not all that great (I'd like to be able to give the >(probably non-Erlang-literate) user a message as to exactly >why it crashed.) -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From hp@REDACTED Wed Apr 23 01:34:12 2003 From: hp@REDACTED (HP Wei) Date: Tue, 22 Apr 2003 19:34:12 -0400 (EDT) Subject: optimization ? Message-ID: <200304222334.h3MNYCL7020183@ram.rentec.com> Thank you very much for giving various pointers. I will pick up the tool fprof. I looked at the codes in file.erl in the lib/kernel/src and found that all system file related operations are done through a file server. The overhead perhaps explains why this function for extracting a list of subdirectories is slow (in comparison to python's version which calls a C-function directly as I understand). Perhaps, if necessary, I will need to study the foreign language interface in Erlang. --HP >According to fprof function spends most time in {file,read_link_info}: > CNT ACC >{test,dirs,3} 1086 2365.887 >{file,read_link_info,1} 1010 2152.686 >{erlang,'++',2}, 1085 24.044 ---------------------- >Anyway, it looks like the real culprit is file:read_link_info From raimo.niskanen@REDACTED Wed Apr 23 08:34:48 2003 From: raimo.niskanen@REDACTED (Raimo Niskanen) Date: Wed, 23 Apr 2003 08:34:48 +0200 Subject: catching errors from linked processes: simplest way? References: <3EA4E176.9070106@st.se>, <20030422153516.0d82b09d.cpressey@catseye.mb.ca>, <20030422164432.299014e4.cpressey@catseye.mb.ca> Message-ID: You could add some supervision to the client by using a toplevel catch. Then you will get a stack dump. The following code also demonstrates a line number macro trick with the process dictionary that is possible if you have a toplevel catch in the client. Runtime result: 21> test:top(). {'EXIT',{{badmatch,b}, [{test,foo,0}, {test,do,0}, {test,top,0}, {erl_eval,expr,3}, {erl_eval,exprs,4}, {shell,eval_loop,2}]}} at test:22 error / Raimo Niskanen, Erlang/OTP, Ericsson AB -module(test). -export([top/0]). -define(line, put(location,{?MODULE,?LINE}),). top() -> ?line case catch do() of {'EXIT',_} = Exit -> {Module,Line} = get(location), io:format("~p at ~w:~w~n", [Exit,Module,Line]), error; Result -> {ok,Result} end. do() -> ?line foo(), ?line bar(). foo() -> ?line a=b. bar() -> ok. Chris Pressey wrote: > On Tue, 22 Apr 2003 15:35:16 -0500 > Chris Pressey wrote: > > >>If I do the translation in the client, I would have: >> >> foo(A, B) -> >> case A of >> true -> >> bar(B); >> false -> >> throw(only_applies_under_condition_a) >> end. >> >>which is hardly any improvement over the original. > > > Ah! I think I see a compromise: notify the supervisor of the nature of > any potential upcoming errors. So the code becomes something like: > > foo(A, B) -> > supervisor:potential_error(only_applies_under_condition_a, [A,B]), > A = true, bar(B). > > where supervisor:potential_error/2 sends a message to the supervisor, > which stores it in a dictionary using the pid the message came from as > the key, and which retrieves it when an error actually does occur. > > The code is still fairly easy to read, and the supervisor doesn't need > to know about the structure of the code it's supervising, yet it can > know some details about what state the process was in when it crashed. > > Sweet! > > -Chris From jay@REDACTED Wed Apr 23 09:36:14 2003 From: jay@REDACTED (Jay Nelson) Date: Wed, 23 Apr 2003 00:36:14 -0700 Subject: catching errors from linked processes (Long) Message-ID: <4.2.2.20030422233328.00ce1a30@duomark.com> These sorts of questions are what make erlang so interesting to me. They appear simple and broad brush at first, but if you look closely they are actually very subtle and involve tradeoffs that you would never recognize in other languages. In C, you must code defensively because once you core dump there are no options and with runaway code there is no telling what will happen next. In erlang you have so many choices it is difficult to decide what to do. There are actually three issues at play in this question: how should code be structured; how should errors be reported; and how should processes be layered. Each of these issues depends on the situation at hand. Taken together they raise another issue: how do you plan to reuse or share the code and processes? Code should be as simple as possible and no simpler. This is the standard erlang admonishment. Sounds well enough -- challenges your skill but makes sense. When it comes to real code though, it is actually deeper than that. The structure of code depends on the stage of development. There are at least 4 stages: get it working; make it clear; worry about errors; and worry about performance. They may not always be performed in this order, but in most cases it is better if they are. Get it working is the great globs of wet clay stuff, where you hack for a few hours until you see reasonable results occasionally. You only feed it valid data with expected results and shape it until it looks like it is working. Make it clear is when you understand the problem after having solved it once. You recognize the repetition and generalization and restructure the code to capture the problem space rather than to issue a handful of correct answers. Much code ends after this step. Worry about errors is when the code structure is fairly stable, but you now consider what wacky input might arrive and what the consequences are. Even if "let it fail" is your motto, you need to reason about what that means at this stage. The clarity model might get dramatically shifted to handle errors because operationally it turns out error handling is more important than code maintenance. Worry about performance should only happen when enough of the other stages are correct so that slow performance is the most glaring problem. Again the code may be restructured against clarity to improve performance. Simple as possible but no simpler means different things for each of the stages of "code development" (as in growth and maturity just like "child development"). Errors Don't worry about errors, just let it fail. That is the erlang way. Like all things erlang it sounds simple and easy, but is actually a very subtle thing. I can think of three good reasons to let it fail: highlight errors in the code so they can be corrected; avoid something really bad from happening and reset to a known state; or notify external systems (or users) about bad data they are supplying so it can be corrected. If you are still actively developing the code, failure is the quickest way to find the exact point where things went wrong. It facilitates finding coding errors even if other users report the error to you. Here the point of failure is most important, followed by information about the failure. Runaway code can be dangerous in some situations. Banks don't want money given away (the US Govt once sent out thousands of checks with refunds for people who shouldn't have gotten them, but it was cheaper to let them keep it then to try to get it back), flying machines can't fail catastrophically, etc. Once the system detects that it is in trouble, failing can stop things from getting out of control as well as reset the state of the process to the initial known restart state. Stopping and restarting is more important here than why the failure occurred. (Could this be called "defensive coding"?) When user input or input from other systems causes unexpected processing, failure can notify them that something should be altered, although it is essential that you determine what effect failure has on the external system (whether human or otherwise). In this case, the information conveyed is probably more important than the failure or where it happened. The external system has to change its behavior based on the error result. In each of these three cases the type and amount of information communicated as part of the failure serves different goals and would vary accordingly. Process layering Supervisor processes can be used to monitor other processes. Typically they would do two things: relay error states and restart the failed process. If collecting and logging the failure is useful, an external process can catch the failures, sort the errors and relay them to other processes, produce statistics or log them to files or databases. [During debugging I could imagine a pop up window like the toolbar process window that showed a tally of process failures counted by type as detected in the error stack trace state.] If the process is a service that needs to remain available the supervisor can restart to a known function state (the initial state). It can also try to reason out why the failure occurred (or just use some simple rule of thumb) and try alternatives like restarting on another node, substituting a different process or after having no luck failing and letting a higher level supervisor try to restart this supervisor and cause a downward cascade of restarts with new parameters supplied by higher level logic. Again, it depends on the goals and purpose as to what behavior the supervisor should take (if one is even necessary). Code and process reuse The partitioning of code and processes may get restructured as soon as you have a second system which needs to reuse some of the functionality. Splitting the code into processes may facilitate reuse, recovery, failure and supervision. I'll have to check my list of reasons for processes. I'm sure I had one for abstraction and code reuse, but I don't think I had one for fault isolation. Fault Isolation = use a process where failure will keep a bad state from propagating through the system causing more damage, and when a restart of the faulted process can produce a fully functioning system automatically (possibly after moving the process or changing its config parameters before restart). The above shows that what erlang tries to do is provide a layered approach to code development. Make each layer understandable and uncluttered, layer process logic so that algorithm, error handling and recovery are not intertwined, and use processes judiciously to manage the abstraction, isolate faults and restart (or upgrade code) in pieces without require the entire system to fail or stop. So the simple "let it fail" to me means: 1) Don't worry about errors when trying to get the code to work 2) When organizing a system of processes (which may occur before #1), really, really worry about what *should* happen when a process dies. Architect the system to "do the right thing" and to dictate what the code should *intend* in the failure cases and how other processes should react. 3) Expect *every* line of code you write to fail the entire process and write the code so that the (un)intended failure happens in an intended way In Chris' code example he used a case statement and received an error that was vague. Using function clause failure provides more information. Here are three different ways of writing the same code. foo(Pred, X) -> case Pred of true -> bar(X) end. This is the method that allows you to add error handling clauses in the case. If you really, really don't want a failure here, put an open ended clause that does something useful (and maybe causes the failure elsewhere). If you don't need too much information to react, the closed case above will fail but not give a lot of info. In that scenario, the clarity of code would override the need for detailed failure info. foo(Pred, X) -> Pred = true, bar(X). Here even less failure info is provided, although the code is probably clearer. In the first example, the reader wonders why the case is left dangling with something left out. Here the Pred is intentionally a roadblock. foo(true, X) -> bar(X). This may end up for clarity or for performance reasons. It is more concise, but relies more on the language and compiler. As it happens, it also provides more info in the failure case. Any of the three choices is valid, but it depends on the stage of code development and the existence and sophistication of external processes and supervisor processes. If you later decide to reuse the code, the restrictions on failure cases, error reporting requirements or other constraints may change and cause a refactoring or rewriting of the code. Notice that in C / Java you don't get the choice. You have to handle the error and assume the caller will understand the error flags you pass back. If the process fails you have no recourse and no second chance. You can use try and catch in Java but the algorithm becomes cluttered and the logic is confusing to get right. jay From svg@REDACTED Wed Apr 23 16:29:14 2003 From: svg@REDACTED (Vladimir Sekissov) Date: Wed, 23 Apr 2003 20:29:14 +0600 (YEKST) Subject: erl_parse bug. Message-ID: <20030423.202914.74734501.svg@surnet.ru> Good day, I've found that some sort of incorrect syntax constructs cause erl_parse to infinit loop: 1> A=a. a 2> A.b. Hangs forever. Best Regards, Vladimir Sekissov From richardc@REDACTED Wed Apr 23 17:00:24 2003 From: richardc@REDACTED (Richard Carlsson) Date: Wed, 23 Apr 2003 17:00:24 +0200 (MET DST) Subject: erl_parse bug. In-Reply-To: <20030423.202914.74734501.svg@surnet.ru> References: <20030423.202914.74734501.svg@surnet.ru> Message-ID: This has been fixed in the coming release. /Richard On Wed, 23 Apr 2003, Vladimir Sekissov wrote: > I've found that some sort of incorrect syntax constructs cause > erl_parse to infinit loop: > > 1> A=a. > a > > 2> A.b. > > Hangs forever. > > Best Regards, > Vladimir Sekissov > Richard Carlsson (richardc@REDACTED) (This space intentionally left blank.) E-mail: Richard.Carlsson@REDACTED WWW: http://user.it.uu.se/~richardc/ "Having users is like optimization: the wise course is to delay it." -- Paul Graham From kent@REDACTED Wed Apr 23 17:02:22 2003 From: kent@REDACTED (Kent Boortz) Date: 23 Apr 2003 17:02:22 +0200 Subject: New list erlang-bugs@erlang.org Message-ID: There is now a new list . On this list OpenSource users of Erlang can submit bug reports. Commercial customers report bugs using the same support address as before. Please send bug reports that include a patch to . As with the erlang-patches list, the erlang-bugs list is open so that anyone can read, discuss, suggest and contribute with corrections and workarounds. Thank you for contributing to the development and use of Erlang/OTP, kent From cpressey@REDACTED Wed Apr 23 22:12:05 2003 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 23 Apr 2003 15:12:05 -0500 Subject: catching errors from linked processes: simplest way? In-Reply-To: <20030422222339.GU53726@frogman.motivity.ca> References: <20030422004917.1b90a16c.cpressey@catseye.mb.ca> <3EA4E176.9070106@st.se> <20030422153516.0d82b09d.cpressey@catseye.mb.ca> <20030422164432.299014e4.cpressey@catseye.mb.ca> <20030422222339.GU53726@frogman.motivity.ca> Message-ID: <20030423151205.56031112.cpressey@catseye.mb.ca> On Tue, 22 Apr 2003 18:23:39 -0400 Vance Shipley wrote: > It seems to me that since the problem you are trying to solve is an > error handling one it should be solved in the error handler. If the > error handler needs to have knowledge of the structure of the code > to do the error handling the way you want then so be it. I ended up using a combination of this (for generic errors, where no real awareness of the structure of the code is needed) and Ulf's suggestion for 'assert' (for specific errors.) 'assert' is simple and clear, and it's not error handling so much as simply error-causing, so it's quite OK to put in mainline code as far as I can see. My program looks nice now, and behaves nicely too. Thanks to everyone who helped me understand! I'm still fuzzy on a few things. Hard to put into words, my head is still swimming: When you start an application (or, actually, any function that hides several processes,) aren't what you really doing, is starting that application's supervisor? That is, if any process in the application exits with an error, the supervisor notices, shuts down all its processes, and returns the error to you (the caller of the application)? So that, from your perspective, the application just looks like a regular function call, which you can catch to handle any of the errors in any of the processes inside it? (I'm thinking specifically of applications that have a finite time domain and a measurable outcome here, not a long-lived application with no definate end.) I realize I might not be explaining it well, but it's something that always confused me from trying to grasp the concept from the OTP docs. Thanks again, -Chris From ds.erl@REDACTED Wed Apr 23 22:18:49 2003 From: ds.erl@REDACTED (Daniel Solaz) Date: Wed, 23 Apr 2003 22:18:49 +0200 Subject: trouble with files bigger than 4GB In-Reply-To: <3EA4F06D.90703@uab.ericsson.se> References: <200304162052.34521@no.siento.las.piennas> <200304181515.42510@no.siento.las.piennas> <3EA4F06D.90703@uab.ericsson.se> Message-ID: <200304232205.25822@no.siento.las.piennas> On Tuesday 22 April 2003 09:34 Raimo Niskanen wrote: > Daniel Solaz wrote: > > Yes, this is described in the lfcompile(5) man page. > > I'll try to hack the appropriate Makefile(s) and recompile so I can > > check whether this is enough to get the code working, where working > > means "like in FreeBSD". > Well, I will fix the simple bug i mentioned above, but if off_t is 4 > bytes, there is not much to do on such a system. There is no high > word to make use of. File size (or absolute position) 4294967296 is > indistinguishable from 0. Absolute position 4294967295 is the same as > error return value -1 from lseek(). Great, FreeBSD issue solved. Thanks. On 32bit Solaris, adding -D_FILE_OFFSET_BITS=64 to the cc call does the trick: off_t becomes 8 bytes long, fopen() means fopen64(), etc. However, according to the docs, this does interact badly with some other OS subsystems. So I'd like to try this first and report whether things work, or at least seem to. But I lack the expertise required to hack configure so that it compiles the off_t size test with -D_FILE_OFFSET_BITS=64 and generates new Makefiles with -D_FILE_OFFSET_BITS=64 in them. Can anyone give me a pointer? -Daniel From lennart.ohman@REDACTED Wed Apr 23 22:42:26 2003 From: lennart.ohman@REDACTED (=?ISO-8859-1?Q?Lennart_=D6hman?=) Date: Wed, 23 Apr 2003 22:42:26 +0200 Subject: catching errors from linked processes: simplest way? References: <20030422004917.1b90a16c.cpressey@catseye.mb.ca> <3EA4E176.9070106@st.se> <20030422153516.0d82b09d.cpressey@catseye.mb.ca> <20030422164432.299014e4.cpressey@catseye.mb.ca> <20030422222339.GU53726@frogman.motivity.ca> <20030423151205.56031112.cpressey@catseye.mb.ca> Message-ID: <3EA6FAB2.9070808@st.se> Hi, glad you found a solution you are satisfies with. Regarding starting an application, or as you put is, the top-most supervisor of that supervision tree: The idea in OTP is that we make a difference depending on in which context a "member process" terminates. During their start-phases (before all processes come past their init-phases (leaving the function named init)): Then you in the sence of making the function call to the start-function will get an error-return value (not an exit or similar). Such errors are referred to as start-errors and reported as such if you run SASL. No process is allowed to terminate during the init-phase. After the successful start-up: Then your start function-call has already returned {ok,Pid}. If you used start-link or otherwised linked yourself to that supervisor, you will get the exit-signal 'shutdown', indicating that the supervisor terminated nicely (i.e cleaning up properly). Processes may also terminate for "natural" reasons. OTP differs between illegal and legal terminations. The permanence of a process determines whether it is legal or illegal (a permanent process may never terminate for instance). Then you can of ocurse also have the scenario where you set the restart intensity of your supervisor(s), to allow restarts before it/they give up and terminate them self/ev. /Lennart Chris Pressey wrote: > On Tue, 22 Apr 2003 18:23:39 -0400 > Vance Shipley wrote: > > >>It seems to me that since the problem you are trying to solve is an >>error handling one it should be solved in the error handler. If the >>error handler needs to have knowledge of the structure of the code >>to do the error handling the way you want then so be it. > > > I ended up using a combination of this (for generic errors, where no > real awareness of the structure of the code is needed) and Ulf's > suggestion for 'assert' (for specific errors.) 'assert' is simple and > clear, and it's not error handling so much as simply error-causing, so > it's quite OK to put in mainline code as far as I can see. > > My program looks nice now, and behaves nicely too. > > Thanks to everyone who helped me understand! > > I'm still fuzzy on a few things. Hard to put into words, my head is > still swimming: > > When you start an application (or, actually, any function that hides > several processes,) aren't what you really doing, is starting that > application's supervisor? > > That is, if any process in the application exits with an error, the > supervisor notices, shuts down all its processes, and returns the error > to you (the caller of the application)? So that, from your perspective, > the application just looks like a regular function call, which you can > catch to handle any of the errors in any of the processes inside it? > > (I'm thinking specifically of applications that have a finite time > domain and a measurable outcome here, not a long-lived application with > no definate end.) > > I realize I might not be explaining it well, but it's something that > always confused me from trying to grasp the concept from the OTP docs. > > Thanks again, > -Chris -- ------------------------------------------------------------- Lennart Ohman phone : +46-8-587 623 27 Sjoland & Thyselius Telecom AB cellular: +46-70-552 6735 Sehlstedtsgatan 6 fax : +46-8-667 8230 SE-115 28 STOCKHOLM, SWEDEN email : lennart.ohman@REDACTED From hp@REDACTED Wed Apr 23 22:52:45 2003 From: hp@REDACTED (HP Wei) Date: Wed, 23 Apr 2003 16:52:45 -0400 (EDT) Subject: string conversion, format functions Message-ID: <200304232052.h3NKqjtW007584@wren.rentec.com> I have a string "123" and want to convert it to an integer or float, and vice versa. In python, I go to the string module and there are string.atoi(), string.atof(), and str(number). So, by habit, I went to string module doc in Erlang I could not find the counterparts of these functions. Where are they ? ------------------------- B = 3. I want to form a string "0003". ** Can io:format generate such a printout ? ** Can it be redirected to a string ? ** If not, how do folks in Erlang world do this padding? thanks, hp From cpressey@REDACTED Wed Apr 23 23:16:55 2003 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 23 Apr 2003 16:16:55 -0500 Subject: string conversion, format functions In-Reply-To: <200304232052.h3NKqjtW007584@wren.rentec.com> References: <200304232052.h3NKqjtW007584@wren.rentec.com> Message-ID: <20030423161655.4e51616b.cpressey@catseye.mb.ca> On Wed, 23 Apr 2003 16:52:45 -0400 (EDT) HP Wei wrote: > I have a string "123" and want to convert it to an integer > or float, and vice versa. > > In python, I go to the string module and > there are string.atoi(), string.atof(), and str(number). > So, by habit, I went to string module doc in Erlang > I could not find the counterparts of these functions. Where are they ? They're BIFs (Built In Functions); they can also be found in the module 'erlang': list_to_integer(String) list_to_float(String) integer_to_list(Integer) etc. btw, there is no integer_to_float; use coercion (Integer + 0.0 works) Also, converting the string "123" into a float will fail. > ------------------------- > B = 3. > > I want to form a string "0003". > ** Can io:format generate such a printout ? Hmmm... good question! If it can, it's not documented. (Why is there no formatting code for integers in io:format?) I tried 17> io:fwrite("~5.1.0f~n", [3 + 0.0]). 003.0 ok 18> io:fwrite("~5.0.0f", [3 + 0.0]). ** exited: {format,[{io,format,[<0.21.0>,"~5.0.0f",[3.00000]]}, {erl_eval,expr,3}, {erl_eval,exprs,4}, {shell,eval_loop,2}]} ** I also tried 20> io:fwrite("~5.0.0p~n", [3]). 3 ok No luck... > ** Can it be redirected to a string ? Yes, see io_lib:format/2. > ** If not, how do folks in Erlang world do this padding? I guess the best way right now is: 23> string:right(integer_to_list(3), 4, $0). "0003" > thanks, > hp Hope that helps, -Chris From spearce@REDACTED Wed Apr 23 23:37:06 2003 From: spearce@REDACTED (Shawn Pearce) Date: Wed, 23 Apr 2003 17:37:06 -0400 Subject: string conversion, format functions In-Reply-To: <200304232052.h3NKqjtW007584@wren.rentec.com> References: <200304232052.h3NKqjtW007584@wren.rentec.com> Message-ID: <20030423213706.GA23053@spearce.org> Strange, but they are in erlang, not strings: list_to_integer/1 integer_to_list/1 since a string is a list, they work quite well. :) HP Wei wrote: > I have a string "123" and want to convert it to an integer > or float, and vice versa. > > In python, I go to the string module and > there are string.atoi(), string.atof(), and str(number). > So, by habit, I went to string module doc in Erlang > I could not find the counterparts of these functions. Where are they ? > > ------------------------- > B = 3. > > I want to form a string "0003". > ** Can io:format generate such a printout ? > ** Can it be redirected to a string ? > ** If not, how do folks in Erlang world do this padding? > > thanks, > hp > -- Shawn. /* * [...] Note that 120 sec is defined in the protocol as the maximum * possible RTT. I guess we'll have to use something other than TCP * to talk to the University of Mars. * PAWS allows us longer timeouts and large windows, so once implemented * ftp to mars will work nicely. */ -- from /usr/src/linux/net/inet/tcp.c, concerning RTT [round trip time] From matthias@REDACTED Wed Apr 23 23:39:28 2003 From: matthias@REDACTED (Matthias Lang) Date: Wed, 23 Apr 2003 23:39:28 +0200 Subject: string conversion, format functions In-Reply-To: <20030423161655.4e51616b.cpressey@catseye.mb.ca> References: <200304232052.h3NKqjtW007584@wren.rentec.com> <20030423161655.4e51616b.cpressey@catseye.mb.ca> Message-ID: <16039.2064.665614.254484@antilipe.corelatus.se> > > B = 3. > > > > I want to form a string "0003". > > ** Can io:format generate such a printout ? Try 9> B = 3. 3 10> io:fwrite("~4.4.0w\n", [B]). 0003 ok integers are formatted using the 'term' format (~w), there's no need for an explicit 'integer' format. You can use io_lib if you want to generate strings rather than printing to output. Matthias From cpressey@REDACTED Thu Apr 24 00:08:31 2003 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 23 Apr 2003 17:08:31 -0500 Subject: catching errors from linked processes (Long) In-Reply-To: <4.2.2.20030422233328.00ce1a30@duomark.com> References: <4.2.2.20030422233328.00ce1a30@duomark.com> Message-ID: <20030423170831.31762002.cpressey@catseye.mb.ca> On Wed, 23 Apr 2003 00:36:14 -0700 Jay Nelson wrote: > Code should be as simple as possible and no simpler. Concurrency is harder than you believe :) > Errors > > Don't worry about errors, just let it fail. That is the erlang way. > Like all things erlang it sounds simple and easy, but is actually a > very subtle thing. > > I can think of three good reasons to let it fail: highlight errors in > the code so they can be corrected; avoid something really bad from > happening and reset to a known state; or notify external systems > (or users) about bad data they are supplying so it can be corrected. My program is definately an example of the third case. I left out the details of my program to more easily communicate the problems, but for the curious, here's some info. Basically we have a toy programming language that's laxly specified, especially when it comes to limitations. There are many implementations of the language (compilers & interpreters) and in order to attain various goals, their authors have placed various limitations on them. The idea behind my program was to write a general interpreter for which the limitations can be specified by the user. That way, the user can test their code to get an idea of what kind of implementations it will run on (and exactly how it will fail on others.) I started out handling errors (and because the user can select the limitations, there are a wide variety of possible errors) by returning either {ok, Result} or {error, Reason} to the caller. This is fine when it's only the immediate caller that cares about whether your function succeeded or not. Unfortunately that's rarely the case. Often, a function two or three levels up from the immediate caller will care. So you have to cascade the error back up the chain. You can usually tell that code does this when it has the following pattern in it: case Blah of ... {error, Reason} -> {error, Reason} end It's unwieldy to do it manually like this. Enter: catch and sometimes throw. This allows a non-local exit, so we can communicate the error to the function, several levels up, that cares about it, without manually passing it around. catch is fine for when it's only the immediate *process* that cares about whether your function succeeded or not. Unfortunately *that's* not always the case either, especially when you start exploiting concurrency (most implementations of the toy language in question are strictly sequential; mine currently uses 5 processes.) Sometimes another process will care about the result, so you *still* have to cascade the error, back up a chain, this time a chain of processes. Enter: [spawn_]link and sometimes exit. *Then* you have error bliss :) > Fault Isolation = use a process where failure will keep a bad state > from propagating through the system causing more damage, and when a > restart of the faulted process can produce a fully functioning system > automatically (possibly after moving the process or changing its > config parameters before restart). Or, in my case at least, make it fail the entire system as a unit, in a consistent way. What Lennart said is starting to make sense; it's that I'm too used to the idea (from sequential programming) that the process you start is going to be the process that does the work. Not so. Clearly it is sometimes better for the process you start to be the one that *supervises* the processes that do the work and *centralizes* their results (errors & otherwise), like a funnel. > foo(true, X) -> bar(X). > > This may end up for clarity or for performance reasons. It is more > concise, but relies more on the language and compiler. As it happens, > it also provides more info in the failure case. This is what I'd prefer, but my code was a little too complicated to allow it. A nice side-effect of it is that if you name the function well, you get an almost self-descriptive error message. I still think it would be nice if, whenever an error occurred, the 'EXIT' message contained not only the call stack, but also the parameters to the function that failed. Still, you can't have everything, and when I do need the supervisor to know something about the state of the process that failed, I can arrange it fairly easily. > Notice that in C / Java you don't get the choice. You have to handle > the error and assume the caller will understand the error flags you > pass back. If the process fails you have no recourse and no second > chance. You can use try and catch in Java but the algorithm becomes > cluttered and the logic is confusing to get right. > > jay What's even worse in C is that you can't even return an aggregate like {error, Reason}. If you want to return an error, you either have to incorporate it into the data type you're returning (like -1 if all your valid results are positive integers) or pass a parameter by reference. And figuring out where to put a catch (in Java, Erlang or any other language) is always a bit tricky - you want it to be neither too high nor too low in the chain. A supervisor can let you neatly avoid having to decide that in many cases, I'm sure. -Chris From vances@REDACTED Thu Apr 24 00:26:02 2003 From: vances@REDACTED (Vance Shipley) Date: Wed, 23 Apr 2003 18:26:02 -0400 Subject: trouble with files bigger than 4GB In-Reply-To: <200304232205.25822@no.siento.las.piennas> References: <200304162052.34521@no.siento.las.piennas> <200304181515.42510@no.siento.las.piennas> <3EA4F06D.90703@uab.ericsson.se> <200304232205.25822@no.siento.las.piennas> Message-ID: <20030423222602.GM53726@frogman.motivity.ca> I can tell you what I had to do to build a 64 bit emulator. I built and installed a version of gcc which used -m64 as the default. Then when running configure and make on the source distribution I had that version of gcc first in the path. -Vance On Wed, Apr 23, 2003 at 10:18:49PM +0200, Daniel Solaz wrote: } } On 32bit Solaris, adding -D_FILE_OFFSET_BITS=64 to the cc call does the } trick: off_t becomes 8 bytes long, fopen() means fopen64(), etc. } However, according to the docs, this does interact badly with some } other OS subsystems. } } So I'd like to try this first and report whether things work, or at } least seem to. But I lack the expertise required to hack configure so } that it compiles the off_t size test with -D_FILE_OFFSET_BITS=64 and } generates new Makefiles with -D_FILE_OFFSET_BITS=64 in them. Can } anyone give me a pointer? } } -Daniel From cpressey@REDACTED Thu Apr 24 01:07:48 2003 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 23 Apr 2003 18:07:48 -0500 Subject: string conversion, format functions In-Reply-To: <16039.2064.665614.254484@antilipe.corelatus.se> References: <200304232052.h3NKqjtW007584@wren.rentec.com> <20030423161655.4e51616b.cpressey@catseye.mb.ca> <16039.2064.665614.254484@antilipe.corelatus.se> Message-ID: <20030423180748.17864954.cpressey@catseye.mb.ca> On Wed, 23 Apr 2003 23:39:28 +0200 Matthias Lang wrote: > 9> B = 3. > 3 > 10> io:fwrite("~4.4.0w\n", [B]). > 0003 > ok > > integers are formatted using the 'term' format (~w), there's no need > for an explicit 'integer' format. Wow. Would you believe, I got so used to using ~p that I completely forgot ~w even existed? When I started using it, I just assumed ~p behaved exactly like ~w, only prettier. I didn't think to check that the format parameters had a different meaning. Now I'm starting to see some of the lovelier warts of io:format :) If ~n is defined to be \n on all platforms then it's completely redundant. It just gives you a false sense of abstraction. ~r doesn't exist. If format parameters mean different things for different formatting codes then programs written with io:format become that much harder to read and maintain, becuase they require that much more memorization. (I can never remember which leading integer is field width and which is precision anyway.) And then there's ~i. That's just disturbing. It's almost funny. Thankfully, I couldn't find it used anywhere in OTP with a quick grep. (If it is, it's used with a field width or precision... and that's even more disturbing.) If hex/other bases are added to io:format, it'll just get nastier. Not really a problem at this point though, since whatever elegance there once was in it has apparently already left town :) It's kind of strange, when you think about it, have there even been any significant advances in "output formatting technology" since, what, FORTRAN? None that have caught peoples' imagination enough to be adopted, anyway - Perl's 'reports' are pretty nice, but I don't think I've ever seen a Perl program that actually *uses* them... -Chris From jay@REDACTED Thu Apr 24 05:24:37 2003 From: jay@REDACTED (Jay Nelson) Date: Wed, 23 Apr 2003 20:24:37 -0700 Subject: string conversion, format functions Message-ID: <4.2.2.20030423193830.00cf2200@duomark.com> Chris wrote: > It's kind of strange, when you think about it, have there > even been any significant advances in "output formatting > technology" since, what, FORTRAN? None that have > caught peoples' imagination enough to be adopted, Hate to bring it up again, but I do remember coding in LISP and using the "format language" as we called in. You could write a format string that included looping and conditional branching constructs in the *execution* of the format string. So you could pass a list of arguments or functions, and then there were characters like colon or ~ or something that delimited a loop and caused iteration. You could skip over arguments or back up and use them again. And who hasn't used the automatic pluralizer!!? Of course, the standard example was the format string that evaluated an s-expression and if it had an error would print out the statement with an arrow pointing at the point of syntax failure. Now that was a tricky format string! Was just about a whole REPL in a single format. Not that this was highly recommended, but sometimes it was just the most concise way to do something complicated. I guess ~i is so that you can construct an io:format string on the fly and combine it with a list of stuff that was generated elsewhere to get a nice little dynamic formatter. > anyway - Perl's 'reports' are pretty nice, but I don't > think I've ever seen a Perl program that actually > *uses* them... I've only written packed tags to files to communicate with other programs, or HTML which isn't positional so I haven't done the pretty formatting, except wait... no, even my email formatter didn't need to do anything fancy. Can't imagine too many inventory systems written in Perl, but why not, eh? jay *Common LISP The Language, Second Edition, Guy L. Steele Jr. (also called "The Bible" or just "Steele") -- of course From jay@REDACTED Thu Apr 24 05:35:52 2003 From: jay@REDACTED (Jay Nelson) Date: Wed, 23 Apr 2003 20:35:52 -0700 Subject: string conversion, format functions Message-ID: <4.2.2.20030423203338.00a2a640@duomark.com> Tone is completely lost in email postings. My examples from Lisp were to be taken as absurdity (although they are all true). You are right that there have been no great improvements. Most of the focus I believe has been on graphical UI rather than formatting -- at least until Joe started the erlguten project ;-) jay From jay@REDACTED Thu Apr 24 08:19:07 2003 From: jay@REDACTED (Jay Nelson) Date: Wed, 23 Apr 2003 23:19:07 -0700 Subject: string conversion, format functions Message-ID: <4.2.2.20030423231219.00ced910@duomark.com> > It's kind of strange, when you think about it, have there > even been any significant advances in "output formatting > technology" since, what, FORTRAN? I guess I forgot Cobol, Snobol and RPG. Since RPG was my first serious programming, I should have remembered. It was by far the best of the three both for its conditional formatting brevity and its pictorial layout. Even the terminal screens were easily mapped into the layout (which was typically pencilled out on graph paper during the design). Snobol was much better for searching and parsing strings than producing them as I recall -- somewhat reminiscent of Perl with its "content addressable arrays" and overloading + for string concatenation and math. I did dabble with REFAL (Recursive Functional Applicative Language) which used a model wherein the entire program was the current display; if the beginning of the string was executable it ran and produced another entire display; and so on until the beginning of the display was not executable and therefore was the output. It was designed for AI type symbolic problem solving, but might have allowed for some sort of formatting although in a very tedious way. jay From bernardp@REDACTED Thu Apr 24 12:47:36 2003 From: bernardp@REDACTED (Pierpaolo BERNARDI) Date: Thu, 24 Apr 2003 12:47:36 +0200 Subject: string conversion, format functions References: <4.2.2.20030423193830.00cf2200@duomark.com> Message-ID: <005f01c30a4f$681f9420$79f06850@c1p4e3> From: "Jay Nelson" > Standard English nomenclature for fairly large integers (up to > 10 ^6 at least) based on appending the suffix -illion to Latin names > of integers. > > This worked for bignums and an example is given of the text > for 2 ^200 which encompasses a paragraph of 10 lines! Hey! this works in Erlang too, if you can cope with Italian names instead of English: 13> in_lettere:cardinale(pblib:expt(2,200)). "un nonilione seicentosei ottilioni novecentotrentotto settilioni quarantaquattro sestilioni duecentocinquantotto quintilioni novecentonovanta quadrilioni duecentosettantacinque trilioni cinquecentoquarantuno miliardi novecentosessantadue milioni novantaduemilatrecentoquarantuno nonilioni centosessantadue ottilioni seicentodue settilioni cinquecentoventidue sestilioni duecentodue quintilioni novecentonovantatr? quadrilioni settecentoottantadue trilioni settecentonovantadue miliardi ottocentotrentacinque milioni trecentounomilatrecentosettantasei" 8-) P. From raimo.niskanen@REDACTED Thu Apr 24 14:15:28 2003 From: raimo.niskanen@REDACTED (Raimo Niskanen) Date: Thu, 24 Apr 2003 14:15:28 +0200 Subject: trouble with files bigger than 4GB References: <3EA4F06D.90703@uab.ericsson.se>, <200304232205.25822@no.siento.las.piennas>, <20030423222602.GM53726@frogman.motivity.ca> Message-ID: Would it be sufficient to have kind of the following shell script (named gcc) before the real gcc in the path? #!/bin/sh exec /usr/local/bin/gcc -m64 ${1+"$@"} / Raimo Niskanen, Erlang/OTP, Ericsso AB Vance Shipley wrote: > I can tell you what I had to do to build a 64 bit emulator. I built > and installed a version of gcc which used -m64 as the default. Then > when running configure and make on the source distribution I had that > version of gcc first in the path. > > -Vance > > On Wed, Apr 23, 2003 at 10:18:49PM +0200, Daniel Solaz wrote: > } > } On 32bit Solaris, adding -D_FILE_OFFSET_BITS=64 to the cc call does the > } trick: off_t becomes 8 bytes long, fopen() means fopen64(), etc. > } However, according to the docs, this does interact badly with some > } other OS subsystems. > } > } So I'd like to try this first and report whether things work, or at > } least seem to. But I lack the expertise required to hack configure so > } that it compiles the off_t size test with -D_FILE_OFFSET_BITS=64 and > } generates new Makefiles with -D_FILE_OFFSET_BITS=64 in them. Can > } anyone give me a pointer? > } > } -Daniel From erik@REDACTED Thu Apr 24 15:34:08 2003 From: erik@REDACTED (Erik Pearson) Date: Thu, 24 Apr 2003 06:34:08 -0700 Subject: UBF byte register question Message-ID: <6CF88685-7659-11D7-81B8-0050E4594D1D@adaptations.com> I'm wondering what the scope and lifetime of a UBF byte register is supposed to be. The byte register allows the association of an arbitrary UBF value with a single byte (that byte being any byte that is not reserved by UBF.) The reason for the byte register is to allow more compact UBF messages, since you can first send several commonly used values which are associated with a specific byte. When that byte is seen later, the associated value replaces the byte. The register is set by sending value >B where value is any UBF value, > means "store in", and B is any byte that is not reserved by UBF(A). E.g. "Universal Binary Format" >U U $ would be equivalent to "Universal Binary Format" $ or 'person' >p "Brown" >b # {p "John" b} & {p "Patricia" b} & {p "James" b} & $ would be equivalent to # {'person' "John" "Brown"} & {'person' "Patricia" "Brown"} & {'person' "James" "Brown"} & $ So I'm wondering long the byte register should live for, and who should see it. The spec (http://www.sics.se/~joe/ubf/site/ubfa.html) doesn't specify, as far as I can tell. My best guess is that the the byte registers are only valid for the single object following one or more byte register settings. The only unit of transaction at UBF(A) is the data object, which is terminated with a $ (dollar sign.). However, this would make the byte register useful only for longish lists which contain repeated elements. I am tempted to suggest that the byte register could live for a longer span -- for the length of some sort of 'session' (network connection, etc.) However, such concepts don't live in the realm of UBF(A). It would also be tempting to think of the byte register having a longer lifetime, allowing for a dynamic cache of frequently used values to persist between a client and server (adjusted by analyzing the frequency and size of objects being transmitted). As to who should see a given byte register, if the span of the byte register is a single object (or session), then it would clearly be valid only for the current client. Since there is no concept of client at UBF(A), there is really no sense in making this distinction. However, if a byte register could persist for a longer period of time, it would make sense to address the issue of multiple sessions or clients accessing the same byte register. Anyway, thanks for bearing with my seemingly endless UBF blitherings! Erik Pearson Adaptations desk +1 510 527 5437 cell +1 510 517 3122 From etxuwig@REDACTED Thu Apr 24 16:14:40 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Thu, 24 Apr 2003 16:14:40 +0200 (MEST) Subject: mnesia:match_object() on an ordered_set Message-ID: I started writing some code happily assuming that calling mnesia:match_object/2 on an ordered_set table will return an ordered set of objects. For a brief moment, some doubt snuck in and I decided to check the actual implementation... It turns out, AFAICT, that mnesia simply prepends objects written during the transaction, thus breaking the ordered_set semantics, and -- In my opinion -- violating the Principle of Least Surprise(tm). The Mnesia documentation doesn't make any promises regarding order, so this behaviour doesn't formally violate the Mnesia interface. However, where anything is written about the expected semantics of match_object(), the following can be found in the ETS Reference Manual: "On tables of the ordered_set type, the result is in the same order as in a first/next traversal." Given the current implementation of mnesia:match_object(), I don't think preserving the order would have to impact performance, esp. not on large sets (and on small sets, I don't think it matters.) I've not made a patch. I could suggest a fix, but not today. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From joe@REDACTED Thu Apr 24 16:48:43 2003 From: joe@REDACTED (Joe Armstrong) Date: Thu, 24 Apr 2003 16:48:43 +0200 (CEST) Subject: Let some other process fix the error (Long) In-Reply-To: <4.2.2.20030422233328.00ce1a30@duomark.com> Message-ID: On Wed, 23 Apr 2003, Jay Nelson wrote: > These sorts of questions are what make erlang so interesting > to me. They appear simple and broad brush at first, but if > you look closely they are actually very subtle and involve > tradeoffs that you would never recognize in other languages. > In C, you must code defensively because once you core dump > there are no options and with runaway code there is no telling > what will happen next. In erlang you have so many choices it > is difficult to decide what to do. > ... a very nice description of Erlang philosophy ... Amazingly people like Jay (who I have never met) and many other seem to have intuitively understand the Erlang principles - this must be more by "osmosis" than by reading the documentation. > Don't worry about errors, just let it fail. That is the Erlang way. > Like all things Erlang it sounds simple and easy, but is actually a > very subtle thing. The real principle is "let some other process fix the error" The "let if fail philosophy" is a consequence of this. Let me explain: Erlang was *designed* for making fault-tolerant systems, so: 1) To make something fault tolerant you need at least *two* computers (obviously) 2) If one computer fails you must fix the error on the *other* computer. This means that: 3) To fix an error you do not make any attempt to do it locally - you can't fix an error on a computer if the computer has just crashed - you must do it somewhere else. In the Erlang model *everything* is a process - even computers - so we want the same semantics. Thus processes do not do their own error recovery (they can't they have crashed) - other processes must clean up after them. - this is the "let some other process fix the error" principle. Question 1: If some process (A) crashes which of the many other processes in the system is responsible for the recovery operations? Answer: Those processes which are linked to A. Question 2: How do the linked processes know what to do - surely they need to know why A died? Answer: The reason for the exit is sent as an argument in a signal which is sent from the dieing process to all the processes in its link set. To implement this places a number of requirements on the programming language and run-time system - namely: 1) We must be able to remotely detect errors 2) We must be able to automatically diagnose errors "Let it fail" is often the *only* sensible thing to do. Let me explain... - There are exceptions - There are errors - They are not the same thing Start with exceptions: The run-time system generates exceptions - these occur when the run-time system does not know what to do. For example if a divide by zero condition occurs the run-time system does not know what to do - so what does it do? - it aborts the process with a {'EXIT', divide_by_zero} exception. This is fine and in line with our fault-handling philosophy "some other process will fix the error." What about Errors? Well what is an error? An error is "a deviation between what the program is supposed to do" and what it is observed to do. What it is supposed to do is "what was in the specification". Example (my favorite) -- let's suppose the spec say we are to write a function asm that turns a load opcode into the instruction 1 and a store opcode into the opcode 2. This is easy: asm(load) -> 1; asm(store) -> 2. Now suppose that what system tries to call asm(jump) - what should happen? Suppose you are the programmer and you are used to writing defensive code (just like they taught you) - you'd write: asm(load) -> 1; asm(store) -> 2; asm(X) -> and then what?? What code do you write? - the programmer is now in the situation that the run-time system was faced with when it encountered a divide-by-zero situation you cannot wrote any sensible code here - all you can do is terminate the program. Remember "Some other process will fix the error". So maybe you write: asm(load) -> 1; asm(store) -> 2; asm(X) -> exit({bad_arg_to, asm, X}). But why bother. The Erlang compiler compiles asm(load) -> 1; asm(store) -> 2. almost as if it had been defined: asm(load) -> 1; asm(store) -> 2; asm(X) -> exit({bad_arg, asm, X}). The defensive code *detracts* from the pure case and confuses the reader - and the diagnostic is often no better than that which the compiler supplies automatically. Now the "some other process will fix the error" philosophy only makes sense if you have a process based language with total Independence between processes. You *can't do this in a sequential language* - you get ONE try (your processes) and it crashes you loose control. You *can't do this with thread based concurrency* - threads *share* resources (usually memory) - if one thread corrupts shared memory - disaster. You *can't do this with unix process like concurrency* - you can observe failure but not accurately diagnose the reason for failure. This design was not accidental - Erlang was *designed* to program fault-tolerant systems. The key requirement the *one* requirement that I always considered far more important than anything else was to be able to make a system which could recover from software errors. We knew that our systems would end up with millions of lines of code and be written by large teams of programmers - in such systems there are bound to be many mistakes. I can think of no other way of programming such a system *without* independent processes. The *reason* for independent processes is NOT efficiency (I don't give a hoot about efficiency) - it is to allow large teams of programmers to work together. Give each programmer their own processes to work with and let them hack away - if their process dies, who cares, "some other process will fix the error." From this the worker-supervisor model is a short step away. The basic idea is "try to do something - if you can't do it give up and try to do something simpler." There are two other points to note: 1) All programmers are not equal Some are better than others - so then you let your better programmer programs the error recovery strategies, and let them identify and program the code that does the error recovery. 2) All code is not equal As Martin Bj?rkland once said: - There is code that can recover from errors - There is code that will not recover from errors - You have to make your mind up In particular the error recovery code *must* be correct (so don't mess with error_handler.erl) Taking 1) and 2) together you arrive at the following: Try to structure you problem so that you can write it as "lots of regular 'pure' code with a well defined structure' *and* - "a small module of stuff that sucks" Get your inexperienced programmers to write "referentially transparent" *pure*?code Get your lead programmers to write the messy stuff. Now if you use OTP you get the mess for free - every time I look at the OTP stuff I think "Oh my goodness - couldn't it have been written in a *much* more simple manner - I start hacking and only then do I remember *why* it was written as it was written." There is an underlying logic to Erlang - which I have always known but find very difficult to explain - it is particularly difficult to explain it to programmers who think "threads" and "sequential" code. My current "best argument" is one I've partially ventilated here: " ... look to make a fault-tolerant system you need TWO computers not ONE right ... and If you've got TWO computers you need to start thinking about distributed programming *whether you like or not* and if you're going to do distributed computing then you'll have to think about the following ... and so on..." The reaction is varied - everything from (rarely) "you're absolutely right" to - (more commonly) "what about efficiency" Me, I can make an incorrect program run arbitrarily quickly - that is no challenge, the following program, for example, computes factorial(10000000000) in less than a picotwinkle. factorial(N) -> 42. /Joe From enewhuis@REDACTED Thu Apr 24 17:08:13 2003 From: enewhuis@REDACTED (Eric Newhuis) Date: Thu, 24 Apr 2003 10:08:13 -0500 Subject: How Does One Sort Strings? Message-ID: <002301c30a73$53eb1d20$34c2cf0a@futuresource.com> Given a list of strings ["I", "want", "to", "ride", "my", "bicycle"] how can I sort them in Erlang? Lets suppose there are 100s - 1000s of strings. -------------- next part -------------- An HTML attachment was scrubbed... URL: From joe@REDACTED Thu Apr 24 17:08:32 2003 From: joe@REDACTED (Joe Armstrong) Date: Thu, 24 Apr 2003 17:08:32 +0200 (CEST) Subject: UBF byte register question In-Reply-To: <6CF88685-7659-11D7-81B8-0050E4594D1D@adaptations.com> Message-ID: On Thu, 24 Apr 2003, Erik Pearson wrote: > I'm wondering what the scope and lifetime of a UBF byte register is > supposed to be. The byte register allows the association of an > arbitrary UBF value with a single byte (that byte being any byte that > is not reserved by UBF.) > ... good question ... :-) > background (or my attempt at such)> > > The reason for the byte register is to allow more compact UBF messages, > since you can first send several commonly used values which are > associated with a specific byte. When that byte is seen later, the > associated value replaces the byte. > > The register is set by sending > > value >B > > where value is any UBF value, > means "store in", and B is any byte > that is not reserved by UBF(A). > > E.g. > > "Universal Binary Format" >U > U $ > > would be equivalent to > > "Universal Binary Format" $ > > or > > 'person' >p > "Brown" >b > # {p "John" b} & > {p "Patricia" b} & > {p "James" b} & $ > > would be equivalent to > > # {'person' "John" "Brown"} & > {'person' "Patricia" "Brown"} & > {'person' "James" "Brown"} & $ > > > > So I'm wondering long the byte register should live for, and who should > see it. There is actually an optimal (though unimplementable) algorithm - it's comes from the old "page replacement algorithm" It is "When you run out of byte registers, you have to throw one away - (ie reuse it) - so all you do is reuse the next register whose next future reference is longest away in time from the current usage." To implement this needs the pre-cognitive will_receive(Msg) statement (Bj?rn) will_receive(X) means that the message X will be received at some point in time in the future, and returns the value of this time. In pseudo code Ts = map(fun(I) -> {will_receive(I), I} end, ByteRegisters), B = element(2,hd(reverse(sort(Ts))), This should work (if I understand things correctly) on a quantum computer - otherwise don't hold your breath ... > > The spec (http://www.sics.se/~joe/ubf/site/ubfa.html) doesn't specify, > as far as I can tell. > Correct - this was *deliberate* :-) Golly - so we actually need yet ANOTHER operator (say !) which means "clear the byte cache" - or even Two operators say 'atom' ^ and 'atom' = which could save and restore a bye cache "context" If you encounter ^ you should *save* all the byte cache entries in a object named "context" - otherwise you restore the context - this could make for some *very* efficient protocols. > My best guess is that the the byte registers are only valid for the > single object following one or more byte register settings. The only > unit of transaction at UBF(A) is the data object, which is terminated > with a $ (dollar sign.). However, this would make the byte register > useful only for longish lists which contain repeated elements. > > I am tempted to suggest that the byte register could live for a longer > span -- for the length of some sort of 'session' (network connection, > etc.) However, such concepts don't live in the realm of UBF(A). > > It would also be tempting to think of the byte register having a longer > lifetime, allowing for a dynamic cache of frequently used values to > persist between a client and server (adjusted by analyzing the > frequency and size of objects being transmitted). > > As to who should see a given byte register, if the span of the byte > register is a single object (or session), then it would clearly be > valid only for the current client. Since there is no concept of client > at UBF(A), there is really no sense in making this distinction. > However, if a byte register could persist for a longer period of time, > it would make sense to address the issue of multiple sessions or > clients accessing the same byte register. > > Anyway, thanks for bearing with my seemingly endless UBF blitherings! > Carry on please /Joe PS the above posting contained at least one joke. > > Erik Pearson > Adaptations > desk +1 510 527 5437 > cell +1 510 517 3122 > From eleberg@REDACTED Thu Apr 24 17:22:26 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Thu, 24 Apr 2003 17:22:26 +0200 (MEST) Subject: How Does One Sort Strings? Message-ID: <200304241522.h3OFMQq20230@cbe.ericsson.se> > From: "Eric Newhuis" > To: > Subject: How Does One Sort Strings? > Date: Thu, 24 Apr 2003 10:08:13 -0500 > MIME-Version: 1.0 > X-Priority: 3 > X-MSMail-Priority: Normal > X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2919.6600 > X-Scanned-By: MIMEDefang 2.30 (www . roaringpenguin . com / mimedefang) > > Given a list of strings ["I", "want", "to", "ride", "my", "bicycle"] how can I sort them in Erlang? Lets suppose there are 100s - 1000s of strings. lists:sort/1 bengt From hakan@REDACTED Thu Apr 24 18:17:07 2003 From: hakan@REDACTED (Hakan Mattsson) Date: Thu, 24 Apr 2003 18:17:07 +0200 (MEST) Subject: mnesia:match_object() on an ordered_set In-Reply-To: Message-ID: On Thu, 24 Apr 2003, Ulf Wiger wrote: Uffe> I started writing some code happily assuming that calling Uffe> mnesia:match_object/2 on an ordered_set table will return Uffe> an ordered set of objects. For a brief moment, some doubt Uffe> snuck in and I decided to check the actual implementation... Uffe> Uffe> It turns out, AFAICT, that mnesia simply prepends objects Uffe> written during the transaction, thus breaking the Uffe> ordered_set semantics, and -- In my opinion -- violating the Uffe> Principle of Least Surprise(tm). Uffe> Uffe> The Mnesia documentation doesn't make any promises regarding Uffe> order, so this behaviour doesn't formally violate the Mnesia Uffe> interface. However, where anything is written about the Uffe> expected semantics of match_object(), the following can be Uffe> found in the ETS Reference Manual: Uffe> Uffe> "On tables of the ordered_set type, the result is in the Uffe> same order as in a first/next traversal." The Mnesia API does only support first/next traversal with dirty semantics and for a match_object with dirty semantics there are no transaction store to bother about. ;-) Uffe> Given the current implementation of mnesia:match_object(), I Uffe> don't think preserving the order would have to impact Uffe> performance, esp. not on large sets (and on small sets, I Uffe> don't think it matters.) For fragmented tables it would have a tremendous impact, as the order only is preserved within each fragment. In order to return an ordered result, it would require a quite substantial sort operation. Of course Mnesia could ensure that the result of a match_object on an ordered_set always should be ordered, but is it worth the performance penalty? /H?kan --- H?kan Mattsson Ericsson High Availability Software, DBMS Internals http://www.ericsson.com/cslab/~hakan/ From hp@REDACTED Thu Apr 24 19:26:50 2003 From: hp@REDACTED (HP Wei) Date: Thu, 24 Apr 2003 13:26:50 -0400 (EDT) Subject: controlled poll in tv ? Message-ID: <200304241726.h3OHQoL7027602@ram.rentec.com> I have an ets table which is monitored by tv. That table (a list of tuples) is updated by a process at a regular interval n. I can set the polling interval in tv to be n/2 so as to not miss seeing any update. The more precise way is to trigger tv to poll as soon as the ets_table is updated. Can this be done ? HP From bjarne@REDACTED Thu Apr 24 19:25:15 2003 From: bjarne@REDACTED (=?iso-8859-1?Q?Bjarne_D=E4cker?=) Date: Thu, 24 Apr 2003 19:25:15 +0200 Subject: ACM SIGPLAN Erlang Workshop - call for papers - remainder Message-ID: <001f01c30a86$7eb396a0$1d0d69d4@segeltorp> All Erlang users, developers, researchers, enthusiasts etc. are invited to the 2nd ACM SIGPLAN Erlang Workshop which will be held in Uppsala on August 29, 2003. Please see the call for papers http://www.erlang.se/workshop/2003/ Programme chairman is Thomas Arts thomas.arts@REDACTED and authors are invited to write and mail him abstracts or full paper on the following and other Erlang related topics: Language concepts, Implementation issues, Specification and type checking, Design issues especially of large concurrent distributed reliable systems, Runtime profiling and performance measurements, Testing, debugging, tracing and formal verification tools, Programming techniques. The ACM SIGPLAN Erlang Workshop is part of the Principles, Logics, and Implementations of High-Level Programming Languages conference http://www.it.uu.se/pli03/ See you all in Uppsala in August! Bjarne -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthias@REDACTED Thu Apr 24 20:01:19 2003 From: matthias@REDACTED (Matthias Lang) Date: Thu, 24 Apr 2003 20:01:19 +0200 Subject: How Does One Sort Strings? In-Reply-To: <002301c30a73$53eb1d20$34c2cf0a@futuresource.com> References: <002301c30a73$53eb1d20$34c2cf0a@futuresource.com> Message-ID: <16040.9839.69915.152696@antilipe.corelatus.se> Eric Newhuis writes: > Given a list of strings ["I", "want", "to", "ride", "my", > "bicycle"] how can I sort them in Erlang? Lets suppose > there are 100s - 1000s of strings. Bengt already told you the easy solution. That's one of the cool things about Erlang: the easy way often works with quite decent performance: 4> file:read_file("/home/matthias/toread/CD-Writing.txt"). {ok,<>} 5> {ok, Bin} = file:read_file("/home/matthias/toread/CD-Writing.txt"). {ok,<<32,32,67,...>>>} 6> size(Bin). 70219 7> Tokens = string:tokens(binary_to_list(Bin), " \n\t"), bequiet. bequiet 8> length(Tokens). 9184 9> lists:sort(Tokens). ["!", "!", "\"", "\"", "\"\b\"f\bfe\bea\bat\btu\bur\bre\bes\bs\"\b\"", ... all of that was "instant". If you don't like the built-in sort order, take a look at lists:sort/2. BTW, I strongly recommend the index to the Erlang documentation. It got a whole lot better recently (I think in the R7->R8 transition, not sure). For this particular example, the first entry for "sort" answers your question. See: http://www.erlang.org/doc/r9b/doc/index.html Matt From fritchie@REDACTED Thu Apr 24 20:17:31 2003 From: fritchie@REDACTED (Scott Lystig Fritchie) Date: Thu, 24 Apr 2003 13:17:31 -0500 Subject: Let some other process fix the error (Long) In-Reply-To: Message of "Thu, 24 Apr 2003 16:48:43 +0200." Message-ID: <200304241817.h3OIHVuc039392@snookles.snookles.com> >>>>> "ja" == Joe Armstrong writes: ja> You *can't do this with unix process like concurrency* - you can ja> observe failure but not accurately diagnose the reason for ja> failure. Ja, it's sometimes nice to know if there was a particular type of failure in some other process ... but an OTP supervisor process cares very little about the type of failure one of its children experienced. Knowing the cause of the failure is important from a logging point of view. However, AFAIK, the only reason why it cares is if the dead child was configured to be permitted to die without restart. Last week, I stumbled across the research of George Candea and Armando Fox at Stanford. They've been doing research into "crash-only computing" and "recursively rebootable" software systems. It takes an Erlang OTP person just a few minutes to read their work before saying, "Wow, they're implementing OTP-like supervisor behaviors for Java systems." Well, there are a few differences: * Each recursively-restartable Java component must be running in its own JVM -- operating system process separation provides the smallest unit of failure. The same principle could be applied to a distributed system of independent OS processes communicating via CORBA or other IPC mechanism. * Restart behavior isn't configured at what an OTP person would call a particular supervisor process. Instead, there's a single recovery manager component which maintains a tree of component dependencies. All restartable components are leaves of the tree. It uses an OTP-like "all-for-one" component restart strategy: if a component monitoring agent notifies the recovery manager that a component has failed, the recovery manager will attempt to restart all components that have the same dependency tree parent. If that doesn't fix the problem, the manager restarts all components with the same dependency tree grandparent. And so on, until the system is running without faults. For more info, see: http://www.stanford.edu/~candea/research.html http://swig.stanford.edu/public/projects/RR In a past life, I tried preaching this kind of restart logic for a multi-OS-process, multi-OS-instance system. My preaching fell upon deaf ears, much to my chagrin. It's nice to see that I wasn't a (utterly, completely) crazy man raving in the wilderness. :-) -Scott From hp@REDACTED Thu Apr 24 22:30:47 2003 From: hp@REDACTED (HP Wei) Date: Thu, 24 Apr 2003 16:30:47 -0400 (EDT) Subject: invoking functions on a remote machine without erl running Message-ID: <200304242030.h3OKUltW025441@wren.rentec.com> Let me first describe an ideal situation: Suppose there are two machines, hp@REDACTED and hp@REDACTED in the network, on which there are two erl running. >From hp@REDACTED, I want to carry out a function Fun on hp@REDACTED I understand that this can be done by: Return = rpc:call(hp@REDACTED, Mod, Fun, Args). -------------------- Now, due to some regulations, I could not leave a process such as erl on hp@REDACTED 24 hours a day. So, how do I perform Mod:Fun in this case when there is no erl running on hp@REDACTED ?? One way I can think of is: on hp@REDACTED, I can use os:cmd("rsh m2 /path/to/erl") and do rcp:call() and then kill the erl job on hp@REDACTED Any other way ? What if m2 asks for password when I do 'rsh m2 ...' ? --HP From jeinhorn@REDACTED Thu Apr 24 22:48:35 2003 From: jeinhorn@REDACTED (Jeff Einhorn) Date: Thu, 24 Apr 2003 15:48:35 -0500 Subject: ets:match(Continuation) usage question. Message-ID: I was wondering what happens if updates are made to an ets table while an ets:match(Continuation) search is being ran? thanks for your time, -jeff Jeffrey M. Einhorn Software Engineer Web Development Group FutureSource, LLC jeinhorn@REDACTED http://www.futuresource.com From svg@REDACTED Thu Apr 24 23:08:09 2003 From: svg@REDACTED (Vladimir Sekissov) Date: Fri, 25 Apr 2003 03:08:09 +0600 (YEKST) Subject: invoking functions on a remote machine without erl running In-Reply-To: <200304242030.h3OKUltW025441@wren.rentec.com> References: <200304242030.h3OKUltW025441@wren.rentec.com> Message-ID: <20030425.030809.41645930.svg@surnet.ru> Good day, hp> Now, due to some regulations, I could not leave a hp> process such as erl on hp@REDACTED 24 hours a day. hp> So, how do I perform Mod:Fun in this case when hp> there is no erl running on hp@REDACTED ?? hp> hp> One way I can think of is: hp> on hp@REDACTED, I can use os:cmd("rsh m2 /path/to/erl") and You can configure hp@REDACTED as slave node. Please look documentation on `slave' module. Another option is `erl_call', which can start node if necessary. Binary is in: $ERL_ROOT/lib/erl_interface-*.*.*/bin/erl_call hp> What if m2 asks for password when I do 'rsh m2 ...' ? Both, ssh and rsh, have options to allow login without asking a password. For rsh it is .rhosts file in user directory on remote host if I don't forget. Best Regards, Vladimir Sekissov From hp@REDACTED Fri Apr 25 00:10:25 2003 From: hp@REDACTED (HP Wei) Date: Thu, 24 Apr 2003 18:10:25 -0400 (EDT) Subject: mapping implemented in functions vs in structures Message-ID: <200304242210.h3OMAPL7004180@ram.rentec.com> I want to map entity x1 on machine m1 to y1 on m2 ... I can see there are two choices and don't know which one is the more idiomatic way in erlang world: (1) functions m1_m2(x1) -> y1; m1_m2(x2) -> y2. m3_m6(a1) -> b1; m3_m6(a2) -> b2.... At run time, suppose A = m1, B = m2, X = x1. To get y1, I will need to form a string S ="m1_m2(x1)" and evaluate it. btw, how do I do this ? erl_eval:expr() looks complicated. (2) structures {{m1_m2, [{x1, y1}, {x2, y2}]}, {m3_m6, [{a1, b1}, {a2, b2}]} Given A, B, X in (1), finding y1 becomes a matter of parsing the structure. thanks, HP From svg@REDACTED Fri Apr 25 00:33:07 2003 From: svg@REDACTED (Vladimir Sekissov) Date: Fri, 25 Apr 2003 04:33:07 +0600 (YEKST) Subject: mapping implemented in functions vs in structures In-Reply-To: <200304242210.h3OMAPL7004180@ram.rentec.com> References: <200304242210.h3OMAPL7004180@ram.rentec.com> Message-ID: <20030425.043307.130222682.svg@surnet.ru> Good day, But why not: map_el(m1, m2, x1) -> y1; map_el(m1, m2, x2) -> y2; ... or map_el({m1, m2}, x1) -> y1; map_el({m1, m2}, x2) -> y2; ... Best Regards, Vladimir Sekissov hp> I want to map entity x1 on machine m1 to y1 on m2 ... hp> hp> I can see there are two choices and don't know which one hp> is the more idiomatic way in erlang world: hp> hp> (1) functions hp> m1_m2(x1) -> y1; hp> m1_m2(x2) -> y2. hp> m3_m6(a1) -> b1; hp> m3_m6(a2) -> b2.... hp> hp> At run time, hp> suppose A = m1, B = m2, X = x1. hp> To get y1, hp> I will need to form a string S ="m1_m2(x1)" hp> and evaluate it. hp> btw, how do I do this ? erl_eval:expr() looks complicated. hp> hp> (2) structures hp> {{m1_m2, [{x1, y1}, hp> {x2, y2}]}, hp> {m3_m6, [{a1, b1}, hp> {a2, b2}]} hp> hp> Given A, B, X in (1), finding y1 becomes hp> a matter of parsing the structure. hp> hp> thanks, hp> HP From hp@REDACTED Fri Apr 25 00:36:54 2003 From: hp@REDACTED (HP Wei) Date: Thu, 24 Apr 2003 18:36:54 -0400 (EDT) Subject: mapping implemented in functions vs in structures Message-ID: <200304242236.h3OMasL7004744@ram.rentec.com> >But why not: > >map_el(m1, m2, x1) -> y1; >map_el(m1, m2, x2) -> y2; >... > or > >map_el({m1, m2}, x1) -> y1; >map_el({m1, m2}, x2) -> y2; Oh, yeah!!! This is much SIMPLER and clear. Thanks a lot. --hp From hp@REDACTED Fri Apr 25 00:52:21 2003 From: hp@REDACTED (HP Wei) Date: Thu, 24 Apr 2003 18:52:21 -0400 (EDT) Subject: sorting in tv Message-ID: <200304242252.h3OMqLL7004973@ram.rentec.com> Is sorting in tv not done at each automatic polling ??? I have a tv watching an ets table which is updated regularly. The tv is set manually to run automatic polling, and sorting in ascending order based on column 4. The update only changes certain values in column 3 and 4 of the table. After a while, I notice that the table is not sorted any more unless I manually do the sorting again. Is this the expected behavior ? --HP From hp@REDACTED Fri Apr 25 01:27:16 2003 From: hp@REDACTED (HP Wei) Date: Thu, 24 Apr 2003 19:27:16 -0400 (EDT) Subject: testing codes in erl with running processes Message-ID: <200304242327.h3ONRGL7005481@ram.rentec.com> I have an erl session, in which there is a process running. I load a testing module which is unrelated to the running process; then, I type fx(...), without specifying the module name: test:fx(...). erl tells me so dutifully. But after a few seconds, the running process also exits with {badarg...} type of error. Can the action of testing codes somehow interfere with a process running in the background ?? -HP From hp@REDACTED Fri Apr 25 01:53:14 2003 From: hp@REDACTED (HP Wei) Date: Thu, 24 Apr 2003 19:53:14 -0400 (EDT) Subject: prolog like operation in erlang ? Message-ID: <200304242353.h3ONrEtW001281@wren.rentec.com> Another newbie type question: Suppose I define a relation through the following function: rel(x1, m1, m2) -> true; rel(x2, m1, m2) -> true; rel(x3, m3, m6) -> true; .... In prolog, if I am not mistaken, something like rel(X, m1, m2) can give me X = [x1, x2]. In erlang, how do I in general get the corresponding X ?? Or should I encode the relation in a structure in this case ? HP From kent@REDACTED Fri Apr 25 03:26:17 2003 From: kent@REDACTED (Kent Boortz) Date: 25 Apr 2003 03:26:17 +0200 Subject: prolog like operation in erlang ? In-Reply-To: <200304242353.h3ONrEtW001281@wren.rentec.com> References: <200304242353.h3ONrEtW001281@wren.rentec.com> Message-ID: HP Wei writes: > Suppose I define a relation through the following function: > > rel(x1, m1, m2) -> true; > rel(x2, m1, m2) -> true; > rel(x3, m3, m6) -> true; > .... > > In prolog, if I am not mistaken, > something like rel(X, m1, m2) can give me X = [x1, x2]. It has been a long time since I wrote Prolog but to get a result like this in Prolog you have to use something like findall/setof/bagof. > In erlang, how do I in general get the corresponding X ?? > Or should I encode the relation in a structure in this case ? Erlang being functional you can't get a result like that without splitting up the relation to functions with the mappings you want to use. You may be able to simulate what you want using an ets table, something like test() -> T = ets:new(foo,[duplicate_bag]), ets:insert(T, {x1, m1, m2}), ets:insert(T, {x2, m1, m2}), ets:insert(T, {x3, m3, m6}), X = ets:select(T, [{{'$1',m1, m2},[],['$1']}]). but the order of the result will be undefined, kent (did I just write my first match specification? ;-) From matthias@REDACTED Fri Apr 25 06:45:36 2003 From: matthias@REDACTED (Matthias Lang) Date: Fri, 25 Apr 2003 06:45:36 +0200 Subject: testing codes in erl with running processes In-Reply-To: <200304242327.h3ONRGL7005481@ram.rentec.com> References: <200304242327.h3ONRGL7005481@ram.rentec.com> Message-ID: <16040.48496.535292.51504@antilipe.corelatus.se> HP Wei writes: > I have an erl session, in which there is a process running. > > I load a testing module which is unrelated to the running process; > then, > I type fx(...), without specifying the module name: test:fx(...). > erl tells me so dutifully. > But after a few seconds, the running process also exits > with {badarg...} type of error. > > Can the action of testing codes somehow > interfere with a process running in the background ?? If a process is linked to the shell and the shell exits, then that process will receive an exit signal. An error in the shell causes the shell process to exit and restart: 1> self(). <0.25.0> 2> fx(). ** exited: {undef,[{shell_default,fx,[]}, 3> self(). <0.40.0> If you don't want that behaviour, make sure your process isn't linked to the shell process, for instance by starting it via spawn() instead of spawn_link(). Matthias From fritchie@REDACTED Fri Apr 25 07:29:38 2003 From: fritchie@REDACTED (Scott Lystig Fritchie) Date: Fri, 25 Apr 2003 00:29:38 -0500 Subject: ETS keys: how complex in usual cases? Message-ID: <200304250529.h3P5Tcuc042772@snookles.snookles.com> I've been pondering some wacky things lately regarding the keys used for ETS tables. It's possible to use any term as a record's key in an ETS table, but how often is that ability *really* used? Would it be useful to be able to limit the type of term used for an ETS table key if it meant a performance increase? I'd add another option to ets:new(): {keyfmt, Term}. "Term" would be a representative key, examples being: 1, foo, "foo", <<"foo">>, {foo, bar}, and {foo, 1} To illustrate the point using the last example, {foo, 1}, all keys inserted into the table must be a tuple of arity 2 where the first element must be an atom and the second element must be a number. I'm still trying to figure out if I can make my little idea is even feasible. If I can get it to work, the speed improvement may be 15% to possibly 30-35% for very large ETS tables. Would that be worth it? Does Mnesia do anything to its ETS tables that would screw up such a restriction? -Scott From fritchie@REDACTED Fri Apr 25 08:02:20 2003 From: fritchie@REDACTED (Scott Lystig Fritchie) Date: Fri, 25 Apr 2003 01:02:20 -0500 Subject: ETS keys: how complex in usual cases? In-Reply-To: Message of "Fri, 25 Apr 2003 00:29:38 CDT." <200304250529.h3P5Tcuc042772@snookles.snookles.com> Message-ID: <200304250602.h3P62Kuc042932@snookles.snookles.com> Hating to follow up to my own question but ... I forgot to add something. In my current (perhaps faulty) thinking, the key format limit hack would possibly only be required for 'ordered_set' ETS tables. Do your typical applications use 'ordered_set' frequently? ("Correct" ordering of arbitrary Erlang terms is, er, hard. :-) I haven't yet experimented enough with the three other flavors of ETS tables yet; I hope to correct that in the next day or two. -Scott From dgud@REDACTED Fri Apr 25 10:06:23 2003 From: dgud@REDACTED (Dan Gudmundsson) Date: Fri, 25 Apr 2003 10:06:23 +0200 Subject: ETS keys: how complex in usual cases? In-Reply-To: <200304250529.h3P5Tcuc042772@snookles.snookles.com> References: <200304250529.h3P5Tcuc042772@snookles.snookles.com> Message-ID: <16040.60543.993592.12138@rian.du.uab.ericsson.se> Scott Lystig Fritchie writes: > Does Mnesia do anything to its ETS tables that would screw up such a > restriction? Nope From csanto@REDACTED Fri Apr 25 10:38:21 2003 From: csanto@REDACTED (Corrado Santoro) Date: Fri, 25 Apr 2003 10:38:21 +0200 Subject: Announce ERES (Re: prolog like operation in erlang ?) In-Reply-To: <200304242353.h3ONrEtW001281@wren.rentec.com> References: <200304242353.h3ONrEtW001281@wren.rentec.com> Message-ID: <1051259901.3ea8f3fd3b08e@www.cdc.unict.it> Dear all, the question of HP lead me to announce (before time!) ERES, which is an Erlang library to realize rule-processing engines as in Prolog. You may find it at: http://www.diit.unict.it/users/csanto/eres.html Please note that it is an "alpha" version since I still have to implement some optimization and fixes. Also the documentation needs to be improved :)) Anyway, I would appreciate any feedback from those of you which will try ERES. ERES is based on the concept of "knowledge base" which can store a set of "facts". For example, the problem of HP can be solved as: eres:new (mykb). eres:assert_list (mykb, [{x1,m1,m2}, {x2,m1,m2}, {x3,m3,m6}]). Then, using "eres:querykb (mykb, {nil, m1,m2])" will return: [{x1,m1,m2}, {x2,m1,m2}] You can also use lambda expressions in querykb (see the web page). But the main use of ERES is rule processing. You can implement rules such as: pre-condition --> action as function clauses, where the pre-condition refers to checking the presence of a certain fact in the knowledge base. For example, if you want to express that "each father is also a male", you can write: myrule (E, {father, X}) -> eres:assert (E, {male, X}), true. Asserting a fact like {father, corrado} will result in the automatical creation of the fact {male, corrado} (see the documentation for more detail). Regards, -Corrado Quoting HP Wei : > Another newbie type question: > > Suppose I define a relation through the following function: > > rel(x1, m1, m2) -> true; > rel(x2, m1, m2) -> true; > rel(x3, m3, m6) -> true; > .... > > In prolog, if I am not mistaken, > something like rel(X, m1, m2) can give me X = [x1, x2]. > > In erlang, how do I in general get the corresponding X ?? > Or should I encode the relation in a structure in this case ? > > HP > > -- ====================================================== Eng. Corrado Santoro, Ph.D. Unversity of Catania - Engineering Faculty Department of Computer Science and Telecommunications Engineering Viale A. Doria, 6 - 95125 CATANIA (ITALY) Tel: +39 095 7382364 Fax: +39 095 338280 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 etxuwig@REDACTED Fri Apr 25 11:41:14 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Fri, 25 Apr 2003 11:41:14 +0200 (MEST) Subject: mnesia:match_object() on an ordered_set In-Reply-To: Message-ID: On Thu, 24 Apr 2003, Hakan Mattsson wrote: >On Thu, 24 Apr 2003, Ulf Wiger wrote: > >Uffe> Given the current implementation of mnesia:match_object(), I >Uffe> don't think preserving the order would have to impact >Uffe> performance, esp. not on large sets (and on small sets, I >Uffe> don't think it matters.) > >For fragmented tables it would have a tremendous impact, as >the order only is preserved within each fragment. In order >to return an ordered result, it would require a quite >substantial sort operation. True, unless one writes a custom mnesia_frag_hash callback which manages fragments with some global order. This is what I had in mind to do with XML Query for Mnesia. It does bring up the question how far one should try to preserve the semantics. It would of course be nice if one could guarantee the same semantics for fragmented tables as for basic tables, but certainly not at any price (allowing only the lowest common denominator is also a price to pay, of course.) >Of course Mnesia could ensure that the result of a >match_object on an ordered_set always should be ordered, >but is it worth the performance penalty? Given the current implementation, I'd say yes. ;-) This is the function in mnesia.erl that adds objects from the transaction store to the found set: add_match([], Objs, Type) -> Objs; add_match([{Oid, _, delete}|R], Objs, Type) -> add_match(R, deloid(Oid, Objs), Type); add_match([{Oid, Val, delete_object}|R], Objs, Type) -> add_match(R, lists:delete(Val, Objs), Type); add_match([{Oid, Val, write}|R], Objs, Type) -> case Type of bag -> add_match(R, [Val | lists:delete(Val, Objs)], Type); _ -> add_match(R, [Val | deloid(Oid,Objs)],Type) end. deloid(Oid, []) -> []; deloid({Tab, Key}, [H | T]) when element(2, H) == Key -> deloid({Tab, Key}, T); deloid(Oid, [H | T]) -> [H | deloid(Oid, T)]. Given that Type == ordered_set, Objs would be an ordered list to start with, and sort_insert(Key, Val, Objs) would not be slower than [Val | deloid(Oid,Objs)]. In fact, the following sort_insert(Key,Val,Objs) is actually more than twice as fast as the current implementation in mnesia.erl (on a given sample with 1000 Objs, 10 written objs in the lower key range, and 10 in the upper key range.) sort_insert(Key, Val, [H|T]) when element(2,H) == Key -> [Val | T]; sort_insert(Key, Val, [H|_]=L) when element(2,H) > Key -> [Val | L]; sort_insert(Key, Val, [H|T]) -> [H | sort_insert(Key, Val, T)]; sort_insert(_, _, []) -> []. The reason for this is mostly that deloid/2 is too generic. It traverses the whole list each time, even after it's found a matching key. Assuming set semantics, this is not necessary. I fail to see why lists:keydelete/3 wouldn't do the job. The modified mnesia:add_match/3 would then become: add_match([{{Tab,Key}, Val, write}|R], Objs, Type) -> case Type of bag -> add_match(R, [Val | lists:delete(Val, Objs)], Type); ordered_set -> add_match(R, sort_insert(Key,Val,Objs), Type); _ -> add_match(R, [Val | lists:keydelete(Key,2,Objs)],Type) end. Even with this fix, my sort_insert/3 is some 20% faster. (: At the moment, I fail to see why on this particular test. On a non-contiguous range of objects, where R contains new records as well as updated ones, my sort_insert version is much faster, as deloid/keydelete must traverse the entire set for each new object. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From etxuwig@REDACTED Fri Apr 25 12:11:41 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Fri, 25 Apr 2003 12:11:41 +0200 (MEST) Subject: mnesia:match_object() on an ordered_set In-Reply-To: Message-ID: On Fri, 25 Apr 2003, Ulf Wiger wrote: >On Thu, 24 Apr 2003, Hakan Mattsson wrote: > >>On Thu, 24 Apr 2003, Ulf Wiger wrote: >> >>Uffe> Given the current implementation of mnesia:match_object(), I >>Uffe> don't think preserving the order would have to impact >>Uffe> performance, esp. not on large sets (and on small sets, I >>Uffe> don't think it matters.) >> >>For fragmented tables it would have a tremendous impact, as >>the order only is preserved within each fragment. In order >>to return an ordered result, it would require a quite >>substantial sort operation. > >True, unless one writes a custom mnesia_frag_hash callback >which manages fragments with some global order. This is >what I had in mind to do with XML Query for Mnesia. Actually, given the current implementation of mnesia:match_object/2, the order is _not_ preserved, even within the fragment. ;-) As to preserving a global order, mnesia_frag in its default implementation makes this hard. On the other hand, what's the point of having multiple ordered set fragments if objects are distributed among the fragments using a hashing algorithm? (: Each ordered_set fragment will contain only a pseudo-random subset of the global set, so it's doubtful whether there is any point to the local ordering anyway. Using a custom fragmentation scheme, one may distribute objects such that e.g. all objects belonging to one particular document fall into the same fragment; then there is some point to having an ordered_set fragment. It's still quite feasible to have a hashing algorithm at the top, so that the order among documents is undefined, but the order _within_ documents is well defined. Fixing mnesia:match_object/2 for ordered sets should make this scheme work well. (A random thought: if an ets:match_object/3 could allow one to specify a target ets table, a corresponding mnesia:match_object/3 run over a fragmented table could drop all found objects in an ordered_set table, and the problem would be solved. This ets:match_object/3 function would also have very pleasant memory characteristics, since it would not build large heap structures.) /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From etxuwig@REDACTED Fri Apr 25 13:04:54 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Fri, 25 Apr 2003 13:04:54 +0200 (MEST) Subject: mnesia:match_object() on an ordered_set In-Reply-To: Message-ID: On Fri, 25 Apr 2003, Ulf Wiger wrote: >(A random thought: if an ets:match_object/3 could allow one >to specify a target ets table, a corresponding >mnesia:match_object/3 run over a fragmented table could >drop all found objects in an ordered_set table, and the >problem would be solved. This ets:match_object/3 function >would also have very pleasant memory characteristics, since >it would not build large heap structures.) (I notice that I keep following up on my own posts...) Perhaps this is really a version of ets:new()...? e.g. ets:new(found_set, [{type, ordered_set}, {select, {Tab, Pattern}}]). This would create a new ETS table, and populate it with the results from ets:select(Tab, Pattern). The next step would be to perform a join operation. ;-) /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From hakan@REDACTED Fri Apr 25 13:22:55 2003 From: hakan@REDACTED (Hakan Mattsson) Date: Fri, 25 Apr 2003 13:22:55 +0200 (MEST) Subject: mnesia:match_object() on an ordered_set In-Reply-To: Message-ID: On Fri, 25 Apr 2003, Ulf Wiger wrote: Uffe> On Fri, 25 Apr 2003, Ulf Wiger wrote: Uffe> Uffe> >On Thu, 24 Apr 2003, Hakan Mattsson wrote: Uffe> > Uffe> >>On Thu, 24 Apr 2003, Ulf Wiger wrote: Uffe> >> Uffe> >>Uffe> Given the current implementation of mnesia:match_object(), I Uffe> >>Uffe> don't think preserving the order would have to impact Uffe> >>Uffe> performance, esp. not on large sets (and on small sets, I Uffe> >>Uffe> don't think it matters.) Uffe> >> Uffe> >>For fragmented tables it would have a tremendous impact, as Uffe> >>the order only is preserved within each fragment. In order Uffe> >>to return an ordered result, it would require a quite Uffe> >>substantial sort operation. Uffe> > Uffe> >True, unless one writes a custom mnesia_frag_hash callback Uffe> >which manages fragments with some global order. This is Uffe> >what I had in mind to do with XML Query for Mnesia. Uffe> Uffe> Actually, given the current implementation of Uffe> mnesia:match_object/2, the order is _not_ preserved, even Uffe> within the fragment. ;-) With "as the order only is preserved within each fragment", I was referring to the persistent order, not the transient order during the transaction. Sorry for the confusion. Uffe> As to preserving a global order, mnesia_frag in its default Uffe> implementation makes this hard. On the other hand, what's Uffe> the point of having multiple ordered set fragments if Uffe> objects are distributed among the fragments using a hashing Uffe> algorithm? (: Each ordered_set fragment will contain only Uffe> a pseudo-random subset of the global set, so it's doubtful Uffe> whether there is any point to the local ordering anyway. In most cases it would not be any point. But if you have an access pattern with frequent matching of a partitially bound key, it could make a big difference. You would in the standard case (using the default hash function) still need to perform the match in all fragments, but ets would not need to perform an exhaustive search of the entire table. Uffe> Using a custom fragmentation scheme, one may distribute Uffe> objects such that e.g. all objects belonging to one Uffe> particular document fall into the same fragment; then there Uffe> is some point to having an ordered_set fragment. It's Uffe> still quite feasible to have a hashing algorithm at the top, Uffe> so that the order among documents is undefined, but the Uffe> order _within_ documents is well defined. Uffe> Uffe> Fixing mnesia:match_object/2 for ordered sets should make Uffe> this scheme work well. If the documented behavior of mnesia:match_object/2 on an ordered_set, is changed to also guarantee an ordered result, then this implies that this is consequently implemented. The semantics should be the same for both ordinary tables and fragmented tables and not rely on any customized fragmentation scheme. /H?kan --- H?kan Mattsson Ericsson High Availability Software, DBMS Internals http://www.ericsson.com/cslab/~hakan/ From etxuwig@REDACTED Fri Apr 25 13:52:00 2003 From: etxuwig@REDACTED (Ulf Wiger) Date: Fri, 25 Apr 2003 13:52:00 +0200 (MEST) Subject: mnesia:match_object() on an ordered_set In-Reply-To: Message-ID: On Fri, 25 Apr 2003, Hakan Mattsson wrote: >Uffe> As to preserving a global order, mnesia_frag in its default >Uffe> implementation makes this hard. On the other hand, what's >Uffe> the point of having multiple ordered set fragments if >Uffe> objects are distributed among the fragments using a hashing >Uffe> algorithm? (: Each ordered_set fragment will contain only >Uffe> a pseudo-random subset of the global set, so it's doubtful >Uffe> whether there is any point to the local ordering anyway. > >In most cases it would not be any point. But if you have an >access pattern with frequent matching of a partitially >bound key, it could make a big difference. You would in the >standard case (using the default hash function) still need >to perform the match in all fragments, but ets would not >need to perform an exhaustive search of the entire table. Good point. >If the documented behavior of mnesia:match_object/2 on an >ordered_set, is changed to also guarantee an ordered >result, then this implies that this is consequently >implemented. The semantics should be the same for both >ordinary tables and fragmented tables and not rely on any >customized fragmentation scheme. Considering that my suggested change basically doubles the performance of the merge of the found set and the transaction store, given an ordered_set, one might want to implement it anyway, without documenting it as a guarantee. /Uffe -- Ulf Wiger, Senior Specialist, / / / Architecture & Design of Carrier-Class Software / / / Strategic Product & System Management / / / Ericsson AB, Connectivity and Control Nodes From mickael.remond@REDACTED Fri Apr 25 14:33:35 2003 From: mickael.remond@REDACTED (Mickael Remond) Date: Fri, 25 Apr 2003 14:33:35 +0200 Subject: Erlang in a french magazine (L'informaticien) Message-ID: Hello, An introduction article (by Fr?d?ric Mazu?) has been published in a french magazine called "l'informaticien" (mars 2003 - Issue 4). I unfortunately did not manage to get a magazine myself, but the article is mentionned on the cover page ("Erlang: an industrial language"), in the summary (Erlang: Discovery of one of the most promising functionnal language). The article is 3 pages long and is pretty good, putting Erlang in perspective with the switch toward a more concurrent and functionnal approach of development pushed by Web services and .Net. Here is a link to the summary of the magazine (In french, sorry): http://www.linformaticien.fr/images/num004/P05G.gif Cheers, -- Micka?l R?mond http://www.erlang-projects.org/ From hp@REDACTED Fri Apr 25 14:51:24 2003 From: hp@REDACTED (HP Wei) Date: Fri, 25 Apr 2003 08:51:24 -0400 (EDT) Subject: testing codes in erl with running processes Message-ID: <200304251251.h3PCpOtW017960@wren.rentec.com> >HP Wei writes: > > I have an erl session, in which there is a process running. > > > > I load a testing module which is unrelated to the running process; > > then, > > I type fx(...), without specifying the module name: test:fx(...). > > erl tells me so dutifully. > > But after a few seconds, the running process also exits > > with {badarg...} type of error. > > > > Can the action of testing codes somehow > > interfere with a process running in the background ?? > >If a process is linked to the shell and the shell exits, then that >process will receive an exit signal. An error in the shell causes the >shell process to exit and restart: > > 1> self(). > <0.25.0> > 2> fx(). > ** exited: {undef,[{shell_default,fx,[]}, > 3> self(). > <0.40.0> > >If you don't want that behaviour, make sure your process isn't linked >to the shell process, for instance by starting it via spawn() instead >of spawn_link(). I checked my code for that process at issue. It uses spawn(Mod, loop, [Tab]). In the loop(), there is a receive stop -> stop after 30000 -> loop(Tab) end. I use your simple test: self(). and fx(). ---------> the shell exited as you described. And after a few moment, that process also died !! Any idea whether there is bug somewhere ?? --HP From hp@REDACTED Fri Apr 25 14:57:28 2003 From: hp@REDACTED (HP Wei) Date: Fri, 25 Apr 2003 08:57:28 -0400 (EDT) Subject: testing codes in erl with running processes Message-ID: <200304251257.h3PCvStW018068@wren.rentec.com> >HP Wei writes: > > I have an erl session, in which there is a process running. > > > > I load a testing module which is unrelated to the running process; > > then, > > I type fx(...), without specifying the module name: test:fx(...). > > erl tells me so dutifully. > > But after a few seconds, the running process also exits > > with {badarg...} type of error. > > > > Can the action of testing codes somehow > > interfere with a process running in the background ?? > >If a process is linked to the shell and the shell exits, then that >process will receive an exit signal. An error in the shell causes the >shell process to exit and restart: > > 1> self(). > <0.25.0> > 2> fx(). > ** exited: {undef,[{shell_default,fx,[]}, > 3> self(). > <0.40.0> > >If you don't want that behaviour, make sure your process isn't linked >to the shell process, for instance by starting it via spawn() instead >of spawn_link(). hi, forget about my previous email. I just realized that in my process, I refer to an ets table. And an ets table is associated with the running shell. This should explain why that process dies. If this is the case, I probably have no way to avoid this from happening. The easy way is to develop code in another erl ? HP From eleberg@REDACTED Fri Apr 25 15:05:36 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Fri, 25 Apr 2003 15:05:36 +0200 (MEST) Subject: testing codes in erl with running processes Message-ID: <200304251305.h3PD5aq11387@cbe.ericsson.se> > Date: Fri, 25 Apr 2003 08:57:28 -0400 (EDT) > From: HP Wei > Subject: Re: testing codes in erl with running processes > I just realized that in my process, I refer to an ets table. > And an ets table is associated with the running shell. > This should explain why that process dies. > > If this is the case, I probably have no way to avoid this from > happening. The easy way is to develop code in another erl ? write a function that spawns a process, and let that process: 1 create the ets table 2 not die bengt From eleberg@REDACTED Fri Apr 25 15:08:03 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Fri, 25 Apr 2003 15:08:03 +0200 (MEST) Subject: Erlang in a french magazine (L'informaticien) Message-ID: <200304251308.h3PD83q11602@cbe.ericsson.se> > To: erlang-questions@REDACTED > Subject: Erlang in a french magazine (L'informaticien) > From: Mickael Remond > > Here is a link to the summary of the magazine (In french, sorry): no need to apologise. the ability to read french should be required. not writing french, though. definitly not writing. bengt From hp@REDACTED Fri Apr 25 15:43:59 2003 From: hp@REDACTED (HP Wei) Date: Fri, 25 Apr 2003 09:43:59 -0400 (EDT) Subject: testing codes in erl with running processes Message-ID: <200304251343.h3PDhxL7019748@ram.rentec.com> >> I just realized that in my process, I refer to an ets table. >> And an ets table is associated with the running shell. >> This should explain why that process dies. >> >> If this is the case, I probably have no way to avoid this from >> happening. The easy way is to develop code in another erl ? > >write a function that spawns a process, and let that process: > >1 create the ets table >2 not die Yes, the problem is resolved. Now, the ets table is owned by the process instead of the shell. Thanks for reminding me of the scoping! HP From Fabien.Dagnat@REDACTED Fri Apr 25 15:42:05 2003 From: Fabien.Dagnat@REDACTED (Fabien Dagnat) Date: Fri, 25 Apr 2003 15:42:05 +0200 Subject: Erlang in a french magazine (L'informaticien) References: Message-ID: <3EA93B2D.9000806@enst-bretagne.fr> Hello, I personnally have this magazine, if someone is intersted I can send a photocopy or I can try to scan it... Cheers Mickael Remond wrote: > Hello, > > An introduction article (by Fr?d?ric Mazu?) has been published in a > french magazine called "l'informaticien" (mars 2003 - Issue 4). > > I unfortunately did not manage to get a magazine myself, but the > article is mentionned on the cover page ("Erlang: an industrial > language"), in the summary (Erlang: Discovery of one of the most > promising functionnal language). > > The article is 3 pages long and is pretty good, putting Erlang in > perspective with the switch toward a more concurrent and functionnal > approach of development pushed by Web services and .Net. > > Here is a link to the summary of the magazine (In french, sorry): > > http://www.linformaticien.fr/images/num004/P05G.gif > > Cheers, > -- Fabien Dagnat -- Ma?tre de Conf?rences Mel : Fabien.Dagnat@REDACTED Web : perso-info.enst-bretagne.fr/~fdagnat/index.php 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 BP 832 29285 Brest Cedex From martin@REDACTED Fri Apr 25 16:45:09 2003 From: martin@REDACTED (martin j logan) Date: 25 Apr 2003 09:45:09 -0500 Subject: ets:match(Continuation) usage question. In-Reply-To: References: Message-ID: <1051281910.10404.245.camel@berimbau> On Thu, 2003-04-24 at 15:48, Jeff Einhorn wrote: > I was wondering what happens if updates are made to an ets table while an > ets:match(Continuation) search is being ran? > thanks for your time, > -jeff Jeff, I am not totally sure if this relates to your question, perhaps one of the ets authors could clarify, but I believe that if you do a ets:match with a continuation while updates are performed that it behaves similar to mnesia:dirty_next under the same circumstance i.e undefined. I think that there is an internal hash that is altered upon an updates. This alterations changes the internal structure in a way that is incompatible with continuations. I am not sure if I am totally on the mark here though. Cheers, Martin > > Jeffrey M. Einhorn > Software Engineer > Web Development Group > FutureSource, LLC > jeinhorn@REDACTED > http://www.futuresource.com > From sean.hinde@REDACTED Fri Apr 25 16:44:21 2003 From: sean.hinde@REDACTED (Sean Hinde) Date: Fri, 25 Apr 2003 15:44:21 +0100 Subject: mnesia:match_object() on an ordered_set In-Reply-To: Message-ID: <66A925B2-772C-11D7-B7D5-000393A45C3C@mac.com> > Perhaps this is really a version of ets:new()...? > > > e.g. > > ets:new(found_set, [{type, ordered_set}, > {select, {Tab, Pattern}}]). > > This would create a new ETS table, and populate it with the > results from ets:select(Tab, Pattern). > > The next step would be to perform a join operation. ;-) > > I like this - yes please OTP team! Sean From eleberg@REDACTED Fri Apr 25 17:06:24 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Fri, 25 Apr 2003 17:06:24 +0200 (MEST) Subject: upgrade of supervisors child specifications Message-ID: <200304251506.h3PF6Oq22346@cbe.ericsson.se> greetings, how do i change (when doing an upgrade) the contents of a supervisors child specifications? background: there exists a supervisor with its children. the output of supervisor:which_children(my_supervisor) => [{Id, Child,Type,Modules}, ...] due to reasons it has been decided to change Id to OtherId during upgrade. i have identified the other places where Id is stored (ets/mnesia tables) and successfully transformed these tables. now i need to change the contents of my_supervisor's child specifications. the code in supervisor.erl hints at a tantelising possiblity: code_change(_, State, _) -> case apply(State#state.module, init, [State#state.args]) of {ok, {SupFlags, StartSpec}} -> case catch check_flags(SupFlags) of ok -> update_childspec(State, StartSpec); as one can see StartSpec is returned from :init/1. is this possible to use? how? (ie, when/why is supervisor:code_change/3 called) it is fine to just point me to the right place in the documentation. bengt From mbj@REDACTED Fri Apr 25 22:11:15 2003 From: mbj@REDACTED (Martin Bjorklund) Date: Fri, 25 Apr 2003 22:11:15 +0200 (CEST) Subject: upgrade of supervisors child specifications In-Reply-To: <200304251506.h3PF6Oq22346@cbe.ericsson.se> References: <200304251506.h3PF6Oq22346@cbe.ericsson.se> Message-ID: <20030425.221115.41637560.mbj@bluetail.com> Bengt Kleberg wrote: > greetings, > > how do i change (when doing an upgrade) the contents of a supervisors > child specifications? [...] > it is fine to just point me to the right place in the documentation. If you're using the release_handler and release upgrade scripts, it is indeed possible. See chapter 4.7.1.9 of the SASL User's guide (http://www.erlang.org/doc/r9b/lib/sasl-1.9.4/doc/html/part_frame.html). The code_change function in the supervisor will be called from the relup interpreter. If you don't use the release_handler, you can "roll your own" by calling the functions in sys(3). (you might want to look at the relup interpreter in release_handler_1.erl for inspiration) In your case, I think you'll have to first terminate the old child, then update the supervisor (i.e. load the code and tell it to switch to the new code), then start the new child. /martin From jay@REDACTED Sun Apr 27 01:10:15 2003 From: jay@REDACTED (Jay Nelson) Date: Sat, 26 Apr 2003 16:10:15 -0700 Subject: Directory structure for a release Message-ID: <4.2.2.20030426154630.00ce27d0@duomark.com> I am trying to package up some code according to OTP principles so that I can do code upgrade / downgrade and have bootable nodes and a pool of clients. I am probably getting confused between traditional code partitioning and the OTP way so I wanted a little guidance. I am trying to avoid having a lump of code that ends up causing things like in the OTP distribution where some useful utilities are part of the HTTP module and so on. Since I am just starting now is the time to get the directory partitioning right. I have the following "code sets": 1) Utilities (bin_utils, tcp_proxy) 2) HTTP utilities (web_utils, ProxyModule) 3) Host supervisor I've got all the lib/App/ebin, src, priv and so on, but my question has to do with what is an app and what is a code organization structure. I expect to use #1 Utilities for many projects. I expect to use #2 HTTP Utilities only for this application. Likewise the hostsupervisor is specific to this application. Originally, I thought to put all three in separate directories and to have other directories for other shareable or non- shareable pieces, but it means each becomes an app with *.app file and so on. It also means (I believe) that they are regarded as part of an application tree whether or not they have processes running or are code-only. Now I am wondering if one of the two following approaches is better: 1) All in one directory 2) Host supervisor / HTTP utils in one; Utilities in other Reasons for #1: a) They are all part of a single application b) Code upgrades can still occur on a module basis Reasons for #2: a) The first directory is really the application b) Utilities is shareable to other applications One of my concerns is whether code is compiled and/or loaded if it is not used. In other words, if I use the first approach and dump everything in a single app directory and later write a new app that uses some utilities, will it require all the modules in the app directory or only the ones listed in the script file. What advantages and disadvantages are there to having an app directory that contains only code and no processes as in #2? Does it make configuration harder with no gain in code partitioning or loaded binaries? If I write a 2nd application do I just dump it in the same directory and write a different release configuration, or should I go with approach #2 so that I create a new app directory? Is it best to have as few directories as possible under lib, but at least one per bootable application? Is there any advantage to partitioning the directories on a finer scale so that they are equivalent to libraries of related modules, or should there be one big utilities library (code-only app) containing all shareable code (a la stdlib)? jay From ulf.wiger@REDACTED Sun Apr 27 20:30:21 2003 From: ulf.wiger@REDACTED (Wiger Ulf) Date: Sun, 27 Apr 2003 20:30:21 +0200 Subject: Directory structure for a release References: <4.2.2.20030426154630.00ce27d0@duomark.com> Message-ID: <000701c30ceb$102f77a0$fd7a40d5@telia.com> (I had a longer answer to this almost ready, but Outlook Express segfaulted and left nothing of it, so here's a short answer) - Unless you run with the '-mode embedded' flag, erlang will not load modules unless they are actually called. - How you want to organize your code is pretty much up to you and your administrative routines, but OTP's release handler likes to upgrade code on a per-application basis. This is rather an argument for _more_ applications than fewer. - I would try to create my applications so that each module in an application logically belongs there. Typically, I would try to have one interface module (possibly a few) for one application, and keep only modules in there that are specific to implementing that interface. - It is perhaps useful to have a 'utilities' grab-bag application for those modules that don't seem to belong anywhere else, but I personally don't think it should be the norm. - It's perfectly OK to have several code roots (several lib/ directories), if you feel that that's a more comfortable way to organize your code. - To build different "systems", I'd create different "release" directories, under which I'd collect database, logs, application-specific files, and OTP release handler scripts. All the code might well reside in one place, under one lib (just be careful then with release_handler:remove_release()) /Uffe ----- Original Message ----- From: "Jay Nelson" To: Sent: den 27 april 2003 01:10 Subject: Directory structure for a release > I am trying to package up some code according to OTP > principles so that I can do code upgrade / downgrade > and have bootable nodes and a pool of clients. > > I am probably getting confused between traditional code > partitioning and the OTP way so I wanted a little guidance. > I am trying to avoid having a lump of code that ends up > causing things like in the OTP distribution where some > useful utilities are part of the HTTP module and so on. > Since I am just starting now is the time to get the directory > partitioning right. > > I have the following "code sets": > > 1) Utilities (bin_utils, tcp_proxy) > 2) HTTP utilities (web_utils, ProxyModule) > 3) Host supervisor > > I've got all the lib/App/ebin, src, priv and so on, but my > question has to do with what is an app and what is a > code organization structure. > > I expect to use #1 Utilities for many projects. I expect to > use #2 HTTP Utilities only for this application. Likewise > the hostsupervisor is specific to this application. > > Originally, I thought to put all three in separate directories > and to have other directories for other shareable or non- > shareable pieces, but it means each becomes an app with > *.app file and so on. It also means (I believe) that they > are regarded as part of an application tree whether or not > they have processes running or are code-only. > > Now I am wondering if one of the two following approaches > is better: > > 1) All in one directory > 2) Host supervisor / HTTP utils in one; Utilities in other > > Reasons for #1: > a) They are all part of a single application > b) Code upgrades can still occur on a module basis > > Reasons for #2: > a) The first directory is really the application > b) Utilities is shareable to other applications > > One of my concerns is whether code is compiled and/or > loaded if it is not used. In other words, if I use the first > approach and dump everything in a single app directory > and later write a new app that uses some utilities, will it > require all the modules in the app directory or only the ones > listed in the script file. > > What advantages and disadvantages are there to having > an app directory that contains only code and no processes > as in #2? Does it make configuration harder with no gain > in code partitioning or loaded binaries? > > If I write a 2nd application do I just dump it in the same > directory and write a different release configuration, or > should I go with approach #2 so that I create a new app > directory? > > Is it best to have as few directories as possible under lib, > but at least one per bootable application? Is there any > advantage to partitioning the directories on a finer scale > so that they are equivalent to libraries of related modules, > or should there be one big utilities library (code-only app) > containing all shareable code (a la stdlib)? > > jay > From cpressey@REDACTED Mon Apr 28 00:34:54 2003 From: cpressey@REDACTED (Chris Pressey) Date: Sun, 27 Apr 2003 17:34:54 -0500 Subject: Directory structure for a release In-Reply-To: <4.2.2.20030426154630.00ce27d0@duomark.com> References: <4.2.2.20030426154630.00ce27d0@duomark.com> Message-ID: <20030427173454.2f75c3b9.cpressey@catseye.mb.ca> On Sat, 26 Apr 2003 16:10:15 -0700 Jay Nelson wrote: > [...] > I have the following "code sets": > > 1) Utilities (bin_utils, tcp_proxy) > 2) HTTP utilities (web_utils, ProxyModule) > 3) Host supervisor > > I've got all the lib/App/ebin, src, priv and so on, but my > question has to do with what is an app and what is a > code organization structure. > > I expect to use #1 Utilities for many projects. I expect to > use #2 HTTP Utilities only for this application. Likewise > the hostsupervisor is specific to this application. > > Originally, I thought to put all three in separate directories > and to have other directories for other shareable or non- > shareable pieces, but it means each becomes an app with > *.app file and so on. It also means (I believe) that they > are regarded as part of an application tree whether or not > they have processes running or are code-only. For what it's worth, my thought is that if those utilities are really shareable and they aren't in a seperate application, that will force other systems that do share them to include the entire ensemble. In your case, does it make sense to make all systems that use bin_utils, also have the host supervisor installed? If so, package them together, and if not, don't. Not always that simple of course, but like that. Library applications do seem a bit non-intuitive, but aside from that I don't think there's any reason not to use them. I would, however, recommend against grouping all utilities together simply because they're all utilities. I now have a monolithic shared library application that is bigger than most of the applications that use it, and most of them only use a fraction of what's in it. I sometimes wonder if it wouldn't be better to have a global "grab bag" of handy, pre-tested, generic functions to be copy-pasted into code... -Chris From jay@REDACTED Mon Apr 28 02:28:56 2003 From: jay@REDACTED (Jay Nelson) Date: Sun, 27 Apr 2003 17:28:56 -0700 Subject: Directory structure for a release Message-ID: <4.2.2.20030427171723.00cfd990@duomark.com> Chris wrote: > I would, however, recommend against grouping all > utilities together simply because they're all utilities. I > now have a monolithic shared library application that > is bigger than most of the applications that use it, and > most of them only use a fraction of what's in it. This is one of my biggest fears because my goal is to make an embedded bootable application that runs from flash or a network loadable image. Does the boot script list only the modules that are actually used, or does it list all modules in a given application? Or more to the point, in an embedded system, are only the used modules loaded or all modules loaded that are part of any application that is loaded? Is there some sort of tree-shaker utility that eliminates module functions that are not called from the code? This would be difficult in the case of {M, F, A} type calls, but is there any tool for the static utility code? I have pretty much settled on one utility application which has no processes and no included applications for things like lists, bin_utils and proxies that are all generally useful, and a separate application for the externally visible functionality. I understand why OTP likes to do things on an application level, but at some point the web of directories is difficult to maintain so I am trying to reduce the number of applications as much as possible. If my catch-all utility application gets too big, I will separate it into pieces and organize them into a hierarchy of related utility applications so that my top-level application can often just include a single utility application (which may include sub-hierarchy utility applications). For now I expect I'll end up with 5-10 utility modules and hope that a particular application will only load the ones that it uses. jay From erlang@REDACTED Mon Apr 28 08:57:56 2003 From: erlang@REDACTED (Peter-Henry Mander) Date: Mon, 28 Apr 2003 07:57:56 +0100 Subject: Erlang in a french magazine (L'informaticien) References: <3EA93B2D.9000806@enst-bretagne.fr> Message-ID: <3EACD0F4.2060900@manderp.freeserve.co.uk> Ne pourrait-on persuader L'Informaticien de produire une copie electronique disponible sur Internet, au lieu de violer leur copyright? (-: sorry, I couldn't help myself) I'm sure that having a follow-up and links online would be beneficial for them and for the Erlang community. Pete. Fabien Dagnat wrote: > Hello, > I personnally have this magazine, if someone is intersted I can send a > photocopy or I can try to scan it... > > Cheers > > Mickael Remond wrote: > >> Hello, >> An introduction article (by Fr?d?ric Mazu?) has been published in a >> french magazine called "l'informaticien" (mars 2003 - Issue 4). >> >> I unfortunately did not manage to get a magazine myself, but the >> article is mentionned on the cover page ("Erlang: an industrial >> language"), in the summary (Erlang: Discovery of one of the most >> promising functionnal language). >> >> The article is 3 pages long and is pretty good, putting Erlang in >> perspective with the switch toward a more concurrent and functionnal >> approach of development pushed by Web services and .Net. >> >> Here is a link to the summary of the magazine (In french, sorry): >> >> http://www.linformaticien.fr/images/num004/P05G.gif >> >> Cheers, >> > > From eleberg@REDACTED Mon Apr 28 09:47:32 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Mon, 28 Apr 2003 09:47:32 +0200 (MEST) Subject: upgrade of supervisors child specifications Message-ID: <200304280747.h3S7lWq19812@cbe.ericsson.se> > Date: Fri, 25 Apr 2003 22:11:15 +0200 (CEST) > To: eleberg@REDACTED > Cc: erlang-questions@REDACTED > Subject: Re: upgrade of supervisors child specifications > From: Martin Bjorklund > Mime-Version: 1.0 > Content-Transfer-Encoding: 7bit > X-OriginalArrivalTime: 25 Apr 2003 20:11:17.0453 (UTC) FILETIME=[D465FFD0:01C30B66] > > Bengt Kleberg wrote: > > greetings, > > > > how do i change (when doing an upgrade) the contents of a supervisors > > child specifications? > > [...] > > > it is fine to just point me to the right place in the documentation. > > If you're using the release_handler and release upgrade scripts, it is > indeed possible. See chapter 4.7.1.9 of the SASL User's guide > (http://www.erlang.org/doc/r9b/lib/sasl-1.9.4/doc/html/part_frame.html). > The code_change function in the supervisor will be called from the > relup interpreter. > thank you. > > In your case, I think you'll have to first terminate the old child, > then update the supervisor (i.e. load the code and tell it to switch > to the new code), then start the new child. i am not allowed to terminate the old child. will this make it more difficult? :-) bengt From mickael.remond@REDACTED Mon Apr 28 09:56:22 2003 From: mickael.remond@REDACTED (Mickael Remond) Date: Mon, 28 Apr 2003 09:56:22 +0200 Subject: Erlang in a french magazine (L'informaticien) In-Reply-To: <3EACD0F4.2060900@manderp.freeserve.co.uk> (Peter-Henry Mander's message of "Mon, 28 Apr 2003 07:57:56 +0100") References: <3EA93B2D.9000806@enst-bretagne.fr> <3EACD0F4.2060900@manderp.freeserve.co.uk> Message-ID: Peter-Henry Mander writes: > Ne pourrait-on persuader L'Informaticien de produire une copie > electronique disponible sur Internet, au lieu de violer leur copyright? > > (-: sorry, I couldn't help myself) > > I'm sure that having a follow-up and links online would be beneficial > for them and for the Erlang community. I already proposed them to put the article online on Erlang-projects, along with an English translation, with proper credits and link to the magazine, and the author of the article. I hope they will agree. It will good promotion for both Erlang and the magazine I think. -- Micka?l R?mond http://www.erlang-projects.org/ From chris.williams@REDACTED Mon Apr 28 10:47:27 2003 From: chris.williams@REDACTED (Chris Williams) Date: Mon, 28 Apr 2003 10:47:27 +0200 (MEST) Subject: Directory structure for a release In-Reply-To: <4.2.2.20030427171723.00cfd990@duomark.com> Message-ID: > Does the boot script list only the modules that are actually > used, or does it list all modules in a given application? Or > more to the point, in an embedded system, are only the > used modules loaded or all modules loaded that are part > of any application that is loaded? The boot script lists what modules that are defined by the modules parameter in your application file ("app" file). (See http://www.erlang.se/doc/doc-5.2/lib/kernel-2.8.0/doc/html/app.html) This file should be in the "ebin" directory of your application. When the boot script is generated it fetches the module information from all "app" files. i.e. all applications files (Including erlangs) that are defined in your "rel" file. (http://www.erlang.se/doc/doc-5.2/lib/sasl-1.9.4/doc/html/rel.html) If you use the flag '-mode embedded' it will only load the modules that are defined in your generated boot file. //Chris ps You can look in the "script" file that is generated at the same time as the boot file to see what files are loaded. On Sun, 27 Apr 2003, Jay Nelson wrote: > Chris wrote: > > > I would, however, recommend against grouping all > > utilities together simply because they're all utilities. I > > now have a monolithic shared library application that > > is bigger than most of the applications that use it, and > > most of them only use a fraction of what's in it. > > This is one of my biggest fears because my goal is to > make an embedded bootable application that runs from > flash or a network loadable image. > > Does the boot script list only the modules that are actually > used, or does it list all modules in a given application? Or > more to the point, in an embedded system, are only the > used modules loaded or all modules loaded that are part > of any application that is loaded? > > Is there some sort of tree-shaker utility that eliminates > module functions that are not called from the code? This > would be difficult in the case of {M, F, A} type calls, but > is there any tool for the static utility code? > > I have pretty much settled on one utility application which > has no processes and no included applications for > things like lists, bin_utils and proxies that are all generally > useful, and a separate application for the externally > visible functionality. I understand why OTP likes to do > things on an application level, but at some point the web > of directories is difficult to maintain so I am trying to > reduce the number of applications as much as possible. > > If my catch-all utility application gets too big, I will separate > it into pieces and organize them into a hierarchy of related > utility applications so that my top-level application can often > just include a single utility application (which may include > sub-hierarchy utility applications). For now I expect I'll end > up with 5-10 utility modules and hope that a particular > application will only load the ones that it uses. > > jay > > From thomas.arts@REDACTED Mon Apr 28 11:43:03 2003 From: thomas.arts@REDACTED (Thomas Arts) Date: Mon, 28 Apr 2003 11:43:03 +0200 Subject: CFP Erlang workshop References: <005001c2d8b4$3cb17190$a22d1081@ituniv398> Message-ID: <014601c30d6a$90a56a00$a22d1081@ituniv398> ACM Sigplan Erlang Workshop Call for papers: http://www.erlang.se/workshop/2003/ The Erlang workshop will be in Uppsala (Sweden) on August 29. Please submit an article or paper before May 5th if you like to present something. Note that we need to have a base for selecting papers before May 5th, but that you have until July 16th for a final version of your paper. Email your papers/abstracts to thomas.arts@REDACTED Kind regards Thomas --- Dr Thomas Arts Program Manager Software Engineering and Management IT-university in Gothenburg Box 8718, 402 75 Gothenburg, Sweden http://www.ituniv.se/ Tel +46 31 772 6031 Fax +46 31 772 4899 From DANIESC.SCHUTTE@REDACTED Mon Apr 28 16:13:15 2003 From: DANIESC.SCHUTTE@REDACTED (DANIESC SCHUTTE) Date: Mon, 28 Apr 2003 16:13:15 +0200 Subject: erlang make utility - some help required. Message-ID: Greetings all, can anyone give me an indication what I am doing wrong in my Emakefile. Thanks. Daniel Emakefile content: {card_info, [{i, '/home2/bv/include'}]}. Erlang output (with card info in local directory) 43> make:all(). =ERROR REPORT==== 28-Apr-2003::17:22:11 === Error in process <0.157.0> with exit value: {function_clause,[{filename,basename,[{card_info,[{i,'/home2/bv/include'}]}]},{make,recompilep,4},{make,process,4},{erl_eval,expr,3},{erl_eval,exprs,4},{shell,eval_loop,2}]} ** exited: {function_clause,[{filename, basename, [{card_info,[{i,'/home2/bv/include'}]}]}, {make,recompilep,4}, {make,process,4}, {erl_eval,expr,3}, {erl_eval,exprs,4}, {shell,eval_loop,2}]} ** ##################################################################################### The information contained in this message and or attachments is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any system and destroy and copies. ##################################################################################### From wicak.noeg@REDACTED Mon Apr 28 15:29:11 2003 From: wicak.noeg@REDACTED (wicaksono ) Date: Mon, 28 Apr 2003 20:29:11 +0700 Subject: AXE10 Message-ID: Hi all, does AXE10 system use erlang as their programming language? =========================================================================================== Malas antri buat mendapatkan print-out tagihan telepon ? Klik aja http://billinfo2.plasa.com Gratis Perpanjangan dan Pendaftaran Nama Domain http://idc.plasa.com diperpanjang hingga April 2003! =========================================================================================== From siri@REDACTED Mon Apr 28 16:44:55 2003 From: siri@REDACTED (Siri Hansen (EAB)) Date: Mon, 28 Apr 2003 16:44:55 +0200 Subject: erlang make utility - some help required. In-Reply-To: References: Message-ID: <16045.15975.883767.598752@gargle.gargle.HOWL> There seems to be two problems: 1) I think you are running an old version of the tools application in which make.erl cannot read an Emakefile with compiler options. tools-2.2 includes this fix. Which OTP release are you running? 2) The include directory name must be a string and not an atom, i.e. your file should look like this: {card_info, [{i, "/home2/bv/include"}]}. /siri DANIESC SCHUTTE wrote: > Greetings all, > > can anyone give me an indication what I am doing wrong in my Emakefile. > > Thanks. > Daniel > > Emakefile content: > {card_info, [{i, '/home2/bv/include'}]}. > > > Erlang output (with card info in local directory) > 43> make:all(). > > =ERROR REPORT==== 28-Apr-2003::17:22:11 === > Error in process <0.157.0> with exit value: {function_clause,[{filename,basename,[{card_info,[{i,'/home2/bv/include'}]}]},{make,recompilep,4},{make,process,4},{erl_eval,expr,3},{erl_eval,exprs,4},{shell,eval_loop,2}]} > ** exited: {function_clause,[{filename, > basename, > [{card_info,[{i,'/home2/bv/include'}]}]}, > {make,recompilep,4}, > {make,process,4}, > {erl_eval,expr,3}, > {erl_eval,exprs,4}, > {shell,eval_loop,2}]} ** > > > ##################################################################################### > The information contained in this message and or attachments is intended > only for the person or entity to which it is addressed and may contain > confidential and/or privileged material. Any review, retransmission, > dissemination or other use of, or taking of any action in reliance upon, > this information by persons or entities other than the intended recipient > is prohibited. If you received this in error, please contact the sender and > delete the material from any system and destroy and copies. > ##################################################################################### From Fabien.Dagnat@REDACTED Mon Apr 28 16:16:47 2003 From: Fabien.Dagnat@REDACTED (Fabien Dagnat) Date: Mon, 28 Apr 2003 16:16:47 +0200 Subject: Questions and discussion on UBF Message-ID: <3EAD37CF.9020902@enst-bretagne.fr> Hello, As I am working on using contracts on component (or service, if one prefer) oriented specifications, I'm looking at UBF. I'm asking myself why allowing any type for messages in the contracts. I know that this is linked with the fact that in Erlang a message may be of any type. But: - a programming rule specifies that all messages should be tagged. - as a "universal" format, it should conform to other language culture too. Indeed, in a more abstract view (than erlang usual one), it would be "better" to name (give a tag) messages (from a specification point of view). Combined with some (yet to completly implement) type system, it would perhaps be possible to ensure that a server respect its contracts... My second question is why just allowing named type in the automaton description. More precisely why not having something like: +STATE start ls => files() & start; {get, file()} => binary() & start | noSuchFile() & stop. Is there any technical (or philosophical) limitation that I haven't thougth of? I think it would save type definitions and help reading the automaton (without always shifting to type definitions to remember what are the message types). I know that the current syntax is similar in this point to the message definition in WSDL, but I don't see WSDL as a panacea of XML encoding of interfaces. Next, to go back to my point on universality. Why not having: +STATE start ls() => files() & start; get(file : string()) => binary() & start | noSuchFile() & stop. My point here is that I would like to add to the contract some pre and post conditions and to do this usually we have to refer to some arguments of the message. Furthermore, to do this, I would like to add some state variables to the state. For exemple, a bank account contract could be: +STATE start open() => ok() & created. +STATE created deposit(sum : int()) => ok() & credit(sum). +STATE credit(balance : int()) deposit(sum : int()) => if (sum > 0) ok() & credit(balance + sum); withdraw(sum : int()) => if (sum <= balance) ok() & credit(balance - sum); balance() => {ok, sum} with sum = balance & credit(balance). I don't advocate that this is a great example of the interest of pre and post conditions. But, I think it is sufficiently interesting to illustrates what I was thinking of. It is clear that this way of thinking contracts embed a lot more (behavioral) semantics that the current UBF. Indeed, it shift some part of the server state to the "contract checker". But, it could gave some interesting property like the fact that the "contract checker" could use several servers giving them the needed state with the message (we would get some fault tolerance or some load balancing capacity). Finally, why not allowing a return state in the ANYSTATE declaration. Suppose, I would like to have a stop message available in all states that brings the server in a stopped state. For example, +STATE stopped start() => ok() & s1. +STATE s1 ... +STATE s2 ... +ANYSTATE stop() => ok() & stopped. Thanks in advance for any answer, opinion, criticism... Fabien -- Fabien Dagnat -- Ma?tre de Conf?rences Mel : Fabien.Dagnat@REDACTED Web : perso-info.enst-bretagne.fr/~fdagnat/index.php 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 BP 832 29285 Brest Cedex From mickael.remond@REDACTED Mon Apr 28 17:02:37 2003 From: mickael.remond@REDACTED (Mickael Remond) Date: Mon, 28 Apr 2003 17:02:37 +0200 Subject: erlang make utility - some help required. In-Reply-To: ("DANIESC SCHUTTE"'s message of "Mon, 28 Apr 2003 16:13:15 +0200") References: Message-ID: "DANIESC SCHUTTE" writes: > Greetings all, > > can anyone give me an indication what I am doing wrong in my Emakefile. > > Thanks. > Daniel > > Emakefile content: > {card_info, [{i, '/home2/bv/include'}]}. Hello, I have no way to reproduce your problem from here but I see one main potential problem. I would use a string to define the include path. Another problem might be that extension of the Erlang file is missing (But I am not sure about this one). What I would do: {'card_info.erl', [{i, "/home2/bv/include"}]}. Tell me if this works. -- Micka?l R?mond http://www.erlang-projects.org/ From Laszlo.Varga@REDACTED Mon Apr 28 17:10:48 2003 From: Laszlo.Varga@REDACTED (Laszlo Varga) Date: Mon, 28 Apr 2003 17:10:48 +0200 (MEST) Subject: AXE10 Message-ID: <200304281510.h3SFAmk09815@duna273.eth.ericsson.se> AFAIK there is no ERLANG VM for AXE processor. Cheers Laszlo > From: "wicaksono " > Subject: AXE10 > To: erlang-questions@REDACTED > Date: Mon, 28 Apr 2003 20:29:11 +0700 > MIME-Version: 1.0 > Content-Transfer-Encoding: 8bit > X-Scanner: exiscan for exim4 (http://duncanthrax.net/exiscan/) *19A9pn-0003NP-00*fQQU4obaMOs* > X-Bogo-Received-From: 192.168.17.22 > X-Bogosity: No, tests=bogofilter, spamicity=0.311637, version=0.11.1.3 > X-OriginalArrivalTime: 28 Apr 2003 14:43:51.0255 (UTC) FILETIME=[95975670:01C30D94] > > Hi all, > does AXE10 system use erlang as their programming > language? > ================================================================================ =========== > Malas antri buat mendapatkan print-out tagihan telepon ? Klik aja http://billinfo2.plasa.com > Gratis Perpanjangan dan Pendaftaran Nama Domain http://idc.plasa.com diperpanjang hingga April 2003! > ================================================================================ =========== From DANIESC.SCHUTTE@REDACTED Mon Apr 28 17:37:45 2003 From: DANIESC.SCHUTTE@REDACTED (DANIESC SCHUTTE) Date: Mon, 28 Apr 2003 17:37:45 +0200 Subject: erlang make utility - some help required. Message-ID: I changed the include to be a string, (the erl extension can be omitted). (It works if I just give the module name as an atom - without anything else. But requires the include files. I'm using tools 2.0.1 OTP R9 thanks for your input >>> Mickael Remond 04/28/03 05:02PM >>> "DANIESC SCHUTTE" writes: > Greetings all, > > can anyone give me an indication what I am doing wrong in my Emakefile. > > Thanks. > Daniel > > Emakefile content: > {card_info, [{i, '/home2/bv/include'}]}. Hello, I have no way to reproduce your problem from here but I see one main potential problem. I would use a string to define the include path. Another problem might be that extension of the Erlang file is missing (But I am not sure about this one). What I would do: {'card_info.erl', [{i, "/home2/bv/include"}]}. Tell me if this works. -- Micka?l R?mond http://www.erlang-projects.org/ ##################################################################################### The information contained in this message and or attachments is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any system and destroy and copies. ##################################################################################### From mike@REDACTED Mon Apr 28 18:56:07 2003 From: mike@REDACTED (Mike Williams) Date: 28 Apr 2003 16:56:07 GMT Subject: AXE10 References: <200304281510.h3SFAmk09815@duna273.eth.ericsson.se> Message-ID: AXE10 is written in PLEX, a programming language invented during the mid 1970s. PLEX is a very simple language, for example there is no way to call a subroutine/function with parameters. What has kept PLEX alive and successful for so many years is: 1. The Block and Signal Concept (extremely light weight concurency) 2. The ability to statically declare the size of arrays (called files in PLEX) and change the size at run time. 3. No wild pointers or memory leackage problems 4. Very fine grained MMU protections 5. Extensive hardware support in PLEX machines for non intrusive debugging at run time even out in exhanges in operation. 6. The reload variable concept, variables which are reloaded after a system crash /m In article <200304281510.h3SFAmk09815@REDACTED>, Laszlo.Varga@REDACTED (Laszlo Varga) writes: |> AFAIK there is no ERLANG VM for AXE processor. |> |> Cheers |> Laszlo |> > From: "wicaksono " |> > Subject: AXE10 |> > To: erlang-questions@REDACTED |> > Date: Mon, 28 Apr 2003 20:29:11 +0700 |> > MIME-Version: 1.0 |> > Content-Transfer-Encoding: 8bit |> > X-Scanner: exiscan for exim4 (http://duncanthrax.net/exiscan/) |> *19A9pn-0003NP-00*fQQU4obaMOs* |> > X-Bogo-Received-From: 192.168.17.22 |> > X-Bogosity: No, tests=bogofilter, spamicity=0.311637, version=0.11.1.3 |> > X-OriginalArrivalTime: 28 Apr 2003 14:43:51.0255 (UTC) |> FILETIME=[95975670:01C30D94] |> > |> > Hi all, |> > does AXE10 system use erlang as their programming |> > language? |> > |> ================================================================================ |> =========== |> > Malas antri buat mendapatkan print-out tagihan telepon ? Klik aja |> http://billinfo2.plasa.com |> > Gratis Perpanjangan dan Pendaftaran Nama Domain http://idc.plasa.com |> diperpanjang hingga April 2003! |> > |> ================================================================================ |> =========== |> From erlang@REDACTED Mon Apr 28 20:43:22 2003 From: erlang@REDACTED (Peter-Henry Mander) Date: Mon, 28 Apr 2003 19:43:22 +0100 Subject: ets:update_counter/3 taking a looooong time! Message-ID: <3EAD764A.6000801@manderp.freeserve.co.uk> Hi Gurus, I'm puzzled. I'm trying to build a stressor tool using the Megaco stack provided with Erlang/OTP R9B, and using fprof I seem to have isolated where the bottleneck is, except I don't believe it's in ets:update_counter/3. The stressor creates a bunch of processes which run through a standard add modify and subtract Megaco message sequence. It runs wonderfully fast as long as there are no more than 16 or 17 processes started concurrently, each sending the message sequences. Below this threshold I manage to get 1500 calls setup per second, above I only get a pitiful 4 to 6 call setups a second. If I increase the process count gradually to 2000, I can start 16 new processes and still get a high rate, but any more than 16 at once kills the setup rate again. I get the impression that some sort of staggered process startup is required, it's as if there's a process being starved somewhere. The attached gives the output of fprof, and the last line indicates that all the time is spent waiting for ets:update_counter/3 to return a new transaction ID to megaco_config:incr_trans_id_counter/1. The functions above in the deleted lines creates a Megaco ActionRequest record. What have I done wrong? I feel as if there's a solution staring me in the face, but I just don't see it! Pete. -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: stressor-analysis.txt URL: From erik@REDACTED Mon Apr 28 22:09:26 2003 From: erik@REDACTED (Erik Pearson) Date: Mon, 28 Apr 2003 13:09:26 -0700 Subject: Questions and discussion on UBF In-Reply-To: <3EAD37CF.9020902@enst-bretagne.fr> Message-ID: <4FD59E67-79B5-11D7-B0F5-0050E4594D1D@adaptations.com> Hi Fabien, Quite a lot to chew on -- I'll bite off just one piece! On Monday, April 28, 2003, at 07:16 AM, Fabien Dagnat wrote: > Hello, > As I am working on using contracts on component (or service, if one > prefer) oriented specifications, I'm looking at UBF. > > > I'm asking myself why allowing any type for messages in the contracts. > I know that this is linked with the fact that in Erlang a message may > be of any type. But: > - a programming rule specifies that all messages should be tagged. > - as a "universal" format, it should conform to other language > culture too. > Indeed, in a more abstract view (than erlang usual one), it would be > "better" to name (give a tag) messages (from a specification point of > view). Combined with some (yet to completly implement) type system, it > would perhaps be possible to ensure that a server respect its > contracts... I think I see what you mean here, but please correct me if not. This would basically be extending the UBF(C) from Msg$ => {Reply, NextState}$ to {SendTag, Msg}$ => {ReplyTag, Reply, NextState}$ In short, I think this would start breaking down the simplicity of UBF. Can't you get that just by always using types which are structures, and having the first element be a constant which serves as your tag? > > My second question is why just allowing named type in the automaton > description. > More precisely why not having something like: > +STATE start > ls => files() & start; > {get, file()} => binary() & start > | noSuchFile() & stop. > Is there any technical (or philosophical) limitation that I haven't > thougth of? I think it would save type definitions and help reading > the automaton (without always shifting to type definitions to remember > what are the message types). I know that the current syntax is similar > in this point to the message definition in WSDL, but I don't see WSDL > as a panacea of XML encoding of interfaces. > > Next, to go back to my point on universality. Why not having: > +STATE start > ls() => files() & start; > get(file : string()) => binary() & start > | noSuchFile() & stop. > My point here is that I would like to add to the contract some pre and > post conditions and to do this usually we have to refer to some > arguments of the message. Furthermore, to do this, I would like to add > some state variables to the state. > For exemple, a bank account contract could be: > +STATE start > open() => ok() & created. > +STATE created > deposit(sum : int()) => ok() & credit(sum). > +STATE credit(balance : int()) > deposit(sum : int()) => if (sum > 0) ok() & credit(balance + sum); > withdraw(sum : int()) => if (sum <= balance) ok() & credit(balance - > sum); > balance() => {ok, sum} with sum = balance & > credit(balance). > > I don't advocate that this is a great example of the interest of pre > and post conditions. But, I think it is sufficiently interesting to > illustrates what I was thinking of. > > It is clear that this way of thinking contracts embed a lot more > (behavioral) semantics that the current UBF. Indeed, it shift some > part of the server state to the "contract checker". But, it could gave > some interesting property like the fact that the "contract checker" > could use several servers giving them the needed state with the > message (we would get some fault tolerance or some load balancing > capacity). > > Finally, why not allowing a return state in the ANYSTATE declaration. > Suppose, I would like to have a stop message available in all states > that brings the server in a stopped state. For example, > > +STATE stopped > start() => ok() & s1. > +STATE s1 > ... > +STATE s2 > ... > +ANYSTATE > stop() => ok() & stopped. > > Thanks in advance for any answer, opinion, criticism... > > Fabien > -- > Fabien Dagnat -- Ma?tre de Conf?rences > Mel : Fabien.Dagnat@REDACTED > Web : perso-info.enst-bretagne.fr/~fdagnat/index.php > 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 > BP 832 > 29285 Brest Cedex > > > Erik Pearson Adaptations desk +1 510 527 5437 cell +1 510 517 3122 From erik@REDACTED Mon Apr 28 22:19:12 2003 From: erik@REDACTED (Erik Pearson) Date: Mon, 28 Apr 2003 13:19:12 -0700 Subject: UBF assoc lists Message-ID: Hi UBFers, So, one of the biggest applications I have of UBF type stuff is sending user profile data between servers. This data tends to be clumped into batches of tens to thousands of records, consisting of from 1 to a couple hundred fields. It can also consist of one record for "real time" data synchronization. I've tended to send records with name,value pairs, so that empty fields are not sent. This saves quite a bit of bandwidth of there are just a few fields to send out of a couple hundred. My challenge is to apply this to UBF. First thought, a list of structs of two elements each: {12345 # {'first-name' "John"} & {'last-name "Smith"} & } $ (where 12345 is the user id} but sending the constants for holding names would kill al of bandwidth. So, perhaps the field name constants could be stored in the regsiter. Well, the register is limited in size, about a couple hundred free bytes. The those bytes may be slowly disappearing :). So, what about extending the register to have arbitrary byte sequences indexes? Then... 'first-name' >f1 'last-name' >f2 {12345 # {f1 "John"} & {f2 "Smith"} & } $ Just a thought. Erik. (And yes, I do realize that by taking the field names out of the realm of UBF(B) that I'm giving up type checking and verification at the UBF(B) level -- I guess it becomes the application's responsibility -- but it might be nice to explore that some more...) Erik Pearson Adaptations desk +1 510 527 5437 cell +1 510 517 3122 From pete@REDACTED Mon Apr 28 21:10:37 2003 From: pete@REDACTED (Peter-Henry Mander) Date: Mon, 28 Apr 2003 20:10:37 +0100 Subject: ets:update_counter/3 taking a looooong time! References: <3EAD764A.6000801@manderp.freeserve.co.uk> Message-ID: <3EAD7CAD.60909@manderp.freeserve.co.uk> .... and to follow up, yes indeed, a staggered start does make the setup time run consistently around 33 to 35 calls per second. But that's not brilliant. The 1500 calls per second burst makes me want to improve that considerably! /grumble/ I'm going home! )-: Pete. Peter-Henry Mander wrote: > Hi Gurus, > > I'm puzzled. > > I'm trying to build a stressor tool using the Megaco stack provided with > Erlang/OTP R9B, and using fprof I seem to have isolated where the > bottleneck is, except I don't believe it's in ets:update_counter/3. > > The stressor creates a bunch of processes which run through a standard > add modify and subtract Megaco message sequence. It runs wonderfully > fast as long as there are no more than 16 or 17 processes started > concurrently, each sending the message sequences. Below this threshold I > manage to get 1500 calls setup per second, above I only get a pitiful 4 > to 6 call setups a second. If I increase the process count gradually to > 2000, I can start 16 new processes and still get a high rate, but any > more than 16 at once kills the setup rate again. > > I get the impression that some sort of staggered process startup is > required, it's as if there's a process being starved somewhere. > > The attached gives the output of fprof, and the last line indicates that > all the time is spent waiting for ets:update_counter/3 to return a new > transaction ID to megaco_config:incr_trans_id_counter/1. The functions > above in the deleted lines creates a Megaco ActionRequest record. > > What have I done wrong? I feel as if there's a solution staring me in > the face, but I just don't see it! > > Pete. > > > ------------------------------------------------------------------------ > > > ... calling processes deleted ... > > {[{{transaction,action_request_single,3}, 3, 12602.531, 0.030}], > { {megaco,call,3}, 3, 12602.531, 0.030}, % > [{{megaco_messenger,call,3}, 3, 12602.521, 0.025}]}. > > {[{{megaco,call,3}, 3, 12602.521, 0.025}], > { {megaco_messenger,call,3}, 3, 12602.521, 0.025}, % > [{{megaco_messenger,call_or_cast,4}, 3, 12602.513, 11.633}]}. > > {[{{megaco_messenger,call,3}, 3, 12602.513, 11.633}, > {{megaco_messenger,prepare_send_options,2}, 1, 0.000, 1222.965}], > { {megaco_messenger,call_or_cast,4}, 4, 12602.513, 1234.598}, % > [{{megaco_messenger,prepare_send_options,2}, 3, 12602.502, 0.408}, > {{megaco_messenger,encode_request,2}, 3, 1231.677, 0.029}, > {{megaco_messenger,wait_for_reply,1}, 2, 270.899, 270.862}, > {{megaco_messenger,send_request,5}, 3, 2.205, 2.316}, > {{megaco_messenger,override_send_options,2}, 1, 0.034, 0.036}, > {{megaco_messenger,to_local_trans_id,1}, 3, 0.029, 0.000}, > {{transaction,action_request_single,3}, 1, 0.000, 7011.844}]}. > > {[{{megaco_messenger,call_or_cast,4}, 3, 12602.502, 0.408}, > {{ets,update_counter,3}, 1, 0.000, 2104.955}], > { {megaco_messenger,prepare_send_options,2}, 4, 12602.502, 2105.363}, % > [{{megaco_config,incr_trans_id_counter,1}, 3, 12602.484, 0.435}, > {{megaco_config,reset_trans_id_counter,4}, 1, 2104.947, 0.049}, > {{megaco_messenger,override_send_options,2}, 2, 0.074, 0.076}, > {{megaco_messenger,call_or_cast,4}, 1, 0.000, 1222.965}]}. > > {[{{megaco_messenger,prepare_send_options,2}, 3, 12602.484, 0.435}], > { {megaco_config,incr_trans_id_counter,1}, 3, 12602.484, 0.435}, % > [{{ets,update_counter,3}, 3, 12602.424, 0.034}, > {{megaco_config,lookup_local_conn,1}, 3, 0.257, 0.258}, > {{erlang,setelement,3}, 2, 0.016, 0.000}]}. From garry@REDACTED Tue Apr 29 04:37:07 2003 From: garry@REDACTED (Garry Hodgson) Date: Mon, 28 Apr 2003 22:37:07 -0400 (EDT) Subject: Binary parsing In-Reply-To: <00b701c308dc$51d644d0$1e00a8c0@design> References: <00b701c308dc$51d644d0$1e00a8c0@design> Message-ID: <2003042822371051583853@kestrel.sage.att.com> "Inswitch Solutions - Erlang Evaluation" wrote: > I have a C/C++ port which receives bytes to be parsed for a specific = > protocol. > The parsing could be done in C/C++ or I can forward the bytes to Erlang = > and > make the parsing here. > What would be the best choice ? depends what you care about. in particular, there's a tradeoff in runtime vs. dev time. i'd much rather write this in erlang. the pattern matching on binaries is *really* nice, and writing parsers in an FPL is much cleaner than the c/c++ equivalent. > By means of performance how is binary pattern matching in Erlang = > compared to C/C++ code? i'd expect the c/c++ to run faster, but have no data to base this on. ---- Garry Hodgson, Senior Hacker, AT&T Labs No act is more patriotic than speaking out when your government is doing the wrong thing in your name. This is not your right but your sacred duty. And none are more treasonous than those who would silence these voices. From siri@REDACTED Tue Apr 29 07:52:34 2003 From: siri@REDACTED (Siri Hansen (EAB)) Date: Tue, 29 Apr 2003 07:52:34 +0200 Subject: erlang make utility - some help required. In-Reply-To: References: Message-ID: <16046.4898.265101.943179@gargle.gargle.HOWL> The tools version you use can't read compiler options in an Emakefile. You need OTP R9B-1. /siri DANIESC SCHUTTE wrote: > I changed the include to be a string, (the erl extension can be omitted). (It works if I just give the module name as an atom - without anything else. But requires the include files. > > I'm using tools 2.0.1 OTP R9 > > thanks for your input > > > >>> Mickael Remond 04/28/03 05:02PM >>> > "DANIESC SCHUTTE" writes: > > > Greetings all, > > > > can anyone give me an indication what I am doing wrong in my Emakefile. > > > > Thanks. > > Daniel > > > > Emakefile content: > > {card_info, [{i, '/home2/bv/include'}]}. > > Hello, > > I have no way to reproduce your problem from here but I see one main > potential problem. I would use a string to define the include path. > Another problem might be that extension of the Erlang file is missing > (But I am not sure about this one). > > What I would do: > > {'card_info.erl', [{i, "/home2/bv/include"}]}. > > Tell me if this works. > > -- > Micka?l R?mond > http://www.erlang-projects.org/ > > > ##################################################################################### > The information contained in this message and or attachments is intended > only for the person or entity to which it is addressed and may contain > confidential and/or privileged material. Any review, retransmission, > dissemination or other use of, or taking of any action in reliance upon, > this information by persons or entities other than the intended recipient > is prohibited. If you received this in error, please contact the sender and > delete the material from any system and destroy and copies. > ##################################################################################### From joe@REDACTED Tue Apr 29 10:05:59 2003 From: joe@REDACTED (Joe Armstrong) Date: Tue, 29 Apr 2003 10:05:59 +0200 (CEST) Subject: Questions and discussion on UBF In-Reply-To: <3EAD37CF.9020902@enst-bretagne.fr> Message-ID: I think the answer to most of these questions has to do with complexity. At the outset I wanted things to be *as simple as possible* - that why things are as they are. If you want more complexity I think you should layer them on top of the existing infratructure. /Joe On Mon, 28 Apr 2003, Fabien Dagnat wrote: > Hello, > As I am working on using contracts on component (or service, if one > prefer) oriented specifications, I'm looking at UBF. > > > I'm asking myself why allowing any type for messages in the contracts. I > know that this is linked with the fact that in Erlang a message may be > of any type. But: > - a programming rule specifies that all messages should be tagged. > - as a "universal" format, it should conform to other language > culture too. > Indeed, in a more abstract view (than erlang usual one), it would be > "better" to name (give a tag) messages (from a specification point of > view). Combined with some (yet to completly implement) type system, it > would perhaps be possible to ensure that a server respect its contracts... > > My second question is why just allowing named type in the automaton > description. > More precisely why not having something like: > +STATE start > ls => files() & start; > {get, file()} => binary() & start > | noSuchFile() & stop. > Is there any technical (or philosophical) limitation that I haven't > thougth of? I think it would save type definitions and help reading the > automaton (without always shifting to type definitions to remember what > are the message types). I know that the current syntax is similar in > this point to the message definition in WSDL, but I don't see WSDL as a > panacea of XML encoding of interfaces. > > Next, to go back to my point on universality. Why not having: > +STATE start > ls() => files() & start; > get(file : string()) => binary() & start > | noSuchFile() & stop. > My point here is that I would like to add to the contract some pre and > post conditions and to do this usually we have to refer to some > arguments of the message. Furthermore, to do this, I would like to add > some state variables to the state. > For exemple, a bank account contract could be: > +STATE start > open() => ok() & created. > +STATE created > deposit(sum : int()) => ok() & credit(sum). > +STATE credit(balance : int()) > deposit(sum : int()) => if (sum > 0) ok() & credit(balance + sum); > withdraw(sum : int()) => if (sum <= balance) ok() & credit(balance - > sum); > balance() => {ok, sum} with sum = balance & credit(balance). > > I don't advocate that this is a great example of the interest of pre > and post conditions. But, I think it is sufficiently interesting to > illustrates what I was thinking of. > > It is clear that this way of thinking contracts embed a lot more > (behavioral) semantics that the current UBF. Indeed, it shift some part > of the server state to the "contract checker". But, it could gave some > interesting property like the fact that the "contract checker" could use > several servers giving them the needed state with the message (we would > get some fault tolerance or some load balancing capacity). > > Finally, why not allowing a return state in the ANYSTATE declaration. > Suppose, I would like to have a stop message available in all states > that brings the server in a stopped state. For example, > > +STATE stopped > start() => ok() & s1. > +STATE s1 > ... > +STATE s2 > ... > +ANYSTATE > stop() => ok() & stopped. > > Thanks in advance for any answer, opinion, criticism... > > Fabien > From joe@REDACTED Tue Apr 29 10:44:22 2003 From: joe@REDACTED (Joe Armstrong) Date: Tue, 29 Apr 2003 10:44:22 +0200 (CEST) Subject: The Erlang way - dynamic upgrade of a server and UBF extensions Message-ID: I want to add some things to UBF so we can make fault-tolerent systems. This can be done with only a little change to UBF. I havn't thought out all the details so I thought I'd try the idea out first. All comments are welcome. The UBF extensions provide an alternative solution to the problem of dynamically upgrading or migrating a server or of dynamically upgrading software. Firstly a bit of philosophy The Erlang way ============== 1) everything is a process 2) processes communicate by message passing 3) processes obey protocols 4) errors are handled non locally Should I add more points? UBF === UBF describes (specifies) 3) above Extensions to UBF ================= A) ? (a undefined type) - to denote absence of an argument B) The protocol versioning tag C) The next IP word. A) Undefined Type ================= Just use ? in UBF(A) to denote a missing value (easy) B) + C) ======= Client UBF packets to a server should begin +---------------+---------------------+ | VersionNumber | ... rest of packet | +---------------+---------------------+ And server replies should begin +---------------+---------+---------------------+ | VersionNumber | NextIP | ... rest of packet | +---------------+---------+---------------------+ B) Protocol versioning ====================== The version number is an integer 1 2 3 ... etc. This is to allow dynamic upgrade of services I have not thought out all the details but the idea is this: Assume that a client has versions 1,2,3,6,8,10,11 of some software The server speaks versions 1,2,3,4,5,9,10,14 At the start of the session we enter "protocol negotiation mode" Both sides agree that version 10 is the highest common version of the protocol that they both understand. A session starts at level 10. The client S/W crashes - this is detected by the client SW T The next message it sends to the server is a version 8 message The server realizes that something has gone wrong - it cannot handle version 8 messages - so they go back into protocol negotiation mode. They agree on version 3 and continue. This should allow "dynamic introduction of new services" with fallback to previous versions if things go wrong. C) Next IP ========== This is to allow dynamic migration of services. There are two basic approaches to making things reliable. I'd like to suggest a third. The two common methods are: 1) Fixed server IP The server has a fixed IP. To make things fault-tolerant the fixed IP is the IP of a switch - the switch dispatches the request to a back-end. (This is the common cluster solution - the switch is big and expensive and can act as a front-end to many back-end servers) 2) Two fixed IP's This is the DNS solution. My machine has two addresses for DNS - I try the first, if it is broken I try the second. I propose a third method: Each packet contains a NextIP field. This is the address where the Next message should be sent. Example. I have a server at 127.45.67.223 a) The client connects to 127.45.67.223 b) Client and server exchange messages The server becomes heavily loaded, or, the operator wants to take the server out of operation. At some point the client receives a rpc reply with a NEW IP address (not 127.45.67.223) but something different. The client closes the connection to 127.45.67.223 connects to the new address and carries on. I think that B) + C) above would solve a lot of problems. Comments? /Joe From erik@REDACTED Tue Apr 29 13:37:11 2003 From: erik@REDACTED (Erik Pearson) Date: Tue, 29 Apr 2003 04:37:11 -0700 Subject: The Erlang way - dynamic upgrade of a server and UBF extensions In-Reply-To: Message-ID: Hi Joe, A. great B. don't know enough about this problem domain. C. Hmm, I'm worried about what happens when the server experiences difficulties that degrade the quality of service to the point it has problems even telling clients to reroute to the next ip address. Perhaps, tying into B, there could be an explicit set of configuration negotiations between client and server (perhaps relating to versions?), such that a server can tell a client what the fallback measures are for degradation of services from that server -- e.g. if latency falls below .25 sec, then here is a set of other ip addresses to try, etc. This policy could be dynamically adjusted, of course, and having it be persistent would be great so it doesn't have be be renegotiated each time (the version neg. protocol would handle that...). How would this fit into the current client->server model? Perhaps "out of band" messages could be sent as replies to clients -- this would ensure serialization as well (e.g. if all clients were servers and servers clients, a server could broadcast reconfiguration information, but there would be no guarantee that clients would see it before blasting through another few messages -- if a server is trying to calm a traffic storm, it might be a good idea to get the immediate attention of all clients who are actually interacting with the server...) Another area that has concerned me is error signaling. Although this could fall into the application realm, experience informs me that at least a framework for the formatting of error messages (e.g. predefined types) would be very helpful. A communication mode (ala out of band messages, or rpc style.) I don't know if this would be best as a hard art of UBF(C), or perhaps a set of "recommended practices". Erik. On Tuesday, April 29, 2003, at 01:44 AM, Joe Armstrong wrote: > > I want to add some things to UBF so we can make fault-tolerent > systems. This can be done with only a little change to UBF. I havn't > thought out all the details so I thought I'd try the idea out first. > > All comments are welcome. > > The UBF extensions provide an alternative solution to the problem > of dynamically upgrading or migrating a server or of dynamically > upgrading software. > > Firstly a bit of philosophy > > The Erlang way > ============== > > 1) everything is a process > 2) processes communicate by message passing > 3) processes obey protocols > 4) errors are handled non locally > > Should I add more points? > > UBF > === > > UBF describes (specifies) 3) above > > Extensions to UBF > ================= > > A) ? (a undefined type) - to denote absence of an argument > > B) The protocol versioning tag > > C) The next IP word. > > A) Undefined Type > ================= > > Just use ? in UBF(A) to denote a missing value (easy) > > B) + C) > ======= > > Client UBF packets to a server should begin > > +---------------+---------------------+ > | VersionNumber | ... rest of packet | > +---------------+---------------------+ > > And server replies should begin > > +---------------+---------+---------------------+ > | VersionNumber | NextIP | ... rest of packet | > +---------------+---------+---------------------+ > > B) Protocol versioning > ====================== > > The version number is an integer 1 2 3 ... etc. > > This is to allow dynamic upgrade of services > > I have not thought out all the details but the idea is this: > > Assume that a client has versions 1,2,3,6,8,10,11 of some software > The server speaks versions 1,2,3,4,5,9,10,14 > > At the start of the session we enter "protocol negotiation mode" > > Both sides agree that version 10 is the highest common version of the > protocol that they both understand. > > A session starts at level 10. > > The client S/W crashes - this is detected by the client SW > T > The next message it sends to the server is a version 8 message > > The server realizes that something has gone wrong - it cannot handle > version 8 messages - so they go back into protocol negotiation mode. > They agree on version 3 and continue. > > This should allow "dynamic introduction of new services" with > fallback to > previous versions if things go wrong. > > C) Next IP > ========== > > This is to allow dynamic migration of services. > > There are two basic approaches to making things reliable. I'd like > to suggest a third. > > The two common methods are: > > 1) Fixed server IP > > The server has a fixed IP. To make things fault-tolerant the fixed IP > is the > IP of a switch - the switch dispatches the request to a back-end. > > (This is the common cluster solution - the switch is big and > expensive and can act as a front-end to many back-end servers) > > 2) Two fixed IP's > > This is the DNS solution. My machine has two addresses for DNS - I > try the > first, if it is broken I try the second. > > I propose a third method: Each packet contains a NextIP field. This is > the address where the Next message should be sent. > > Example. I have a server at 127.45.67.223 > > a) The client connects to 127.45.67.223 > > b) Client and server exchange messages > > The server becomes heavily loaded, or, the operator wants to take the > server out of operation. > > At some point the client receives a rpc reply with a NEW IP address > (not 127.45.67.223) but something different. > > The client closes the connection to 127.45.67.223 connects to the new > address and carries on. > > I think that B) + C) above would solve a lot of problems. > > Comments? > > /Joe > > > > Erik Pearson Adaptations desk +1 510 527 5437 cell +1 510 517 3122 From Fabien.Dagnat@REDACTED Tue Apr 29 14:01:02 2003 From: Fabien.Dagnat@REDACTED (Fabien Dagnat) Date: Tue, 29 Apr 2003 14:01:02 +0200 Subject: Questions and discussion on UBF References: Message-ID: <3EAE697E.9080900@enst-bretagne.fr> Hi, Erik Pearson wrote: > Hi Fabien, > > I think I see what you mean here, but please correct me if not. This > would basically be extending the UBF(C) from > > Msg$ => {Reply, NextState}$ > > to > > {SendTag, Msg}$ => {ReplyTag, Reply, NextState}$ > > In short, I think this would start breaking down the simplicity of UBF. > Can't you get that just by always using types which are structures, and > having the first element be a constant which serves as your tag? > Joe Armstrong wrote: > I think the answer to most of these questions has to do with complexity. > > At the outset I wanted things to be *as simple as possible* - that > why things are as they are. If you want more complexity I think you > should layer them on top of the existing infratructure. > > /Joe > I agree with both of these answers, but I think they don't go against my point of view. Fact 1: if everyone is following the rule that every message must be tagged, why not imposing it? Perhaps my proposal was to much different from erlang and the solution would be to impose either Tag or {Tag,...}. Fact 2: The interest of contracts (IMHO) is impose some rules to get some guaranties. Fact 3: In all my proposal the increment of complexity will only be: - on the contract checker that will have to include some state management and basic boolean expression evaluation - on the contract compiler I don't think they add complexity to all the machinery of types and conversion and to the programs people (client) would have to write (except from the contract). Thanks Fabien -- Fabien Dagnat -- Ma?tre de Conf?rences Mel : Fabien.Dagnat@REDACTED Web : perso-info.enst-bretagne.fr/~fdagnat/index.php 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 BP 832 29285 Brest Cedex From jay@REDACTED Tue Apr 29 15:47:34 2003 From: jay@REDACTED (Jay Nelson) Date: Tue, 29 Apr 2003 06:47:34 -0700 Subject: The Erlang way - dynamic upgrade of a server and UBF extensions Message-ID: <4.2.2.20030429062650.00cff350@duomark.com> I like clear, clean, simple, regular data structures. Especially in a functional language they make for obvious code. One thing I've always felt was missing in data protocols is the versioning on every packet. I think that is an essential feature. The IP failover seems to handle a reasonable case of essentially connectionless single packet transmission, or the equivalent of frequency hopping. More complex failover can be part of a data packet listing multiple IPs or a hierarchy or mapping to particular versions of the protocol, as agreed in UBF(B) or UBF(C) contracts. I like the idea of always having a packet header. It is much simpler if the size of the packet is specified, but I wonder if that is too much of a burden on the client. I would rather: <> = gen_tcp:recv(Socket, 4), Packet = gen_tcp:recv(Socket, Length) ... then to parse a stream a few bytes at a time calling recv. Trying to come up with a header runs into three problems: 1) If packet size is first, 4 bytes might be wasteful to a small msg protocol. 2) If version comes first to determine the size of the packet length field, either a fixed version size (too limiting) is needed or the integer UBF(A) spec is used with byte by byte recv parsing. 3) Having a size at the front means the client has to assemble the whole message, compute the size and then send all, rather than streaming out data. Not sure who should have the easier job, the client or server. Given that the client is written more often (and probably by a wider range of programmers of varying skill level) I would guess it is better to make things easy on the client. That would argue for a header as Joe proposed without a length and the version coming first (presumably an integer in UBF(A) format). The server has to do byte by byte gen_tcp:recv in this scenario. jay From kramer@REDACTED Tue Apr 29 22:14:22 2003 From: kramer@REDACTED (Reto Kramer) Date: Tue, 29 Apr 2003 13:14:22 -0700 Subject: Network partition and OTP Message-ID: <2A6AC44C-7A7F-11D7-BDED-000393B64312@acm.org> I'm looking for information on how OTP behaves when the network between nodes fails, and reconnects (nodes stay up all the time). ** Question 1 ** In particular the behavior of "global", the "distributed application controller" and Ulf's "locker" (contrib page) is what I'd like to understand better in network partition/reconnect scenarios. I've found references to work of Thomas Arts et al [1,2] and Ulf Wiger [3] and snippets here and there, but it would be most helpful to me if an OTP wizard could illuminate this topic comprehensively. For "global" one has to expect "name conflict" errors when the network comes back together. By extension I guess the same applies to the application controller (via it's use of global). Not sure about Ulf's locker. Using Ulf's release handling tutorial example, I can generate a naming conflict and observe what happens (start n1 then n2 (owner), suspend erl process that runs n2, dist fails over to n1, then resume erl that runs n2, ping n1 -> naming conflict, kills dist_server on n2, supervisor restarts n2 which takes over from n1 - takeover handshake not logged - does it happen?). =INFO REPORT==== 29-Apr-2003::12:59:39 === global: Name conflict terminating {dist_server,<1930.59.0>} ** Question 2 ** is there any risk of loosing messages that were buffered by the dist_server instance just before it got killed? I'm worried that while the global:register etc call are atomic across nodes [docs and 2], a potential client (client of dist_server I mean here) is not part of the atomic conflict resolution/re-registering process. I noticed the "relay" function in Ulf's release handling tutorial [3], but am not sure it kicks in when global detects the naming conflict upon reconnect - I guess not, correct? ** Question 3 ** - somewhat related to the above: Is there any library support for "majority voting" and/or "lease management" in OTP that I've not discovered yet? In particular I'm interested in rejecting a global:register/2 if the process calling the function is not in a node majority-set. Thanks, - Reto References: Thomas Arts et al [1,2], Ulf Wiger [3] [1] http://www.ericsson.com/cslab/~thomas/publ2.shtml (resource locker case study) [2] http://www.erlang.org/ml-archive/erlang-questions/200107/msg00031.html (christian paper) [3] (OTP release handling tutorial by Ulf) - was on the newsgroup, cannot find ref right now ______________________ There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies. And the other way is to make it so complicated that there are no obvious deficiencies. C.A.R. Hoare 1980 Turing Award Lecture -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: text/enriched Size: 2741 bytes Desc: not available URL: From etxhua@REDACTED Wed Apr 30 09:49:19 2003 From: etxhua@REDACTED (Asko Husso) Date: Wed, 30 Apr 2003 09:49:19 +0200 (MEST) Subject: Network partition and OTP Message-ID: <200304300749.h3U7nJq21818@cbe.ericsson.se> In the AXD301 product this problem is handled by setting the kernel flag 'dist_auto_connect' to 'once'. Why You may ask? Because the most ugliest (perverted?) thing that can happen is if one uses the automatic node reconnect feature and have flipping communication (down->up->down and so on). This can really screw up the distributed applications (global, dist_ac). Before we changed to dist_auto_connect'=='once' we could see some systems (at customer site) that were totally screwed up in the dist_ac. We could only pray that this disastrous situation would escalate to node restart so everything would clear up. What happens then if connection can only be setup once? Well, we have implemented a simple resolve protocol that is activated between the two nodes that looses connection. (UPD ports always ready to receive messages, one on each Erlang node). Both involved nodes makes a decision on which node is more important and selects the least important node. Minor handshaking and one of the the nodes is restarted (the least prior. node). When it comes up again it will reconnect. This solution have worked quite well and has been enhanced as we found more ugly cases. We even try to discover which of the two nodes is the "guilty" party. For example, if one node looses connection to more than one node it "must" be guilty. Such case can happen for instance if there is some huge garbage collect that takes up all execution. In that case only the "guilty" node is restarted and the other involved nodes are unharmed. I feel that the automatic node reconnect feature might be nice for small systems with very few applications. But it will still be lot of work to handle the reconnect case correctly. I'm not sure but I think that very few have thought about handling this error case. Haven't seen anything in the OTP documentation about this but then I seldom read all documentation that carefully.. Asko Husso E-mail:etxhua@REDACTED Ericsson AB Phone: +46 8 7192324 Varuv?gen 9B S-126 25 Stockholm-?lvsj?, Sweden From joe@REDACTED Wed Apr 30 10:32:13 2003 From: joe@REDACTED (Joe Armstrong) Date: Wed, 30 Apr 2003 10:32:13 +0200 (CEST) Subject: The Erlang way - dynamic upgrade of a server and UBF extensions In-Reply-To: <4.2.2.20030429062650.00cff350@duomark.com> Message-ID: On Tue, 29 Apr 2003, Jay Nelson wrote: > I like clear, clean, simple, regular data structures. Especially > in a functional language they make for obvious code. One > thing I've always felt was missing in data protocols is the > versioning on every packet. I think that is an essential feature. > Yes - Actually I woke up in the middle of the night (as one does) and thought about this and the packet length problem. It might not have been clear in my last mail that the version was the version number of the contract not of the protocol. I think we need a prefix like this: +------+-----------+-------------------+ | UBFv | Contractv | ..................| +------+-----------+-------------------+ UBFv is the version of the UBF protocol itself Contractv is the version of the contract (ie the data) > The IP failover seems to handle a reasonable case of > essentially connectionless single packet transmission, > or the equivalent of frequency hopping. More complex > failover can be part of a data packet listing multiple IPs > or a hierarchy or mapping to particular versions of the > protocol, as agreed in UBF(B) or UBF(C) contracts. > Interesting - perhaps the whole of client-server RPC is wrong. Should it be cluster-cluster RPC. The client could enclose a list of IPs and the server could reply to any client in the list. On *every* reply the server would reply with a list of servers to be used on the next call - one the next call the client could choose *any* server. (This will not be wildly efficient - because of globally replicate the state in the clusters at either end - *but* it will be easy to program fault-tolerent applications) > I like the idea of always having a packet header. It is much > simpler if the size of the packet is specified, but I wonder if > that is too much of a burden on the client. I would rather: > > <> = gen_tcp:recv(Socket, 4), > Packet = gen_tcp:recv(Socket, Length) ... > At first I thought - you're right and then I thought (later) you're wrong. In UBF if you get any pack of any size you just add it to the input queue, then you parse it byte-at-a-time until you hit $ then pop the recognition stack. If you want the length first you can't just output the data structure as it is generated - which made me think you need yet another type for streaming media. That would need yet another operator. Lists are sent as # a & b & c & d & ... So I guess infinite streams are * a ! b ! c ! ... Or something. I also though more about the versioning problem - synchronous change in the middle of a session would be very difficult to program and understand. So how about: When A and B communicate A knows that it can speak versions 1,2,3,4,8,12,20 of a contract B knows that is can speak versions 1,2,3,9,12,20,32 of a contract At the start A & B negotiate the highest common protocol this is version 20 - and they proceed. A gets a SW exception at some point (a bug) - it fails and removes 20 from its "available contracts" list. The session is restarted from the beginning - this time A can speak versions 1,2,3,4,8,12 and so a retry is done at level 12 (not 20). Both sides therefor degrade to the level where they think they understand the protocol. (And A's error log has an entry to tell the programmer why level 20 failed - a contract violation). This seems simple enough that it might work. /Joe > then to parse a stream a few bytes at a time calling recv. > > > Trying to come up with a header runs into three problems: > > 1) If packet size is first, 4 bytes might be wasteful to a small > msg protocol. > > 2) If version comes first to determine the size of the packet > length field, either a fixed version size (too limiting) is needed > or the integer UBF(A) spec is used with byte by byte recv parsing. > > 3) Having a size at the front means the client has to assemble > the whole message, compute the size and then send all, rather > than streaming out data. > > Not sure who should have the easier job, the client or server. > Given that the client is written more often (and probably by a > wider range of programmers of varying skill level) I would guess > it is better to make things easy on the client. That would argue > for a header as Joe proposed without a length and the version > coming first (presumably an integer in UBF(A) format). The > server has to do byte by byte gen_tcp:recv in this scenario. > > jay > From eleberg@REDACTED Wed Apr 30 11:03:24 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Wed, 30 Apr 2003 11:03:24 +0200 (MEST) Subject: The Erlang way - dynamic upgrade of a server and UBF extensions Message-ID: <200304300903.h3U93Oq28844@cbe.ericsson.se> > X-Authentication-Warning: enfield.sics.se: joe owned process doing -bs > Date: Wed, 30 Apr 2003 10:32:13 +0200 (CEST) > From: Joe Armstrong > Yes - everybody alwas forgets the version number - *everything* > should always have a version number. The trouble is when you create > something you think it is perfect and will never need upgrading - this > is always false. > > Erlang modules should begin: > > -need_version(2.3). > > Or something. does 2.3 refer to erlang itself? if so, perhaps 'R9A' would be a better version number? the question might be taken to indicate that need_version/1 should be need_version/2 instead. like this: -need_version(erlang, 'R9A'). -need_version(syntax_tools, 1.2). > They got this right in XML :-) and PDF and postscript. bengt From wicak.noeg@REDACTED Wed Apr 30 13:33:12 2003 From: wicak.noeg@REDACTED (wicaksono ) Date: Wed, 30 Apr 2003 18:33:12 +0700 Subject: the beginner Message-ID: hi all, i'am just starting this erlang. I try to make first aplication using windows as my os. I create a file at c>Program Files\erl5.2\math1.erl as user guide. but while I compile it always show ./math1.erl:8: premature end ./math1.erl:8: no module definition error what is that mean ? sorry for my stupied question regards, Wicak =========================================================================================== "TELKOMNet Instan memberikan diskon 40% untuk akses malam hari dari pukul 23.00 sampai 06.00. Berlaku untuk wilayah Jawa Timur mulai 1 Mei 2003 sampai 30 Juni 2003." =========================================================================================== From joe@REDACTED Wed Apr 30 13:47:55 2003 From: joe@REDACTED (Joe Armstrong) Date: Wed, 30 Apr 2003 13:47:55 +0200 (CEST) Subject: the beginner In-Reply-To: Message-ID: You've probably typed the program in incorrectly. Your error is in line 8 - stare at it and compare it with the example. If that fails post the file so we can see what you actually wrote and then we can say what went wrong. Cheers /Joe On Wed, 30 Apr 2003, wicaksono wrote: > hi all, i'am just starting this erlang. I try to make > first aplication using windows as my os. I create a file > at c>Program Files\erl5.2\math1.erl as user guide. > but while I compile it always show > > ./math1.erl:8: premature end > ./math1.erl:8: no module definition > error > > what is that mean ? > > sorry for my stupied question > > regards, > > Wicak > =========================================================================================== > "TELKOMNet Instan memberikan diskon 40% untuk akses malam hari dari pukul 23.00 sampai 06.00. > Berlaku untuk wilayah Jawa Timur mulai 1 Mei 2003 sampai 30 Juni 2003." > =========================================================================================== > From eleberg@REDACTED Wed Apr 30 13:51:38 2003 From: eleberg@REDACTED (Bengt Kleberg) Date: Wed, 30 Apr 2003 13:51:38 +0200 (MEST) Subject: the beginner Message-ID: <200304301151.h3UBpcq20063@cbe.ericsson.se> > From: "wicaksono " ...deleted > first aplication using windows as my os. I create a file > at c>Program Files\erl5.2\math1.erl as user guide. > but while I compile it always show > > ./math1.erl:8: premature end > ./math1.erl:8: no module definition > error > > what is that mean ? it would help if you included your file (math1.erl) in the email. without it i can only guess that you might have forgotten the line: -module(math1). at the beginning of your file. bengt From taavi@REDACTED Wed Apr 30 14:02:24 2003 From: taavi@REDACTED (Taavi Talvik) Date: Wed, 30 Apr 2003 15:02:24 +0300 (EEST) Subject: the beginner In-Reply-To: Message-ID: <20030430150118.R49966-100000@valu.uninet.ee> On Wed, 30 Apr 2003, Joe Armstrong wrote: Most probably you are missing final '.' in function definition. best regards, taavi > You've probably typed the program in incorrectly. > > Your error is in line 8 - stare at it and compare it with the example. > > If that fails post the file so we can see what you actually wrote and > then we can say what went wrong. > > Cheers > > /Joe > > > > On Wed, 30 Apr 2003, wicaksono wrote: > > > hi all, i'am just starting this erlang. I try to make > > first aplication using windows as my os. I create a file > > at c>Program Files\erl5.2\math1.erl as user guide. > > but while I compile it always show > > > > ./math1.erl:8: premature end > > ./math1.erl:8: no module definition > > error > > > > what is that mean ? > > > > sorry for my stupied question > > > > regards, > > > > Wicak > > =========================================================================================== > > "TELKOMNet Instan memberikan diskon 40% untuk akses malam hari dari pukul 23.00 sampai 06.00. > > Berlaku untuk wilayah Jawa Timur mulai 1 Mei 2003 sampai 30 Juni 2003." > > =========================================================================================== > > > > ----------------------------------------------------------- Taavi Talvik | Internet: taavi@REDACTED AS Uninet | phone: +372 6800013 Parnu mnt. 105 | fax: +372 6800001 Tallinn 11312, Estonia | gsm: +372 56569996 From D.WILLIAMS@REDACTED Wed Apr 30 14:04:00 2003 From: D.WILLIAMS@REDACTED (WILLIAMS Dominic) Date: Wed, 30 Apr 2003 14:04:00 +0200 Subject: the beginner Message-ID: > From: wicaksono [mailto:wicak.noeg@REDACTED] > > hi all, i'am just starting this erlang. I try to make > first aplication using windows as my os. I create a file > at c>Program Files\erl5.2\math1.erl as user guide. > but while I compile it always show > > ./math1.erl:8: premature end > ./math1.erl:8: no module definition > error > > what is that mean ? > Hi, What have you put in your math1.erl file? Did you forget the full stop ('.') at the end of the program? Here is the program from the tutorial: -module(math1). -export([factorial/1]). factorial(0) -> 1; factorial(N) -> N * factorial(N-1). ^^^ This compiles fine, but if you forget the full stop at the end, like this: -module(math1). -export([factorial/1]). factorial(0) -> 1; factorial(N) -> N * factorial(N-1) ^^^ the compiler gives the "premature end" error. Regards, Dominic. From vlad_dumitrescu@REDACTED Wed Apr 30 15:26:42 2003 From: vlad_dumitrescu@REDACTED (Vlad Dumitrescu) Date: Wed, 30 Apr 2003 15:26:42 +0200 Subject: The Erlang way - dynamic upgrade of a server and UBF extensions References: Message-ID: Hi everyone, If I may drop my two-pence in this conversations, there are some things I came to think about: - the versioning problem is not UBF related. The same applies to any client-server communication. Maybe a protocol_version-negotiating protocol is needed, if there aren't any already. - about sending IP addresses in packets: seems a bit heavy on the band... And this also applies to communication between regular Erlang processes: just replace "IP" with "Pid". Usually in Erlang process registration is not too heavyweight, but already the global registration is on the edge to become so, I think. One way to solve this would be to take our own medicine: separate the normal behaviour from the exceptional cases and let some kind of supervisor process notify clients of a process that the Pid is no longer valid. In this case the supervisor would be more of a proxy. Likewise, a server should not try to do it's own load balancing, but let a specialized part of the system handle this case too. Just some quick thoughts, but maybe there lies something interesting here. Best regards, Vlad From erlang@REDACTED Wed Apr 30 15:57:55 2003 From: erlang@REDACTED (Peter-Henry Mander) Date: Wed, 30 Apr 2003 14:57:55 +0100 Subject: The Erlang way - dynamic upgrade of a server and UBF extensions References: Message-ID: <3EAFD663.9030209@manderp.freeserve.co.uk> And here's my 1e-2 Euros. About the idea of embedding IP addresses in the IP packet data: please don't do it! If your packet passes through a NAT/PAT firewall/router you're embedded addresses become meaningless. I don't know what to suggest in it's place though, sorry. Pete. Vlad Dumitrescu wrote: > Hi everyone, > > If I may drop my two-pence in this conversations, there are some things I > came to think about: > > - the versioning problem is not UBF related. The same applies to any > client-server communication. Maybe a protocol_version-negotiating protocol > is needed, if there aren't any already. > > - about sending IP addresses in packets: seems a bit heavy on the band... > And this also applies to communication between regular Erlang processes: > just replace "IP" with "Pid". Usually in Erlang process registration is not > too heavyweight, but already the global registration is on the edge to > become so, I think. > One way to solve this would be to take our own medicine: separate the > normal behaviour from the exceptional cases and let some kind of supervisor > process notify clients of a process that the Pid is no longer valid. In this > case the supervisor would be more of a proxy. Likewise, a server should not > try to do it's own load balancing, but let a specialized part of the system > handle this case too. > > Just some quick thoughts, but maybe there lies something interesting here. > Best regards, > Vlad > > From enano@REDACTED Wed Apr 30 16:02:35 2003 From: enano@REDACTED (Miguel Barreiro Paz) Date: Wed, 30 Apr 2003 16:02:35 +0200 (CEST) Subject: The Erlang way - dynamic upgrade of a server and UBF extensions In-Reply-To: <3EAFD663.9030209@manderp.freeserve.co.uk> References: <3EAFD663.9030209@manderp.freeserve.co.uk> Message-ID: > About the idea of embedding IP addresses in the IP packet data: please > don't do it! If your packet passes through a NAT/PAT firewall/router > you're embedded addresses become meaningless. I don't know what to Indeed. Please don't repeat that ugly side of FTP, RTSP or the H.323 protocol family. From jay@REDACTED Wed Apr 30 16:25:54 2003 From: jay@REDACTED (Jay Nelson) Date: Wed, 30 Apr 2003 07:25:54 -0700 Subject: The Erlang way - dynamic upgrade of a server and UBF extensions In-Reply-To: References: <4.2.2.20030429062650.00cff350@duomark.com> Message-ID: <4.2.2.20030430065532.00a29ac0@duomark.com> Joe wrote: > It might not have been clear in my last mail that the version was the >version number of the contract not of the protocol. Ah, yes. Definitely needed, although I suppose it has to be a triplet of UBF(A), UBF(B) and UBF(C) versions unless they are guaranteed to all be lockstep upgraded with each version. Enforcing the Contractv adds data to the header, but also forces the implementer to supply one, and since it is so often forgotten, probably a good idea. >The client could enclose a list of IPs and the server could reply to any >client in the list. > > On *every* reply the server would reply with a list of servers to be >used on the next call - one the next call the client could choose >*any* server. [Vlad later added: the versioning problem is not UBF related. The same applies to any client-server communication. Maybe a protocol_version-negotiating protocol is needed, if there aren't any already.] Vlad has an interesting point that separation gives more options and retains clarity. I wonder if a good contract interface should have an initial handshake that determines versions available and exchanges a list of server IPs, as well as a directory server to access if you lose contact. Example: => server A supports v1, 2, 4, 6; contact IP1, IP2 or IP3 for support; contact IP5 for directory assistance <= server B supports v1, 3, 5, 6, 7; contact IP11, IP12 for support; contact IP15 for directory assistance This meta-contract / meta-protocol would be exchanged on initiation of session, or on request by either side. If IP11 and IP12 fail (each of which should support the same versions), the caller can access IP15 to get a new handshake with a different set of servers (presumably by listing the failing ones and asking for other options -- which could be answered 'none available'). Not part of UBF or the packet format, but as a reasonable failover mechanism in the application-specific protocol. > > <> = gen_tcp:recv(Socket, 4), > > Packet = gen_tcp:recv(Socket, Length) ... > > > >At first I thought - you're right and then I thought (later) you're wrong. > >In UBF if you get any pack of any size you just add it to the input queue, >then you parse it byte-at-a-time until you hit $ then pop the recognition >stack. Easy, but my initial reaction based on some projects I've been considering is to have a "packet router". A process that receives the next packet, checks the type and forwards it to an appropriate process to handle. The router needs to get a full packet, and it should be able to quickly analyse the data for destination determination (i.e., check the first UBF field on the packet). If the router has to process byte-by-byte it doesn't offer any advantage. You would like the server to efficiently handle a heavy load and rely on a distributed backend to keep up with the load. Reading blocks of data off the socket is much more efficient. A simple compromise is to encourage a contract protocol that starts out with a length field. >If you want the length first you can't just output the data structure >as it is generated - which made me think you need yet another type >for streaming media. (better is a unique indicator of "infinite length" and no other change) Which is why I also thought, "no, that's wrong" after I posted the reply. Some applications dribble out their data as is necessary and they are essentially an infinite stream. But even an error logger has a fixed size in each packet even if it dribbles out data. If the source was non-formatted (think of listening to morse code and transcribing it as digital characters), you probably don't want to receive it all as a client, then compute the size and forward it to the server for processing. I suspect true infinite or unformatted streamed sources are rather rare. As much as I find it annoying to put the size in the Content-length tag of HTML (especially since it is in the middle of the document, meaning you have to keep two buffers and then append them or stream them together) it sure makes for more efficient server options. >A gets a SW exception at some point (a bug) - it fails and removes >20 from its "available contracts" list. > >The session is restarted from the beginning - this time >A can speak versions 1,2,3,4,8,12 and so a retry is >done at level 12 (not 20). > > Both sides therefor degrade to the level where they think they >understand the protocol. (And A's error log has an entry to tell the >programmer why level 20 failed - a contract violation). I think this is a good approach. > This seems simple enough that it might work. Now there's a goal that all designers and implementers should aspire to! jay From jay@REDACTED Wed Apr 30 16:38:17 2003 From: jay@REDACTED (Jay Nelson) Date: Wed, 30 Apr 2003 07:38:17 -0700 Subject: The Erlang way - dynamic upgrade of a server and UBF extensions In-Reply-To: References: Message-ID: <4.2.2.20030430072603.00d03ee0@duomark.com> Vlad wrote: >separate the >normal behaviour from the exceptional cases and let some kind of supervisor >process notify clients of a process that the Pid is no longer valid. In this >case the supervisor would be more of a proxy. Likewise, a server should not >try to do it's own load balancing, but let a specialized part of the system >handle this case too. This is worth thinking about, but there is a key difference from the supervisor. A supervisor watches other processes and tries to right them when they fall down. The supervisor is behind the curtains and no other process knows about it. In the client / server approach, the supervisor would notice something is wrong and somehow try to influence the conversation. How does the supervisor initiate a conversation with a client that likely doesn't accept connections? Similarly, the load balancing is an issue that involves pushing the single point of failure up one level of processes but not eliminating it. I like the idea of using a "packet router" to receive the protocol, of having multiple of these and allowing the client to try others on failure and having available some sort of directory assistance especially if the client discovers that none of the new servers have implemented the latest protocol properly. I guess one way to do the supervisor approach is to follow Joe's analogy of an office manager that "fires" the failing server and "hires" a stand in. You need a packet router to do that seamlessly though: 1) Client contacts packet router, handshakes, makes request 2) Packet router gives to Server A for a response 3) Client makes 2nd request 4) Packet router gives it to Server A, A fails 5) Supervisor notices, updates packet router with message to put Server A in a non-preferred list 6) Packet router re-routes request to Server B 7) Client receives response It may mean that packet router has to return the response to the client in all cases or you may lose your grip on the socket in the failed process. Anyone tried to keep a copy of the socket in two processes, one of which owns it, fails and the other of which retakes controlling_process and then hands it off to a third process to finish the task? jay From wicak.noeg@REDACTED Wed Apr 30 16:44:15 2003 From: wicak.noeg@REDACTED (wicaksono ) Date: Wed, 30 Apr 2003 21:44:15 +0700 Subject: the beginner In-Reply-To: Message-ID: hi all, thanks for all your response my file math1.erl as Wiliam Dominic writen. -module(math1). -export([factorial/1]). factorial (0) ->1; factorial (N) -> N * factorial (N-1). one that make me confused, the error point to line 8 but it only has 4 line :( I have tried to compile with so many formats ( in space format), but it still didn't work. thanks Wicak =========================================================================================== "TELKOMNet Instan memberikan diskon 40% untuk akses malam hari dari pukul 23.00 sampai 06.00. Berlaku untuk wilayah Jawa Timur mulai 1 Mei 2003 sampai 30 Juni 2003." =========================================================================================== From vances@REDACTED Wed Apr 30 17:19:20 2003 From: vances@REDACTED (Vance Shipley) Date: Wed, 30 Apr 2003 11:19:20 -0400 Subject: The Erlang way - dynamic upgrade of a server and UBF extensions In-Reply-To: References: <3EAFD663.9030209@manderp.freeserve.co.uk> Message-ID: <20030430151920.GG89739@frogman.motivity.ca> Gentlemen, I think you have missed the point in that it is NAT which is ugly. -Vance On Wed, Apr 30, 2003 at 04:02:35PM +0200, Miguel Barreiro Paz wrote: } } > About the idea of embedding IP addresses in the IP packet data: please } > don't do it! If your packet passes through a NAT/PAT firewall/router } > you're embedded addresses become meaningless. I don't know what to } } Indeed. Please don't repeat that ugly side of FTP, RTSP or the H.323 } protocol family. From enano@REDACTED Wed Apr 30 17:58:41 2003 From: enano@REDACTED (Miguel Barreiro Paz) Date: Wed, 30 Apr 2003 17:58:41 +0200 (CEST) Subject: The Erlang way - dynamic upgrade of a server and UBF extensions In-Reply-To: <20030430151920.GG89739@frogman.motivity.ca> References: <3EAFD663.9030209@manderp.freeserve.co.uk> <20030430151920.GG89739@frogman.motivity.ca> Message-ID: > I think you have missed the point in that it is NAT which is ugly. Sure it is. As hell. But: - reality says it's needed. Outlaw NAT and half of the people with cable modems and *DSL routers are banned out of the net. - with or without NAT, endpoint information (IP addresses, TCP port numbers) ought to be in its place: as IP headers or TCP headers, respectively. Tomorrow we will pack it into any other transport without great problems. If we embed endpoint information *into* payload, we are looking for trouble. (RFC1627 meets reality) Regards, Miguel From matthias@REDACTED Wed Apr 30 20:55:47 2003 From: matthias@REDACTED (Matthias Lang) Date: Wed, 30 Apr 2003 20:55:47 +0200 Subject: the beginner In-Reply-To: References: Message-ID: <16048.7219.121008.245331@antilipe.corelatus.se> wicaksono writes: > my file math1.erl as Wiliam Dominic writen. > > -module(math1). > -export([factorial/1]). > factorial (0) ->1; > factorial (N) -> N * factorial (N-1). > > one that make me confused, the error point to line 8 but > it only has 4 line :( > > I have tried to compile with so many formats ( in space > format), but it still didn't work. I suspect the file you're compiling is not the one you've shown above. Perhaps you're starting the compiler in a different directory to where the file is. Here's what happens on my system: matthias >cat math1.erl -module(math1). -export([factorial/1]). factorial (0) ->1; factorial (N) -> N * factorial (N-1). matthias >erl Erlang (BEAM) emulator version 5.1.1 [source] Eshell V5.1.1 (abort with ^G) 1> c(math1). {ok,math1} 2> math1:factorial(100). 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 i.e. it works exactly as intended. Matt From cpressey@REDACTED Wed Apr 30 21:40:38 2003 From: cpressey@REDACTED (Chris Pressey) Date: Wed, 30 Apr 2003 14:40:38 -0500 Subject: The Erlang way - dynamic upgrade of a server and UBF extensions In-Reply-To: References: Message-ID: <20030430144038.56007576.cpressey@catseye.mb.ca> On Wed, 30 Apr 2003 15:26:42 +0200 "Vlad Dumitrescu" wrote: > Hi everyone, > > If I may drop my two-pence in this conversations, there are some > things I came to think about: > > - the versioning problem is not UBF related. The same applies to any > client-server communication. Maybe a protocol_version-negotiating > protocol is needed, if there aren't any already. Well, there's HTTP 1.1's Upgrade header field. That would take care of version negotiation, but it wouldn't help for trading cluster address info. > - about sending IP addresses in packets: seems a bit heavy on the > band... I agree, for both of these. Negotiate version (and whatever else is not going to change for the duration of the conversation) once at the start, and you obviate the need to send it over and over again. (Someday I'd dearly like to hear Joe's definition of the word "everything" :) I'm not sure if a supervisor is an applicable idea here, but I definately think some kind of negotiation-upon-starting-the-protocol is. -Chris