You can subscribe to this list here.
2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2001 |
Jan
|
Feb
(5) |
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
(127) |
Oct
(37) |
Nov
(4) |
Dec
(1) |
2002 |
Jan
|
Feb
|
Mar
(3) |
Apr
|
May
(2) |
Jun
|
Jul
(16) |
Aug
(4) |
Sep
(6) |
Oct
(2) |
Nov
(1) |
Dec
(3) |
2003 |
Jan
(1) |
Feb
(3) |
Mar
(1) |
Apr
(1) |
May
(2) |
Jun
(3) |
Jul
(2) |
Aug
(3) |
Sep
(3) |
Oct
(5) |
Nov
(16) |
Dec
(28) |
2004 |
Jan
(13) |
Feb
(9) |
Mar
(3) |
Apr
(9) |
May
|
Jun
(10) |
Jul
(2) |
Aug
(3) |
Sep
(3) |
Oct
(4) |
Nov
(6) |
Dec
(7) |
2005 |
Jan
|
Feb
(1) |
Mar
(19) |
Apr
(4) |
May
(5) |
Jun
(6) |
Jul
(5) |
Aug
(3) |
Sep
(7) |
Oct
(24) |
Nov
(7) |
Dec
(4) |
2006 |
Jan
(11) |
Feb
(3) |
Mar
(9) |
Apr
(7) |
May
(31) |
Jun
(25) |
Jul
(13) |
Aug
(9) |
Sep
(9) |
Oct
(23) |
Nov
(35) |
Dec
(13) |
2007 |
Jan
(49) |
Feb
(26) |
Mar
(22) |
Apr
(12) |
May
(24) |
Jun
(34) |
Jul
(42) |
Aug
(75) |
Sep
(52) |
Oct
(35) |
Nov
(41) |
Dec
(36) |
2008 |
Jan
(26) |
Feb
(33) |
Mar
(57) |
Apr
(82) |
May
(97) |
Jun
(78) |
Jul
(79) |
Aug
(61) |
Sep
(54) |
Oct
(32) |
Nov
(49) |
Dec
(48) |
2009 |
Jan
(54) |
Feb
(32) |
Mar
(59) |
Apr
(65) |
May
(149) |
Jun
(131) |
Jul
(80) |
Aug
(40) |
Sep
(26) |
Oct
(63) |
Nov
(12) |
Dec
(21) |
2010 |
Jan
(10) |
Feb
(16) |
Mar
(41) |
Apr
(43) |
May
(53) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2012 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2015 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
From: Stephen W. <sw...@in...> - 2001-09-17 19:00:30
|
> I agree with Bob and others who would rather drop polymorphic > equality. However, you have a point in what you write above, so some > other, more useful mechanism should be added to replace it. (By this > I do not mean type classes.) ... I agree that another mechanism could be introduced that allows efficient implementation of equality. Dropping polymorphic equality without such a replacement is bad. In any case, I remain firmly in the Kennedy/Reppy/Sestoft/Weeks camp (apologies if I've misrepresented somebody) of not spend our time and efforts on making incompatible changes to SML 97 and instead spending it on improvements (like the FFI and compilation management). I agree with Dave Berry that if we focus on getting a portable C FFI and compilation management system, then the libraries are much more likely to follow. Therefore, we should spend our effort there. Designing and specifying a new set of libraries is too much effort. It would be better to let libraries evolve from code that people write. The most significant obstacle to this evolution is the lack of portability between implementations. In addition to language differences and lack of compilation management, another reason for portability problems is the presence of optional modules in the standard basis and the fact that base types can be different sizes (31 vs 32 bit ints and words). |
From: Derek D. <dr...@cs...> - 2001-09-17 18:53:19
|
> After quickly perusing the SML definition, I still don't know what's > a "clausal function definition". Could someone enlighten me ? fun f <pattern1> = ... | f <pattern2> = ... ... | f <patternN> = ... Derek |
From: Daniel C. W. <dc...@ag...> - 2001-09-17 18:47:20
|
At 10:41 AM 9/17/2001 -0700, Stephen Weeks wrote: > > I would eliminate equality polymorphism entirely. > >I have several objections to dropping polymorphic equality. I'm not sure what Bob had in mind... but eliminating eqtypes does not necessarily mean the elimination of polymorphic equality. As OCaml has polymorphic "equality" without equality types. We can simply define a polymorphic "equality" function which treats all values which are not eqtypes in the current framework to behave in some appropriate way i.e. (fn x => x) = (fn x => x) yields false 1.0 = 1.0 yields false here (op =) : 'a * 'a -> bool as opposed to ''a * ''a -> bool Another semantics would be for (op =) to be a partial function i.e. 'a * 'a -> bool option (or it could raise an exception of some sort) Anyway, getting ride of eqtypes does not meaning doing without polymorphic equality. We just need to choose an appropriate runtime semantics for it. The simplest modification that is backward compatible, would be to define a new polymorphic partial equality function. val (op =?) : 'a * 'a -> bool option which returns NONE when comparing values that are not eqtypes under the current SML97 definition. To remain backward compatible we can define (op =) as val (op =) = Option.valOf o (op =?) Any code that type checked under the old semantics will still work, and only broken programs will break. New programs can take advantage of the extra information the =? operator gives them and report an error. Compilers can easily specialize (op =?) when it there's enough type information for it to figure out that =? will always return (SOME b). I'd personally like to avoid type class like features if it all possible. I'd prefer to have an extensible record mechanism by which I can uses to implement dictionary passing when I want type class like features. |
From: Matthias B. <bl...@re...> - 2001-09-17 18:21:43
|
Stephen Weeks wrote: > > > I would eliminate equality polymorphism entirely. > > I have several objections to dropping polymorphic equality. > > * Loss of overloaded = on ints, words, chars, etc. > * Loss of performance. > * Excessive code to write, and decrease in maintainability. > > The first point is obvious, but minor. The next two points are neither obvious > nor minor, so I will explain. Suppose I want to implement equality on the > following datatype. > > datatype t = A | B | C > > If there is no polymorphic equality, I have to write > > val equals: t * t -> bool = > fn (A, A) => true > | (B, B) => true > | (C, C) => true > | _ => false > > On the other hand, with polymorphic equality, I can write > > val equals: t * t -> bool = op = > > For large enumerations (I can think of one in the MLton sources with over 150 > variants), the first approach is a lot of code. It is also error prone, since I > have to remember to add a new case whenever I add a variant. Finally, I don't > think any SML compiler will do the right thing for the first approach, which is > to implement equals as a single integer comparison. I know that for the second, > MLton will use a single comparison, and I hope that other compilers do too. > > Similar arguments apply even when there are non-value carrying variants. I agree with Bob and others who would rather drop polymorphic equality. However, you have a point in what you write above, so some other, more useful mechanism should be added to replace it. (By this I do not mean type classes.) Why do I not want polymorphic equality: Because it rarely does the Right Thing. In fact, I never ever use it in my code. The overloading problem can be fixed as such: by using overloading. Loss of performance only applies to some cases. In real programs I found that custom equality predicates are better. Excessive code -- perhaps that one is true to some extend (which is why we should consider designing an alternative to PE). ------------------------------------------------------------------------- Here is a strawman design, just for fun. Don't take it too serious! What I would like to see is a new syntactic construct that takes a type constructor T of arity n and binds a function name to a comparison function for instantiations of T parameterized by comparison functions for the type arguments of T. To make this concrete, let me invent some syntax for a new kind of expression. There is a new keyword "equality" and a new expression of the form <expr> ::= <tycon> equality For example "int equality" would be an expression of type (int * int -> bool), and Steve's "equals" function could be defined using "val equals = t equality", and hopefully it would be implemented at least as efficient for this type as the PE version. If <tycon> has arity > 0, then the expression takes additional curried arguments which are comparison functions for the respective type parameters. Example: list equality : ('a * 'a -> bool) -> 'a list * 'a list -> bool ((list equality) (t equality)) : t list * t list -> bool So "equality" is a shorthand for writing out what Steve did above. It has the advantage of being brief and automatically exhaustive without having the disadvantage of requiring an entire data structure to be compared under structural equality. For example, I could have a type "symbol = int * string" for which I define equality by hand as fun samesymbol ((stamp, _): symbol, (stamp', _): symbol) = stamp = stamp' which then allows me to define equality of symbol lists as val samesymbols = (list equality) samesymbol The point is that one can "roll ones own" equality test wherever necessary while still being able to incorporate structural equality tests at minimal notational cost where this is appropriate. (For recursive types one might want some form of explicit fixpoint construct to avoid having to do a fully recursive structural equality test for the recursive part of that type. I am not sure what one would want the syntax for this to look like.) ---------------------------------end of strawman------------------------------------- In any case, this is not supposed to be a serious proposal. Instead, I tried to show that there are alternative designs that do not require polymorphic equality and which are as powerful and more flexible. Matthias |
From: Stephen W. <sw...@in...> - 2001-09-17 17:41:28
|
> I would eliminate equality polymorphism entirely. I have several objections to dropping polymorphic equality. * Loss of overloaded = on ints, words, chars, etc. * Loss of performance. * Excessive code to write, and decrease in maintainability. The first point is obvious, but minor. The next two points are neither obvious nor minor, so I will explain. Suppose I want to implement equality on the following datatype. datatype t = A | B | C If there is no polymorphic equality, I have to write val equals: t * t -> bool = fn (A, A) => true | (B, B) => true | (C, C) => true | _ => false On the other hand, with polymorphic equality, I can write val equals: t * t -> bool = op = For large enumerations (I can think of one in the MLton sources with over 150 variants), the first approach is a lot of code. It is also error prone, since I have to remember to add a new case whenever I add a variant. Finally, I don't think any SML compiler will do the right thing for the first approach, which is to implement equals as a single integer comparison. I know that for the second, MLton will use a single comparison, and I hope that other compilers do too. Similar arguments apply even when there are non-value carrying variants. |
From: Stefan M. <monnier+lists.smlnj.users/news/@flint.cs.yale.edu> - 2001-09-17 16:45:07
|
>>>>> "Dave" == Dave Berry <da...@ta...> writes: >> 9. At the level of syntax, I would support fixing the case ambiguity, >> eliminating clausal function definitions entirely, fixing the treatment of >> "and" and "rec" in val bindings, changing the syntax of handlers, and >> probably make a few other surface syntax changes. After quickly perusing the SML definition, I still don't know what's a "clausal function definition". Could someone enlighten me ? Stefan |
From: John H. R. <jh...@re...> - 2001-09-17 14:45:49
|
I think the most important area of focus should be libraries. There is already a lot of good SML library code around (e.g., the SML/NJ Library that Emden Gansner and I maintain, MoSML's libraries, MLRISC, CKit, ...), but it is very hard to support these across multiple platforms. The problem is the lack of a standard way to specify library construction and use. I suggest that a group of interested people develop a proposal for a standard way to package library source code (Matthias Blume would probably be a good person to organize this effort). As far as language changes go, I think that aside from recursive modules, we should stick to fixing up small problems in a compatible way. My list includes: vector expressions and patterns; or-patterns; pattern guards; functional record update; mutable records; and polymorphic recursion. - John |
From: Peter S. <se...@di...> - 2001-09-17 14:38:53
|
I completely agree with Andy Kennedy * that there is a need for a fairly simple, typed functional language, * that SML'97 fits the bill well, * that the syntax of case etc is not what keeps programmers away, and * that it is unclear who would benefit from `evolving' Standard ML in the radical ways proposed. Let me add * that in all probability, lack of interoperability is a serious obstacle to widespread adoption (and SML.NET may fix that), * that Standard ML is better left as it is, and * if you want to develop a different language, call it something else. [Various name proposals left out, upon careful consideration] Peter |
From: Allyn D. <di...@de...> - 2001-09-17 14:31:40
|
Weighing in on some of the practical issues which Andreas mentioned or responded to: > - Making the language safer, ie. removing common sources of > programming errors or encouraging the use of features that > help catching errors early on > (eg. convenient syntax for annotating function types) Yes please on convenient syntax for annotating functions! That has been an exceeding annoyance over the years: the syntax for annotation of function types lacks severely in readability. I would wish for a function type declaration in the core language, separate from the function term -- rather like what is available in Haskell. > - Increasing expressiveness where that proved to be insufficient > (eg. polymorphic recursion) I have not much found the need for polymorphic recursion. But I have found a need for existential types in function declarations. My particular uses for existential types would have been solvable by extensible datatypes. So far I have bitten the bullet and not used the exn hack for providing extensible datatypes. If existential types were available would they serve to eliminate other programmers' uses of the exn hack? (Extensible data types require extra effort for efficient implementation). > - Enabling simpler or more efficient implementation > (eg. wraparound arithmetics) We almost have this in the library for those implementations that have implemented Word32, although we would have to add some signed comparisons to the WORD signature. One thing that I would tolerate in ML would be out-of-order and machine-specific arithmetic exceptions for better efficiency -- but then again I am not a numerical analyst, if there are any such using SML they should be consulted. > Should it be a specific design goal of > the language to support interactive development, or can that safely be left > to each implementation? Given MLton's lack of a read-eval-print loop, we already have a major implementation which uses the older compile-examine-tweak method of development. I do not find the standardization of read-eval-print necessary for the language, but I hope that some compiler will maintain this mode since it provides more rapid turnaround than batch compilation. > How important is ML-style type inference? Necessary for compatibility, but any new features in the language could require explicit type annotations -- which, IMO, should be used wherever possible for documentation even in existing code. > A very fundamental question is > whether to insist on explicit import lists, with specified signatures for > imported modules, or to instead rely on a CM-like dependency inference > mechanism (which works in 99% of the cases, but not all). I have found CM to be a very useful tool in supporting top-down development for projects using separate compilation. Also its ability to perform "smart recompilation" is very useful. I would like to see tighter integration of a CM-like tool with SML to the extent that CM could issue warning messages of the form "you have specified a dependency on structure / signature /file XXX but no such dependency is visible in your code". I would happily see dependency information of some form standardized in the module language so as to be able to move between SML implementations without having to port implementation-specific dependency annotations. ... re syntax: we have to leave the existing unfortunate syntax for unterminated _if_ and _case_ for compatibility. My major request for a syntax extension -- other than separate function type declarations in core -- would be the addition of _where_ so that we don't have to use _and_ when dependencies are unidirectional. This is, once again, a request based on issues of documentation in the code, not on functionality. -- Allyn di...@de... |
From: Robert H. <Rob...@cs...> - 2001-09-17 14:23:39
|
I agree with Matthias's point about shadowing. I am neutral about what an interactive top level "ought" to provide. We could, if we wished, provide for post-hoc re-definition a la Scheme, simply by making it syntactically easy for top-level definitions to be an allocation and initialization of a ref. This is not incompatible with good notions such as lexical scope. Bob -----Original Message----- From: Matthias Blume [mailto:bl...@re...] Sent: Monday, September 17, 2001 10:09 AM To: Dave Berry Cc: Robert Harper; 'Andreas Rossberg'; sml...@li... Subject: Re: [Sml-implementers] Structure sharing and type abbreviations Dave Berry wrote: > > At 15:00 14/09/2001, Robert Harper wrote: > >2. How much should the language be tied to the existence of an interactive > >system? > > The current notion of the top-level is a complete anachronism, and > positively hinders the development of a decent programming environment. It > inherits from Lisp the concept of redefining a function in isolation from > the rest of the current scope, but this is unsuitable for a strongly-typed, > statically-scoped language like ML. I believe that every definition in a > program should have a unique path that can be used to identifiy it, without > having to add any extrinsic information such as the line number within a > file. This would have the corollary that no identifier could be redefined > in the same scope. (Inner or outer scopes could contain other definitions > of the identifier, but they would have different paths). I disagree with this view. If you prohibit redefinitions of names, you get a serious modularity problem: Any program that has a global or local name "foo" can no longer be linked with a library that exports a binding under the name "foo". The ability to redefine (in some way or the other, including perhaps a way of "ending" or "containing" the scope of a formely global definition -- which can be seen as a form of redefinition) is absolutely essential for avoiding this problem. See my thesis and our (Andrew Appel's and my) TOPLAS paper on this. As for the interactive toplevel: I agree with you that having it is pretty useless for anyone outside the theorem-proving community. The "default" implementation should be a batch compiler, an interactive toplevel can easily be provided by an application library. I am currently pushing SML/NJ in this direction (and quite successfully, I think). On the other hand, I do not agree with your assessment that there is something fundamentally flawed about the way the interactive toplevel works in ML. This is precisely because it does _not_ work like the Lisp or Scheme toplevel where a function or variable can be redefined "after the fact". In ML, every definition starts a new scope, so everything stays perfectly consistent. (Of course, to those who are emotionally attached to the Lisp way, this is also one of the main weaknesses of the ML toplevel because it does not allow for "interactive patching" of broken code.) Anyway, I can live with the idea of not having an interactive toplevel. (I haven't been using it for a while anyway -- except for issuing commands such as CM.make...) On the other hand, not being able to redefine (locally or at the (non-interactive) toplevel) a globally bound name is absolutely unacceptable IMO. Matthias |
From: Matthias B. <bl...@re...> - 2001-09-17 14:09:51
|
Dave Berry wrote: > > At 15:00 14/09/2001, Robert Harper wrote: > >2. How much should the language be tied to the existence of an interactive > >system? > > The current notion of the top-level is a complete anachronism, and > positively hinders the development of a decent programming environment. It > inherits from Lisp the concept of redefining a function in isolation from > the rest of the current scope, but this is unsuitable for a strongly-typed, > statically-scoped language like ML. I believe that every definition in a > program should have a unique path that can be used to identifiy it, without > having to add any extrinsic information such as the line number within a > file. This would have the corollary that no identifier could be redefined > in the same scope. (Inner or outer scopes could contain other definitions > of the identifier, but they would have different paths). I disagree with this view. If you prohibit redefinitions of names, you get a serious modularity problem: Any program that has a global or local name "foo" can no longer be linked with a library that exports a binding under the name "foo". The ability to redefine (in some way or the other, including perhaps a way of "ending" or "containing" the scope of a formely global definition -- which can be seen as a form of redefinition) is absolutely essential for avoiding this problem. See my thesis and our (Andrew Appel's and my) TOPLAS paper on this. As for the interactive toplevel: I agree with you that having it is pretty useless for anyone outside the theorem-proving community. The "default" implementation should be a batch compiler, an interactive toplevel can easily be provided by an application library. I am currently pushing SML/NJ in this direction (and quite successfully, I think). On the other hand, I do not agree with your assessment that there is something fundamentally flawed about the way the interactive toplevel works in ML. This is precisely because it does _not_ work like the Lisp or Scheme toplevel where a function or variable can be redefined "after the fact". In ML, every definition starts a new scope, so everything stays perfectly consistent. (Of course, to those who are emotionally attached to the Lisp way, this is also one of the main weaknesses of the ML toplevel because it does not allow for "interactive patching" of broken code.) Anyway, I can live with the idea of not having an interactive toplevel. (I haven't been using it for a while anyway -- except for issuing commands such as CM.make...) On the other hand, not being able to redefine (locally or at the (non-interactive) toplevel) a globally bound name is absolutely unacceptable IMO. Matthias |
From: Andrew K. <ak...@mi...> - 2001-09-17 13:26:28
|
I'm reading the list (co-author of MLj and forthcoming SML.NET) as are Nick Benton and Claudio Russo. I'll be making a response of my own to the suggestions when I've thought about it carefully, but my initial=20 reactions are * Keep it simple. Get rid of dark corners and extend minimally. There's a point in functional-language-space for an expressive but feature-light language and Haskell and Ocaml certainly don't live there. I particularly like the fact that types don't play any part in the semantics (except for minimal surface-level=20 overloading).=20 * At the same time, I worry that breaking away from SML'97 will only serve to confuse and deter potential converts. The user base is small enough already and fixing the syntax of case and handle isn't going to attract hordes of new users. Given the chance, I'd do lots of things differently (in particular, not biasing the syntax against imperative programmers) but I don't think that we want yet another functional language right now.=20 * Who are supposed to be the beneficiaries of the changes? Compiler writers,=20 existing users, potential users, language geeks? - Andrew. > -----Original Message----- > From: Robert Harper [mailto:Rob...@cs...]=20 > Sent: Sunday, September 16, 2001 10:32 PM > To: 'Dave Berry'; Stephen Weeks;=20 > sml...@li... > Subject: RE: [Sml-implementers] extensions to SML >=20 >=20 > These are all good suggestions. Before we proceed any=20 > further, let me raise a point of order. Are all of the=20 > "right" people, ie those with an interest in the development=20 > and implementation of Standard ML, reading this list? >=20 > Bob >=20 > _______________________________________________ > Sml-implementers mailing list Sml...@li... > https://lists.sourceforge.net/lists/listinfo/sml-implementers >=20 |
From: Andreas R. <ros...@ps...> - 2001-09-17 12:54:01
|
Objectives and procedures of language evolution seem to be a very common problem. Looking at how other language camps cope with it might probably give some guidance (in a positive or negative way ;-). IMHO, valid goals for changing/extending the language include: - Fixing obvious quirks (eg. syntactic or semantic ambiguities) - Reducing the complexity of the language by removing obsolete/unused features (eg. abstype) - Making the language safer, ie. removing common sources of programming errors or encouraging the use of features that help catching errors early on (eg. convenient syntax for annotating function types) - Increasing convenience of common programming techniques (eg. laziness) - Increasing expressiveness where that proved to be insufficient (eg. polymorphic recursion) - Extending the range of possible application domains (eg. concurrency) - Removing hurdles for portabiliy (eg. seperate compilation) - Enabling simpler or more efficient implementation (eg. wraparound arithmetics) Backward compatibility is probably the most fundamental problem. In my opinion, incompatible changes cannot always be avoided if you want to have a reasonably clean language in the end. If possible in any way, there should be transition paths for users, however. The standard way of implementing this seems to keep old features as deprecated (raising warnings) for some reasonable amount of time. If that is not enough, implementations can still support an SML'97 switch, preferably in a way that allows interoperability with new code. The steps for a language modification to `become real' could be that some group of people 1. comes up with a design for a particular extension, 2. makes a proof-of-concept implementation in one of the existing compilers, 3. writes a proposal in form of necessary modifications to the Definition, 4. lets the Definition's authors promote the proposal to the status of a `blessed addenda'. Something similar has recently been discussed for Haskell. Ideally, every step should be followed by discussion in a wider forum. Arguably, many of the more obvious extensions (eg. withtype, where structure) have already passed stage 2. The main problem that I understand you are hinting at is that some of the more ambitious extensions no longer fit into the current framework of the Definition and it is unavoidable that at one point the whole Definition and accumulated addendas have to be substituted by a more decent, type-theoretic specification. Since this may be a lot of work that takes a considerable amount of time I think it would be reasonable to adopt simpler and obvious changes in the current framework at first. Redesign of the language specification may also be the right moment to make most incompatible changes. Some specific points: > A very fundamental question is > whether to insist on explicit import lists, with specified signatures for > imported modules, or to instead rely on a CM-like dependency inference > mechanism (which works in 99% of the cases, but not all). There is also room for a middle course, namely requiring the programmer to specify what is imported but no explicit signatures. This has the advantage of making units more readable (explicit binders for all identifiers) and enabling unambiguous dependency analysis while not being overly inconvenient for the programmer. > Should it be a specific design goal of > the language to support interactive development, or can that safely be left > to each implementation? The language semantics should be designed in a way that does not preclude interactive environments, but IMO it is not necessary to specify the details of how such an environment actually could look like. If we assume that all `persistent' and thus potentially interchanged source code is written in the separate compilation model then an interactive environment just needs to be able to import such sources in some way. > How important is ML-style type inference? IMHO, very important. Personally, I would not like to see any major compromises with respect to this - I already strongly dislike the inconvenience of annotations forced by overloading and records. But if there are features that require annotations then the rules for providing these should at least be very intuitive and straight-forward (ie. local type inference or something similar is not an option). > If implementations are allowed to differ on the extent to which they support > type inference (plausible, especially if we admit both interactive and > non-interactive implementations), then what is the official "interchange" > format for programs by which we can be assured that code will be transferred > among implementations? Having corners of `implementation-defined behaviour' - that's how the C world calls it - is IMHO a very bad idea (SML'97 already contains some wrt the context used to resolve overloading or record typing). And it would seriously complicate matters for all sides - users and implementers - if the `interchange format' is not ordinary source code. > Datatype's cannot be made transparent with seriously changing the > language. In particular, contrary to popular opinion, making datatype's > abstract would *preclude* programs that are currently *admitted*. I am aware of that (and marked that point as incompatible). However, I believe changing it would only break a rather small number of programs. Moreover, the problems related to sharing seem likely to disappear if we move to using "where" exclusively. One advantage of transparent datatypes is that they make typed programming in a distributed environment easier - processes do not need to share their type declarations if they are not generative. > Either we should have a fully > worked-out, extensible overloading system (I'm very skeptical) or drop it > entirely (a better idea, IMO). Working with OCaml from time to time, where the latter is the case, I have to say that it sometimes is a nuisance. Taking into account the rich set of numeric types the Standard Basis provides I do not really see how it could be handled without some form of overloading. Removing generic equality would make lack of overloading even more problematic (note that OCaml not only has polymorphic equality but also polymorphic ordering to escape this). > First-class polymorphism raises problems for type inference. A simple solution might be not to introduce arbitrary rank-2 types but to take the same approach as for recursive types and tie first-class polymorphism to datatypes (as suggested by Mark Jones and others and implemented in Haskell systems). This way, any use of first-class polymorphism is marked by the occurance of a corresponding constructor which serves as an implicit type annotation. The only language constructs requiring modifications to their typing rules are constructor application and matches, type inference still works as expected. > At the level of syntax, I would support fixing the case ambiguity, > eliminating clausal function definitions entirely, Wow, please, no! In my average ML code clausal function definitions are probably the single most frequently used construct besides application! OTOH, I would strongly plead for a more accurate specification of their syntax... > fixing the treatment of > "and" and "rec" in val bindings, ...or probably removing all non-recursive uses of "and" altogether. > I would like to add a clean treatment of hierarchical extensible tagging > as a generalization of the current exn type. That would be great. Please also consider enabling programmers to introduce their own extensible types. They could possibly subsume some of the expressiveness of objects. > I would like to revamp datatype's to better harmonize them with modules > and to avoid the annoying problem of repetition of datatype declarations in > signatures and structures. I know how to do this, and have a preliminary > proposal for it, but it is entirely incompatible with the current mechanism > (but perhaps the old one could continue to be supported for a transition > period). The rough idea is to follow the Harper-Stone semantics, by which a > datatype is simply a compiler-implemented structure with a special form of > signature that provides hooks into the pattern compiler. This proposal > would also admit user-implemented datatypes (aka views, or abstract value > constructors), but I am not certain that this is a good idea. That sounds very interesting. Actually, IMO abstract views are one of the features that ML modules are seriously lacking (one thing I forgot on my little list :-). To me they seem absolutely essential to avoid the fundamental abstraction vs. convenience conflicts in designing interfaces. Finally let me ask how the ML2000 effort relates to all of this. May we conclude that you consider it more or less dead by now? Best regards, - Andreas -- Andreas Rossberg, ros...@ps... "Computer games don't affect kids; I mean if Pac Man affected us as kids, we would all be running around in darkened rooms, munching magic pills, and listening to repetitive electronic music." - Kristian Wilson, Nintendo Inc. |
From: Robert H. <Rob...@cs...> - 2001-09-16 21:34:54
|
I tend to agree with much of what Dave says here about the top level, which is why I raise the issue. In many ways the typical SML top level is not even as good as a Scheme top level, eg in not supporting post hoc re-definition of top-level functions. Personally, I think that the importance of top-level development is overrated, and can even be counterproductive, but for those who value that sort of thing, it's clear that what we have is entirely inadequate. I'd like to see the issue separated out, however, from the more fundamental issues of language and library design. Bob -----Original Message----- From: Dave Berry [mailto:da...@ta...] Sent: Sunday, September 16, 2001 10:17 AM To: Robert Harper; 'Andreas Rossberg' Cc: sml...@li... Subject: RE: [Sml-implementers] Structure sharing and type abbreviations At 15:00 14/09/2001, Robert Harper wrote: >2. How much should the language be tied to the existence of an interactive >system? The current notion of the top-level is a complete anachronism, and positively hinders the development of a decent programming environment. It inherits from Lisp the concept of redefining a function in isolation from the rest of the current scope, but this is unsuitable for a strongly-typed, statically-scoped language like ML. I believe that every definition in a program should have a unique path that can be used to identifiy it, without having to add any extrinsic information such as the line number within a file. This would have the corollary that no identifier could be redefined in the same scope. (Inner or outer scopes could contain other definitions of the identifier, but they would have different paths). Implementations could still provide an interactive development mode, but they would require a different design from the naive approaches currently used. >3. Backward compatibility is an important issue, but should it be allowed to >ossify the language? ... Should there be >a break with the past to clean up and move forward, or should we limit >attention to only compatible changes? Users really do value stability (see e.g. http://www.dcs.ed.ac.uk/home/pxs/sfpw.ps). Incompatible changes should come in rare, large bursts -- e.g. you could define minor compatible changes to clean up SML'97, followed by an SML'02 with more far-reaching changes. >2. Datatype's cannot be made transparent with seriously changing the >language. By transparent, do you mean that the representation of a datatype should be deducible from any type that it matches? Or. to use another example, that this snippet shouldn't elaborate: struct datatype 'a foo = Foo of 'a * 'a type t = 'a * 'a sig type t datatype 'a foo = Foo of t end Isn't this what O'Caml implements? If so, how do they avoid the problems you encountered? I'm interested to read that you've changed your mind about this. Have you written up your experiences in more detail? >7. First-class polymorphism raises problems for type inference. There are >some limited uses for it, in particular for existentials, but the cost seems >very high. Isn't it fairly easy to allow it if and only if the type of the function is explicitly specified? >9. At the level of syntax, I would support fixing the case ambiguity, >eliminating clausal function definitions entirely, fixing the treatment of >"and" and "rec" in val bindings, changing the syntax of handlers, and >probably make a few other surface syntax changes. I'd support making identifiers case-insensitive, simplifying clausal function definitions to make them reasonable to parse (IIRC it suffices to always require parentheses when defining infix operators), dropping the optional type qualification in "x:ty as ...", and making all structures, functors and signatures share the same name space. Actually, I'd like a completely redesigned syntax that is more familiar to mainstream programmers. >Having said all this, let me mention the most difficult, over-arching >problem: what is the means by which these (or other) modifications would be >specified and implemented in a practical compiler? How would these ideas >(or others that we may agree upon) be made "real"? Those are two questions: specification and implementation. For specification, a web site seems the best bet. I don't know whether it's possible to get the copyright of the definition back from MIT, but it would be useful to have either that or an equivalent specification on the web. Then updates could be announced and tracked easily. Regarding implementation, there are many (possibly too many) SML compilers, but perhaps if we have a common interchange format for libraries, it would be easier to share at least the front-end of a compiler. >Finally, let us not forget that the mere existence of a rich collection of >libraries is at least as important as fixing the last 10% of oddities in the >language, or eking out another 2% performance on certain specified >benchmarks. In my experience there is far more than 2% of performance to be eked out, unless you've got cross-module optimisations working at last. And libraries can drive the requirements for language changes -- e.g. Okasaki's work (among others). In fact, maybe that's the best way to drive language requirements. Dave. |
From: Robert H. <Rob...@cs...> - 2001-09-16 21:31:58
|
These are all good suggestions. Before we proceed any further, let me raise a point of order. Are all of the "right" people, ie those with an interest in the development and implementation of Standard ML, reading this list? Bob |
From: Derek R. D. <dr...@cs...> - 2001-09-16 16:47:49
|
Dave Berry wrote: > > >2. Datatype's cannot be made transparent with seriously changing the > >language. > > By transparent, do you mean that the representation of a datatype should be > deducible from any type that it matches? Or. to use another example, that > this snippet shouldn't elaborate: > struct > datatype 'a foo = Foo of 'a * 'a > type t = 'a * 'a > sig > type t > datatype 'a foo = Foo of t > end To clarify: the transparent interpretation of datatypes is one in which datatype specifications expose the implementation of a datatype as a recursive sum type. In the opaque interpretation (i.e. the Definition), the recursive sum type is never exposed. The motivation for the transparent interpretation is that, in a type-directed compiler, it is difficult to inline datatype constructors and destructors if the implementation of the datatype is not exposed. In addition, it would seem that the transparent interpretation allows more type equations to hold, so it would appear to be more permissive than the Definition. But in fact, there are cases where the transparent interpretation is not as permissive as the Definition. For instance, if you take what I think your example above is supposed to be, and you change the definition of type 'a t to type 'a t = 'a * 'a foo then the structure matches the signature under the opaque interpretation (i.e. the Definition), but not under the transparent interpretation. As it stands, your example appears to be fine under both the transparent and opaque interpretations of datatypes. An analysis of the "permissiveness gap" is given in a TR by Crary et al. from 1998, available at the following URL: http://www.cs.cmu.edu/~crary/papers/1998/datatype/datatype.ps.gz > Isn't this what O'Caml implements? If so, how do they avoid the problems > you encountered? I'm interested to read that you've changed your mind about > this. Have you written up your experiences in more detail? I'm pretty sure O'Caml also has an opaque interpretation of datatypes. As I said, the problems with implementing the opaque interpretation efficiently come up in the type-directed setting, not in ordinary compilation. We have a new way of dealing with the opaque interpretation in TILT that clears up these problems. We are in the process of writing up a new TR with more compelling examples of the "permissiveness gap" between the opaque and transparent interpretations and with a description of our approach to implementing the opaque interpretation in a type-directed compiler. Stay tuned. Derek |
From: Dave B. <da...@ta...> - 2001-09-16 14:41:32
|
At 15:00 14/09/2001, Robert Harper wrote: >2. How much should the language be tied to the existence of an interactive >system? The current notion of the top-level is a complete anachronism, and positively hinders the development of a decent programming environment. It inherits from Lisp the concept of redefining a function in isolation from the rest of the current scope, but this is unsuitable for a strongly-typed, statically-scoped language like ML. I believe that every definition in a program should have a unique path that can be used to identifiy it, without having to add any extrinsic information such as the line number within a file. This would have the corollary that no identifier could be redefined in the same scope. (Inner or outer scopes could contain other definitions of the identifier, but they would have different paths). Implementations could still provide an interactive development mode, but they would require a different design from the naive approaches currently used. >3. Backward compatibility is an important issue, but should it be allowed to >ossify the language? ... Should there be >a break with the past to clean up and move forward, or should we limit >attention to only compatible changes? Users really do value stability (see e.g. http://www.dcs.ed.ac.uk/home/pxs/sfpw.ps). Incompatible changes should come in rare, large bursts -- e.g. you could define minor compatible changes to clean up SML'97, followed by an SML'02 with more far-reaching changes. >2. Datatype's cannot be made transparent with seriously changing the >language. By transparent, do you mean that the representation of a datatype should be deducible from any type that it matches? Or. to use another example, that this snippet shouldn't elaborate: struct datatype 'a foo = Foo of 'a * 'a type t = 'a * 'a sig type t datatype 'a foo = Foo of t end Isn't this what O'Caml implements? If so, how do they avoid the problems you encountered? I'm interested to read that you've changed your mind about this. Have you written up your experiences in more detail? >7. First-class polymorphism raises problems for type inference. There are >some limited uses for it, in particular for existentials, but the cost seems >very high. Isn't it fairly easy to allow it if and only if the type of the function is explicitly specified? >9. At the level of syntax, I would support fixing the case ambiguity, >eliminating clausal function definitions entirely, fixing the treatment of >"and" and "rec" in val bindings, changing the syntax of handlers, and >probably make a few other surface syntax changes. I'd support making identifiers case-insensitive, simplifying clausal function definitions to make them reasonable to parse (IIRC it suffices to always require parentheses when defining infix operators), dropping the optional type qualification in "x:ty as ...", and making all structures, functors and signatures share the same name space. Actually, I'd like a completely redesigned syntax that is more familiar to mainstream programmers. >Having said all this, let me mention the most difficult, over-arching >problem: what is the means by which these (or other) modifications would be >specified and implemented in a practical compiler? How would these ideas >(or others that we may agree upon) be made "real"? Those are two questions: specification and implementation. For specification, a web site seems the best bet. I don't know whether it's possible to get the copyright of the definition back from MIT, but it would be useful to have either that or an equivalent specification on the web. Then updates could be announced and tracked easily. Regarding implementation, there are many (possibly too many) SML compilers, but perhaps if we have a common interchange format for libraries, it would be easier to share at least the front-end of a compiler. >Finally, let us not forget that the mere existence of a rich collection of >libraries is at least as important as fixing the last 10% of oddities in the >language, or eking out another 2% performance on certain specified >benchmarks. In my experience there is far more than 2% of performance to be eked out, unless you've got cross-module optimisations working at last. And libraries can drive the requirements for language changes -- e.g. Okasaki's work (among others). In fact, maybe that's the best way to drive language requirements. Dave. |
From: Dave B. <da...@ta...> - 2001-09-16 14:41:31
|
At 16:03 14/09/2001, Stephen Weeks wrote: >Here is my list of extensions to standardize, in decreasing order of >importance. > >* decent library >* compilation management >* FFI >... > >I rate the importance of a library at least an order of magnitude above >the rest. If you have a standard interface to C and a standard for compilation management, then it becomes much easier to write libraries. Any SML programmer will be able to write libraries that run on any SML compiler. That seems a "base level" that everyone on this list should aim for. I suggest an IDL interface for the C FLI. People should not have to write any C themselves. I know SML/NJ were working on this, as were the MLWorks team. For compilation management, the simpler (for the programmer) the better. The simplest I can think of is: * A list of files, in order of compilation * A specification of the exported features * A list of dependent libraries (i.e. other groups). More advanced systems could add tools for generating this list and for avoiding unnecessary recompilation, but the simple list could be the common interchange format. (Ideally the export specification would be a signature, but that would require supporting functors and signatures as members of signatures). Dave. |
From: Robert H. <Rob...@cs...> - 2001-09-15 20:40:00
|
I would eliminate equality polymorphism entirely. Bob -----Original Message----- From: Stephen Weeks [mailto:sw...@in...] Sent: Friday, September 14, 2001 7:03 PM To: sml...@li... Subject: [Sml-implementers] extensions to SML Sorry for changing the thread name. Here's my 2 cents. One way find out what SML needs is to look at what extensions current implementations make, which were presumably added because of a need. In doing so, one can get some feel for the importance of standardizing an extension by looking at how many implementations have some variant of it. Using this metric, here is my list of extensions to standardize, in decreasing order of importance. (I am mostly familiar with MLton and SML/NJ, but have dabbled with the ML Kit, Moscow ML, and Poly/ML. So, this list is somewhat biased.) * decent library * compilation management * FFI * higher-order functors * other tweaks to the type system I rate the importance of a library at least an order of magnitude above the rest. I rate higher-order functors and other type system tweaks another order of magnitude down. For compilation management, I would like to see explicit dependency information, as well some support for managing the module level namespace (a la CM). If people want to build tools that generate the dependencies, fine. I'm not sure what to argue for in an FFI, since that seems to be an area of active research, but it sure would be nice to standardize something, if even a simple subset. As to some of the specific tweaks mentioned by others, my feelings are to reject any incompatible change, unless it is wrong in the current definition, or excessively complicates the definition and is unused. Here are a few specifics. * dropping local I strongly argue against dropping local. It is not complex or problematic, and dropping it will break old code. For example, there are over 300 uses in MLton. * dropping eqtypes I don't strongly object to this. But I am very wary of any incompatible change. Also, I wanted to make sure that people weren't also thinking about dropping polymorphic equality, which is essential in some cases. * dropping overloading Overloading as it stands is not hard to reason about and is useful. And dropping will break a lot of programs in a lot of places. * dropping sharing I would find dropping sharing devastating, unless it could be simulated with "where", without much syntactic change. To repeat my main point -- I don't think any of the type system changes or language extensions mentioned in earlier emails are fixing the main problems with SML, which are: the lack of a decent standard library, the lack of standard FFI support, and the lack of a standard way of managing large programs. _______________________________________________ Sml-implementers mailing list Sml...@li... https://lists.sourceforge.net/lists/listinfo/sml-implementers |
From: Stephen W. <sw...@in...> - 2001-09-14 23:03:35
|
Sorry for changing the thread name. Here's my 2 cents. One way find out what SML needs is to look at what extensions current implementations make, which were presumably added because of a need. In doing so, one can get some feel for the importance of standardizing an extension by looking at how many implementations have some variant of it. Using this metric, here is my list of extensions to standardize, in decreasing order of importance. (I am mostly familiar with MLton and SML/NJ, but have dabbled with the ML Kit, Moscow ML, and Poly/ML. So, this list is somewhat biased.) * decent library * compilation management * FFI * higher-order functors * other tweaks to the type system I rate the importance of a library at least an order of magnitude above the rest. I rate higher-order functors and other type system tweaks another order of magnitude down. For compilation management, I would like to see explicit dependency information, as well some support for managing the module level namespace (a la CM). If people want to build tools that generate the dependencies, fine. I'm not sure what to argue for in an FFI, since that seems to be an area of active research, but it sure would be nice to standardize something, if even a simple subset. As to some of the specific tweaks mentioned by others, my feelings are to reject any incompatible change, unless it is wrong in the current definition, or excessively complicates the definition and is unused. Here are a few specifics. * dropping local I strongly argue against dropping local. It is not complex or problematic, and dropping it will break old code. For example, there are over 300 uses in MLton. * dropping eqtypes I don't strongly object to this. But I am very wary of any incompatible change. Also, I wanted to make sure that people weren't also thinking about dropping polymorphic equality, which is essential in some cases. * dropping overloading Overloading as it stands is not hard to reason about and is useful. And dropping will break a lot of programs in a lot of places. * dropping sharing I would find dropping sharing devastating, unless it could be simulated with "where", without much syntactic change. To repeat my main point -- I don't think any of the type system changes or language extensions mentioned in earlier emails are fixing the main problems with SML, which are: the lack of a decent standard library, the lack of standard FFI support, and the lack of a standard way of managing large programs. |
From: Robert H. <Rob...@cs...> - 2001-09-14 19:05:56
|
Personally, I'd much, much rather have "where type" (and "where structure", with a per-type interpretation), than any form of "sharing". I'd happily live without "sharing" entirely, as long as I have type definitions in specifications and "where type" to create these. I use these mechanisms entirely independently of modules, especially when I'm trying hard to impose good abstraction boundaries between modules. You don't need them very much if you never use abstraction, and never use separate compilation (as distinct from CM-like recompilation). They do arise whenever you use functors or enforced abstraction. The ordering issues were raised, to some extent, in Derek's note. The issue is the scopes of type declarations. Some very liberal forms of sharing specification or where type specification can lead to "scope convolutions", by which I mean that the "semantic signature" you get after elaboration cannot be written down in the external language without very seriously re-structuring the entire module hierarchy. This is evil and pointless, and should be avoided if at all possible. The whole point about scoping (in any form) is to avoid Fortran-like "global pools" of the kind you suggest. Bob -----Original Message----- From: Matthias Blume [mailto:bl...@re...] Sent: Friday, September 14, 2001 11:15 AM To: Robert Harper Cc: 'Andreas Rossberg'; sml...@li... Subject: Re: [Sml-implementers] Structure sharing and type abbreviations Robert Harper wrote: > > More generally, I would like to open discussion about more extensive changes > and extensions to Standard ML. What do the readers on this list think > should be done next in the evolution of the language? > > Bob Harper Not being a type theorist by any stretch of imagination, I am not sure whether there will be fundamental problems with the following. But in my (and I should say "our") recent practical experiences with the ML module system, the notion of "where type" and its ramifications ("rigid types", no sharing specs allowed for them, etc.) seem arbitrary and turn out to be extremely bothersome in practice. Having "where structure" (which turns into a whole-sale set of "where type" specs) around compounds this problem. Both Lal and I independently ran into this recently when trying to restructure significant pieces of ML code. My current resolve is basically to stay away from functors as much as possible, and to use only "sharing" specs unless I absolutely cannot avoid a "where type". So here is my question: Why can't "where type" in any disguise (type abbreviations in signatures, "where structure") and sharing specs all work the same way and be used in any order. Intuitively, one would expect every "where type" and every "sharing type" to throw another constraint into a global pool of type equality constraints where they get propagated as one would expect. What is the rationale for the current non-symmetric design? Is it easier to specify? Is it easier to implement in a compiler? Or does what I am asking for not make sense at a more fundamental level? Matthias |
From: Robert H. <Rob...@cs...> - 2001-09-14 19:01:15
|
Some high-level comments: 1. I completely agree on the need for a well-defined (ie, standard, agreed-upon) separate compilation mechanism. A very fundamental question is whether to insist on explicit import lists, with specified signatures for imported modules, or to instead rely on a CM-like dependency inference mechanism (which works in 99% of the cases, but not all). It's easiest, as a matter of specifying the language, to do the former, but it is much simpler for the programmer to have the latter. 2. How much should the language be tied to the existence of an interactive system? CM as it is currently implemented assumes an interactive system, eg to set parameters. But not all compilers are interactive, which creates a serious problem for compatibility. Remember that LCF-like theorem provers use ML as their "command language". Should it be a specific design goal of the language to support interactive development, or can that safely be left to each implementation? 3. Backward compatibility is an important issue, but should it be allowed to ossify the language? There are several significant changes that have been proposed over the years that would not be backward compatible, but would (it can be argued) improve the language in important respects. Should there be a break with the past to clean up and move forward, or should we limit attention to only compatible changes? 4. In making extensions or revisions what problems are we trying to solve? We all have our favorite things to hate about Standard ML (both syntactic and semantic), but how many of these things really matter in the sense of inhibiting code development or inhibiting evolution of the language? If we evolve the language, in what direction? 5. How important is ML-style type inference? At what point would it be the case that it's not ML any more? Suppose the types of all lambda-abstracted variables must be explicitly specified? Would that be just too awful to contemplate? Here the issues with interactive systems come up again, since the need for "full" type inference is much stronger in the interactive case than (IMO, at least) for larger programs written out "by hand". If implementations are allowed to differ on the extent to which they support type inference (plausible, especially if we admit both interactive and non-interactive implementations), then what is the official "interchange" format for programs by which we can be assured that code will be transferred among implementations? Some more specific comments on your suggestions: 1. Regarding withtype, should this signature sig datatype t = A type u = t * t end match the signature sig datatype t = A withtype u = t * t end ? I would say "yes". Vice versa? There are other examples of a similar nature. I ask this as a conceptual matter; answering in terms of the crude hack by which withtype is currently treated in The Definition doesn't help. 2. Datatype's cannot be made transparent with seriously changing the language. In particular, contrary to popular opinion, making datatype's abstract would *preclude* programs that are currently *admitted*. The interactions with type sharing are also very problematic. In fact, we implemented datatype's transparently in TILT, but realized that this was a bad idea, and have since backed out of it. This required introducing some new internal mechanisms to make the implementation bearably efficient (and to avoid the difficulties associated with Shao's equation). I am opposed to making datatype's be transparent. 3. We now have a type theory that supports both applicative and generative higher-order functors in a single, uniform framework; see my web page for a draft paper on the topic. I would therefore expect future versions of the language to support "true" higher-order modules with both applicative and generative functors. It would also be useful to have both applicative and generative abstraction mechanisms, with datatype's being applicative, rather than generative. Having said that, my belief is that higher-order modules remain an esoteric feature of little practice importance. Indeed, in the presence of a good separate compilation mechanism, the need for even first-order functors is significantly reduced, as has often been observed. 4. I have no objection to dropping abstype; I don't see any particular reason to drop local (or, for that matter, to retain it). 5. First-class modules seriously disrupt the type theory of modularity, and buy you almost nothing but trouble. You can, however, have modules as first-class values, with no difficulties. (These are different concepts; see the aforementioned paper.) 6. Equality types are stupid and should have been dropped ages ago. Ditto all other half-assed forms of overloading. Either we should have a fully worked-out, extensible overloading system (I'm very skeptical) or drop it entirely (a better idea, IMO). 7. First-class polymorphism raises problems for type inference. There are some limited uses for it, in particular for existentials, but the cost seems very high. I've often wished that records could have polymorphic fields (eg, we ran into this with the foxnet signatures), but providing them seems tantamount to admitting first-class polymorphism. AFAIK this is a significant breaking point in the complexity of the language, at least as far as type inference is concerned. 8. Support for laziness is well-understood. IMO it should be completely segregated from datatype's, and provided as a separate language mechanism. This was Okasaki's original proposal; IMO Wadler's variant does not work well in practice, and only confuses issues that are entirely separable. Not very ML-like, it seems to me. Specifically, we need syntax for defining a *possibly recursive* suspended computation, and syntax that supports "forcing" suspensions as part of pattern matching. 9. At the level of syntax, I would support fixing the case ambiguity, eliminating clausal function definitions entirely, fixing the treatment of "and" and "rec" in val bindings, changing the syntax of handlers, and probably make a few other surface syntax changes. 10. I would like to add a clean treatment of hierarchical extensible tagging as a generalization of the current exn type. This would improve our exception-handling mechanism, and support dynamic dispatch for those limited cases where it is useful. I would not support a class mechanism of the kind previously considered as an extension to ML (but I may be in the minority on this). 11. I would like to revamp datatype's to better harmonize them with modules and to avoid the annoying problem of repetition of datatype declarations in signatures and structures. I know how to do this, and have a preliminary proposal for it, but it is entirely incompatible with the current mechanism (but perhaps the old one could continue to be supported for a transition period). The rough idea is to follow the Harper-Stone semantics, by which a datatype is simply a compiler-implemented structure with a special form of signature that provides hooks into the pattern compiler. This proposal would also admit user-implemented datatypes (aka views, or abstract value constructors), but I am not certain that this is a good idea. Having said all this, let me mention the most difficult, over-arching problem: what is the means by which these (or other) modifications would be specified and implemented in a practical compiler? How would these ideas (or others that we may agree upon) be made "real"? Finally, let us not forget that the mere existence of a rich collection of libraries is at least as important as fixing the last 10% of oddities in the language, or eking out another 2% performance on certain specified benchmarks. Bob -----Original Message----- From: Andreas Rossberg [mailto:ros...@ps...] Sent: Friday, September 14, 2001 1:21 PM To: Robert Harper Cc: sml...@li... Subject: Re: [Sml-implementers] Structure sharing and type abbreviations Robert Harper wrote: > > Adding "withtype" to signatures seems entirely reasonable as > well, provided that we can agree on the semantics of signature matching in > their presence. Now I'm puzzled, could you point out what exactly the dark corners are? AFAICS, since it is merely a derived form with obvious rewriting rules (as for the core), adding it should have no effect on matching semantics (the way they are implemented in the Definition, at least). > More generally, I would like to open discussion about more extensive changes > and extensions to Standard ML. What do the readers on this list think > should be done next in the evolution of the language? You asked for it :-) IMHO, the most important issues are fixing the well-known quirks and incorperating the various well-understood extensions to the module system. Second come extensions to the core type system, ie. more powerful notions of polymorphism. Third I would put all the anticipated future extensions of modules. But above all and probably most pressing: - agree on a model for separate compilation Here is the somewhat exhaustive version of my personal wish list. Items marked with * are incompatible changes I assume, the others are more or less extensions. Obviously worth adopting and understood well enough to try finalizing a design: - fix some syntactic annoyances (case, handle, constructor status, etc.) * and ambiguities - drop abstype and local * - transparent datatypes (*) - "where" for structures, and definitional structure specs (dropping sharing *) - withtype in signatures - higher-order modules, including some form of applicative functors - parameterized signatures (having modules as arguments - important IMO if you take higher-order functors seriously) Not so clear yet how, but also worth having at some point: - dropping eqtype * - polymorphic recursion - first-class polymorphism (probably also existential types, most promising seems incorporating both kinds of quantification into datatypes) - polymorphic records - recursive modules Interesting but probably not worth the trouble: - local modules (ie. giving up the core/module stratification) - first-class modules - polymorphic variants (a la OCaml but with less ambitious typing and better integration with ordinary datatypes) - alternative patterns and pattern guards - promoting signatures to first-class citizens of the module language, ie. nested and abstract signatures (I know this leads to an undecidable type system and a no longer strongly normalizing module language but it may still be worthwhile) Regarding standard library support I believe it is important to have: - some support for laziness - concurrency - obligatory support for infinite precision integers - the most common collection types (sets, maps, hashtables) What I personally prefer not to have at all (looking at the ML2000 paper): - objects and classes - any form of subsumption in the core language - requiring explicit type annotations to achieve basic polymorphism - abolishing infix decs (although I could live with OCaml's approach) Best regards, - Andreas -- Andreas Rossberg, ros...@ps... "Computer games don't affect kids; I mean if Pac Man affected us as kids, we would all be running around in darkened rooms, munching magic pills, and listening to repetitive electronic music." - Kristian Wilson, Nintendo Inc. |
From: Andreas R. <ros...@ps...> - 2001-09-14 17:22:39
|
Robert Harper wrote: > > Adding "withtype" to signatures seems entirely reasonable as > well, provided that we can agree on the semantics of signature matching in > their presence. Now I'm puzzled, could you point out what exactly the dark corners are? AFAICS, since it is merely a derived form with obvious rewriting rules (as for the core), adding it should have no effect on matching semantics (the way they are implemented in the Definition, at least). > More generally, I would like to open discussion about more extensive changes > and extensions to Standard ML. What do the readers on this list think > should be done next in the evolution of the language? You asked for it :-) IMHO, the most important issues are fixing the well-known quirks and incorperating the various well-understood extensions to the module system. Second come extensions to the core type system, ie. more powerful notions of polymorphism. Third I would put all the anticipated future extensions of modules. But above all and probably most pressing: - agree on a model for separate compilation Here is the somewhat exhaustive version of my personal wish list. Items marked with * are incompatible changes I assume, the others are more or less extensions. Obviously worth adopting and understood well enough to try finalizing a design: - fix some syntactic annoyances (case, handle, constructor status, etc.) * and ambiguities - drop abstype and local * - transparent datatypes (*) - "where" for structures, and definitional structure specs (dropping sharing *) - withtype in signatures - higher-order modules, including some form of applicative functors - parameterized signatures (having modules as arguments - important IMO if you take higher-order functors seriously) Not so clear yet how, but also worth having at some point: - dropping eqtype * - polymorphic recursion - first-class polymorphism (probably also existential types, most promising seems incorporating both kinds of quantification into datatypes) - polymorphic records - recursive modules Interesting but probably not worth the trouble: - local modules (ie. giving up the core/module stratification) - first-class modules - polymorphic variants (a la OCaml but with less ambitious typing and better integration with ordinary datatypes) - alternative patterns and pattern guards - promoting signatures to first-class citizens of the module language, ie. nested and abstract signatures (I know this leads to an undecidable type system and a no longer strongly normalizing module language but it may still be worthwhile) Regarding standard library support I believe it is important to have: - some support for laziness - concurrency - obligatory support for infinite precision integers - the most common collection types (sets, maps, hashtables) What I personally prefer not to have at all (looking at the ML2000 paper): - objects and classes - any form of subsumption in the core language - requiring explicit type annotations to achieve basic polymorphism - abolishing infix decs (although I could live with OCaml's approach) Best regards, - Andreas -- Andreas Rossberg, ros...@ps... "Computer games don't affect kids; I mean if Pac Man affected us as kids, we would all be running around in darkened rooms, munching magic pills, and listening to repetitive electronic music." - Kristian Wilson, Nintendo Inc. |
From: Matthias B. <bl...@re...> - 2001-09-14 15:15:42
|
Robert Harper wrote: > > More generally, I would like to open discussion about more extensive changes > and extensions to Standard ML. What do the readers on this list think > should be done next in the evolution of the language? > > Bob Harper Not being a type theorist by any stretch of imagination, I am not sure whether there will be fundamental problems with the following. But in my (and I should say "our") recent practical experiences with the ML module system, the notion of "where type" and its ramifications ("rigid types", no sharing specs allowed for them, etc.) seem arbitrary and turn out to be extremely bothersome in practice. Having "where structure" (which turns into a whole-sale set of "where type" specs) around compounds this problem. Both Lal and I independently ran into this recently when trying to restructure significant pieces of ML code. My current resolve is basically to stay away from functors as much as possible, and to use only "sharing" specs unless I absolutely cannot avoid a "where type". So here is my question: Why can't "where type" in any disguise (type abbreviations in signatures, "where structure") and sharing specs all work the same way and be used in any order. Intuitively, one would expect every "where type" and every "sharing type" to throw another constraint into a global pool of type equality constraints where they get propagated as one would expect. What is the rationale for the current non-symmetric design? Is it easier to specify? Is it easier to implement in a compiler? Or does what I am asking for not make sense at a more fundamental level? Matthias |
From: Robert H. <Rob...@cs...> - 2001-09-14 14:34:26
|
I support adding "where structure", since it is clearly necessary in practice. Adding "withtype" to signatures seems entirely reasonable as well, provided that we can agree on the semantics of signature matching in their presence. More generally, I would like to open discussion about more extensive changes and extensions to Standard ML. What do the readers on this list think should be done next in the evolution of the language? Bob Harper -----Original Message----- From: Andreas Rossberg [mailto:ros...@ps...] Sent: Friday, September 14, 2001 10:18 AM Cc: sml...@li... Subject: Re: [Sml-implementers] Structure sharing and type abbreviations Dave Berry wrote: > > Should we also consider supporting "where structure..."? And perhaps > removing the "and" derived form of "where type...", which I believe is > ambiguous. It is not ambiguous, only tedious to parse. As it stands this part of the grammar is LALR(2) but a bunch of ugly transformations can turn it into LALR(1). Of course, it is pretty useless anyway. Regarding "where" for structures: I second it would be great if all implementations supported it (together with a derived form for definitional structure specifications) since that would allow getting rid of sharing constraints in programs altogether. IMHO this would be preferable to relying on a relaxed structure sharing semantics. Still I think adopting the proposal is a good idea. I would also opt for variation 2 since I do not see any application for such obfuscated uses of sharing (but maybe I'm just not imaginative enough...) BTW, another old issue that definitely ought to be fixed by all implementations: allow the "datatype ... withtype" derived form in signatures... - Andreas -- Andreas Rossberg, ros...@ps... "Computer games don't affect kids; I mean if Pac Man affected us as kids, we would all be running around in darkened rooms, munching magic pills, and listening to repetitive electronic music." - Kristian Wilson, Nintendo Inc. _______________________________________________ Sml-implementers mailing list Sml...@li... https://lists.sourceforge.net/lists/listinfo/sml-implementers |