D - D vs. LX
- Christophe de Dinechin (10/10) Aug 16 2001 Interestingly, my background is close to that of Walter: I also
- Christophe de Dinechin (24/24) Aug 16 2001 1/ Macros
- jacob navia (10/16) Aug 17 2001 I agree with this viewpoint. Macros are necessary.
- Walter (2/5) Aug 17 2001 Thanks for the laugh! Great satire.
- Axel Kittenberger (6/9) Aug 17 2001 Many confuse conditional compilation with macro's, that are actually two...
- Christophe de Dinechin (16/16) Aug 16 2001 2/ Why D?
- Christophe de Dinechin (26/26) Aug 16 2001 3/ C source code compatibility
- Christophe de Dinechin (19/19) Aug 16 2001 4/ Multiple inheritance:
- Christophe de Dinechin (37/37) Aug 16 2001 5/ Templates
- Walter (3/7) Aug 23 2001 I like the explicit instantiation. Since there is an STL workalike for A...
- Charles Hixson (4/11) Aug 23 2001 But in an earlier thread it was claimed that STL for Ada was 10 times as...
- Walter (5/16) Aug 23 2001 <3B7C8E79.109F4270@earthlink.net>...
- Russell Bornschlegel (11/19) Aug 23 2001 Source.
- Charles Hixson (29/56) Aug 23 2001 But I think that Eiffel generics give an equivalent amount of
- Walter (2/7) Aug 25 2001 This sounds like a serious problem with Eiffel.
- Charles Hixson (8/18) Aug 27 2001 This is a problem. As to serious... well, that sort of depends on what
- Christophe de Dinechin (27/27) Aug 16 2001 6/ Creating objects on the stack
- Christophe de Dinechin (19/19) Aug 16 2001 7/ Trigraphs:
- Christophe de Dinechin (15/15) Aug 16 2001 8/ Operator overloading
- jacob navia (8/17) Aug 17 2001 the
- Christophe de Dinechin (31/51) Aug 18 2001 Jacob,
- Christophe de Dinechin (3/3) Aug 16 2001 9/ Object oriented gradualism
- Walter (3/6) Aug 23 2001 For example, you only get a virtual function pointer in a class if the c...
- Christophe de Dinechin (20/20) Aug 16 2001 10/ Bit fields of arbitrary size
- Christophe de Dinechin (21/21) Aug 16 2001 11/ Support for 16-bit computers
- Christophe de Dinechin (89/89) Aug 16 2001 12/ RTTI
- Walter (21/23) Aug 23 2001 That's similar to a trick I use. For example, suppose I need an enum val...
- Christophe de Dinechin (10/10) Aug 16 2001 13/ Garbage collection
- Christophe de Dinechin (28/28) Aug 16 2001 14/ Declaration vs. Definition - Modularity aspect
- Sean L. Palmer (21/49) Oct 22 2001 This is where I disagree.
- Walter (3/6) Oct 23 2001 Forward references would look just like in C:
- Axel Kittenberger (3/6) Oct 23 2001 I think strictly ansi speaking this is not a valid prototype, strict C
- Sean L. Palmer (4/10) Oct 23 2001 This post now thoroughly cleansed of nits. ;)
- Christophe de Dinechin (33/33) Aug 16 2001 15/ Declaration vs. Definition - Extensibility aspect
- Christophe de Dinechin (37/37) Aug 16 2001 16/ Modules - Encapsulation
- Christophe de Dinechin (16/16) Aug 16 2001 17/ Modules - Importing
- Christophe de Dinechin (21/21) Aug 16 2001 18/ Modules - Shortening references
- Christophe de Dinechin (14/14) Aug 16 2001 19/ Modules - Child modules
- Christophe de Dinechin (20/20) Aug 16 2001 19/ Real typedefs
- Walter (6/11) Aug 22 2001 Yes, that is a problem with D right now. I've been thinking of changing ...
- Christophe de Dinechin (29/29) Aug 16 2001 20/ Arrays and Strings
- Christophe de Dinechin (20/20) Aug 16 2001 21/ Synchronize
- Sean L. Palmer (4/24) Oct 22 2001 Why not just "synch" or "sync" ? ;) Long keywords == more typing.
- Christophe de Dinechin (35/35) Aug 16 2001 22/ Try/Catch/Finally and destructors
- Walter (8/12) Sep 03 2001 It's actually not that bad in practice. Remember that C++ has "finally"
- Sean L. Palmer (14/21) Oct 22 2001 Question:
- Walter (4/16) Dec 15 2001 What happens is that the "A a;" creates a reference to an A, not an inst...
- Sean L. Palmer (18/38) Dec 15 2001 Something I'm really going to miss I think in D is guaranteed order of
- Pavel Minayev (18/28) Dec 15 2001 automatically
- Walter (10/20) Dec 15 2001 At first I had thought that this problem could not be solved, as I was t...
- Pavel Minayev (12/16) Dec 15 2001 this
- Walter (6/16) Dec 15 2001 Yes! Just call them "static this() { }" and "static ~this() { }" at the
- Pavel Minayev (6/8) Dec 15 2001 ----- Original Message -----
- Walter (3/11) Dec 15 2001 You should get an error message.
- Pavel Minayev (4/5) Dec 16 2001 Then why "static" is needed, since there are no non-static
- Walter (3/8) Dec 16 2001 For consistency with the way they are defined for classes.
- Pavel Minayev (7/17) Dec 16 2001 From my POV, module is sort of class, with only one instance
- Walter (3/8) Dec 16 2001 While that will certainly work, I'd like to stick with one way of doing
- Sean L. Palmer (5/24) Dec 17 2001 Because you don't want to publish the module ctor and dtor functions to ...
-
Walter
(3/29)
Dec 17 2001
That's a good reason. Wish I'd thought of it
. - Sean L. Palmer (9/37) Dec 17 2001 That's neat and all, but I'm talking about individual class objects. No...
- Pavel Minayev (5/8) Dec 17 2001 What's wrong with objects? Operator new calls the constructor, garbage
- Sean L. Palmer (9/17) Dec 18 2001 I forgot you can manually delete an object in D.
- Walter (6/10) Dec 17 2001 I know what you mean - you want to declare some functionality, and then ...
- Rajiv Bhagwat (7/18) Dec 17 2001 There is a whole philosophy based on it. Check out 'Resource Management'...
- Pavel Minayev (11/12) Dec 17 2001 at
- Roland (30/34) Dec 18 2001 I've never realised that (ready D specs, it's time i try it..)
- Walter (7/41) Dec 18 2001 You can use the synchronize statement to achieve the same affect, at lea...
- Roland (6/9) Dec 19 2001 nice
- Walter (5/15) Dec 19 2001 least
- Roland (6/11) Dec 20 2001 The good news is that it doen't seem too complicate
- Walter (6/15) Dec 20 2001 Linux
- Pavel Minayev (4/7) Dec 20 2001 for
- Christophe de Dinechin (18/18) Aug 16 2001 33/ Complex numbers
- Christophe de Dinechin (8/8) Aug 16 2001 34/ HTML compilation
- Walter (4/12) Sep 02 2001 Making it a separate tool means people won't use it. -Walter
- Christophe de Dinechin (18/18) Aug 16 2001 35/ printf rules?
- Phil Brooks (9/36) Sep 13 2001 What about the performance of printf vs some object oriented printing.
- Walter (3/5) Sep 15 2001 D will support use of printf(), other methods may be supplied via the
- Christophe de Dinechin (22/22) Aug 16 2001 My last post tonight, because I'm tired of typing... The sieve in LX.
- Christophe de Dinechin (32/32) Aug 16 2001 Ach, a post by Chris Friesen reminded me about the switch statement. LX ...
- Christophe de Dinechin (70/70) Aug 16 2001 Ach, yet another post from the silly LX guy. Someone else talked about
- interested (21/21) Aug 17 2001 What about runtime analysis of a classes members. Instead of assuming an...
- Christophe de Dinechin (11/32) Aug 17 2001 What you are describing is more or less the Objective-C runtime.
- Kent Sandvik (12/17) Aug 17 2001 I agree, looking at all the application frameworks out there, MFC, MacAp...
- Phil Brooks (12/26) Sep 13 2001 How does LX compare when it comes to runtime (
- Phil Brooks (3/35) Sep 13 2001 Oops, I started changing references from D to LX below and didn't get
Interestingly, my background is close to that of Walter: I also developed video games for a living, I also worked on a commercial C++ implementation, and I also designed my own language, called LX. More information on LX can be found at http://mozart-dev.sf.net. So I am going to start a big series of post to try to compare D and LX. To avoid polluting the newsgroup too much, I am going to try to post all of them under the same thread. I am obviously biased. On the other hand, I believe there is much to be gained if we exchange ideas and compare designs. Please bear with me... Christophe
Aug 16 2001
1/ Macros I do believe in the necessity of macros. Because it is simple technology doesn't mean it is obsolete (unlike "register ;-) It is obsolete only for modularization (#include). But there is still no better way for environment-dependent compilation (#ifdef), or for textual replacements (see my extensive use of '.tbl' files in the LX compiler). Back in the 1990's, I worked on the Alsys Ada compiler, which had a hidden preprocessor for internal use (#ifdefs), disabled on customer versions since that was not part of the Ada spec. I always thought this was silly :-) Your examples did not convince me either: you take seleted examples of macro applications (for example dealing with different compilers), and then say "it's useless in D". Well, then, you have to make sure that D is absolutely perfectly portable. I hope you covered the various cases of machine idioms that I documented in http://home.earthlink.net/~descubes/C-- and in particular, that you have a D-defined identifier for everything that has possibly ever been put in an autoconf file :-) Another point is that, if you don't have a standard preprocessor, then your customers will use another one. I have this very problem with LX, because one part of its syntax makes it incompatible with the C preprocessor (LX numbers like 16#FFFF), so I need to recommend another preprocessor like m4, which is quite complicated... Christophe
Aug 16 2001
"Christophe de Dinechin" <descubes earthlink.net> wrote in message news:3B7C8D0B.DC4770AD earthlink.net...1/ Macros I do believe in the necessity of macros. Because it is simple technology doesn't mean it is obsolete (unlike "register ;-) It is obsolete only for modularization (#include). But there is still no better way for environment-dependent compilation (#ifdef), or for textual replacements (see my extensive use of '.tbl' files in the LX compiler).I agree with this viewpoint. Macros are necessary. The D spec document pointed the problem with macros, they go through all scopes! That is a good insight. Let's keep it. We need then SCOPED macros! A macro should be defined in a scope and should take typed arguments. A template is just a macro. The template discussion should solve this. Templates ARE macros. I will post later what I mean exactly with that, and a template spec.
Aug 17 2001
Christophe de Dinechin wrote in message <3B7C8D0B.DC4770AD earthlink.net>...I hope you covered the various cases of machine idioms that I documented in http://home.earthlink.net/~descubes/C--Thanks for the laugh! Great satire.
Aug 17 2001
Christophe de Dinechin wrote:1/ MacrosMany confuse conditional compilation with macro's, that are actually two completly different things, in C they are handled by the same instance, but a language can either implement only one of the two, or handle them both with different instances. In my eyes conditional compiliation is a must, Macros are not.
Aug 17 2001
2/ Why D? When I was slashdotted on LX, I got one major feedback: you need to explain why people would need to use your language, what it does that C++ or Java can't do. Curiously, ease of use or implementation is a concern only to a microscopic minority. Even the '10% productivity increase' claim you make is probably difficult to sell. Hey, Perl is a successful language! In the case of LX, the objective is to make a compiled, yet extensible programming language. There are many things you can write in LX easily that you can absolutely not write in C++ or any other existing language. See some examples below (in future posts), or on http://mozart-dev.sf.net/lx.html. This doesn't mean that simplicity and ease of implementation / specification are not important. They were the starting point for LX initially. But they are now only secondary objective, and I "sell" LX differently than I used to. Christophe
Aug 16 2001
3/ C source code compatibility If you decide to drop it, you may as well go the whole way. LX, for instance, has an indentation based syntax with a lot of optional punctuation that makes it much more concise than C or C++ in many common cases, even though it appears more verbose at first. My gut feeling there is that D is only a marginal, incremental improvement over C or Java, whereas LX is a radical change (for the best, I hope). But of course, I am very biased... Maybe it's time to give an example: import IO = LX.Text_IO -- Validated "template" type: "integer" passes the test, "object" doesn't generic type ordered if with ordered A, B with boolean C := A < B -- This function is implicitly template because "ordered" is. function Min(ordered A) return ordered is return A -- This function takes a variable number of arguments function Min(ordered A, others) return ordered is with ordered B := Min(others) if A < B then return A; else return B procedure TestIt() is with integer X := Min(5, 4, 2, 3, 1, 5) with real Y := Min(1.4, 7.0, 2.9) Christophe
Aug 16 2001
4/ Multiple inheritance: I think you did almost the right thing: dumping implementation-side multiple inheritance, while keeping it at the interface side. But here too, I believe LX goes one step further, by also decoupling interface inheritance and implementation inheritance for the single-inheritance case: -- Interface inheritance type large_integer like integer function Foo(integer I) return integer function Bar(large_integer L) return integer is return Foo(L) -- OK -- Implementation inheritance. "record" is an empty base type type point_2D is record with coordinate X, Y type point_3D is point_2D with coordinate Z What this gives you is more flexibility for future evolution of the software, because implementation and interface are no longer so tied together. Christophe
Aug 16 2001
5/ Templates You say that you are looking for a solution. Look at the LX generic types, I'm sure they will give you interesting ideas, notably implicitly template types ("ordered" above). Any template type like array also makes functions that use it implicitly template, which reduces the code clutter in things like the STL dramatically. LX generics can be parameterized with any kind of object, not just integer/types (see the parameterization of array with a range argument below). generic [type value] type range written range of value is record with value low, high function range(range.value low, high) return range written low..high is result.low := low result.high := high generic [range index; type item] type array written array[index] of item function Min(array A of ordered, others) return ordered is result := Min(others) with array.item I for I in A loop result := Min(result, I) Template validation (see ordered) and predicated template specialization also simplify many things: -- C++ style full specialization generic type array for array[1..5, integer] -- C++ style partial specialization generic [range index; type item] type array for array [index, pointer[item]] -- Predicate-based specialization generic type array when size(array.item) = size(integer) Granted, some of this is a bit difficult to implement, and my LX compiler is only halfway through it... But I'm making good progress already. Previous posts suggested the Ada or Eiffel generics model. There was one major difference between Ada and C++: implicit instantiation. In Ada or Eiffel, you have to explicitly instantiate everything. This basically makes the STL impossible to implement. Christophe
Aug 16 2001
Christophe de Dinechin wrote in message <3B7C8E79.109F4270 earthlink.net>...There was one major difference between Ada and C++: implicit instantiation. In Ada or Eiffel, you have to explicitly instantiate everything. This basically makes the STL impossible to implement.I like the explicit instantiation. Since there is an STL workalike for Ada, which I haven't looked at, somebody must have dealt with this problem.
Aug 23 2001
Walter wrote:Christophe de Dinechin wrote in message <3B7C8E79.109F4270 earthlink.net>... ... I like the explicit instantiation. Since there is an STL workalike for Ada, which I haven't looked at, somebody must have dealt with this problem.But in an earlier thread it was claimed that STL for Ada was 10 times as large as the equivalent STL for C++. So the dealing with it may not have been easy.
Aug 23 2001
"Charles Hixson" <charleshixsn earthlink.net> wrote in message news:3B851445.6010005 earthlink.net...Walter wrote:<3B7C8E79.109F4270 earthlink.net>...Christophe de Dinechin wrote in messageAda,... I like the explicit instantiation. Since there is an STL workalike forLarge in source or large in object?which I haven't looked at, somebody must have dealt with this problem.But in an earlier thread it was claimed that STL for Ada was 10 times as large as the equivalent STL for C++. So the dealing with it may not have been easy.
Aug 23 2001
Walter wrote:"Charles Hixson" <charleshixsn earthlink.net> wrote in message news:3B851445.6010005 earthlink.net...Source. "Rational ships a C++ version of The Booch Components that was originally designed for and implemented in Ada by Grady Booch. ... The Ada version is 125,000 non-commented source lines compared to the C++ version's 10,000 lines -- inheritance combined with templates can be a very powerful mechanism for organizing libraries without loss of performance or clarity." -Stroustrup in D&EoC++, citing Booch's _Object Oriented Analysis and Design with Applications, 2nd edition" -RBBut in an earlier thread it was claimed that STL for Ada was 10 times as large as the equivalent STL for C++. So the dealing with it may not have been easy.Large in source or large in object?
Aug 23 2001
Russell Bornschlegel wrote:Walter wrote:But I think that Eiffel generics give an equivalent amount of compression. And they are certainly easier to learn and to use. Thus: Tree[L->Comparable] -- L is an arbitrary choice, -- Comparable is a class defined elsewhere ... -- every time this class is instantiated, it -- must have a class that implements Comparable feature root : TreeNode[L]; -- all class references are pointers sentinal : TreeNode[L]; -- or handles, no pointer notation ... -- needed(or even available); end; If you want to specify a non-handle/pointer class, you define it in the class type as an "expanded" class. If you want an abstract class, you define it in the class type as a "deferred" class. Then when you want to create an instance of a Tree, you say something like: thisTree : Tree[String]; and the tree will be ordered in the same way that String is ordered. Sometimes I find this a bit confining, but it is easy to learn, and seems to do the job. Since everything is done via a reference, sizes are known at compile time. (Expanded classes are special here, of course, but they also have special limitations that allow them to be handled easily.) OTOH, for basic stuff, and for tricky stuff, the class library implementors all fall back into C. Not that bad an idea, but it means that C interoperability should have been a higher priority on the language designer's list of features. As it was, this is always tacked on later. And shows it."Charles Hixson" <charleshixsn earthlink.net> wrote in message news:3B851445.6010005 earthlink.net...Source. "Rational ships a C++ version of The Booch Components that was originally designed for and implemented in Ada by Grady Booch. ... The Ada version is 125,000 non-commented source lines compared to the C++ version's 10,000 lines -- inheritance combined with templates can be a very powerful mechanism for organizing libraries without loss of performance or clarity." -Stroustrup in D&EoC++, citing Booch's _Object Oriented Analysis and Design with Applications, 2nd edition" -RBBut in an earlier thread it was claimed that STL for Ada was 10 times as large as the equivalent STL for C++. So the dealing with it may not have been easy.Large in source or large in object?
Aug 23 2001
Charles Hixson wrote in message <3B856897.6050907 earthlink.net>...OTOH, for basic stuff, and for tricky stuff, the class library implementors all fall back into C. Not that bad an idea, but it means that C interoperability should have been a higher priority on the language designer's list of features. As it was, this is always tacked on later. And shows it.This sounds like a serious problem with Eiffel.
Aug 25 2001
Walter wrote:Charles Hixson wrote in message <3B856897.6050907 earthlink.net>...This is a problem. As to serious... well, that sort of depends on what you're doing. Also, this is implementation specific (i.e., not a part of the language specifications), so it's quite possible that some implementations have done it better than the ones that I'm more familiar with. And usually one doesn't need to go there. But it is a problem. And sometimes it can be serious (though not grave, just exceptionally irritating, and requiring lots of extra care to get everything just right).OTOH, for basic stuff, and for tricky stuff, the class library implementors all fall back into C. Not that bad an idea, but it means that C interoperability should have been a higher priority on the language designer's list of features. As it was, this is always tacked on later. And shows it.This sounds like a serious problem with Eiffel.
Aug 27 2001
6/ Creating objects on the stack You say that in D, all objects are by reference. This makes "integer" different than objects, and that was a compromise I was not willing to make for LX. Instead, "integer" is not a built-in type any more than any user-defined object type. Also, for several types (notably simple template types), having them stack-based makes them much more efficient. -- I want this to live on the stack. type complex is record with real Re, Im Using LX pragmas, it is possible to define on a per-type basis how the compiler accesses it. Among the default pragmas are the {dynamic} pragma that specifies that a type resides in garbage collected memory, and thus is always referenced to. At the root of the LX type hierarchy is "record" (and "module", which is just "constant record"). Right above it is "object", which is just "record" with the {dynamic} pragma. So anything that derives from "object" is dynamic. -- I want this to reside in garbage-collected memory type tree is object with tree left, right function tree(tree left, right) return tree is -- Implicit allocation occurs here. result.left := left result.right := right -- I want to do this with a stack based object as a root: {dynamic} type complex_tree is complex with complex_tree left, right Christophe
Aug 16 2001
7/ Trigraphs: Full agreement here. The current LX specification says that an LX compiler must accept, in preferred order: Unicode source, ASCII source, proprietary character set, and that if the native charset is proprietary, then an import and export procedure to Unicode and ASCII must be provided. However, I disagree with the runtime types. You are asking questions about ascii or unicode or char. Well, if these were not basic types, there would be no need to ask. So in LX, the LIBRARY will define the following: - A generic "character" type - A char type, which is a specialization of character for the most common char representation on the machine - Modules for Unicode, ASCII and EBCDIC encodings that offer: - a basic type for representing the chars in memory (ascii, unicode, etc), which is a specialization of character - conversion routines to generic char types, I/O, etc. They also contain declarations for things like: ASCII.CR, ASCII.LF, etc. Something I will repeat like a mantra in my posts: built-in types are EVIL. Yucky. Don't do that. Keep clear. _That_ is obsolete :-) Christophe
Aug 16 2001
8/ Operator overloading Total disagreement here :-) Operator overloading is at the very core of the LX syntax, but it takes a completely different approach than C++ (the 'written' keyword that you may have seen in previous posts already). Written allows for N-ary operator overloading, and also the definition of new infix named operators and implicit conversions: function And(integer A, B) return integer written A and B function MultiplyAndAdd(matrix A, B, C) return matrix written A*B+C function real(integer N) return real written N Without operator overloading, you miss big time on most scientific applications... What is necessary is a much simplified set of lookup and implicit conversion rules, which LX provides (it fits on a page, literally) I also disagree that you can't use operator overloading to create libraries that work. Blitz++ is a good counter example. Christophe
Aug 16 2001
"Christophe de Dinechin" <descubes earthlink.net> wrote in message news:3B7C905D.5CFA76BC earthlink.net...8/ Operator overloading Total disagreement here :-) Operator overloading is at the very core oftheLX syntax, but it takes a completely different approach than C++ (the 'written' keyword that you may have seen in previous posts already). Written allows for N-ary operator overloading, and also the definition of new infix named operators and implicit conversions: function And(integer A, B) return integer written A and B function MultiplyAndAdd(matrix A, B, C) return matrix written A*B+C function real(integer N) return real written NIs this implemented? Is (A*B)+C also equal to MultiplyAndAdd? And (Horror) Is A*(B+C) ALSO equal to MultiplyAndAdd? How about parentheses?
Aug 17 2001
Jacob, It is implemented, and it "works" (that is, I did not find the bugs yet). Explicit parentheses are eliminated during parsing, the tree form is the same, so (A*B)+C is also MultiplyAndAdd. The tree structure being considered is different for A+(B*C), so there is no match. [localhost:~/Development/mozart/lx] ddd% cat test.lx type matrix function mla(matrix A, B, C) written A*B+C matrix P, Q, R matrix M := P * Q + R matrix N := (P*Q) + R matrix O := P* (Q+R) [localhost:~/Development/mozart/lx] ddd% ./lx -parse test.lx -run_semantics -stdout test.lx:9: No written form matches 'P * (Q + R) '. -- Generated by LX using lx-text.stylesheet import LX_BUILTINS using LX_BUILTINS variable type matrix constant procedure mla( in matrix A; in matrix B; in matrix C) written A_ * B_ + C_ variable matrix P variable matrix Q variable matrix R variable matrix M := mla (P, Q, R) variable matrix N := mla (P, Q, R) variable matrix O := P * (Q + R) -- Thank you for using LX. [localhost:~/Development/mozart/lx] ddd% Christophe jacob navia wrote:"Christophe de Dinechin" <descubes earthlink.net> wrote in message news:3B7C905D.5CFA76BC earthlink.net...8/ Operator overloading Total disagreement here :-) Operator overloading is at the very core oftheLX syntax, but it takes a completely different approach than C++ (the 'written' keyword that you may have seen in previous posts already). Written allows for N-ary operator overloading, and also the definition of new infix named operators and implicit conversions: function And(integer A, B) return integer written A and B function MultiplyAndAdd(matrix A, B, C) return matrix written A*B+C function real(integer N) return real written NIs this implemented? Is (A*B)+C also equal to MultiplyAndAdd? And (Horror) Is A*(B+C) ALSO equal to MultiplyAndAdd? How about parentheses?
Aug 18 2001
9/ Object oriented gradualism I just have no idea what you mean by that :-) Christophe
Aug 16 2001
For example, you only get a virtual function pointer in a class if the class actually has any virtual functions in it. Christophe de Dinechin wrote in message <3B7C90A8.DF87D385 earthlink.net>...9/ Object oriented gradualism I just have no idea what you mean by that :-) Christophe
Aug 23 2001
10/ Bit fields of arbitrary size As other posters noted, there are cases where bit fields are just absolutely required. LX allows bit fields, again using predefined pragmas. I used to work a lot on real-time applications, and, no, sorry, bitmasking and shifting was not really an option. {volatile} {align 16} {memory_width 16} {memory_space IO} type chip_control_register is record with integer command {bit_offset 0} {bit_size 3} integer size {bit_offset 4} {bit_size 4} boolean ready {bit_offset 8} {bit_size 1} boolean error {bit_offset 9} {bit_size 1} {address 16#FFFF_ED00} chip_control_register chip_A {address 16#FFFF_ED04} chip_control_register chip_B {address 16#FFFF_ED08} chip_control_register chip_C By the way, the statement that "bitmasking is better because it generates better code" is a very x86-centric view of the universe. The PA-RISC and IA-64 have "extract" and "deposit" instructions, and the compilers are much better at finding those on bit field accesses than on bitmask and shifting (at least at lower optimization levels) Christophe
Aug 16 2001
11/ Support for 16-bit computers I believe what you really meant was: support for the 16-bit segmented memory model on the x86 architecture. LX pragmas also offer a nice answer there. Should you need near/far pointers, which may happen on some 64-bit architectures (where near means 32-bit, and far 64-bit): {near} type near_int_pointer is pointer to integer {far} type far_int_pointer is pointer to integer Regarding more modern uses of {near} and {far}. On IA-64 on HP-UX, there is a 32-bit memory model (for better source compatibility with 32-bit applications). Internally, all pointers are really 64-bit, however, they are converted when used. And, guess what, there are cases where you need a 64-bit pointer from a 32-bit application :-) Not that HP implemented a _far keyword, for that matter... Note that there is also a standard pragma (bit_size, seen above) that might fit the bill: {bit_size 16} type near_int_pointer is pointer to integer {bit_size 32} type far_int_pointer is pointer to integer but to be exhaustive, near and far convey more information than just bit size. Christophe
Aug 16 2001
12/ RTTI LX uses "reflection" rather than RTTI, and the full variant of it (not introspection as in Java). The LX runtime environment that supports it is independent (called Mozart). The key connection between reflection and LX sources are LX pragmas that we already saw a couple of times. When the LX compiler parses: {glop} function foo() is blah; bloh; blih it looks for a pragma handler for {glop}, and passes it a standardized tree representation for function foo. The pragma handler returns what foo should be replaced with. In the future, pragma handlers will possibly be in separate DLL. In any event, the intent is that the user can add their own pragmas. Pragmas can be invoked in a number of phases of the compiler: after parsing, before or after semantics, on references to the object (for pragmas that apply to declarations), before or after expansion, or before or after code generation, or as part of the optimization phase. With reflection, you can implement: persistence, garbage collection, policy control, automatic debugging code generation, etc... See http://mozart-dev.sf.net. Anyway, you talk somewhere about: How do I keep an enum and a char array in sync. Well, if I had a preprocessor, here is what I would do: // file.tbl ZNORT(First) ZNORT(Second) ZNORT(Third) // file.c enum Znort { #define ZNORT(x) x, #include "file.tbl" #undef ZNORT Last } char *Znort_names[] = { #define ZNORT(x) #x, #include "file.tbl" #undef ZNORT NULL } And, in case you wonder, I do use this technique extensively in the LX compiler to keep track of things like tokens, predefined strings, run-time tables, etc. Now, let's assume you don't have macros. That's where reflection RULES. It makes things simpler to read for the end user, but the process is a bit more dirty. import CLX = LX.Compiler {define_pragma named_enum before_semantics} procedure NamedEnumPragma(CLX.context C; CLX.tree T) is using CLX {inline} procedure Error(string S) is CLX.Error C, Position(T), S with enum_type ET := T as enum_type if ET = nil then Error "Not an enum" -- Declare a temporary array, with the enum as an index with declaration ArrayDecl := declaration( name: tempname("enum"), type: quote(array[low..high] of string) initializer: nil) -- Replace "low" and "high" names in the above quote -- with the enum first and last with expression low := quote(X.low) replace low, quote(X), T -- Turn that into <enumtype>.low with expression high := quote(X.high) replace high, quote(X), T replace ArrayDecl, quote(low), low replace ArrayDecl, quote(high), high -- Create the initializer. Don't use 'quote' for a change with string Args of expression with enumerator E for E in ET.enumerators loop Args &= E.name with initializer Init := call( callee: name("array"), arguments: Args) ArrayDecl.initializer := Init -- Now create a function that allows Name(E) and E.name with declaration FDecl := quote(function Name(E arg) return string written E.name is return ArrayDecl[arg]); replace FDecl, quote(E), ET -- Finally, append the two declarations just after the enum type decl InsertDeclaration context: C, after: T, declaration: ArrayDecl InsertDeclaration context: C, after: ArrayDecl, declaration: FDecl -- OK, that was hard. Now for the fun part: see use of {named_decl} procedure Test() is with type X is {named_decl} enum(A, B, C, D) -- Should output AB IO.WriteLn Name(A), B.name Christophe
Aug 16 2001
Christophe de Dinechin wrote in message <3B7C932F.6E190162 earthlink.net>...Anyway, you talk somewhere about: How do I keep an enum and a char array in sync. Well, if I had a preprocessor, here is what I would do:That's similar to a trick I use. For example, suppose I need an enum value and string: #define colors \ X(red) \ X(green) \ X(blue) // Do the enum... #define enum COLOR { colors }; #undef X // Do the corresponding array of strings... #define X(c) #color , char color_strings[] = { colors }; #undef X It's ugly, but I don't get the out-of-sync bugs anymore with it. This trick works with the Digital Mars compiler which works with unlimited size macros. Many C compilers fall over on this because they limit macro expansion text size. For more complex tables, I'll write a separate program that generates C source which is then #Include'd.
Aug 23 2001
13/ Garbage collection LX supports it, but it is a side effect of well-defined pragmas applied to selected types, rather than built-in into the language. The {dynamic} pragma indicates that an object resides on the garbage collected heap. "object" and "record" differ only in that "record" can live on the stack, while "object" is always on the GC heap. By the way, the LX compiler itself, although written in C++, uses a mark-and-sweep garbage collector that uses reflective information generated from C++ source :-) Christophe
Aug 16 2001
14/ Declaration vs. Definition - Modularity aspect Good modularity sometimes imply that you don't make the implementation details public. LX has clearly separate interface and implementation, with a 'body' keyword that allows the kind of repetitions required in C++. -- Interface, in file fact.lxs function factorial(integer N) return integer -- Body, in file fact.lxb. 'body' replaces all arguments function factorial body is ... For completeness, let me also indicate that what LX allows you do to with any object is what the interface says, regardless of whether you see the implementation. No 'private' parts. The exception is for types, where knowing the implementation gives you access to it. -- Type interface type complex with real Re, Im out real Rho, Theta -- This is legal just seeing the above function Re(complex Z) return real is return Z.Re -- Type definition (possibly another file) -- Notice there is no Rho and Theta fields type complex body is real Re, Im -- So we need to tell the compiler what to do when the user does Z.Rho function Rho(complex Z) return real written Z.Rho is return Math.sqrt(Z.Re^2 + Z.Im^2) Christophe
Aug 16 2001
This is where I disagree. The compiler doesn't need a separate interface and implementation. It should be able to find the whole declaration (in D, the declaration and definition are the same thing) and figure out what the public, accessible parts are (the interface) If you link in a library, you don't even need the source as long as you have modern languages work. It saves the programmer the tedium of maintaining two different parts of the source that say the exact same thing. If one were inclined, the IDE could extract the parse info from the .obj files and show the programmer a trimmed down, publics-only source file automatically, on request. Or the IDE class browser could have an option to hide everything but publics. Or the library author could include such a publics-only, no-implementation source file for distribution, merely for programmer reference purposes because the compiler wouldn't need it. Question for Walter: If there were such a thing as forward declaration in D, what would the syntax be? This is only so I could write such a IDE browser tool that showed functions in a standard way. Sean "Christophe de Dinechin" <descubes earthlink.net> wrote in message news:3B7C9418.23275491 earthlink.net...14/ Declaration vs. Definition - Modularity aspect Good modularity sometimes imply that you don't make the implementation details public. LX has clearly separate interface and implementation, with a 'body' keyword that allows the kind of repetitions required in C++. -- Interface, in file fact.lxs function factorial(integer N) return integer -- Body, in file fact.lxb. 'body' replaces all arguments function factorial body is ... For completeness, let me also indicate that what LX allows you do to with any object is what the interface says, regardless of whether you see the implementation. No 'private' parts. The exception is for types, where knowing the implementation gives you access to it. -- Type interface type complex with real Re, Im out real Rho, Theta -- This is legal just seeing the above function Re(complex Z) return real is return Z.Re -- Type definition (possibly another file) -- Notice there is no Rho and Theta fields type complex body is real Re, Im -- So we need to tell the compiler what to do when the user does Z.Rho function Rho(complex Z) return real written Z.Rho is return Math.sqrt(Z.Re^2 + Z.Im^2) Christophe
Oct 22 2001
Sean L. Palmer wrote in message <9r1rj3$2etr$1 digitaldaemon.com>...Question for Walter: If there were such a thing as forward declaration in D, what would the syntax be? This is only so I could write such a IDE browser tool that showed functions in a standard way.Forward references would look just like in C: int foo();
Oct 23 2001
Forward references would look just like in C: int foo();I think strictly ansi speaking this is not a valid prototype, strict C wants to have it look like this: int foo(void);
Oct 23 2001
This post now thoroughly cleansed of nits. ;) Sean "Axel Kittenberger" <axel dtone.org> wrote in message news:9r35rp$5ls$2 digitaldaemon.com...Forward references would look just like in C: int foo();I think strictly ansi speaking this is not a valid prototype, strict C wants to have it look like this: int foo(void);
Oct 23 2001
15/ Declaration vs. Definition - Extensibility aspect Your model of class definition doesn't allow one to extend a base class (without deriving it), which in practice is a severe weakness in large projects. Objective C is the only other compiled language I know that fixes the problem (with categories). What LX does is giving up the notion of "member function" (although you can recreate the X.f() notation with a written form where suitable). Ah ah, but what about dynamic dispatch, then? What LX has is the concept of dynamic object, which is essentially a (type, reference) pair. This is introduced with the any keyword. It allows C++ style dynamic dispatch with two major extensions: a/ You can add "virtual" functions to a base type at any point in the program, not just in the class interface. Thus, any class remains extensible. b/ Dynamic dispatch can apply to more than one argument at a time. type shape type rectangle like shape type type circle like shape -- "Virtual" function, and overrides for the various classes -- There is no single location where these have to be. -- Obviously, this requires a 'bind' phase to generate the vtables -- from the whole program. procedure Draw(any shape S) written S.Draw() procedure Draw(any rectangle S) written S.Draw() procedure Draw(any circle S) written S.Draw -- Multi-way dynamic dispatch function Intersect(any shape S1, S2) return any shape function Intersect(any rectangle S1, S2) return any rectangle function Intersect(any circle S1, S2) return any shape Again, the major point here is that the "class" shape can be extended from wherever in the program. This doesn't break encapsulation, however, because the extensions can only see whatever interface is visible to them. In particular, the body of the shape type is not visible to the extensions. Christophe
Aug 16 2001
16/ Modules - Encapsulation There are two orthogonal aspects that are commonly called "modules": 1/ encapsulating related stuff, and 2/ making declarations available across translation units. For the first aspect, LX uses the "module" type, which is defined as: type module is constant record You define a module interface as follows: module COMPLEX with type complex constant complex I function complex (real Re := 0.0, Im := 0.0) return complex function Add(complex A, B) return complex written A+B function Sub(complex A, B) return complex written A-B ... You define a module implementation as follows (notice how 'body' comes handy here to avoid repeating the whole interface): module COMPLEX body is type complex is record with real Re, Im constant complex I is complex(0.0, 1.0) function complex body is result.Re := Re result.Im := Im function Add body is result.Re := A.Re + B.Re result.Im := A.Im + B.Im ... Because a module is just a constant record, there are many things that are vastly simplified, notably lookup rules. Also, a 'using' statement works both for modules and for objects, since they are essentially the same thing. using COMPLEX complex Z using Z Re := 0.0 Im := 1.0 Christophe
Aug 16 2001
17/ Modules - Importing There are two orthogonal aspects that are commonly called "modules": 1/ encapsulating related stuff, and 2/ making declarations available across translation units. The second aspect of modules, communication across translation units, is handled in LX as follows. Any translation unit is made of a specification (foo.lxs) and an optional body (foo.lxb). Anything declared in a specification file can be imported from another source using import. For instance, we saw above: import IO = LX.Text_IO The "IO =" part is optional, but is useful to help shorten references to a specific import without making the import globally visible. Without it, you have to write LX.Text_IO.WriteLn. With it, you can write IO.WriteLn and it does the same thing. You can import any globally declared entity in a specification. Christophe
Aug 16 2001
18/ Modules - Shortening references When using modules, it is also important to avoid polluting the namespace. That really matters for "million of lines of code" projects. I see from the Sieve example the "import stdio" in D implicitly imports printf, and I believe it is bad. LX still allows you to shorten references (make them implicit) with the "using" keyword. An "using" statement adds an entity to the current context's map (it comes last in the lookups for that context). For instance: function Mod(in out array A of complex) return real with array.index.value I result := 0.0 for I in A.range loop using A[I] -- All references are implicitly to A[I] result += Re * Re + Im * Im result := Math.sqrt(result) Now, remember that modules are simply constant records? This allows one to say: using IO WriteLn "Hello world" Christophe
Aug 16 2001
19/ Modules - Child modules One of the toughest aspects of Ada-style modularity is how can modules be extended safely. LX borrows from Ada the notion of child package, although it is implemented slightly differently. Essentially, what this means is that there is a "master module" LX, which is extended (with knowlege of the internal details of module LX) by a module named LX.Text_IO, which itself is extended (with knowledge of the internal details of module LX.Text_IO) by a module named LX.Text_IO.Formatting This system allows you to structure your software like russian dolls, with each inner doll visible from the outside when you open the larger doll, but also, while inside the larger doll, seing the inside of the larger doll. In other words, you don't break encapsulation, but you preserve extensibility. Christophe
Aug 16 2001
19/ Real typedefs While having 'handle' being separate is sometimes useful, it is also sometimes an impediment (unless you also have conversion rules from a typedef to the typedefed type, and implicit conversion headaches rear their ugly heads). So for LX, I decided to make the creation of a new type not the default, but an option. type coordinate is real coordinate C := 1.0 -- OK function F(real R) return real function F(coordinate C) return coordinate -- Error type distance is other real type time is other real type speed is other real function Div(distance D; time T) return speed written D/T -- OK LATER NOTE: I just discovered you have typealias. OK, let me suggest that typedef should behave the C way (as typealias does today), and that typenew implements the new behavior...?. Don't change the meaning of typedef gratuitously... PS: does your syntax allow: "int typedef handle" as in C? Christophe
Aug 16 2001
Christophe de Dinechin wrote in message <3B7C964C.81944DE9 earthlink.net>...LATER NOTE: I just discovered you have typealias. OK, let me suggest that typedef should behave the C way (as typealias does today), and that typenew implements the new behavior...?. Don't change the meaning of typedef gratuitously...Yes, that is a problem with D right now. I've been thinking of changing the typealias keyword to simply alias.PS: does your syntax allow: "int typedef handle" as in C?No. I saw no need to support such monstrosities. I suspect the reason it is in C at all is because of a bug in an early C compiler that people started depending on <g>.
Aug 22 2001
20/ Arrays and Strings Arrays in LX are constructed generic types, not primitive types. So they don't suffer of any of the problems you mention. I believe this solution is more elegant. Also note that the LX syntax for declaring arrays (determined by a written form on the generic type) doesn't suffer the issues you mention on the C syntax, although there current left to right associativity for named operators requires clumsy parentheses in some cases: array A[1..5] of (pointer to integer) As a reminder, the type is declared with some generic declaration like: generic [range index; type item] type array written array[index] of item In declarations, only the first word appears on the left of the declared name, thus a declaration of an array would use: array A[1..5] of integer Naturally, if you want zero-based arrays with a C-like notation, fine by me: generic [integer size; type item] type carray written item[size] integer X[5] Note that this would cause trouble in the long-term, because the [] notation if not overloaded is for template arguments. Without the declaration above, integer X[5] would be instantiating generic type integer with argument 5. And since integer in LX is actually a generic type, this should be valid... There is no relationship between pointers and arrays in LX (except that both are constructed types). The same should hold for strings as for arrays. They should be constructed, not primitive types. Did I already mention this? Built-in types are EVIL. Christophe
Aug 16 2001
21/ Synchronize I am afraid that your approach to multitasking is too simplistic. In addition, I believe that multitasking belongs to the library, not to the language. LX will offer a multitasking library at some point, which I started discussing from an interface point of view on my web page somewhere. Most notably, with pragmas, you ensure that this seems integrated in the language, yet it remains outside of it. {synchronized} array Buffer[0..1023] of byte The Ada community discovered the hard way that building a given tasking model into the language was convenient, but ultimately closed too many doors. Real-time multitasking doesn't require the same primitives as web-server applications... A possible use in LX of a tasking model implemented in a library can be found at http://mozart-dev.sourceforge.net/lx_tasking.txt. It tries to mimic the "Ada" feel of tasking, but that's just one possible model. The Java feel is actually much simpler to implement :-) PS: I promise, if I ever complete a tasking library, it will have {synchronized} and {synchronised}, as well as {sincronised} for the spelling-impaired :-) Christophe
Aug 16 2001
Why not just "synch" or "sync" ? ;) Long keywords == more typing. Sean "Christophe de Dinechin" <descubes earthlink.net> wrote in message news:3B7C9867.C7F4A052 earthlink.net...21/ Synchronize I am afraid that your approach to multitasking is too simplistic. In addition, I believe that multitasking belongs to the library, not to the language. LX will offer a multitasking library at some point, which I started discussing from an interface point of view on my web page somewhere. Most notably, with pragmas, you ensure that this seems integrated in the language, yet it remains outside of it. {synchronized} array Buffer[0..1023] of byte The Ada community discovered the hard way that building a given tasking model into the language was convenient, but ultimately closed too many doors. Real-time multitasking doesn't require the same primitives as web-server applications... A possible use in LX of a tasking model implemented in a library can be found at http://mozart-dev.sourceforge.net/lx_tasking.txt. It tries to mimic the "Ada" feel of tasking, but that's just one possible model. The Java feel is actually much simpler to implement :-) PS: I promise, if I ever complete a tasking library, it will have {synchronized} and {synchronised}, as well as {sincronised} for the spelling-impaired :-) Christophe
Oct 22 2001
22/ Try/Catch/Finally and destructors I agree with the model. As a matter of fact, this reminds me that I need to add finally as part of the try/catch statement in LX. On the other hand, there are many cases where destructors are indeed useful. For instance, locks, temporary files that need to be deleted when you exit a procedure or delete an object, etc. And it's not like the semantics or implementation is complicated either... Just avoid the X::~X syntax, and you will be fine. [LATER NOTE:] OK, you have destructors, and you do use the ~this syntax. Yuck... One important note: Bertrand Meyer, the author of Eiffel, makes a good point about what he calls "disciplined exceptions." Which means, in short, that by default, an exception repropagates rather than being "swallowed" by a catch. That's the model for LX. You need to use 'resume' to prevent the exception from propagating. The model is "catch clause as cleanup" rather than "catch clause as implicit fix". try do_stuff catch exception_A: fixup_A -- Implciitly rethrow here catch exception_B: fixup_B retry -- restart the 'try' block catch exception_C fixup_C resume -- C++ behavior here, quit the catch handler Optimization note: "finally" is actually very bad for some optimizations on "real, modern" CPUs (that is, not the x86 ;-) To Walter: that's largely because it makes the control flow much more complex, everything now connects to the finally, and the compiler must really take multiple exit pathes into consideration. Christophe
Aug 16 2001
Christophe de Dinechin wrote in message <3B7C9971.8294C753 earthlink.net>...To Walter: that's largely because it makes the control flow much more complex, everything now connects to the finally, and the compiler must really take multiple exit pathes into consideration.It's actually not that bad in practice. Remember that C++ has "finally" clauses too, it's just that they are hidden (implicitly generated by the compiler). The compiler builds finally clauses for each stack allocated object that has a destructor. I never much liked the hidden bloat generated by that. It's a major reason why D has no stack allocated class objects, and "finally" clauses are explicit.
Sep 03 2001
Question: If you have a class class A { this() { ... } ~this() { ... } } Is a struct that contains one of these possible? struct S { A a; } If so, that makes structs have implicit destructors. SeanIt's actually not that bad in practice. Remember that C++ has "finally" clauses too, it's just that they are hidden (implicitly generated by the compiler). The compiler builds finally clauses for each stack allocated object that has a destructor. I never much liked the hidden bloat generated by that. It's a major reason why D has no stack allocated class objects, and "finally" clauses are explicit.
Oct 22 2001
"Sean L. Palmer" <spalmer iname.com> wrote in message news:9r1s8a$2fbv$1 digitaldaemon.com...If you have a class class A { this() { ... } ~this() { ... } } Is a struct that contains one of these possible? struct S { A a; } If so, that makes structs have implicit destructors.What happens is that the "A a;" creates a reference to an A, not an instance of A. So, no implicit destructors are required.
Dec 15 2001
Something I'm really going to miss I think in D is guaranteed order of destruction. I oftentimes use a class as a convenient way to automatically run ctor and dtor code for initialization and cleanup. I have to use smart pointer classes to get that, but it's worth it. In D order of destruction cannot be guaranteed at all. Maybe I'll get used to it... calling explicit Init and Exit functions instead of ctors/dtors etc. But it sure was nice to have all that cleanup work done automatically by the compiler, especially what with exceptions going off and everything, you don't have to put as much work into each function exit point because you know the state of the system will be consistent at each step. An automated refcounting system could do that. I don't think GC every will be able to reliably give me that. And I have many other resources to worry about than just memory. I'd hate for D to make this kind of thing worse instead of better. Sean "Walter" <walter digitalmars.com> wrote in message news:9vf5q9$cq4$1 digitaldaemon.com..."Sean L. Palmer" <spalmer iname.com> wrote in message news:9r1s8a$2fbv$1 digitaldaemon.com...instanceIf you have a class class A { this() { ... } ~this() { ... } } Is a struct that contains one of these possible? struct S { A a; } If so, that makes structs have implicit destructors.What happens is that the "A a;" creates a reference to an A, not anof A. So, no implicit destructors are required.
Dec 15 2001
"Sean L. Palmer" <spalmer iname.com> wrote in message news:9vfc86$g7k$1 digitaldaemon.com...Something I'm really going to miss I think in D is guaranteed order of destruction. I oftentimes use a class as a convenient way toautomaticallyrun ctor and dtor code for initialization and cleanup. I have to usesmartpointer classes to get that, but it's worth it. In D order of destruction cannot be guaranteed at all. Maybe I'll get used to it... callingexplicitInit and Exit functions instead of ctors/dtors etc. But it sure was nicetohave all that cleanup work done automatically by the compiler, especially what with exceptions going off and everything, you don't have to put asmuchwork into each function exit point because you know the state of thesystemwill be consistent at each step.Don't forget about static constructors/destructors. They do exactly what you want, and the latest spec (one with the alpha) defines strict order of their execution: "The order of static initialization is implicitly determined by the import declarations in each module. Each module is assumed to depend on any imported modules being statically constructed first. Other than following that rule, there is no imposed order on executing the module static constructors." Since static constructors for modules you depend on are always called first, it should be exactly what's needed to initialize a module.
Dec 15 2001
"Pavel Minayev" <evilone omen.ru> wrote in message news:9vfhhd$j5q$1 digitaldaemon.com...Don't forget about static constructors/destructors. They do exactly what you want, and the latest spec (one with the alpha) defines strict order of their execution: "The order of static initialization is implicitly determined by the import declarations in each module. Each module is assumed to depend on any imported modules being statically constructed first. Other than following that rule, there is no imposed order on executing the module static constructors." Since static constructors for modules you depend on are always called first, it should be exactly what's needed to initialize a module.At first I had thought that this problem could not be solved, as I was too stuck in a rut thinking about them the C++ #include way. Then I realized the solution was staring me in the face <g> and the implementation almost wrote itself. One irritant about C++ (for me) was that in order to even have a module constructor, I had to wrap it in a dummy class and then create a static instance of that class. In D, I can just write what is intended - "run this code on startup, and this code on termination".
Dec 15 2001
"Walter" <walter digitalmars.com> wrote in message news:9vg29o$s9o$2 digitaldaemon.com...One irritant about C++ (for me) was that in order to even have a module constructor, I had to wrap it in a dummy class and then create a static instance of that class. In D, I can just write what is intended - "runthiscode on startup, and this code on termination".Now the question is, is it possible to run it without any class at all? As far as I could understand from the docs, constructors - even static - can only reside in classes. So your statement about "wrapping it in a dummy class" still applies. Didn't you consider enabling module-level constructors & finalizers - say, two _global_ functions called this() and ~this(), for consistency. Or maybe initialization() & finalization(), as seen in Delphi. Whatever, it would be just cool. P.S. I want more bugs - give me a new alpha! =)
Dec 15 2001
"Pavel Minayev" <evilone omen.ru> wrote in message news:9vg3rr$sue$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:9vg29o$s9o$2 digitaldaemon.com...Yes! Just call them "static this() { }" and "static ~this() { }" at the module level.One irritant about C++ (for me) was that in order to even have a module constructor, I had to wrap it in a dummy class and then create a static instance of that class. In D, I can just write what is intended - "runthiscode on startup, and this code on termination".Now the question is, is it possible to run it without any class at all?P.S. I want more bugs - give me a new alpha! =)I'm working on it. I took some time off to put out 8.25 of the C++ compiler, basically an accumulation of various fixes.
Dec 15 2001
----- Original Message ----- From: "Walter" <walter digitalmars.com> Newsgroups: D Sent: Saturday, December 15, 2001 11:35 PM Subject: Re: D vs. LX - ExceptionsYes! Just call them "static this() { }" and "static ~this() { }" at the module level.And what if I omit "static"?
Dec 15 2001
You should get an error message. "Pavel Minayev" <evilone omen.ru> wrote in message news:9vgd4n$12as$1 digitaldaemon.com...----- Original Message ----- From: "Walter" <walter digitalmars.com> Newsgroups: D Sent: Saturday, December 15, 2001 11:35 PM Subject: Re: D vs. LX - ExceptionsYes! Just call them "static this() { }" and "static ~this() { }" at the module level.And what if I omit "static"?
Dec 15 2001
"Walter" <walter digitalmars.com> wrote in message news:9vglbk$16vc$1 digitaldaemon.com...You should get an error message.Then why "static" is needed, since there are no non-static module constructors?
Dec 16 2001
"Pavel Minayev" <evilone omen.ru> wrote in message news:9vhkt5$1pfv$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:9vglbk$16vc$1 digitaldaemon.com...For consistency with the way they are defined for classes.You should get an error message.Then why "static" is needed, since there are no non-static module constructors?
Dec 16 2001
"Walter" <walter digitalmars.com> wrote in message news:9vhs0a$1t8o$1 digitaldaemon.com..."Pavel Minayev" <evilone omen.ru> wrote in message news:9vhkt5$1pfv$1 digitaldaemon.com...From my POV, module is sort of class, with only one instance existing. As such, it might have a =non-static= constructor. But in general, it's a matter of personal taste. So far, why not just define "static" to be an option for module constructors? And everybody would be satisfied..."Walter" <walter digitalmars.com> wrote in message news:9vglbk$16vc$1 digitaldaemon.com...For consistency with the way they are defined for classes.You should get an error message.Then why "static" is needed, since there are no non-static module constructors?
Dec 16 2001
"Pavel Minayev" <evilone omen.ru> wrote in message news:9vi1fi$2032From my POV, module is sort of class, with only one instance existing. As such, it might have a =non-static= constructor. But in general, it's a matter of personal taste. So far, why not just define "static" to be an option for module constructors? And everybody would be satisfied...While that will certainly work, I'd like to stick with one way of doing things at least in the initial release!
Dec 16 2001
Because you don't want to publish the module ctor and dtor functions to be called by other modules, perhaps. Sean "Pavel Minayev" <evilone omen.ru> wrote in message news:9vi1fi$2032$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:9vhs0a$1t8o$1 digitaldaemon.com..."Pavel Minayev" <evilone omen.ru> wrote in message news:9vhkt5$1pfv$1 digitaldaemon.com...From my POV, module is sort of class, with only one instance existing. As such, it might have a =non-static= constructor. But in general, it's a matter of personal taste. So far, why not just define "static" to be an option for module constructors? And everybody would be satisfied..."Walter" <walter digitalmars.com> wrote in message news:9vglbk$16vc$1 digitaldaemon.com...For consistency with the way they are defined for classes.You should get an error message.Then why "static" is needed, since there are no non-static module constructors?
Dec 17 2001
That's a good reason. Wish I'd thought of it <g>. "Sean L. Palmer" <spalmer iname.com> wrote in message news:9vkevi$b24$1 digitaldaemon.com...Because you don't want to publish the module ctor and dtor functions to be called by other modules, perhaps. Sean "Pavel Minayev" <evilone omen.ru> wrote in message news:9vi1fi$2032$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:9vhs0a$1t8o$1 digitaldaemon.com..."Pavel Minayev" <evilone omen.ru> wrote in message news:9vhkt5$1pfv$1 digitaldaemon.com...From my POV, module is sort of class, with only one instance existing. As such, it might have a =non-static= constructor. But in general, it's a matter of personal taste. So far, why not just define "static" to be an option for module constructors? And everybody would be satisfied..."Walter" <walter digitalmars.com> wrote in message news:9vglbk$16vc$1 digitaldaemon.com...For consistency with the way they are defined for classes.You should get an error message.Then why "static" is needed, since there are no non-static module constructors?
Dec 17 2001
That's neat and all, but I'm talking about individual class objects. Not necessarily modules (though it's nice to see something akin to Turbo Pascal's units again instead of this nightmarish #include bullshit!) Sean "Pavel Minayev" <evilone omen.ru> wrote in message news:9vfhhd$j5q$1 digitaldaemon.com..."Sean L. Palmer" <spalmer iname.com> wrote in message news:9vfc86$g7k$1 digitaldaemon.com...destructionSomething I'm really going to miss I think in D is guaranteed order of destruction. I oftentimes use a class as a convenient way toautomaticallyrun ctor and dtor code for initialization and cleanup. I have to usesmartpointer classes to get that, but it's worth it. In D order ofnicecannot be guaranteed at all. Maybe I'll get used to it... callingexplicitInit and Exit functions instead of ctors/dtors etc. But it sure wastoespeciallyhave all that cleanup work done automatically by the compiler,what with exceptions going off and everything, you don't have to put asmuchwork into each function exit point because you know the state of thesystemwill be consistent at each step.Don't forget about static constructors/destructors. They do exactly what you want, and the latest spec (one with the alpha) defines strict order of their execution: "The order of static initialization is implicitly determined by the import declarations in each module. Each module is assumed to depend on any imported modules being statically constructed first. Other than following that rule, there is no imposed order on executing the module static constructors." Since static constructors for modules you depend on are always called first, it should be exactly what's needed to initialize a module.
Dec 17 2001
"Sean L. Palmer" <spalmer iname.com> wrote in message news:9vkf3j$bb7$1 digitaldaemon.com...That's neat and all, but I'm talking about individual class objects. Not necessarily modules (though it's nice to see something akin to Turbo Pascal's units again instead of this nightmarish #include bullshit!)What's wrong with objects? Operator new calls the constructor, garbage collector will then remove the object, calling destructor for you, or you can explicitly request to remove the object you want.
Dec 17 2001
I forgot you can manually delete an object in D. Still you don't really get the automatic dtor behavior... I suppose you could have one object that must be dtor'd after another object, to hold a pointer to said object. Anyway, nothing that would prevent one from using the language. Sean "Pavel Minayev" <evilone omen.ru> wrote in message news:9vkv3m$let$3 digitaldaemon.com..."Sean L. Palmer" <spalmer iname.com> wrote in message news:9vkf3j$bb7$1 digitaldaemon.com...NotThat's neat and all, but I'm talking about individual class objects.necessarily modules (though it's nice to see something akin to Turbo Pascal's units again instead of this nightmarish #include bullshit!)What's wrong with objects? Operator new calls the constructor, garbage collector will then remove the object, calling destructor for you, or you can explicitly request to remove the object you want.
Dec 18 2001
"Sean L. Palmer" <spalmer iname.com> wrote in message news:9vkf3j$bb7$1 digitaldaemon.com...That's neat and all, but I'm talking about individual class objects. Not necessarily modules (though it's nice to see something akin to Turbo Pascal's units again instead of this nightmarish #include bullshit!) SeanI know what you mean - you want to declare some functionality, and then have some other functionality performed upon the closing }. I use just such a thing for some simple timers, and some debug classes in C++. That feature isn't in D, however.
Dec 17 2001
There is a whole philosophy based on it. Check out 'Resource Management' at www.relisoft.com - Rajiv "Walter" <walter digitalmars.com> wrote in message news:9vlrcd$16lh$2 digitaldaemon.com..."Sean L. Palmer" <spalmer iname.com> wrote in message news:9vkf3j$bb7$1 digitaldaemon.com...NotThat's neat and all, but I'm talking about individual class objects.havenecessarily modules (though it's nice to see something akin to Turbo Pascal's units again instead of this nightmarish #include bullshit!) SeanI know what you mean - you want to declare some functionality, and thensome other functionality performed upon the closing }. I use just such a thing for some simple timers, and some debug classes in C++. That feature isn't in D, however.
Dec 17 2001
"Rajiv Bhagwat" <dataflow vsnl.com> wrote in message news:9vml4d$1nlb$1 digitaldaemon.com...There is a whole philosophy based on it. Check out 'Resource Management'at The reason was that C++ doesn't offer you any built-in capabilities of things such as smart-pointers, and resource management in general - which is probably what most demand. In D, however, you can be sure that all trash will be occasionaly collected by the GC. Of course, in cases where order is important, you have to delete everything explicitly... but I personally have always considered the way "always release after use" a good programming practice...
Dec 17 2001
"Sean L. Palmer" a écrit :Something I'm really going to miss I think in D is guaranteed order of destruction. I oftentimes use a class as a convenient way to automatically run ctor and dtor code for initialization and cleanup. I have to use smart pointer classes to get that, but it's worth it.I've never realised that (ready D specs, it's time i try it..) For example in C++: class LockDevice { public: LockDevice() { ++_busy; //atomic } ~LockDevice() { _busy--; //atomic } int isbusy() { return (_busy!=0); } int busylevel() { return _busy; } private: static int _busy; }; int LockDevice::_busy = 0; void workondevice() { LockDevice lock; //lock device acces if (lock.busylevel()>1) then goto device_is_already_locked; . <work on device> . } //~LockDevice automaticaly unlock device Can i do something similar in D ? Roland
Dec 18 2001
You can use the synchronize statement to achieve the same affect, at least for locking. Otherwise, you'll need to wrap the code in a try-finally statement. "Roland" <rv ronetech.com> wrote in message news:3C1FB8E7.BAEE94DF ronetech.com..."Sean L. Palmer" a écrit :automaticallySomething I'm really going to miss I think in D is guaranteed order of destruction. I oftentimes use a class as a convenient way tosmartrun ctor and dtor code for initialization and cleanup. I have to usepointer classes to get that, but it's worth it.I've never realised that (ready D specs, it's time i try it..) For example in C++: class LockDevice { public: LockDevice() { ++_busy; file://atomic } ~LockDevice() { _busy--; file://atomic } int isbusy() { return (_busy!=0); } int busylevel() { return _busy; } private: static int _busy; }; int LockDevice::_busy = 0; void workondevice() { LockDevice lock; file://lock device acces if (lock.busylevel()>1) then goto device_is_already_locked; . <work on device> . } file://~LockDevice automaticaly unlock device Can i do something similar in D ? Roland
Dec 18 2001
Walter a écrit :You can use the synchronize statement to achieve the same affect, at least for locking. Otherwise, you'll need to wrap the code in a try-finally statement.nice any plan to port D on DOSX ? does it seem complicate ? Roland (sorrry if this question had already been asked, this group is too fast and flight too high for me)
Dec 19 2001
"Roland" <rv ronetech.com> wrote in message news:3C20B16D.5389BC0D ronetech.com...Walter a écrit :leastYou can use the synchronize statement to achieve the same affect, atandfor locking. Otherwise, you'll need to wrap the code in a try-finally statement.nice any plan to port D on DOSX ? does it seem complicate ? Roland (sorrry if this question had already been asked, this group is too fastflight too high for me)The only barrier to running D under DOSX is porting the runtime library.
Dec 19 2001
Walter a écrit :The good news is that it doen't seem too complicate The bad news is that i can't propose my help at this moment and may be Linux will come first ? Thanks Rolandany plan to port D on DOSX ? does it seem complicate ? RolandThe only barrier to running D under DOSX is porting the runtime library.
Dec 20 2001
"Roland" <rv ronetech.com> wrote in message news:3C21E0E6.E9A2C732 ronetech.com...Walter a écrit :LinuxThe good news is that it doen't seem too complicate The bad news is that i can't propose my help at this moment and may beany plan to port D on DOSX ? does it seem complicate ? RolandThe only barrier to running D under DOSX is porting the runtime library.will come first ? Thanks RolandI won't myself be doing the linux port, I have a partner in crime who's looking into it. Porting the phobos rtl shouldn't be too hard. Don't ask for a 16 bit port <g>.
Dec 20 2001
"Walter" <walter digitalmars.com> wrote in message news:9vt62f$1em4$3 digitaldaemon.com...I won't myself be doing the linux port, I have a partner in crime who's looking into it. Porting the phobos rtl shouldn't be too hard. Don't askfora 16 bit port <g>.Oh my god, please, no, I want to make .com files with D! =)
Dec 20 2001
33/ Complex numbers I believe that I can define in LX a complex type (and imaginary type) that is as optimized as your implementation. But, since it is in the library, I can also have: complex of ints, quaternions, tensors, etc. Why cover only complex numbers? Mathematics did not stop a couple of centuries ago :-) Well, someone else already made the point, methinks :-) Oh, by the way, since in LX most things are in the library, this makes several optimizations being actually resolved by operator overloading. For instance, for a processor that has a multiply-and-add instruction (PowerPC, IA-64) function Add(integer A, B) return integer written A+B {builtin add} function MulAdd(integer A, B, C) return integer written A*B+C {builtin mla} You can refer to the CVS repository on SourceForge to see how the LX compiler uses the {builtin} pragma to reference a table that defines the opcodes to emit to the assembler... Christophe
Aug 16 2001
34/ HTML compilation Ah, I see, you discarded the C preprocessor to replace it with an HTML preprocessor. So #include is being replaced with <A REF="http://....">. That's a clever trick. Seriously, I think this is a cute idea, but it has nothing to do with D. It is really a preprocessor that extracts source from HTML files, and that ought to be a separate tool... Christophe
Aug 16 2001
Making it a separate tool means people won't use it. -Walter The HTML thing is an experiment. I think some really cool editors can be built using it. Christophe de Dinechin wrote in message <3B7C9A6E.718B32AF earthlink.net>...34/ HTML compilation Ah, I see, you discarded the C preprocessor to replace it with an HTML preprocessor. So #include is being replaced with <A REF="http://....">. That's a clever trick. Seriously, I think this is a cute idea, but it has nothing to do with D. It is really a preprocessor that extracts source from HTML files, and that ought to be a separate tool... Christophe
Sep 02 2001
35/ printf rules? printf sucks. Really. I could write 218918231231 pages on this. -- Unformatted IO IO.WriteLn "A=", A, " and then B=", B -- Formatted IO -- Definition of WriteLn generic type writable if with writable W IO.Write W procedure WriteLn() is Write Unicode.CR procedure WriteLn(writable X; others) is Write X WriteLn others Now, if you really care about the printf formatting idiotisms, you can implement that in LX too. Not that I would recommend it... Christophe
Aug 16 2001
What about the performance of printf vs some object oriented printing. I would like IO.WriteLn "A=", A, " and then B=", B, " and then C=" to be as fast as printf( "A=%d and then B=%d and then C=%d", A, B, C ); In C++, it is no where near as fast and can never be as fast. How do D and LX stack up when it comes to writing huge amounts of formatted data? Christophe de Dinechin wrote:35/ printf rules? printf sucks. Really. I could write 218918231231 pages on this. -- Unformatted IO IO.WriteLn "A=", A, " and then B=", B -- Formatted IO -- Definition of WriteLn generic type writable if with writable W IO.Write W procedure WriteLn() is Write Unicode.CR procedure WriteLn(writable X; others) is Write X WriteLn others Now, if you really care about the printf formatting idiotisms, you can implement that in LX too. Not that I would recommend it... Christophe
Sep 13 2001
Phil Brooks wrote in message <3BA147BC.DA11B7AB mentor.com>...How do D and LX stack up when it comes to writing huge amounts of formatted data?D will support use of printf(), other methods may be supplied via the runtime library.
Sep 15 2001
My last post tonight, because I'm tired of typing... The sieve in LX. import IO = LX.Text_IO procedure main() is with integer i, count, prime, k, iter with bits flags[8191] for iter in 1..10 loop count := 0 flags[0..8191] := true for i in flags.index loop if flags[i] then prime := i+i+3 k := i + prime for k in i+prime..flags.index.high step prime loop flags[k] := false count += 1 IO.WriteLn count, " primes" And just because people will find bugs in my posts, let me mention it: there is a bug in the D implementation of the Sieve: it should be bit[8191] flags, methinks. Unless, of course, bit is special in that respect. It could be, it's a built-in type. And did I mention that built-in types are EVIL? Christophe
Aug 16 2001
Ach, a post by Chris Friesen reminded me about the switch statement. LX has two forms, one of them I care about, the other being just syntactic sugar. Syntactic sugar first: case when X > 0: do_something_with X when Y > 0: do_something_with Y when others: barf This is really another way to write "elseif". I initially thought I needed that construct because of the indent-sensitive syntax in LX, but it turns out that the indentation-checking is flexible enough to accomodate else if... I still kept the construct... The important one: procedure CheckInt(integer N) is case N is when 1: WriteLn "N is small" when 2..5: WriteLn "I can count N on one hand" when 6..10: WriteLn "I need to use two hands" when other: WriteLn "Sorry, can't do" What is interesting is that it uses a helper, variable-argument-size function to determine which case to take. So you can have a case statement with most anything. The helper function is called Index(X, T1, T2, ..., TN), and it returns the 1-based index of X inside the T1..TN objects. If none matches, it must return an out of range value (N+1 or 0 being good candidates) So for instance you can write an Index function that makes the following legal: procedure Hit(point P; rectangle R; circle C) is case P is when R: WriteLn "We hit the rectangle" when C: WriteLn "We hit the circle" when other: WriteLn "That's a miss... Christophe
Aug 16 2001
Ach, yet another post from the silly LX guy. Someone else talked about delegation. Delegation is probably the one thing that makes nEXtstEp (sorry, MacOS X 10.0.4.1 beta2 preview 3) implementable in Objective-C but not easily in C++. You ought to have this in D. A practical example: I have a window object, that can respond to several "messages" (display, resize, etc). On this window, I have several objects that know about some of the messages, but others they just don't care. One object which has the focus is the one that receives the messages from the operating system. The key issue here is: how do I forward messages that I don't care about to the window behind me, or to some other object that cares? Say the front widget interfcepts "Draw" messages, but just doesn't want to know anything about all others, such as "Resize", "Shutdown", etc... Let's try it the C++ way: class Window { virtual void Draw(...); virtual void Resize(...); ... // 12895 other members }; // Don't forget the semi-colon, it's really important, you know... OK, now, time to implement "widget". The key thing is that, from the operating system's point of view, Widget has to respond to the Window messages. So in C++, it derives from Window, right? Wrong! Let's try that first to see the problem. Assume for now that you try that for a Widget that cares only about the "Draw" message. class Widget : public Window { Window *behind_me; virtual void Draw(...) { /* something really great here */ } virtual void Resize(...) { behind_me->Resize(...); } // 12894 other members like Resize... }; The sad thing is that there is code out there actually written that way. Two major problems: it's very cumbersome to write, and the Widget inherits all of the Windows baggage, which it really doesn't care much about. And what if in MacOS X 10.0.4.1 beta2 preview 4, the OS vendor decides to add a member Recolor(...) in Window? Well, you are out of luck, because you do a very wrong thing with that: you just pass it to the base class, which thinks that it is the main window, and reformats your hard disk as a result. Other approaches: the Window base class may itself have a "delegate" field, and delegate everything. Not much better. There are a few other solutions. But ultimately, the only solutions that I saw working in C++ ran along the lines of having a single "SendMessage()" virtual function in the base class, and then a big switch statement that invokes other member functions. Which is just a way of implementing a much less efficient version of the Objective-C runtime system... In Objective-C, all message passing occurs in such a way that you can forward unknown messages to someone else, hoping that the receiving object knows what to do with it. Forwarding includes all method arguments, etc. In LX, a limited form of delegation is made possible by user-defined implicit conversions. I'm not completely satisfied with the solution yet. You would have: type window function Draw(window W, ...) function Resize(window W, ...) type widget with window Delegate function window(widget W) return window written W is return W.Delegate precedure Draw(widget W) -- Now you can write: procedure Test(widget W) Draw W -- Draw the widget Resize W -- Resize the window (delegate) As I said, I am not totally satisfied. Compared to Objective-C, it restores type safety (you give it up with the implicit conversion for only one type). On the other hand, it still has usability problems with dynamic dispatch and a few other things... Anyway, this is not about LX, it's about D, so if someone comes up with a cool solution in D... I'll be happy to borrow it for LX :-) Christophe
Aug 16 2001
What about runtime analysis of a classes members. Instead of assuming and depending on a classes function members to be located in one place, have it do a search and find the location of the function at runtime? Or if you insist upon using messages, why not use object identifiers with function name calls. So I can call a function of a class through messages, if the function does not exist it returns an error, if the function has moved it will find it and call it properly. Hmmm, maybe messages are better after all, because I could shut off an object to not recieve messages, alter that object and then turn it back on to recieve messages, this by manipulating/reprogramming an object at runtime (maybe I am being a runtime freak :)). Messages would be really interesting come to think of it. An object would need to have a socket where by a delegate could be placed in there, that delegate would know what message to send and whom to send it to. An object that sends messages would need these sockets for delegation. There really is no event handlers anymore, any function could be an event handler, its now on the other side, the delegates reside in the event generator and control what function is called in response to the generation of that event by sending a message to that function. It may even be possible to mix messages and direct function calls, delegate objects/types could be used to mask what is really happening underneath.
Aug 17 2001
What you are describing is more or less the Objective-C runtime. In Obj-C, when you write: [object drawAtX: x Y: y] what it does is create a message packet with a "selector" of drawAtX:y: and arguments (object, x, y), and then invoke a runtime routine (something like __objc_msgSend) to lookup runtime tables for the object that knows how to respond to that. It first checks the given target (object). But the given target may not respond to the message, in which case various forwarding mechanisms exist. Christophe interested wrote:What about runtime analysis of a classes members. Instead of assuming and depending on a classes function members to be located in one place, have it do a search and find the location of the function at runtime? Or if you insist upon using messages, why not use object identifiers with function name calls. So I can call a function of a class through messages, if the function does not exist it returns an error, if the function has moved it will find it and call it properly. Hmmm, maybe messages are better after all, because I could shut off an object to not recieve messages, alter that object and then turn it back on to recieve messages, this by manipulating/reprogramming an object at runtime (maybe I am being a runtime freak :)). Messages would be really interesting come to think of it. An object would need to have a socket where by a delegate could be placed in there, that delegate would know what message to send and whom to send it to. An object that sends messages would need these sockets for delegation. There really is no event handlers anymore, any function could be an event handler, its now on the other side, the delegates reside in the event generator and control what function is called in response to the generation of that event by sending a message to that function. It may even be possible to mix messages and direct function calls, delegate objects/types could be used to mask what is really happening underneath.
Aug 17 2001
A practical example: I have a window object, that can respond to several "messages" (display, resize, etc). On this window, I have several objects that know about some of the messages, but others they just don't care. One object which has the focus is the one that receives the messages from the operating system.I agree, looking at all the application frameworks out there, MFC, MacApp and so forth, they all have a common theme, pass around messages or events from one point to another. As C and C++ does not have runtime binding easily available, what happens is that the framework designers write very convoluted macro or lookup systems for making sure a message is passed from one point to another. Objective-C makes this far easier with its message passing construct. If D has this option, and it's of course another performance burden, but not as bad as one thinks, it would open up a lot of good designs concerning writing application frameworks. If one even thinks big and possibly uses a message passing system that could make use of open standards for calling other entities (SOAP, XML-RPC, and so forth), it could also provide a lot of good solutions. --Kent
Aug 17 2001
How does LX compare when it comes to runtime ( see also the "What is the D runtime like?" thread). Specifically (reposting my last post to the above thread): What does that mean with regards to: running programs that contain LX modules from multiple LX compiler versions features especially if the object model changes between the two? what about stuff like GC? running programs that have a C mainline and are linked with the C linker. running programs that have a C++ mainline? running a D module in a kernel? running a D module as a COM inproc component? Christophe de Dinechin wrote:Interestingly, my background is close to that of Walter: I also developed video games for a living, I also worked on a commercial C++ implementation, and I also designed my own language, called LX. More information on LX can be found at http://mozart-dev.sf.net. So I am going to start a big series of post to try to compare D and LX. To avoid polluting the newsgroup too much, I am going to try to post all of them under the same thread. I am obviously biased. On the other hand, I believe there is much to be gained if we exchange ideas and compare designs. Please bear with me... Christophe
Sep 13 2001
Oops, I started changing references from D to LX below and didn't get all the way through. All of the questions pertain to LX, not to D. Phil Brooks wrote:How does LX compare when it comes to runtime ( see also the "What is the D runtime like?" thread). Specifically (reposting my last post to the above thread): What does that mean with regards to: running programs that contain LX modules from multiple LX compiler versions features especially if the object model changes between the two? what about stuff like GC? running programs that have a C mainline and are linked with the C linker. running programs that have a C++ mainline? running a D module in a kernel? running a D module as a COM inproc component? Christophe de Dinechin wrote:Interestingly, my background is close to that of Walter: I also developed video games for a living, I also worked on a commercial C++ implementation, and I also designed my own language, called LX. More information on LX can be found at http://mozart-dev.sf.net. So I am going to start a big series of post to try to compare D and LX. To avoid polluting the newsgroup too much, I am going to try to post all of them under the same thread. I am obviously biased. On the other hand, I believe there is much to be gained if we exchange ideas and compare designs. Please bear with me... Christophe
Sep 13 2001