|
View:
New views
20 Messages
—
Rating Filter:
Alert me
|
| < Prev | 1 - 2 - 3 - 4 - 5 - 6 - 7 | Next > |
|
|
Re: erlang sucks> HR1=f(HugeRecord),
> HR2=f2(HR1), > ... > g(HR1). But HR2 going unused will emit a compiler warning? If your ellipsis of code uses HR2 then some simple unit tests should detect your mistake before the code is committed. I appreciate that the resulting code is easier to reason about when you have immutable values and single assignment variables. The mental exercise of executing the code in your head becomes simpler when there is only one value throughout the variable's scope. _______________________________________________ erlang-questions mailing list erlang-questions@... http://www.erlang.org/mailman/listinfo/erlang-questions |
|
|
Re: erlang sucksattila.rajmund.nohl@... writes:
> I don't think that immutable variables make it easier to write less > buggier code. On the contrary, I often see code like this: > > HR1=f(HugeRecord), > ... > g(HR1). > > Then someone adds a line to modify the HugeRecord and forgets to update > the call to 'g': > > HR1=f(HugeRecord), > HR2=f2(HR1), > ... > g(HR1). > > Now we have a stupid bug. > Warning: variable 'HR2' is unused Jani Hakala -- University of Jyväskylä, Department of Physics email: jahakala@... _______________________________________________ erlang-questions mailing list erlang-questions@... http://www.erlang.org/mailman/listinfo/erlang-questions |
|
|
Re: erlang sucksOn Thu, 13 Mar 2008, Mats Cronqvist wrote:
> attila.rajmund.nohl@... wrote: >> On Wed, 12 Mar 2008, Anders G S Svensson wrote: >> [...] >> >>> You might not think that when the code is at a customer site and >>> applying patches isn't something the customer (or the layers of >>> management between you and the customer) will let you do. >>> >> >> Thankfully I haven't been in this situation. But I stand by my claim - >> if it's possible, it's often faster to insert io:format calls into the >> call than to try to make sense of hundreds of lines of trace generated by >> two simple function calls. Actually it would be nice if we'd have a tool >> that could parse such trace and the source code and could show me that >> which function was called... >> > i claim that in a real system, it is *always* faster to use the trace BIF > than io:format, if you are equally skilled with both. > for example, the "hundreds of lines of trace" you're talking about would > presumably be the arguments to functions calls? > from the erlang:trace/3 man page; "arity - Used in conjunction with the call > trace flag. {M, F, Arity} will be specified instead of {M, F, Args} in call > trace messages." Actually I do need some of the arguments (how would I know which one of the 10 similarly named functions is called?), I just don't need the whole process state. Bye,NAR -- "Beware of bugs in the above code; I have only proved it correct, not tried it." _______________________________________________ erlang-questions mailing list erlang-questions@... http://www.erlang.org/mailman/listinfo/erlang-questions |
|
|
Re: erlang sucksattila.rajmund.nohl@... wrote:
> On Thu, 13 Mar 2008, Mats Cronqvist wrote: > >> i claim that in a real system, it is *always* faster to use the trace >> BIF than io:format, if you are equally skilled with both. >> for example, the "hundreds of lines of trace" you're talking about >> would presumably be the arguments to functions calls? >> from the erlang:trace/3 man page; "arity - Used in conjunction with >> the call trace flag. {M, F, Arity} will be specified instead of {M, >> F, Args} in call trace messages." > > Actually I do need some of the arguments (how would I know which one of > the 10 similarly named functions is called?), I just don't need the > whole process state. [mats_cronqvist.vcf] begin:vcard fn:Mats Cronqvist n:Cronqvist;Mats org:Kreditor Europe AB email;internet:mats.cronqvist@... title:Senior Developer x-mozilla-html:FALSE version:2.1 end:vcard _______________________________________________ erlang-questions mailing list erlang-questions@... http://www.erlang.org/mailman/listinfo/erlang-questions |
|
|
Re: erlang *****> But now consider
> > f({X,_}\/{_,X}, > {Y,X}\/{X,Y}, > ... > {Z,W}\/{W,Z} > ) So matching this pattern must involve backtracking. Awww. > You could hack around this by requiring that if a head variable is > bound in a disjunctive pattern it is not matched by any other head > pattern. The problem does exist in a single pattern: {{X,_}\/{_,X}, {Y,X}\/{X,Y}, ... {Z,W}\/{W,Z}} We could of course generalise the above restriction, but it doesn't make it tolerable. But what are the real problems with the search for the right match with backtracking? If the programmer has written that silly pattern, he/she should be aware that it might not be very fast. Are there consequences other than the match being slow? > I note that my abstract pattern proposal *already* gives you > disjunctive patterns, BUT in such a way that the disjunctions can't > interact like this. Could you give some reference? I've searched for "abstract pattern" in the archives and found a few mail, but not your paper. Georgy _______________________________________________ erlang-questions mailing list erlang-questions@... http://www.erlang.org/mailman/listinfo/erlang-questions |
|
|
Re: erlang *****One thing that has to be considered in this discussions are guards. Guards are, irrespective of how some people would like to view them, part of pattern matching but those bits which can be difficult to express in a pattern*. As the guard varies with the pattern then they have to be kept together, something like:
foo(Pat11, ...) when Guard1 ; foo(Pat12, ...) when Guard2 ; foo(Pat13, ...) when Guard3 -> ...; etc. Having no "-> Body" after the pattern/guard means that you share the same body as the following clauses down to a clause with a body. In case/receive it would look something like: case ... of Pat1 when Guard1 ; Pat2 when Guard2 -> ...; ... end This is just a suggestion to both include patterns, which you must, and not introduce any new syntax. It also looks a bit more Erlangy. I haven't tried modifying the parser but it will probably need modification of the AST. I don't think there would be any problems in compiling this, or an equivalent. I remember that Richard's abstract patterns would also do this but here it would just be more explicit and dynamic. Robert * I have seen attempts to bake in guard tests into patterns but I think they become largely unreadable and manage to effectively hide the actual pattern. On 17/03/2008, Andras Georgy Bekes <bekesa@...> wrote: > But now consider _______________________________________________ erlang-questions mailing list erlang-questions@... http://www.erlang.org/mailman/listinfo/erlang-questions |
|
|
Re: erlang sucksOn Mar 17, 2008, at 6:31 AM, Jani Hakala wrote: > attila.rajmund.nohl@... writes: > >> I don't think that immutable variables make it easier to write less >> buggier code. On the contrary, I often see code like this: >> >> HR1=f(HugeRecord), >> ... >> g(HR1). >> >> Then someone adds a line to modify the HugeRecord and forgets to >> update >> the call to 'g': >> >> HR1=f(HugeRecord), >> HR2=f2(HR1), >> ... >> g(HR1). >> >> Now we have a stupid bug. >> > The compiler would warn about that > Warning: variable 'HR2' is unused These examples always feel like people are insisting on writing imperative code in a functional language. Why not: HR1 = f2(f(HugeRecord)), ... g(HR1) There you go: no bug. -kevin _______________________________________________ erlang-questions mailing list erlang-questions@... http://www.erlang.org/mailman/listinfo/erlang-questions |
|
|
Re: erlang sucksJani Hakala wrote:
> attila.rajmund.nohl@... writes: > >> I don't think that immutable variables make it easier to write less >> buggier code. On the contrary, I often see code like this: >> >> HR1=f(HugeRecord), >> ... >> g(HR1). >> >> Then someone adds a line to modify the HugeRecord and forgets to update >> the call to 'g': >> >> HR1=f(HugeRecord), >> HR2=f2(HR1), >> ... >> g(HR1). >> >> Now we have a stupid bug. >> > The compiler would warn about that > Warning: variable 'HR2' is unused Unless, in fact, it weren't unused... Something in the "..." could have used it, no? _______________________________________________ erlang-questions mailing list erlang-questions@... http://www.erlang.org/mailman/listinfo/erlang-questions |
|
|
Re: erlang *****Robert On 17/03/2008, Robert Virding <rvirding@...> wrote: One thing that has to be considered in this discussions are guards. Guards are, irrespective of how some people would like to view them, part of pattern matching but those bits which can be difficult to express in a pattern*. As the guard varies with the pattern then they have to be kept together, something like: _______________________________________________ erlang-questions mailing list erlang-questions@... http://www.erlang.org/mailman/listinfo/erlang-questions |
|
|
Re: erlang *****I pointed out that allowing even one outermost level of disjunction of
patterns within a function head makes it possible to express clause choice rules that appear to require exponential time to check. Let me now point out that my proposed fix, "a variable bound inside a disjunction must not be tested in any other pattern" is not enough. Instead of f({X,_}\/{_,X}, {Y,X}\/{X,Y}, ... {Z,W}\/{W,Z} ) -> take f({X,_} \/{_,X}, {Y,X1}\/{X1,Y}, ... {Z,W1}\/{W1,Z} ) when X == X1, ..., W = W1 -> On 18 Mar 2008, at 4:02 am, Andras Georgy Bekes wrote: > So matching this pattern must involve backtracking. Awww. I am somewhat at a loss to interpret "Awww". I would like to think it's "oh dear, now I understand why this is a really bad idea", but I suspect it's "silly little you for caring about such things." OK, let's try this. As noted by the original proposer, '=' in patterns is conjunction. So we can write ({A,_,_,_,_,_,_,_,_} \/ {_,A,_,_,_,_,_,_,_} \/ {_,_,A,_,_,_,_,_,_} \/ ... {_,_,_,_,_,_,_,_,A} ) to express "A is an element of this 9-element tuple". By using ?E(A)=?E(B)=...=?E(I) ... when A /= B, A/= C, ..., A /= I, ..., H /= I we can express "{A,...,I} is a permutation of this 9-element tuple". If you're still with me, you now see how to express any 9x9 Sudoku problem as a single clause match in Erlang extended with pattern disjunction. I respectfully suggest that the Erlang developers have better things to do with their time. > > The problem does exist in a single pattern: > {{X,_}\/{_,X}, > {Y,X}\/{X,Y}, > ... > {Z,W}\/{W,Z}} It was not clear that the original proposal was calling for embedded disjunctions. > > But what are the real problems with the search for the right match > with > backtracking? First, the current Erlang pattern matching compiler does not have to deal with backtracking of any kind. So we are not talking about just a tiny syntactic extension, along the lines of allowing A andalso B as equivalent to case A of true -> case B of true -> true ; false -> false end ; false -> false end On the contrary, we are talking about a tiny syntactic extension with major semantic effect, requiring a major rewrite of a core chunk of any compiler. Second, the current Erlang pattern matching feature currently has predictable costs. If you have no repeated variables (the "linearity" condition, enforced in Haskell and SML) the cost of pattern matching is linear in the size of the pattern; with repeated variables it may be linear in the size of the input. This lets us think of pattern matching as a glorified 'case' statement, and use it freely. > If the programmer has written that silly pattern, he/she > should be aware that it might not be very fast. This is what's called a "counsel of perfection", not in the historic or literal sense (http://en.wikipedia.org/wiki/Evangelical_counsels) but in the vernacular sense (excellent advice which can only be taken by people who are already perfect), see for example (http://forum.wordreference.com/showthread.php?t=5096). I worked at Quintus for quite a while. There were an amazing number of customers who simply could not be made to understand that NO programming language could solve an EXPTIME problem in linear time. If an algorithm could be written in a small number of times, then as far as they were concerned it HAD to run in a short amount of time, and if it didn't, then our Prolog compiler was no d--- good. Now some constraint satisfaction problems of the kind that can be expressed using conjunctions and disjunctions of patterns can be solved efficiently, and some can't. It's really asking too much for the Erlang compiler to tell which are which and use special strategies for the efficiently solvable ones. It is also asking too much to expect J. A. Luser, a typical Erlang programmer, to figure out which ones are going to run fast and which are not, because the speed will NOT depend just on what the conjoined and disjoint patterns are, but on what the Erlang compiler does with them, and poor old Luser doesn't know that (and cannot know what the next release of the compiler will do). This doesn't apply to the present system, where a fairly naive "what you see is what it does" understanding won't mislead you too badly. > Are there consequences > other than the match being slow? Not slow: *unbelievably* slow. > > >> I note that my abstract pattern proposal *already* gives you >> disjunctive patterns, BUT in such a way that the disjunctions can't >> interact like this. > Could you give some reference? > I've searched for "abstract pattern" in the archives and found a few > mail, but not your paper. A Google search for "abstract patterns Erlang" quickly located http://www.erlang.org/ml-archive/erlang-questions/200309/msg00309.html _______________________________________________ erlang-questions mailing list erlang-questions@... http://www.erlang.org/mailman/listinfo/erlang-questions |
|
|
Re: erlang sucksFrom: ok@... > The differences really boil down to this: > guards are for INDEXING. > ... optimization ... reordering ... lack of side effects ... In that, I agree with you. I don't want this for anything other than indexing. I want to _externalize_ the _purely functional_ indexing analysis of whatever is being checked, instead of being forced to always write it in-line wherever any match takes place. I am of the opinion that if I call anything including side effects inside guards, I am doing bad things and things will break. As I said, have it detect what functions are pure functional and only allow those if you want. Everything will then work with user-defined guards, and everybody's happy. I do not understand the resistance to this. There are at least 3 ways to detect pure functional guard use, as has been discussed by myself and others on this list: 1) Have some internal state flag for "inside a guard?", and check that on side-effectful BIFs, tossing an error if it is inside one. Since side effects are generally slower than functional BIFs, adding the overhead there should be less of a hit than the internal reduction counter for process switching. 2) Do compile- and module-load-time deep checking, marking what is known as pure functional, tossing errors earlier than the above. This is weaker in that it can't detect variable-based M:F or fun calls until they're actually invoked; it could simply consider all such calls as dirty. 3) Only allow user-defined pure functional guards from the local module, to avoid any runtime issues. Also, there's the option to make Dialyzer detect these sorts of things. There is no good reason to keep user functions out of guards completely. The whole "oh no, some idiot might put side effects in guards!" is nothing but a strawman, and as I listed above, it can be a sensibly detectable error condition with no difficulty in hot code loading. But honestly I don't see any problem whatsoever in simply allowing anything in guards, side effects or not. It would be nice to be able to send logging info regardless of guard context if you're debugging. The caveats of calling side-effectful code from guards would not be new. Threaded GUI systems are notorious for this yet still work fine; you simply know if you do things a certain way, some function gets called>=0 times. What's the big deal? Pure functional user defined functions in guards would be the norm, as is the case that I want. Calling receive from within another receive guard should throw an error. > If you are generating Erlang code from a DSL, then why not just fix your > code generator? The problem is user-written code that uses the generated stuff. As it is, the human cannot easily defer to the generated stuff for guard decisions without resorting to weird tricks. > f(Msg = #hello{}) -> ... > > is necessarily safe, whereas It may be "safe", but it doesn't abstract what "Hello" is. It still relies on there being a record called "hello" and if the codegen decides to represent it in any other way, this assumption breaks. Hence the need to be able to defer guards to external code. _________________________________________________________________ Climb to the top of the charts! Play the word scramble challenge with star power. http://club.live.com/star_shuffle.aspx?icid=starshuffle_wlmailtextlink_jan _______________________________________________ erlang-questions mailing list erlang-questions@... http://www.erlang.org/mailman/listinfo/erlang-questions |
|
|
Re: erlang sucksOn 18 Mar 2008, at 1:35 pm, David Holz misunderstood: >> f(Msg = #hello{}) -> ... >> >> is necessarily safe, whereas > > It may be "safe", but it doesn't abstract what "Hello" is. This was presented as an example of using ABSTRACT PATTERNS, not RECORDS. As such, it most definitely DOES abstract what "Hello" is > It still relies on there being a record called "hello" and DOESN'T rely on there being any record called "hello" > and if the codegen decides to represent it in any other way, this > assumption breaks. Hence the need to be able to defer guards to > external code. and DOES allow the definition to be external. You can very nearly think of abstract patterns as being the functions you want, but constrained at the point of definition (and by the syntax) so that they are safe to call, WITHOUT any runtime test, and pretty much without any downside that I can see. A note on implementation: #abspat(args) in a clause head would be compiled as load current item into argument register normal function call failure address -- at this point function has left some stuff on the stack code to match those arguments ... failure address: look for next matching clause. The function would exit in one of two ways: failure-return Return no results, Instead of returning to X, return to *X success-return N move the N arguments to a standard place (perhaps the argument registers) Instead of returing to X, return to X + failure address size Note: it would be absurd, as in "what a dreadful waste of effort" for the user-defined things allowed in patterns to merely return true or false. They need to SUCCEED returning a bunch of parts or FAIL. This is not just more efficient than returning 'true' or 'false' and then going a bit Alzheimic and checking to see which it was, it is considerably more expressive. Here is an example. Suppose we have a bunch of messages including {hello,From,_,_,_} {teenaa_koe,_,From,_} {nihao,_,_,From,_,_} and we would like (a) to classify all these as 'hello' messages and (b) recover the From field from them. #hello(From) -> {hello,From,_,_,_}; #hello(From) -> {teenaa_koe,_,From,_}; #hello(From) -> {nihao,_,_,From,_,_}. #hello() -> #hello(_). Now we can not only write f(Msg = #hello()) -> ... From = hello_from(Msg) ... but we can also write f(Msg = #hello(From)) -> ... Abstract patterns not only do not rely on -record, they were intended to replace it! _______________________________________________ erlang-questions mailing list erlang-questions@... http://www.erlang.org/mailman/listinfo/erlang-questions |
|
|
Re: erlang *****On 3/17/08, Richard A. O'Keefe <ok@...> wrote:
> I am somewhat at a loss to interpret "Awww". I would like to think > it's "oh dear, now I understand why this is a really bad idea", but > I suspect it's "silly little you for caring about such things." I think it's "So what? There are lots of programming constructs that when misused can lead to inefficiency." You'd laugh at someone who was concerned about adding recursive functions to a language because a naive user might write "fibb(N) = fibb(N - 1) + fibb(N - 2)" or that adding general looping constructs means we can't ensure arbitrary programs will halt on a given input. I see no reason to worry about similar arguments for disjunctive patterns. _______________________________________________ erlang-questions mailing list erlang-questions@... http://www.erlang.org/mailman/listinfo/erlang-questions |
|
|
Re: erlang sucksKevin Scaldeferri wrote:
> On Mar 17, 2008, at 6:31 AM, Jani Hakala wrote: > > >> attila.rajmund.nohl@... writes: >> >> >>> I don't think that immutable variables make it easier to write less >>> buggier code. On the contrary, I often see code like this: >>> >>> HR1=f(HugeRecord), >>> ... >>> g(HR1). >>> >>> Then someone adds a line to modify the HugeRecord and forgets to >>> update >>> the call to 'g': >>> >>> HR1=f(HugeRecord), >>> HR2=f2(HR1), >>> ... >>> g(HR1). >>> >>> Now we have a stupid bug. >>> >>> >> The compiler would warn about that >> Warning: variable 'HR2' is unused >> > > > These examples always feel like people are insisting on writing > imperative code in a functional language. Why not: > > HR1 = f2(f(HugeRecord)), > ... > g(HR1) i first learned erlang. mats [mats_cronqvist.vcf] begin:vcard fn:Mats Cronqvist n:Cronqvist;Mats org:Kreditor Europe AB email;internet:mats.cronqvist@... title:Senior Developer x-mozilla-html:FALSE version:2.1 end:vcard _______________________________________________ erlang-questions mailing list erlang-questions@... http://www.erlang.org/mailman/listinfo/erlang-questions |
|
|
Re: erlang *****2008/3/18, Matthew Dempsky <matthew@...>:
> > You'd laugh at someone who was concerned about adding recursive > functions to a language because a naive user might write "fibb(N) = > fibb(N - 1) + fibb(N - 2)" or that adding general looping constructs > means we can't ensure arbitrary programs will halt on a given input. > I see no reason to worry about similar arguments for disjunctive > patterns. I think there is always reason to worry about such arguments. I think that one of Erlang's strengths, both compared to more "sophisticated" functional languages like Haskell, and to more mainstream languages like C++, is that fairly average programmers can quickly learn to write pretty solid production code (perhaps not great, elegant or terribly efficient, but good enough for industrial use, even with very high quality standards). Great programmers can write elegant and efficient programs in practically any language, and one of my main gripes about C++ is that great programmers are often able to use this to sway policy decisions towards C++, not understanding (or caring?) that such power tools can be disastrous in the hands of the "average programmer" - after all, why should we base important design decisions on expectations of how badly our design can be abused by stupid people? The main question is really: how easy is it to tell the efficient uses from the horribly inefficient ones? In the fibb example above, it is perfectly reasonable to teach beginners (as we have done in Erlang for years) e.g. that a recursive function will grow the stack if it has outstanding computations when making the recursive call. This appears to be easy to grasp for most programmers, and is immediately obvious in the fibb() example. It is also immediately obvious that it's exponential. This is very different from allowing a subtle change in a complex pattern match to shift evaluation from constant-time or linear to NP - especially when programmers have learned to expect and appreciate that pattern-matching is predictable in cost. I am very much in favour of keeping Erlang's pattern-matching both pure and predictable in cost. I don't mind having list comprehensions, query comprehensions etc that are not. BR, Ulf W _______________________________________________ erlang-questions mailing list erlang-questions@... http://www.erlang.org/mailman/listinfo/erlang-questions |
|
|
Re: erlang *****> But now consider
> > f({X,_}\/{_,X}, > {Y,X}\/{X,Y}, > ... > {Z,W}\/{W,Z} > ) > > I don't have a proof, but my gut feeling is that the combination > of compiling and executing clauses with "or" patterns has to be NP. The current pattern matching is also NP, so it wouldn't be a problem. (Contrary to a common misconception, the meaning of NP is _not_ non-polynomial!) You probably wanted to guess that it is NP-hard (which still doesn't mean non-polynomial, but something quite close to it.) If you want to do the pattern matching of all parameters in on step, then it indeed NP-hard (I even have a proof for it). However, if pattern matchings are done one-by-one and left-to-right, then there is no performance problem. The union operator becomes less flexible in this case, but it is still quite useful. Actually, if we want the pattern matching to be deterministic, we _must_ do such a restriction. For example using the patter {X,_} V {_X}, the value of X could be either element of the tuple. Using the left-to-right rule, X will always be the first element. Regards, Alpar _______________________________________________ erlang-questions mailing list erlang-questions@... http://www.erlang.org/mailman/listinfo/erlang-questions |
|
|
Re: erlang sucksOn Mon, 17 Mar 2008, Kevin Scaldeferri wrote:
> On Mar 17, 2008, at 6:31 AM, Jani Hakala wrote: > >> attila.rajmund.nohl@... writes: >> >>> I don't think that immutable variables make it easier to write less >>> buggier code. On the contrary, I often see code like this: >>> >>> HR1=f(HugeRecord), >>> ... >>> g(HR1). >>> >>> Then someone adds a line to modify the HugeRecord and forgets to >>> update >>> the call to 'g': >>> >>> HR1=f(HugeRecord), >>> HR2=f2(HR1), >>> ... >>> g(HR1). >>> >>> Now we have a stupid bug. >>> >> The compiler would warn about that >> Warning: variable 'HR2' is unused > > These examples always feel like people are insisting on writing > imperative code in a functional language. Why not: > > HR1 = f2(f(HugeRecord)), > ... > g(HR1) Because this is a mock-example, the real code looks more like HR1=HugeRecord#hugeRecordType{someField=SomeValue} ... code uses HR1 HR2=HR1#hugeRecordType{someOtherField=SomeOtherValue} ... g(HR1), % forgot to update variable name h(HR2). % didn't forget to update variable name In this case the compiler won't save my a**. I see this kind of code change all the time. Every week I see a checkin which only fixes a variable name that wasn't updated, so this is not exactly a rare bug. Bye,NAR -- "Beware of bugs in the above code; I have only proved it correct, not tried it." _______________________________________________ erlang-questions mailing list erlang-questions@... http://www.erlang.org/mailman/listinfo/erlang-questions |
|
|
Re: erlang *****> allowing inlined guard expressions
> in the pattern itself, like for example > {integer(X), _, X>3, atom(Y), Z!=[X,Y]} > or > {integer(X>3), _, X, atom(Y), Z!={X,Y]} > would be equivalent to > {X, _, X, Y} when is_integer(X), X>3, is_atom(Y), not(Z ~=[X, > Y]). I looks nice for the type-testing guard BIFs ( is_* ), but I don't know how do you want to write the rest of them: abs(Number) element(N, Tuple) float(Term) hd(List) length(List) node() node(Pid|Ref|Port) round(Number) self() size(Tuple|Binary) tl(List) trunc(Number) ? Georgy _______________________________________________ erlang-questions mailing list erlang-questions@... http://www.erlang.org/mailman/listinfo/erlang-questions |
|
|
Re: erlang *****> > So matching this pattern must involve backtracking. Awww.
> I am somewhat at a loss to interpret "Awww". I would like to think > it's "oh dear, now I understand why this is a really bad idea", but > I suspect it's "silly little you for caring about such things." I meant: "Oh, sh** there is some real problem with this idea I failed to think about. It probably needs radical changes in the compiler/vm with consequences I surely can't foresee." > If you're still with me, you now see how to express any 9x9 Sudoku > problem as a single clause match in Erlang extended with pattern > disjunction. Wow, THAT would be a great advertisement for Erlang ;-) > It's really asking too much for the Erlang compiler > to tell which are which and use special strategies for the > efficiently solvable ones. It is also asking too much to expect J. A. > Luser, a typical Erlang programmer, to figure out which ones are > going to run fast and which are not Back to the real world: I worked with Prolog much, and wouldn't expect anything better than a depth-first search for the first match. I think I'd use it quite happily without having too much trouble with unexpected match times. I think the simple backtracking wouldn't be hard to implement, however, it certainly needs radical changes in the compiler/vm, and has unforeseen consequences. > Second, the current Erlang pattern matching feature currently has > predictable costs. Consequences like this: I might be wrong, but I think a pattern match is an atomic operation in the VM, I mean, the scheduler won't switch to another process in the middle of a pattern match. If this is true, a long pattern match halts the whole Erlang VM. With careful work, you can forge a long-running pattern match in Erlang (as you said: "it may be linear in the size of the input") but with the backtracking-pattern-union match it is just so much easier. I think I am convinced, it is a really-really bad idea. However, if a pattern match is not atomic in the above sense, it can't cause such big trouble. I mean, at least the above problem does not exist. There might be other serious issues I failed to think about. > It was not clear that the original proposal was calling for embedded > disjunctions. It was. Basically I suggested '\/' as a pattern*pattern -> pattern "function", which can be used anywhere. However, what Robert suggests is a nice compromise: > foo(Pat11, ...) when Guard1 ; > foo(Pat12, ...) when Guard2 ; > foo(Pat13, ...) when Guard3 -> > ...; and > case ... of > Pat1 when Guard1 ; > Pat2 when Guard2 -> ...; > ... > end This doesn't need any radical change in the compiler/vm. You simply act as if the only clause body was used for all the patterns. I'd be happy with this solution: it would solve >90% of the cases I'd use pattern union for. But only together with the pattern-match-test guard BIF. I'd still need it :-) However, I don't think the above syntax is a good enough: after the ';' token either a guard can follow (guard expressions separated by ','s) or a new pattern. There should be a new keyword I think. Georgy _______________________________________________ erlang-questions mailing list erlang-questions@... http://www.erlang.org/mailman/listinfo/erlang-questions |
|
|
Re: erlang *****> This is very different from allowing a subtle change in a complex
> pattern match to shift evaluation from constant-time or linear > to NP - especially when programmers have learned to expect > and appreciate that pattern-matching is predictable in cost. Once again, please: NP does _not_ mean non-polynomial, but something very-very different. If you want to say "worse than polynomial" you can say "superpolynomial" or "exponential" (if the running time is indeed something like O(2^n)). > I am very much in favour of keeping Erlang's pattern-matching > both pure and predictable in cost. But, if the left-to-right rule was used for evaluating the disjunctive pattern matching, it would meet your requirements, wouldn't it? Best regards, Alpar _______________________________________________ erlang-questions mailing list erlang-questions@... http://www.erlang.org/mailman/listinfo/erlang-questions |
| < Prev | 1 - 2 - 3 - 4 - 5 - 6 - 7 | Next > |
| Free embeddable forum powered by Nabble | Forum Help |