Re: [q-lang-users] RFC: Conditional syntax
Brought to you by:
agraef
From: Albert G. <Dr....@t-...> - 2006-05-31 13:44:20
|
Tim Haynes wrote: >>0. Keep the old definitions (Ex. 0). > > Backwards compatibility is always good ;) That's right, and normally I'd agree with you, but in this case I argue against it, for the following reasons: - Having two incompatible constructs for exactly the same thing will be confusing. - I really want to use "case" for the new matching conditional. That's the most obvious choice, and will be familiar to both Lisp and Haskell/ML users. Unfortunately, "case" is already declared as a constructor with the old constructs. So I'm afraid that it's either (0) or (1|2), but not both. - AFAICT, nobody really seems to use the current constructs right now. I scanned all Q sources I have lying around on my hard disk (which also includes all the add-on modules and the scripts contributed by you, Peter and Rob), and there's exactly one invokation of switch and one invokation of match. Both are in gqbuilder.q, which belongs to the core distribution, so it can be fixed pretty easily without anyone noticing. And if anyone still uses the old constructs occasionally, it should be an easy matter to parse those scripts with -w to identify all the undefined uses of "switch" and "match" and fix them. So it seems the right time now to make a clean cut. If there's anyone who has a significant amount of code using the old switch and match constructs, please speak up now! Talking about backward compatibility, I think that, even with all the other changes under the hood, Q 7.1 as it is in cvs now should still be 100% backward-compatible, with the following two exceptions: - The apply and compose functions have been removed from stdlib.q. These have been deprecated since the introduction of ($) and (.) in Q 6.1 and 5.3, so it should be safe to remove them now. - The lambda function used to return combinator terms which weren't nice to look at, but could be unparsed, written to a file and read back. With the new built-in lambda function, you'll get an external <<Function>> object instead. I don't think that the latter incompatibility will be much of a problem, except if you want to serialize a partially evaluated stream comprehension (which makes heavy use of embedded lambdas) and store it on disk. I could actually unparse the new "compiled" lambdas to something which can be parsed to reconstruct the function, but I'm afraid that it won't look very pretty, so the <<Function>> notation might actually be preferable, at least for interactive usage. And it's similar to what you'd get for anonymous closures with other FPs, too. >>1. Clauses as a tuple of (guard/pattern, value) pairs (Ex. 1). >>2. Clauses as a stream of (guard/pattern, value) pairs (Ex. 2). > > Having thought `hmm, braces, but not in the perl/C sense' I think I like 2 > more. Nested-parens are all very well in a lisp/scheme language but they're > not what I see in Q. YMMV. :] Note that the parens/braces there actually belong to the tuple/stream arguments of the cond/case functions. There's no syntactic sugar involved here, both cond and case will just be ordinary Q functions. >>3. 1 or 2 with "grouping" sugar (Ex. 3). > > It's certainly neat, watching other languages' switch/case layout come > about as a result of a formatting change, but as with other sugar, I'm > wondering what potential for tooth-rot it's letting in through the back > door. Any? Am I paranoid? Yeah, the "cancer of the semicolon"... That's the reason why I've always been reluctant to add more syntactic sugar to Q. I think that Haskell really goes a little overboard with that (in some cases out of necessity, since there are no user-definable special forms in Haskell). But I'd say that the syntax I've added in Q 7.1 is quite unobtrusive, really makes frequently-used stuff easier to read and write, was not introduced without a second and third thought (in fact I've been thinking about most of these features for years, but refrained from introducing them before everything else was in place), and fits well with the basic syntax. Here is a list of what's new in Q 7.1: - Stream syntax which looks like lists. I think that noone will argue that this is a vast improvement. - List and stream comprehension syntax. This uses a tried and proven set-like notation which comes from mathematics and has been around for centuries, I think. - Lambda syntax. Also uses a tried and proven notation from mathematical logic, which has been around since the 1930s. - If-then-else. Used in many FP textbooks, even if they otherwise use applicative syntax throughout. Note that all of these can still be specified using the basic applicative syntax (using nil_stream/cons_stream, listof/streamof, lambda, ifelse/when) if you prefer that. The proposed grouping notation is also quite common in mathematics, for the purpose of improving readability of sequences and argument lists, albeit with different meanings. I can think of three different reasonable implementations: - Visual cue only. Allow ";" instead of "," in sequences, but without any special meaning. - Nested sequence of same type. [X,Y; ...] will become [[X,Y],...], (X,Y; ...) will become ((X,Y),...) and {X,Y; ...} will become {{X,Y},...}. - Nested tuple. In this case the group always produces a nested tuple, i.e., [X,Y; ...] will become [(X,Y),...], (X,Y; ...) will become ((X,Y),...) and {X,Y; ...} will become {(X,Y),...}. I think that the latter interpretation would be the most useful for Q. Clearly, this kind of notation is not "standard" in the same way as the other items above, though. But, as I pointed out earlier, it would be fairly convenient in different contexts. Cheers, Albert -- Dr. Albert Gr"af Dept. of Music-Informatics, University of Mainz, Germany Email: Dr....@t-..., ag...@mu... WWW: http://www.musikinformatik.uni-mainz.de/ag |