diamond@tkou02.enet.dec.com ("diamond@tkovoa") (12/06/90)
Most of the syntax of C is not particularly difficult. However, there is some pretty solid evidence about the declaration syntax. For how many languages have people written, and recommended to others to use, programs that translate declarations to English and vice-versa? Also I vaguely recall some customer of the Unix operating system and C language having a small problem, because one of their programmers put a "break" statement in a compound statement, but it was the wrong kind of compound statement so the "break" exited from a larger one instead. Other syntactic structures that are equally complex could provide better detection and recovery from user errors. -- Norman Diamond diamond@tkov50.enet.dec.com If this were the company's opinion, I wouldn't be allowed to post it.
thornley@cs.umn.edu (David H. Thornley) (12/09/90)
In article <9012061208.AA08577@decpa.pa.dec.com> diamond@tkou02.enet.dec.com ("diamond@tkovoa") writes: >Most of the syntax of C is not particularly difficult. >However, there is some pretty solid evidence about the declaration syntax. >For how many languages have people written, and recommended to others to >use, programs that translate declarations to English and vice-versa? > How many languages support arrays of pointers to functions returning pointers to functions that return pointers to integers? If you limit yourself to data structures that would work in FORTRAN or Pascal, you have no need for such programs. >Also I vaguely recall some customer of the Unix operating system and C >language having a small problem, because one of their programmers put a >"break" statement in a compound statement, but it was the wrong kind of >compound statement so the "break" exited from a larger one instead. > AT&T, I think. (Some phone company, anyway.) It wasn't a "small" problem either :-). From what I saw of it, it looked like the sort of mistake that could happen with any language, and was due to misunderstanding the language and failing to test the part that failed. I assume you've heard about DO 10 I = 1. 10 (parsed as DO10I = 1.10) ad nauseum. Weinberg, in _The_Psychology_of_Computer_Programming_, had a nice story about a FORTRAN program where a variable in a massive simulation program had been spelled two different ways in the program. The bug was found after the simulations had been conducted, a book written, and a couple of systems designed based on that information. >Other syntactic structures that are equally complex could provide better >detection and recovery from user errors. > No doubt. How much better? Enough to justify moving *lots* of software from C? How about FORTRAN? Actually, simply requiring *all* variables to be declared would solve a *lot* of problems, and break a *lot* of existing code. DHT
Bruce.Hoult@bbs.actrix.gen.nz (12/10/90)
In article <1990Dec9.013923.14456@cs.umn.edu> thornley@cs.umn.edu (David H. Thornley) writes: >>Most of the syntax of C is not particularly difficult. >>However, there is some pretty solid evidence about the declaration syntax. >>For how many languages have people written, and recommended to others to >>use, programs that translate declarations to English and vice-versa? >> >How many languages support arrays of pointers to functions returning >pointers to functions that return pointers to integers? If you limit >yourself to data structures that would work in FORTRAN or Pascal, you >have no need for such programs. Pascal only narrowly misses out on being able to do this, and it's cousins Modula-2 and Oberon can both do it far more readably than can C. -- Bruce.Hoult@bbs.actrix.gen.nz Twisted pair: +64 4 772 116 BIX: brucehoult Last Resort: PO Box 4145 Wellington, NZ
smryan@garth.UUCP (Steven Ryan) (12/18/90)
>How many languages support arrays of pointers to functions returning >pointers to functions that return pointers to integers? If you limit >yourself to data structures that would work in FORTRAN or Pascal, you >have no need for such programs. I already answerred this kind of question before. In Algol 68, it's []proc proc ref int How many languages support arrays of functions returning arrays of functions returning arrays of functions..... [*] Two recursive mode definitions in Algol 68 are (1) mode cell = struct(int data, ref cell link) (2) mode list = proc(list)list Translated into C these would be (1) typedef struct cell{int data; struct cell *link;} cell; (2) cannot be expressed in C I suppose if you limit yourself to data structures that would work in C, you have no need for such programs using (2). Of course, CLU and other more recent languages would permit you to write something akin to (3) mode cell m = struct(m data, ref cell m link) although in fact this cannot be written in C or Algol 68, so I suppose if you limit....... _______________________________________________________________________ * I don't have a copy of revised definition at hand, so I'm not sure if mode func = []proc func is well formed. However mode func = []proc(int)func is. -- ...!uunet!ingr!apd!smryan Steven Ryan ...!{apple|pyramid}!garth!smryan 2400 Geng Road, Palo Alto, CA
kinnersley@kuhub.cc.ukans.edu (Bill Kinnersley) (12/19/90)
In article <20@garth.UUCP>, smryan@garth.UUCP (Steven Ryan) writes: > > How many languages support arrays of functions returning arrays of > functions returning arrays of functions..... [*] > But it seems to me that this will single out languages that fit a particular mold, rather than languages with power. If you want a language with 1) Functions as first-class data (most applicative languages) 2) Arrays (mostly imperative languages) 3) Strong type system there's nothing left but Algol-68 and C. If you're satisfied with lists in place of arrays, that makes it easier. Icon, for example, will let you make lists of functions and return them from functions. But it has no type declarations. Otherwise, ML, Miranda and Russell. -- --Bill Kinnersley
dts@cs.edinburgh.ac.uk (Don Sannella) (12/20/90)
In article <27534.276e5bd3@kuhub.cc.ukans.edu>, kinnersley@kuhub.cc.ukans.edu (Bill Kinnersley) writes: > ... If you want a language with > 1) Functions as first-class data (most applicative languages) > 2) Arrays (mostly imperative languages) > 3) Strong type system > there's nothing left but Algol-68 and C. ... and ML. Don Sannella University of Edinburgh P.S. Does C have a strong type system? This must be some new development I haven't heard about.
augustss@cs.chalmers.se (Lennart Augustsson) (12/20/90)
In article <27534.276e5bd3@kuhub.cc.ukans.edu> kinnersley@kuhub.cc.ukans.edu (Bill Kinnersley) writes: > ..., rather than languages with power. If you want a language with > >1) Functions as first-class data (most applicative languages) > >2) Arrays (mostly imperative languages) > >3) Strong type system > >there's nothing left but Algol-68 and C. > C does not have functions as first class data, you can only use functions pointers as data. To see the difference just try to write a function that does function composition. For simplicity assume that all functions take and return int, i.e. write an int (*compose(f, g))() int (*f)(); int (*g)(); (ANSI-fy if you like) so that (*compose(f,g))(x) == f(g(x)). I claim that this is impossible to do in a portable way. -- Lennart Augustsson Email: augustss@cs.chalmers.se
gudeman@cs.arizona.edu (David Gudeman) (12/20/90)
In article <1990Dec19.222059.6878@mathrt0.math.chalmers.se> Lennart Augustsson writes:
]>
]C does not have functions as first class data, you can only use functions
]pointers as data. To see the difference just try to write a function
]that does function composition.
C does not let you construct functions at run time (which makes the
first-class functions rather anemic) but C does have first class
functions by the usual definition of the term. The term "first-class"
just means that the type of object in question can be passed as an
argument to procedures and returned from procedures as a result. In
procedural languages like C, it also means that you can assign the
values to variables. First-class does not imply any particular
primitive operations on the objects (like construction), and the only
operation that an object needs to make it a function is function
application.
It is not really relevant that the things you pass around are
described in the language documentation as "function pointers". They
behave exactly like a function.
--
David Gudeman
gudeman@cs.arizona.edu
noao!arizona!gudeman
thornley@cs.umn.edu (David H. Thornley) (12/21/90)
In article <20@garth.UUCP> smryan@garth.UUCP (Steven Ryan) writes: >>How many languages support arrays of pointers to functions returning >>pointers to functions that return pointers to integers? If you limit >>yourself to data structures that would work in FORTRAN or Pascal, you >>have no need for such programs. > >[Listing several neat things to do with Algol 68 declarations] > >I suppose if you limit yourself to data structures that would work in C, >you have no need for such programs using (2). > Actually, my comment was in reference to the existence of cdecl to help declare data structures. Is there an algol68decl program? :-) DHT
sommar@enea.se (Erland Sommarskog) (12/26/90)
Also sprach Bill Kinnersley (kinnersley@kuhub.cc.ukans.edu): >1) Functions as first-class data (most applicative languages) >2) Arrays (mostly imperative languages) >3) Strong type system >there's nothing left but Algol-68 and C. I speak neither Algol-68 nor C, but what I know of C it does not have a very strong type system. Neither do I know what the requirement is to make functions as first-class data, but I would guess that Modula-2 and Ob(solet)eron would qualify at least as well as C. I wouldn't say that anyone of them provides a type system strong enough for my taste, though. By the way, I have never understood how strong the type system is in Cobol, but it is possible that it would qualify as well. (A type system strong enough: a language where I can declare types who are implemented in the same, e.g. integer, and which are only compatible through explicit conversions.) -- Erland Sommarskog - ENEA Data, Stockholm - sommar@enea.se "There is only one success, namely to lead your life in your own way" Anyone who can give a source for this?
augustss@cs.chalmers.se (Lennart Augustsson) (12/29/90)
In article <304@coatimundi.cs.arizona.edu> gudeman@cs.arizona.edu (David Gudeman) writes: >In article <1990Dec19.222059.6878@mathrt0.math.chalmers.se> Lennart Augustsson writes: >]> >]C does not have functions as first class data, you can only use functions >]pointers as data. To see the difference just try to write a function >]that does function composition. > >C does not let you construct functions at run time (which makes the >first-class functions rather anemic) but C does have first class >functions by the usual definition of the term. The term "first-class" >just means that the type of object in question can be passed as an >argument to procedures and returned from procedures as a result. In >procedural languages like C, it also means that you can assign the >values to variables. First-class does not imply any particular >primitive operations on the objects (like construction), and the only >operation that an object needs to make it a function is function >application. > I was a bit sloppy in my posting since I did not make clear what I mean by "first class". There are several definitions, but the one I have in mind is that for a type to be first class it should be possible to do the same things with its objects as with objects of other types, such as integers. What this means depends on the language, but typical things would be: send as an argument, return as a result, be expressible without giving it a name (this a crucial point where C fails for functions, you can write 5 as it is (i.e. you don't have to write "int five=5;"), but you cannot write an unnamed function), read, write, etc. C allows passing and returning, but not the others (well, C as such does not allow reading/writing of integers either). C also lacks first class structs (in my definition of the term), because you cannot write unnamed struct values (you can in GCC). -- Lennart Augustsson [This signature is intentionally left blank.]
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (01/03/91)
In article <1990Dec29.101233.1894@mathrt0.math.chalmers.se> augustss@cs.chalmers.se (Lennart Augustsson) writes: [ included in a definition of ``first-class'': ] > be expressible without giving it a > name First-class refers to semantics alone. Why are you trying to include syntax? > (this a crucial point where C fails for functions, [ you can't write an unnamed function ] Huh? Who cares? To get an unnamed function you just have to declare the function and not use its name. The fact that you can't write an unnamed function is not a problem for programmers. In contrast, pre-ANSI C structures were truly not first-class objects. You couldn't pass them by value. This made some problems genuinely more difficult. This is just another example of why syntax is a lot less important than semantics. ---Dan
anw@maths.nott.ac.uk (Dr A. N. Walker) (01/04/91)
In article <18747:Jan220:02:1091@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >Huh? Who cares? To get an unnamed function you just have to declare the >function and not use its name. The fact that you can't write an unnamed >function is not a problem for programmers. Well, it *is* a problem. You have to invent a name. Whether that is a *serious* problem depends on how many of these things there are, and on how inventive the programmers are, but having programs liberally bespattered with f1, f2, f3, ..., f17, ..., f923, ... really isn't very pretty. What's more, in many languages, including C and Pascal, the declarations of f1 and its friends cannot usually be put close to their uses, which means that when you encounter something like z = 2 * sin (theta) * integral (f17, 0, pi) + ... f18, etc, ...; in a program, you're forever scanning around trying to find out what f17, f18, ... mean. If declarations *can* be put close to uses, then we get something like { float f17 (float x) { return blah; }, f18 (...), ...; z = ...; } which is better, but why *not* allow z = 2 * sin (theta) * integral ((float x)(blah), 0, pi) + ...; (or some such)? [A quick flip through some dusty decks reveals many, many such anonymous procedures in my own programming practice, and very convenient they were, too, in a wide variety of applications.] >This is just another example of why syntax is a lot less important than >semantics. That's a matter of semantics! [:-)] Firstly, the line between the two is distinctly blurred. For example, is the restriction that you can't declare the same identifier twice in the same declaration syntactic or semantic? Are the C pointer/array relationships syntax or semantics? One could put forward respectable arguments either way. Secondly, the syntax seriously influences the "software engineering" quality of a language. For example, in C, you have a good chance of getting a procedure and everything you need to know to understand it onto one screen; in Pascal, this is very frequently impossible, both because of the verbosity of Pascal and because of the restrictions on order of declaration; in APL, a screenful of code is likely to be impossible to understand [:-)]. To be effectively used, a language must be both powerful (within its chosen problem domain) and understandable (to the appropriate users). Both syntax and semantics (wherever the line is drawn) are absolutely vital for this. -- Andy Walker, Maths Dept., Nott'm Univ., UK. anw@maths.nott.ac.uk
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (01/05/91)
In article <1991Jan4.152846.15917@maths.nott.ac.uk> anw@maths.nott.ac.uk (Dr A. N. Walker) writes: > In article <18747:Jan220:02:1091@kramden.acf.nyu.edu> > brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: > >Huh? Who cares? To get an unnamed function you just have to declare the > >function and not use its name. The fact that you can't write an unnamed > >function is not a problem for programmers. > Well, it *is* a problem. You have to invent a name. Every coding stylebook I've seen recommends that you give names to everything. It's a very good idea, you know. > but having programs > liberally bespattered with f1, f2, f3, ..., f17, ..., f923, ... really > isn't very pretty. Which is why you choose more meaningful names. Like fxpc, a function that adds c to x. > What's more, in many languages, including C and > Pascal, the declarations of f1 and its friends cannot usually be put > close to their uses, Huh? #define FXPC \ double fxpc(x) double x \ { return x + c; } z = 2 * sin(theta) * integral(fxpc, 0, pi) + ...; Then just dump FXPC at the end of the program, and of course an fxpc declaration in a header file. That looks pretty close to me, and I find it more readable than these ludicrous attempts to put everything on one line. > but why *not* allow > z = 2 * sin (theta) * integral ((float x)(blah), 0, pi) + ...; Who cares? How about because it's a pain to parse, compile, and read? [ syntax versus semantics ] > For > example, is the restriction that you can't declare the same identifier > twice in the same declaration syntactic or semantic? Syntax. It has no effect on semantics. > Are the C > pointer/array relationships syntax or semantics? Depends which one you're talking about. The fact that the evaluation of x[n] is defined as the evaluation of *((x) + (n)) is syntax. > Secondly, the syntax seriously influences the "software > engineering" quality of a language. I agree that syntax is an extremely important part of a language. That's why I'm spending a lot of time on Q's syntax. ---Dan
jwl@garnet.berkeley.edu (James Wilbur Lewis) (01/05/91)
In article <11883:Jan502:21:0191@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
- [ syntax versus semantics ]
-> For
-> example, is the restriction that you can't declare the same identifier
-> twice in the same declaration syntactic or semantic?
-
-Syntax. It has no effect on semantics.
Gee, all the C grammars I've seen allow the same identifier to be declared
any number of times. If you can show me a C declaration grammar that
disallows multiple occurrences of the same identifier, but generates all
valid C declarations, I'll eat my hat!
-- Jim Lewis (computer scientist, and damn proud of it)
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (01/05/91)
In article <1991Jan5.044445.15116@agate.berkeley.edu> jwl@garnet.berkeley.edu (James Wilbur Lewis) writes: > In article <11883:Jan502:21:0191@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: > - [ syntax versus semantics ] > -> For > -> example, is the restriction that you can't declare the same identifier > -> twice in the same declaration syntactic or semantic? > -Syntax. It has no effect on semantics. > Gee, all the C grammars I've seen allow the same identifier to be declared > any number of times. Who said he was referring specifically to C? ---Dan
jwl@garnet.berkeley.edu (James Wilbur Lewis) (01/05/91)
In article <13857:Jan506:12:5891@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: -In article <1991Jan5.044445.15116@agate.berkeley.edu> jwl@garnet.berkeley.edu (James Wilbur Lewis) writes: -> In article <11883:Jan502:21:0191@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: -> - [ syntax versus semantics ] -> -> For -> -> example, is the restriction that you can't declare the same identifier -> -> twice in the same declaration syntactic or semantic? -> -Syntax. It has no effect on semantics. -> Gee, all the C grammars I've seen allow the same identifier to be declared -> any number of times. - -Who said he was referring specifically to C? No one did, although it was a reasonable thing to infer from the context. Perhaps the poster who asked the above question can verify that he was referring to C. It doesn't really matter; my challenge still stands. Choose any language you like, or make one up, subject to the conditions of the original question: that it allows a large number of identifiers to be declared in a single declaration, with the restriction that each identifier may appear at most once in that declaration. I believe that you're wrong to refer to that restriction as "syntactic", and am interested in seeing what kind of grammar you can write that will generate all the valid declarations for that language (and no invalid declarations). Please show *all* your work. :-) -- Jim Lewis
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (01/05/91)
In article <1991Jan5.081755.23488@agate.berkeley.edu> jwl@garnet.berkeley.edu (James Wilbur Lewis) writes: > Choose any language you like, or make one up, subject to the conditions of > the original question: that it allows a large number of identifiers to be > declared in a single declaration, with the restriction that each identifier > may appear at most once in that declaration. I believe that you're wrong to > refer to that restriction as "syntactic", and am interested in seeing what > kind of grammar you can write that will generate all the valid declarations > for that language (and no invalid declarations). One of the failures of the modern computer science curriculum is that it teaches people to think that ``syntax'' refers to a certain type of formal grammar. To answer the (trivial) challenge: Parse each declaration into its multiset of identifiers. If the multiset contains any duplicates, the declaration is illegal. Otherwise it passes this stage of parsing. Done. ---Dan
jwl@garnet.berkeley.edu (James Wilbur Lewis) (01/06/91)
In article <14679:Jan509:13:1391@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: -In article <1991Jan5.081755.23488@agate.berkeley.edu> jwl@garnet.berkeley.edu (James Wilbur Lewis) writes: -> Choose any language you like, or make one up, subject to the conditions of -> the original question: that it allows a large number of identifiers to be -> declared in a single declaration, with the restriction that each identifier -> may appear at most once in that declaration. I believe that you're wrong to -> refer to that restriction as "syntactic", and am interested in seeing what -> kind of grammar you can write that will generate all the valid declarations -> for that language (and no invalid declarations). - -One of the failures of the modern computer science curriculum is that it -teaches people to think that ``syntax'' refers to a certain type of -formal grammar. I didn't restrict you to any particular *type* of grammar! I would accept BNF, yacc input, a regular expression, a recursive transition network, a context-sensitive grammar...but make no mistake, syntax IS about *grammar*, both in linguistics and computer science! To quote from one of my NLP texts: ``Traditional notions of syntax include ideas like "part of speech" and "phrase marker" in discussing the structure of a sentence.'' [Birnbaum and Selfridge, from _Inside Computer Understanding_, p. 331] It is meaningless to talk about parts of speech, phrase markers, or (I claim) any other syntactic issues, without at least implicit reference to a grammar. The construction "int x, y, z, x;" is an invalid C declaration not because it violates C syntax -- it doesn't, for any reasonable grammar -- but simply because C compilers do not assign meaning (semantics!) to a program containing this construct (even though a reasonable interpretation exists). And what are we to make of "int x; float x;"? This is *clearly* a semantic error, sort of a C version of "Colorless green ideas sleep furiously." -To answer the (trivial) challenge: Parse each declaration into its -multiset of identifiers. If the multiset contains any duplicates, the -declaration is illegal. Otherwise it passes this stage of parsing. Done. I asked for a grammar and you gave me a decision procedure. *BZZZZZT*, thank you for playing; your consolation prize is a one-week subscription to sci.lang. :-) -- Jim Lewis
oz@yunexus.yorku.ca (Ozan Yigit) (01/06/91)
In article <14679:Jan509:13:1391@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >One of the failures of the modern computer science curriculum is that it >teaches people to think that ``syntax'' refers to a certain type of >formal grammar. ... and some people are destined to eat the menu instead of the meal. Dan, I am eagerly awaiting your ``fix'' to the past or present computer science curriculum. If you have something important (!) to say, why not just say it, instead of keep implying that you have something important? Here, I'll be nice, and give you something on the topic I happen to have around, just to get you started: Minsky, Computation: Finite and Infinite Machines, pp 226: [1] ... we defined a rule of inference to be an effetive test to decide wheter a string s can be deduced from a set of strings s1,...sn. We required the test to be effective so that we could require the test of a proof to be effective. But we did not really tie things down securely enough, for one might still make a rule of inference depend (in some effective way) upon some understanding of what the strings ``mean''. That is, one might have some rule of inference depend upon a certain ``interpretation'' of the strings as asserting things about some well-understood subject matter; the strings might, for example, be sentences in English. (For example, the strings in chapter 4 - the ``regular espressions'' were understood to represent the ``regular sets'', and our proofs about regular expressions used references to these understood meanings.) To avoid such dangerous questions, we propose to restrict ourselves to rules of inference that concern themselves entirely with the arrangement of symbols within strings -- i.e., to the visible form of the strings as printed on a page -- and we rule out reference to meanings. This will force us, for the present, to direct our attention toward what is often called the domain of ``syntax'' -- questions about how expressions are assembled and analysed -- rather than the domain of ``semantics'' -- questions of the meanings of expressions. [deja vu !!] cheers... oz --- [1] Minsky, Marvin, Computation: Finite and Infinite Machines, Prentice-hall Series in Automatic Computation, Englewood Cliffs, N.J., 1967 --- The king: If there's no meaning Usenet: oz@nexus.yorku.ca in it, that saves a world of trouble ......!uunet!utai!yunexus!oz you know, as we needn't try to find any. Bitnet: oz@[yulibra|yuyetti] Lewis Carroll (Alice in Wonderland) Phonet: +1 416 736-5257x3976
thorinn@diku.dk (Lars Henrik Mathiesen) (01/07/91)
jwl@garnet.berkeley.edu (James Wilbur Lewis) writes: >Choose any language you like, or make one up, subject to the conditions of >the original question: that it allows a large number of identifiers to be >declared in a single declaration, with the restriction that each identifier >may appear at most once in that declaration. I believe that you're wrong to >refer to that restriction as "syntactic", and am interested in seeing what >kind of grammar you can write that will generate all the valid declarations >for that language (and no invalid declarations). Please show *all* your >work. :-) Being a quite unoriginal type of person (or perhaps I'm just lazy) I'll give a reference instead: A. van Wijngarden et al., Revised Report on the Algorithmic Language ALGOL 68, _Acta_Informatica_ 5, 1975; reprinted Springer-Verlag, Berlin and New York, 1976. In ALGOL 68 all context dependencies are described in a two-level (van Wijngarden) grammar; the rest of the formal description consists of some basic definitions and an operational semantics. The semantics does have some restrictions, but violating them just gives undefined runtime behaviour (it's stuff like dereferencing null pointers and dangling pointers). -- Lars Mathiesen, DIKU, U of Copenhagen, Denmark [uunet!]mcsun!diku!thorinn Institute of Datalogy -- we're scientists, not engineers. thorinn@diku.dk
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (01/07/91)
In article <19876@yunexus.YorkU.CA> oz@yunexus.yorku.ca (Ozan Yigit) writes: > ... we defined a rule of inference to be an effetive test to decide > wheter a string s can be deduced from a set of strings s1,...sn. In the article that you're responding to I gave exactly such an effective test. I conclude that the repeated-variable-in-declaration problem is syntactic, by Minsky's definition (which I agree with). Done. ---Dan
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (01/07/91)
In article <1991Jan6.033646.9847@agate.berkeley.edu> jwl@garnet.berkeley.edu (James Wilbur Lewis) writes: > -One of the failures of the modern computer science curriculum is that it > -teaches people to think that ``syntax'' refers to a certain type of > -formal grammar. > I didn't restrict you to any particular *type* of grammar! I would accept > BNF, yacc input, a regular expression, a recursive transition network, > a context-sensitive grammar...but make no mistake, syntax IS about > *grammar*, both in linguistics and computer science! To quote from > one of my NLP texts: See, this is exactly what I'm talking about. > The construction "int x, y, z, x;" is an invalid C declaration not because > it violates C syntax -- it doesn't, for any reasonable grammar -- but > simply because C compilers do not assign meaning (semantics!) to a program > containing this construct (even though a reasonable interpretation exists). By that argument, every syntactic restriction is a semantic restriction, because C compilers won't assign meaning to things that aren't syntactically correct. What does this have to do with standard definitions of ``syntax''? > And what are we to make of "int x; float x;"? This is *clearly* a > semantic error, What does this have to do with the question at hand? > -To answer the (trivial) challenge: Parse each declaration into its > -multiset of identifiers. If the multiset contains any duplicates, the > -declaration is illegal. Otherwise it passes this stage of parsing. Done. > I asked for a grammar and you gave me a decision procedure. *BZZZZZT*, > thank you for playing; your consolation prize is a one-week subscription > to sci.lang. :-) This is an effective parsing procedure independent of semantics, so by Minsky's definitions it has to do with syntax. You have heard of Minsky, I hope? Anyway, syntax does *not* mean any particular type of formal grammar, or even a combination of such types. ---Dan
hilfingr@rama.cs.cornell.edu (Paul N. Hilfinger) (01/07/91)
In article <1991Jan6.033646.9847@agate.berkeley.edu> jwl@garnet.berkeley.edu (James Wilbur Lewis) writes: >In article <14679:Jan509:13:1391@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: ... >-One of the failures of the modern computer science curriculum is that it >-teaches people to think that ``syntax'' refers to a certain type of >-formal grammar. > >I didn't restrict you to any particular *type* of grammar! I would accept >BNF, yacc input, a regular expression, a recursive transition network, >a context-sensitive grammar...but make no mistake, syntax IS about >*grammar*, both in linguistics and computer science! Context-sensitive and type-0 grammars are indeed capable of expressing scope rules (e.g., "identifiers must be declared in an enclosing scope before use", "an identifier may only be declared once") and other static restrictions (such as type restrictions). The Algol 68 grammar, for example, completely describes what we generally call the "static semantics" of that language. Attribute grammars have similar capabilities. As a result, the term "syntax" really is used by some to include static semantic properties. Of course, the extensive use of context-free grammars of languages augmented with semi-formal English text has resulted in the imprecise use of the term "syntax" or "grammar" to refer to "context-free syntax". However, since Mr. Lewis appears not to be committing that particular imprecision, I must disagree with his conclusion. The distinction between "syntax" and "semantics" is fuzzy. Syntax is supposed to be "structure" and semantics is supposed to be "meaning". However, one can explain the incorrectness of an undeclared identifier either by saying "it is nonsense to use an identifier that has no defined meaning"---a semantic explanation---or "an identifier that forms a primary-expression must be textually identical to a preceding direct-declarator immediately within an enclosing translation-unit, or compound-statement"---which makes no reference to the meaning of anything and is structural or syntactic. As an even more concrete example of this fuzziness, consider the description of a language that has only a fixed number of possible identifiers, but requires definition before use. It is possible, in principle, to define the scope rules in this language either in (context-free) BNF or with (context-sensitive) traditional English semantics. Paul Hilfinger
oz@yunexus.yorku.ca (Ozan Yigit) (01/07/91)
In article <50360@cornell.UUCP> hilfingr@cs.cornell.edu (Paul N. Hilfinger) writes: |> ... As a result, the term "syntax" really is used by some |> to include static semantic properties. I think, for the purposes of the current discussion (whatever that was) the terminology must converge at some point, from a study in sublety of meaning [which I sincerely doubt is attributable to any of the posters in the current discussion] to something we can all use to communicate and accomplish whatever we are after. |> The distinction between "syntax" and "semantics" is fuzzy. Syntax is |> supposed to be "structure" and semantics is supposed to be "meaning". Right. Here is what in Stoy[1] has to say in this topic: Syntax deals with the free properties of a language. The sorts of question that arise here are: is X a grammatically correct program? What are the proper subexpressions of the expression E? The semantics of a language attempts to give the language an interpretation, and to supply a meaning, or value, to the expressions, programs etc. in the language. The boundary between sytax and semantics is a bit fuzzy in places. For example, is the question whether the occurence of a name is within the the scope of some definition of that name a matter of syntax or semantics? We could regard it as a (context-sensitive) syntactic question, or we could do as most compilers do, and make it part of the semantics. We should not be worried by the fuzziness, however: the distinction remains obvious, important and useful for the majority of the cases. ... I hope this is good enough to get to some sort of agreement as to what we mean when we say "syntax", and "semantics". oz --- [1] Stoy, Joseph E., Denotational Semantics: The Scott-Strachey Approach to Programming Language Theory, MIT Press, Cambridge, Mass. 1977 --- The king: If there's no meaning Usenet: oz@nexus.yorku.ca in it, that saves a world of trouble ......!uunet!utai!yunexus!oz you know, as we needn't try to find any. Bitnet: oz@[yulibra|yuyetti] Lewis Carroll (Alice in Wonderland) Phonet: +1 416 736-5257x3976
jwl@garnet.berkeley.edu (James Wilbur Lewis) (01/08/91)
In article <23484:Jan619:01:5391@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >In article <19876@yunexus.YorkU.CA> oz@yunexus.yorku.ca (Ozan Yigit) writes: >> ... we defined a rule of inference to be an effetive test to decide >> wheter a string s can be deduced from a set of strings s1,...sn. > >In the article that you're responding to I gave exactly such an >effective test. I conclude that the repeated-variable-in-declaration >problem is syntactic, by Minsky's definition (which I agree with). Done. There's something fishy with this line of reasoning. You seem to think that the existence of an effective procedure to distinguish valid from non-valid strings implies that the property of "validity" is purely syntactic. Now in a sense, this is true because any effective recognition procedure corresponds to some Type 0 grammar. But this, to me, stretches the traditional notion of "syntax" well past the breaking point. Does the existence of a Type 0 grammar for prime numbers imply that primeness is a syntactic property? Or what about an effective procedure for computing the meaning (object code) of a C source file? In principle, we could pair off the C strings with their meanings in some suitable notation and capture the relationship in an unrestricted grammar, and so (by this fishy defininition) render all discussions of "C semantics" meaningless. This is where the fuzziness between syntax and semantics comes from. For a given language, one can either specify it with a relatively simple grammar and allow the possibility of syntactically valid but meaningless strings, or use a more powerful grammar formalism and reduce most questions of validity to purely syntactic issues. To me, this implies that when someone claims "X is a syntactic property of language L", it is a reasonable thing to ask them what grammar they're using. To be honest, I *was* surprised to hear that Algol 68 used a context-sensitive grammar to syntactically enforce its declaration rules. I'm still curious to see what the grammar rules look like -- that challenge of mine wasn't totally facetious, though I'd better retract the part about "eating my hat" if Dan comes up with a grammar having the desired properties. :-) But I'm still not going to be impressed with a non-constructive existence proof for a Type 0 grammar, for the reasons outlined above. We should also be aware of the difference between formal language specification and the practical realities of compiler construction. If feature X is specified by a context-sensitive grammar, but implemented via semantic actions in a parser using a context-free grammar, is X "syntax" or "semantics"? I think any linguist would take a dim view of resorting to the existence of a Type 0 grammar as an argument for some language feature being a syntactic property. According to Chomsky (quoted in Winograd, _Language as a Cognitive Process_): "Reduction of the class of grammars is the major goal of linguistic theory". His characterization of the problem: "The gravest defect of the theory of transformational grammar is its enormous latitude and descriptive power. Virtually anything can be expressed as a phrase-marker...virtually any imaginable rule can be described in transformational terms. Therefore, a critical problem in making transformational grammar a substantive theory with explanatory force is to restrict the category of admissible phrase-markers, admissible transformations, and admissible derivations." These arguments apply just as well to the languages that computer scientists are accustomed to dealing with, so it's not surprising that we tend to think in terms of CFL's when dealing with issues of syntax. Not only is it not a defect in the CS curriculum (most of us, after all, *have* been exposed to the more powerful classes of formal grammars), but as Chomsky argues above, it's good linguistic sense. And *that* is about as close to the horse's mouth as we are going to get in this discussion! -- Jim Lewis
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (01/08/91)
In article <1991Jan7.202423.23420@agate.berkeley.edu> jwl@garnet.berkeley.edu (James Wilbur Lewis) writes: > In article <23484:Jan619:01:5391@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: > >In article <19876@yunexus.YorkU.CA> oz@yunexus.yorku.ca (Ozan Yigit) writes: > >> ... we defined a rule of inference to be an effetive test to decide > >> wheter a string s can be deduced from a set of strings s1,...sn. > >In the article that you're responding to I gave exactly such an > >effective test. I conclude that the repeated-variable-in-declaration > >problem is syntactic, by Minsky's definition (which I agree with). Done. > There's something fishy with this line of reasoning. You seem to think > that the existence of an effective procedure to distinguish valid from > non-valid strings implies that the property of "validity" is purely > syntactic. Well, not really. I think the procedure has to be not only effective in the theoretical sense but also practical. I don't care for a parser that doesn't run at a reasonable speed. In this case, though, recognizing doubled strings is quite practical. > In principle, we could pair > off the C strings with their meanings in some suitable notation and capture the > relationship in an unrestricted grammar, and so (by this fishy defininition) > render all discussions of "C semantics" meaningless. I see what you're saying, but I don't agree. It really is possible to define a language feature in such a way that it cannot be turned into syntax. Let's come down out of the clouds for a moment and consider a real example. Is ``(a % b) + (a / b) * b always equals a,'' for integral a and non-zero integral b, a semantic property or a syntactic property? ``Obviously semantic'' is everyone's first response. But consider the integers from -32768 to 32767. An operation on integers in this range doesn't have to be specified mathematically. It can be specified as just one really big switch statement. Inside that switch statement, numbers lose their meaning as such. ``57'' as a string reflects everything that 57 as a number does, because ``57'' only appears at a finite number of spots inside our big switch statement---our parser---and has properties entirely determined by the fixed symbols near it in the statement. (I'm not explaining this too well, but bear with me.) Now Programmer Dan chimes in. ``Real programmers don't use big, slow, sloppy syntactic switch statements in place of efficient, concise mathematical semantics,'' he says. That's true but it's besides the point. Just because something is an awful mess when expressed syntactically doesn't change the fact that it's syntactic! But there is a problem with our switch statement. *It depends on the integer size.* If the integer size is different, our semantic model of integer operations stays the same. Our syntactic model explodes. *This* is what makes the integer operations semantics and not syntax: no single syntactic definition suffices for arbitrarily large integers. Anyone understand what I'm getting at? Please try to explain it better than I just did. > This is where the fuzziness between syntax and semantics comes from. For > a given language, one can either specify it with a relatively simple > grammar and allow the possibility of syntactically valid but meaningless > strings, or use a more powerful grammar formalism and reduce most questions of > validity to purely syntactic issues. Agreed. I'd say that a feature is semantic if the most powerful *fixed* grammar for the language can't express the feature. ---Dan
anw@maths.nott.ac.uk (Dr A. N. Walker) (01/09/91)
In article <11883:Jan502:21:0191@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >Every coding stylebook I've seen recommends that you give names to >everything. It's a very good idea, you know. Really? Do you write #define ONE 1 #define TWO 2 #define TWENTYFOUR 24 #define SIXTY 60 secs = (((days*TWENTYFOUR + hours)*SIXTY + minutes)*SIXTY + seconds; for (j = ONE; ; j += TWO) ...; /* step through odd integers */ in preference to secs = (((days * 24 + hours) * 60 + minutes) * 60 + seconds; for (j = 1; ; j += 2) ...; ? Somewhere between that and #define BUFSIZE 4096 char buffer[BUFSIZE]; which I hope everyone prefers to char buffer[4096] there is a grey area, in which it's a matter of taste. The vast majority of functions fall one side of the line, but to deny the possibility that a few fall the other [especially when, in some languages, extra expressive power is obtained that way] seems unrealistic. >Which is why you choose more meaningful names. Like fxpc, a function >that adds c to x. I think I'd find "faddc" more expressive; but anyway, it all gets rather messy when the function delivers the absolute value of the difference between the reciprocal third powers of r1 and r2 -- "famr3r1r2"? Ugh! > #define FXPC \ > double fxpc(x) double x \ > { return x + c; } > > z = 2 * sin(theta) * integral(fxpc, 0, pi) + ...; OK, that's quite neat for some simple cases (though I personally don't like multi-line defines). It has a snag: I can imagine some very hard-to-find bugs of the sort { double c = some very messy expression; #define FXPC ... as above ... z = ... integral (fxpc, 0, pi) ... + c + ... lots of uses of c; } where the "c" that occurs in "fxpc" is not the one that occurs elsewhere in the compound statement -- not too obscure if it leads to a compilation error, but tuf if there just happens to be some global with the same name and an appropriate type. >> [anonymous functions] >Who cares? How about because it's a pain to parse, compile, and read? Why is it easier to parse, compile or read a function body when it's tacked on to a declaration than when it occurs elsewhere? Is "7" easier to read in "int i = 7;" than in "j += 7;"? [I'll get back to syntax and to anonymous functions in separate articles, as the threads have diverged somewhat.] -- Andy Walker, Maths Dept., Nott'm Univ., UK. anw@maths.nott.ac.uk
anw@maths.nott.ac.uk (Dr A. N. Walker) (01/09/91)
In article <1991Jan5.081755.23488@agate.berkeley.edu> jwl@garnet.berkeley.edu (James Wilbur Lewis) writes: [I asked ...] >-> -> is the restriction that you can't declare the same identifier >-> -> twice in the same declaration syntactic or semantic? [and Dan Bernstein replied ...] >-> -Syntax. It has no effect on semantics. >Perhaps the poster who asked the above question can verify that he was >referring to C. Not particularly. My point was simply that it's a grey area. When I was learning to program, we were taught [this was in the days when BNF was the greatest thing since sliced bread] that (the moral equivalent of) main () { int i, i; exit (0);} was "syntactically correct" ('cos it was produced by the BNF), but "semantically incorrect" (there was a section labelled "semantics" after each bit of syntax that described what the syntax meant, and what conditions had to be attached). It was "impossible to prevent such programs syntactically" (ie, using BNF). There you are, then; it's semantics. Well, I've loaned out my Algol 68 Report, but the Draft (MR93) refers instead to "context conditions" -- the (moral equivalent of the) above is a "program" but not a "proper program" (one that satisfies conditions such as "No proper program contains a reach containing two defining occurrences of a given identifier"), and even less a "meaningful program" (one whose elaboration is defined by the Report). MR93 makes it clear that whether the distinction between programs and proper programs is syntactic or not is a matter of taste. By the Revised Report, the above text isn't even a "program" -- it can't be generated by the syntax --, and therefore the restriction is clearly syntactic (though in a real compiler, it will be checked by exactly the same piece of code that it always was: "is this identifier already in the current chunk of the symbol table?"). Later work with 2-level grammars (or with attribute grammars, as others have pointed out) makes it clear that even the "meaningful" programs can be described completely by syntax, and there is thus no need for semantics at all. However, you will find no trace of this in most definitions of more recent languages (including C, Modula-N and Pascal); almost universally, there is a syntax that generates improper programs, and a set of statements in natural language about proper and meaningful programs. Even the use of denotational semantics seems to be confined to formalising this natural language; in this model, a language is defined by its semantics, and the syntax is sugar for the reader. Since both extremes are espoused by reasonable people, I deduce that, like so much else, it's a matter of taste. >Choose any language you like, or make one up, subject to the conditions of >the original question: that it allows a large number of identifiers to be >declared in a single declaration, with the restriction that each identifier >may appear at most once in that declaration. As others have pointed out, this is easy with a two-level grammar. For details, see the Revised Report, or [better!] "Grammars of Programming Languages" by Cleaveland and Uzgalis (Elsevier, 1977). -- Andy Walker, Maths Dept., Nott'm Univ., UK. anw@maths.nott.ac.uk
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (01/09/91)
In article <1991Jan8.165344.13870@maths.nott.ac.uk> anw@maths.nott.ac.uk (Dr A. N. Walker) writes: > In article <11883:Jan502:21:0191@kramden.acf.nyu.edu> > brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: > >Every coding stylebook I've seen recommends that you give names to > >everything. It's a very good idea, you know. [ rebuttal ] Sorry. What I meant by ``everything'' was ``every object.'' You want references? How about Ledgard's books? > (though I personally > don't like multi-line defines). Me neither. The C preprocessor sucks. But every language has its share of syntactic problems. > It has a snag: I can imagine some very > hard-to-find bugs of the sort > { double c = some very messy expression; > #define FXPC ... as above ... That isn't a snag: if c is local then you'll pass it to fxpc as well. You can't criticize every language construct just because programs can abuse global variables. (I note that most compilers will warn you about the redefinition of c anyway.) > >> [anonymous functions] > >Who cares? How about because it's a pain to parse, compile, and read? > Why is it easier to parse, compile or read a function body when > it's tacked on to a declaration than when it occurs elsewhere? Because juxtaposition is heavily overloaded, and when you allow function definitions within expressions you start having to assign meanings to (a)(b)(c)(d)(e). ---Dan
gudeman@cs.arizona.edu (David Gudeman) (01/09/91)
In article <1991Jan7.185658.20240@basho.uucp> John Lacey writes: ]brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: ]>Every coding stylebook I've seen recommends that you give names to ]>everything. It's a very good idea, you know. ]... ]Do you really gives names to everything? Every integer constant, ]every string, every character? Or do you let them go nameless? More importantly, do you always give names to intermediate objects? In C you have to give a name to a struct within a function when all you are going to do is return it. For integers you write return i + 1; not res = i + 1; return res; But for structs you have to write res = malloc(sizeof(foo)); res.f1 = x1; res.f2 = x2;...; return res; instead of return res(x1,x2,...); Personally, I think this constitutes an important difference between integers and structs in C. I'm not sure that the term "first class" should be used to make this distinction, though (a few weeks ago I _knew_ that this usage of the term was wrong, but now I'm not so sure). -- David Gudeman gudeman@cs.arizona.edu noao!arizona!gudeman
anw@maths.nott.ac.uk (Dr A. N. Walker) (01/10/91)
In article <14305:Jan800:43:4391@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >[...] It really is possible to >define a language feature in such a way that it cannot be turned into >syntax. > [ example of "a%b + a/b*b = a" expressed as a switch deleted ] > > [...] Our syntactic model explodes. *This* >is what makes the integer operations semantics and not syntax: no single >syntactic definition suffices for arbitrarily large integers. But this depends on what you mean by a syntactic definition. A two-level grammar is perfectly capable of dealing with arbitrarily large integers (and so are other models of syntactic structure). But it starts to look like a programming language -- in other words, at one extreme, a syntax is merely a program that when fed your program as input will halt and either print "OK" or print "KO", and the *real* problem is bootstrapping the syntax program ('cos we would like to write it in a sensible language, and we can't until we know enough of the syntax of the sensible language). At the other extreme, we all agree that syntax is (say) BNF, and then we find, as you say, that some things can't be expressed. > I'd say that a feature is semantic if the most powerful *fixed* >grammar for the language can't express the feature. Explain "fixed". A finite two-level grammar can express all features of C (for example), including all those normally thought of as semantic (such as the undesirability of following null pointers, or indexing off the end of an array). The only reason why this is more interesting than the fact that a finite C program (such as a very careful interpreting load-and-go compiler) can do the same thing is that the two-level grammar *itself* has rather a simple syntax, so that most people would [after some study] agree whether or not a 2LG is syntactically correct, and it is probably rather easy to automate this. (I don't know whether anyone has tried.) To give a flavour of what a 2LG would look like for Dan's problem, we would have an upper level which is very like traditional BNF, thus INT: DIGIT | INT DIGIT DIGIT: zero | one | two | ... On the lower level, the higher level constructs can appear *inside the LHS*, so that a finite collection of rules can represent an unbounded collection of actual rules. For example, we might have things like expression INT1 minus INT2: expression dec INT1 minus dec INT2. expression zero minus INT: negative INT. expression INT minus zero: INT. ANYTHING dec INT one: ANYTHING INT zero. ANYTHING dec INT two: ANYTHING INT one. ANYTHING dec INT zero: ANYTHING borrow dec INT. ANYTHING borrow INT: ANYTHING INT nine. ... In the lower level, occurrences of higher constructs such as INT must be replaced identically on both sides, so, for example, the third rule generates things like "expression one seven minus zero: one seven.", but not "expression zero zero four three minus zero: six nine.". Note that you will also need some clever-ish rules to get rid of leading zeros, and if you want to prevent chasing down blind alleys, you will need predicates on the lines of expression INT1 minus INT2: where positive INT1 and positive INT2, expression dec INT1 minus dec INT2. After a page or three of such rules, we can have every expectation that "expression one seven mod three plus one seven div three times three" will eventually yield "one seven". Full details are left to the reader. [:-)] -- Andy Walker, Maths Dept., Nott'm Univ., UK. anw@maths.nott.ac.uk
karl@ima.isc.com (Karl Heuer) (01/11/91)
In article <1991Jan8.165344.13870@maths.nott.ac.uk> anw@maths.nott.ac.uk (Dr A. N. Walker) writes: >In article <11883:Jan502:21:0191@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >>Every coding stylebook I've seen recommends that you give names to >>everything. It's a very good idea, you know. I'm afraid I can't agree with that statement in its full generality. >Really? Do you write [abridged --kwzh] > #define TWENTYFOUR 24 > #define SIXTY 60 > secs = (((days*TWENTYFOUR + hours)*SIXTY + minutes)*SIXTY + seconds; >in preference to > secs = (((days * 24 + hours) * 60 + minutes) * 60 + seconds; >? On the other hand, I can't agree with this part of the counterexample either. The first version is silly, but there does exist a non-silly version&: #define HOUR_DAY 24 #define MIN_HOUR 60 #define SEC_MIN 60 secs = (((days*HOUR_DAY+hours)*MIN_HOUR+minutes)*SEC_MIN+seconds; Note that the constant "60" deserves *two* names, since it has two independent uses. It's just a historical coincidence that they have the same value. >Somewhere between that and > #define BUFSIZE 4096 > char buffer[BUFSIZE]; >which I hope everyone prefers to > char buffer[4096] No, I would not (necessarily). BUFSIZE is already so horribly overloaded as to be virtually meaningless. ("Why does linbuf[] have BUFSIZE elements?" "Oh, all the arrays do. It's just some number that we hope is big enough to prevent overflow." "Is there any reason why linbuf[] and genbuf[] have to have the same size?" "No.") If it is specific to this one buffer, then there is little reason to prefer #define BUFSIZE 4096 char buffer[BUFSIZE]; read(fd, buffer, BUFSIZE); to char buffer[4096]; read(fd, buffer, sizeof(buffer)); which avoids the need to invent a separate name for the size.$ A good first approximation is to name something iff it gets used more than once. Anonymous functions would be useful for once-only instances such as handing them off to qsort(). qsort((void *)sa, n, sizeof(char *), (int (*)(void const *, void \ const *)){ return strcmp(*(char const **)%0, *(char const **)%1); }); Karl W. Z. Heuer (karl@ima.isc.com or uunet!ima!karl), The Walking Lint ________ & This is not meant to imply that I always use the named form. Since these particular constants are extremely unlikely to change and will probably be understood in context even without being named, I would not object to the unnamed version of the code fragment. $ I'm assuming here that all the references are within the same file.
pcg@cs.aber.ac.uk (Piercarlo Grandi) (01/11/91)
On 8 Jan 91 17:33:02 GMT, anw@maths.nott.ac.uk (Dr A. N. Walker) said: [ ... on whether invalid declarations can be forbidden on purely syntactive grounds, which it cannot be done with a context free grammar ... ] anw> As others have pointed out, this is easy with a two-level grammar. anw> For details, see the Revised Report, or [better!] "Grammars of anw> Programming Languages" by Cleaveland and Uzgalis (Elsevier, 1977). Ah, here you take out the book which is the nuclear weapon of context sensitive grammar debates. I agree with what you say, as far as it goes, but you omit to remind us that that book clearly demonstrates what the *semantics* of a language can easily be formalized with a two level grammar, which throws a spanner in the well oiled structure of this type of debate (Bernstein writes provocative, edgy but sensible things, everybody else stop chewing their sandwich and jumps on him with glee :->). Context sensitive grammar generators (they do exist!) can do pretty impressive things -- just consider that people have been using simple context free grammars to do, in favourable conditions, code generation! Two level or attribute grammars are strange beasts indeed, at least from the usual CS perspective under which grammars stop at context free. End of debate while a lot of people stop jumping on Bernstein and rush to the library (not the bookshop -- out of print for a long time) to get a copy of the book over which to finish munching their sandwich? :-) -- Piercarlo Grandi | ARPA: pcg%uk.ac.aber.cs@nsfnet-relay.ac.uk Dept of CS, UCW Aberystwyth | UUCP: ...!mcsun!ukc!aber-cs!pcg Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk
jeff@aiai.ed.ac.uk (Jeff Dalton) (02/01/91)
In article <28228:Jan902:38:1891@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >I'm still pretty sure that ``first-class'' means what we think it does. >Unfortunately, it appears that the Scheme literature has gone out of its >way to abuse the term, so we can't use the standard definition of >``first-class'' without causing a ruckus. It's always a shame when >useful terms are killed in this way. Actually, it seems that some C fans are going out of their way to abuse the term, because for some reason they can't stand the idea that functions might not be first class in C. Look at some non-Scheme literature such as Stoy's book on denotational semantics, for example.