December 01, 2009 Re: dynamic classes and duck typing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Tue, 01 Dec 2009 03:13:28 -0800, Walter Bright wrote: > retard wrote: >> Overall these simplifications don't remove any crucial high level language features, in fact they make the code simpler and shorter. For instance there isn't high level code that can only be written with 8-bit byte primitives, static methods or closures, but not with 32-bit generic ints, singletons, and generic higher order functions. The only thing you lose is some type safety and efficiency. > > I'm no expert on Python, but there are some things one gives up with it: > > 1. the ability to do functional style programming. The lack of immutability makes for very hard multithreaded programming. Even if the language doesn't enforce immutability it's indeed possible to use immutable data types in a language without pure/const/final attributes. Python et al support functional style programming. The fact that php doesn't only proves that its author had no idea of what he was doing. Early php versions even had a limitation on recursion, 50 levels or something like that. They still have those limitations, somewhat relaxed. Probably no other language performs so poorly with functional code than php. > > 2. as you mentioned, there's the performance problem. It's fine if you don't need performance, but once you do, the complexity abruptly goes way up. In D, there's the simplicity problem. It's fine if you don't need readability, but once you do, the efficiency abruptly goes way down. > > 3. no contract programming (it's very hard to emulate contract > inheritance) True, this is a commonly overlooked feature. I don't know any other languages than Eiffel or D that support this. I'm not sure how hard it would be to emulate this feature in languages where you can define your own class mechanism. > > 4. no metaprogramming Dynamic languages support dynamic metaprogramming. Ever heard of e.g. lisp macros? > > 5. simple interfacing to C In case you mean no unnecessary wrappers etc., this has more to do with the execution model than language features. Most scripting languages are interpreted, and require some sort of assistance from the runtime system. If the language was compiled instead, they wouldn't necessarily need those. > > 6. scope guard (transactional processing); Python has the miserable > try-catch-finally paradigm Ok. On the other hand, I don't know why this can't be done with runtime metaprogramming features. > > 7. static verification Dynamic language users argue that since the language is much simpler, you don't need to verify anything. And you still have unit test frameworks. > > 8. RAII Ok. I think this could also be enforced dynamically. > > 9. versioning I don't know why this can't be done dynamically. > 10. ability to manage resources directly Ok. > > 11. inline assembler Ok. Note that I wrote >> Overall these simplifications don't remove any crucial ___high level___ language features, > > 12. constants I don't know why this can't be done dynamically with wrapper objects. |
December 01, 2009 Re: dynamic classes and duck typing | ||||
---|---|---|---|---|
| ||||
Posted in reply to retard | retard, el 1 de diciembre a las 11:42 me escribiste: > Tue, 01 Dec 2009 03:13:28 -0800, Walter Bright wrote: > > > retard wrote: > >> Overall these simplifications don't remove any crucial high level language features, in fact they make the code simpler and shorter. For instance there isn't high level code that can only be written with 8-bit byte primitives, static methods or closures, but not with 32-bit generic ints, singletons, and generic higher order functions. The only thing you lose is some type safety and efficiency. > > > > I'm no expert on Python, but there are some things one gives up with it: > > > > 1. the ability to do functional style programming. The lack of immutability makes for very hard multithreaded programming. > > Even if the language doesn't enforce immutability it's indeed possible to use immutable data types in a language without pure/const/final attributes. And BTW, Python *have* some built-in immutable types (strings, tuples, integers, floats, frozensets, and I don't remember if there is anything else). Python uses convention over hard-discipline (no public/private for example), so you can make your own immutable types, just don't add mutating methods and don't mess with. I agree it's arguable, but people actually use this conventions (they are all consenting adults :), so things works. I can only speak from experience, and my bug count in Python is extremely low, even when doing MT (the Queue module provides a very easy way to pass messages from one thread to another). I agree that, when you don't care much for performance, things are much easier :) > > 2. as you mentioned, there's the performance problem. It's fine if you don't need performance, but once you do, the complexity abruptly goes way up. > > In D, there's the simplicity problem. It's fine if you don't need readability, but once you do, the efficiency abruptly goes way down. > > > > > 3. no contract programming (it's very hard to emulate contract > > inheritance) > > True, this is a commonly overlooked feature. I don't know any other languages than Eiffel or D that support this. > > I'm not sure how hard it would be to emulate this feature in languages where you can define your own class mechanism. There are libraries to do contracts in Python: http://www.wayforward.net/pycontract/ http://blitiri.com.ar/git/?p=pymisc;a=blob;f=contract.py;h=0d78aa3dc9f3af5336c8d34ce521815ebd7d5ea0;hb=HEAD I don't know if they handle contract inheritance though. There is a PEP for that too: http://www.python.org/dev/peps/pep-0316/ But I don't many people really wants DbC in Python, so I don't think it would be implemented. > > 4. no metaprogramming > > Dynamic languages support dynamic metaprogramming. Ever heard of e.g. lisp macros? Exactly! You can even generate code dynamically! This is a very nice example: http://code.activestate.com/recipes/362305/ It makes "self" implicit in *pure Python*. If you say dynamic languages don't have metaprogramming capabilities, you just don't have any idea of what a dynamic language really is. > > 5. simple interfacing to C > > In case you mean no unnecessary wrappers etc., this has more to do with the execution model than language features. Most scripting languages are interpreted, and require some sort of assistance from the runtime system. If the language was compiled instead, they wouldn't necessarily need those. In D you need interfacing code too, it can be a little simpler, that's true. > > 6. scope guard (transactional processing); Python has the miserable > > try-catch-finally paradigm WRONG! See the with statement: http://www.python.org/dev/peps/pep-0343/ with lock: some_non_mt_function() with transaction: some_queries() with file(fname) as f: x = f.read(10) f.write(x) > > 8. RAII > > Ok. > > I think this could also be enforced dynamically. Again, the with statement. > > > > 9. versioning > > I don't know why this can't be done dynamically. It can, and it's pretty common, you can do things like this: class A: if WHATEVER: def __init__(self): pass else: def __init__(self, x): pass > > 10. ability to manage resources directly What do you mean by resource? > > 11. inline assembler You can do bytecode manipulation, which is the assembler of dynamic languages :) I really think the *only* *major* advantage of D over Python is speed. That's it. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- Cuando el Mártir estaba siendo perseguido y aglutinado por los citronetos, aquellos perversos que pretendian, en su maldad, piononizar las enseñanzas de Peperino. -- Peperino Pómoro |
December 01, 2009 Re: dynamic classes and duck typing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Leandro Lucarella | Leandro Lucarella wrote: > retard, el 1 de diciembre a las 11:42 me escribiste: >> Tue, 01 Dec 2009 03:13:28 -0800, Walter Bright wrote: >> >>> retard wrote: >>>> Overall these simplifications don't remove any crucial high level >>>> language features, in fact they make the code simpler and shorter. For >>>> instance there isn't high level code that can only be written with >>>> 8-bit byte primitives, static methods or closures, but not with 32-bit >>>> generic ints, singletons, and generic higher order functions. The only >>>> thing you lose is some type safety and efficiency. >>> I'm no expert on Python, but there are some things one gives up with it: >>> >>> 1. the ability to do functional style programming. The lack of >>> immutability makes for very hard multithreaded programming. >> Even if the language doesn't enforce immutability it's indeed possible to use immutable data types in a language without pure/const/final attributes. > > And BTW, Python *have* some built-in immutable types (strings, tuples, > integers, floats, frozensets, and I don't remember if there is anything > else). Python uses convention over hard-discipline (no public/private for > example), so you can make your own immutable types, just don't add > mutating methods and don't mess with. I agree it's arguable, but people > actually use this conventions (they are all consenting adults :), so > things works. I agree that statically enforced immutability is unnecessary if you are able to rigidly follow an immutability convention. C++ also has immutability by convention. People who work in large teams with programmers of all skill levels tell me, however, that having a convention and being sure it is followed 100% are two very different things. > I can only speak from experience, and my bug count in Python is extremely > low, even when doing MT (the Queue module provides a very easy way to pass > messages from one thread to another). How about the GIL? > I agree that, when you don't care much for performance, things are much > easier :) I would also agree that your bug count and complexity should be low as long as you're staying within the paradigms that Python (or any language) was designed to support. >>> 2. as you mentioned, there's the performance problem. It's fine if you >>> don't need performance, but once you do, the complexity abruptly goes >>> way up. >> In D, there's the simplicity problem. It's fine if you don't need readability, but once you do, the efficiency abruptly goes way down. That, I strongly disagree with. >>> 3. no contract programming (it's very hard to emulate contract >>> inheritance) >> True, this is a commonly overlooked feature. I don't know any other languages than Eiffel or D that support this. >> >> I'm not sure how hard it would be to emulate this feature in languages where you can define your own class mechanism. I suspect it is a very hard problem to do with just front end rewriting, 1. I've never seen anyone manage to do it 2. I had to adjust the code generator to make it work > But I don't many people really wants DbC in Python, so I don't think it > would be implemented. That goes back to if you're staying inside the supported paradigms or not. >>> 4. no metaprogramming >> Dynamic languages support dynamic metaprogramming. Ever heard of e.g. lisp macros? > > Exactly! You can even generate code dynamically! This is a very nice > example: > http://code.activestate.com/recipes/362305/ > > It makes "self" implicit in *pure Python*. > > If you say dynamic languages don't have metaprogramming capabilities, you > just don't have any idea of what a dynamic language really is. Ok, can you do Bill Baxter's swizzler? Can you do Don Clugston's FPU code generator? >>> 5. simple interfacing to C >> In case you mean no unnecessary wrappers etc., this has more to do with the execution model than language features. Most scripting languages are interpreted, and require some sort of assistance from the runtime system. If the language was compiled instead, they wouldn't necessarily need those. > > In D you need interfacing code too, it can be a little simpler, that's > true. The interfacing in D is nothing more than providing a declaration. There is no code executed. >>> 6. scope guard (transactional processing); Python has the miserable >>> try-catch-finally paradigm > > WRONG! See the with statement: > http://www.python.org/dev/peps/pep-0343/ > > with lock: > some_non_mt_function() > > with transaction: > some_queries() > > with file(fname) as f: > x = f.read(10) > f.write(x) Looks like you're right, and it's a recently added new feature. I suggest it proves my point - Python had to add complexity to support another paradigm. Python's "with" doesn't look any simpler than scope guard. >>> 8. RAII >> Ok. >> >> I think this could also be enforced dynamically. > > Again, the with statement. Yes, you can emulate RAII with the with statement, but with RAII (objects that destruct when they go out of scope) you can put this behavior in the object rather than explicitly in the code every time you use it. It's more complicated to have to remember to do it every time on use. >>> 9. versioning >> I don't know why this can't be done dynamically. > > It can, and it's pretty common, you can do things like this: > > class A: > if WHATEVER: > def __init__(self): > pass > else: > def __init__(self, x): > pass > >>> 10. ability to manage resources directly > > What do you mean by resource? Garbage collection isn't appropriate for managing every resources. Scarce ones need handling manually. Even large malloc's often are better done outside of the gc. >>> 11. inline assembler > > You can do bytecode manipulation, which is the assembler of dynamic > languages :) That doesn't help if you really need to do a little assembler. > I really think the *only* *major* advantage of D over Python is speed. > That's it. I probably place a lot more importance on static verification rather than relying on convention and tons of unit tests. |
December 01, 2009 Re: dynamic classes and duck typing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Leandro Lucarella | Leandro Lucarella wrote: > retard, el 1 de diciembre a las 11:42 me escribiste: >> Tue, 01 Dec 2009 03:13:28 -0800, Walter Bright wrote: >> >>> retard wrote: >>>> Overall these simplifications don't remove any crucial high level >>>> language features, in fact they make the code simpler and shorter. For >>>> instance there isn't high level code that can only be written with >>>> 8-bit byte primitives, static methods or closures, but not with 32-bit >>>> generic ints, singletons, and generic higher order functions. The only >>>> thing you lose is some type safety and efficiency. >>> I'm no expert on Python, but there are some things one gives up with it: >>> >>> 1. the ability to do functional style programming. The lack of >>> immutability makes for very hard multithreaded programming. >> Even if the language doesn't enforce immutability it's indeed possible to use immutable data types in a language without pure/const/final attributes. > > And BTW, Python *have* some built-in immutable types (strings, tuples, > integers, floats, frozensets, and I don't remember if there is anything > else). Python uses convention over hard-discipline (no public/private for > example), so you can make your own immutable types, just don't add > mutating methods and don't mess with. I agree it's arguable, but people > actually use this conventions (they are all consenting adults :), so > things works. > > I can only speak from experience, and my bug count in Python is extremely > low, even when doing MT (the Queue module provides a very easy way to pass > messages from one thread to another). But wait, my understanding is that threading in Python is a complete shame: one global lock. Is that correct? FWIW, that's such a bad design that _nobosy_ I know every brought it up except in jest. > I agree that, when you don't care much for performance, things are much > easier :) I've hoped to leave my trace in history with a one-liner: "Inefficient abstractions are a dime a dozen". Didn't seem to catch up at all :o). > I really think the *only* *major* advantage of D over Python is speed. > That's it. In wake of the above, it's actually huge. If you can provide comparable power for better speed, that's a very big deal. (Usually dynamic/scripting languages are significantly more powerful because they have fewer constraints.) Andrei |
December 01, 2009 Re: dynamic classes and duck typing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote:
> Leandro Lucarella wrote:
>> with file(fname) as f:
>> x = f.read(10)
>> f.write(x)
>
> Looks like you're right, and it's a recently added new feature. I suggest it proves my point - Python had to add complexity to support another paradigm. Python's "with" doesn't look any simpler than scope guard.
Actually "with" is an awful abstraction as defined in Java (the new version), C#, and Python. Scheme also has am unwind-protect function. I strongly believe all of the above are hopelessly misguided. Scope guard is the right thing, and I am convinced it will prevail.
Andrei
|
December 01, 2009 Re: dynamic classes and duck typing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | I suggest Walter to don't try to say that D2 is "better" than Python, it's a waste of time and it means nothing. Walter Bright: >can you do Bill Baxter's swizzler? Can you do Don Clugston's FPU code generator?< Python is more more flexible. See the __getattr__ standard method: class Reg4(object): ORDER = dict((c,i) for i,c in enumerate("wxyz")) def __init__(self, data=None): self.data = [None] * 4 if data: for i, item in enumerate(data): self.data[i] = item def __getattr__(self, attr): assert sorted(list(attr)) == ['w', 'x', 'y', 'z'] self.data[:] = (self.data[Reg4.ORDER[c]] for c in attr) r = Reg4("ABCD") print r.data r.xyzw print r.data Output: ['A', 'B', 'C', 'D'] ['B', 'C', 'D', 'A'] If you want the r.xyzw() syntax, that too can be done, creating new methods on the fly. In Python there's also the __getattribute__ that's a little more powerful than __getattr__: http://pyref.infogami.com/__getattribute__ >That doesn't help if you really need to do a little assembler.< That Reg4() class can actually use true SSE registers, generating and running very efficient asm computational kernels using corepy: http://www.corepy.org/ And you can also use GPUs with PyCuda and PyOpenCL in Python: http://mathema.tician.de/software/pycuda http://python-opencl.next-touch.com/ With Python + CorePy today you can write heavy numerical code that's faster than all D code. Bye, bearophile |
December 01, 2009 Re: dynamic classes and duck typing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright, el 1 de diciembre a las 10:46 me escribiste: > >And BTW, Python *have* some built-in immutable types (strings, tuples, integers, floats, frozensets, and I don't remember if there is anything else). Python uses convention over hard-discipline (no public/private for example), so you can make your own immutable types, just don't add mutating methods and don't mess with. I agree it's arguable, but people actually use this conventions (they are all consenting adults :), so things works. > > I agree that statically enforced immutability is unnecessary if you are able to rigidly follow an immutability convention. C++ also has immutability by convention. People who work in large teams with programmers of all skill levels tell me, however, that having a convention and being sure it is followed 100% are two very different things. Yes, I know, probably Python (and most dynamic languages) and Java are the two extremes in this regard. > >I can only speak from experience, and my bug count in Python is extremely low, even when doing MT (the Queue module provides a very easy way to pass messages from one thread to another). > > How about the GIL? The GIL is a performance issue. As I said, that's the only point where D is stronger than Python (and maybe other dynamic languages, I mention Python because is the language I use the most). > >I agree that, when you don't care much for performance, things are much easier :) > > I would also agree that your bug count and complexity should be low as long as you're staying within the paradigms that Python (or any language) was designed to support. Of course. But Python is a very flexible language (or I use too few paradigms when programming ;). > >>>4. no metaprogramming > >>Dynamic languages support dynamic metaprogramming. Ever heard of e.g. lisp macros? > > > >Exactly! You can even generate code dynamically! This is a very nice > >example: > >http://code.activestate.com/recipes/362305/ > > > >It makes "self" implicit in *pure Python*. > > > >If you say dynamic languages don't have metaprogramming capabilities, you just don't have any idea of what a dynamic language really is. > > Ok, can you do Bill Baxter's swizzler? Can you do Don Clugston's FPU code generator? I don't know any of those things, but I know Python have very good metaprogramming capabilities (decorators and metaclasses being probably the 2 bigger features in this regard). > >>>5. simple interfacing to C > >>In case you mean no unnecessary wrappers etc., this has more to do with the execution model than language features. Most scripting languages are interpreted, and require some sort of assistance from the runtime system. If the language was compiled instead, they wouldn't necessarily need those. > > > >In D you need interfacing code too, it can be a little simpler, that's true. > > The interfacing in D is nothing more than providing a declaration. There is no code executed. Unless you want to pass D strings to C, then you have to execute toStringz(), which is a really thin "wrapper", but it's a wrapper. Using C from D is (generally) error prone and painful, so I usually end up writing more D'ish wrappers to make the D coding more pleasant. And BTW, you can access C dynamic libraries in Python via the ctype module: http://docs.python.org/library/ctypes.html It's not safe, and of course, being a dynamic language, you can access C code at "compile time" (because there it no compile time), but you can interface with C very easily: >>> import ctypes >>> libc = ctypes.cdll.LoadLibrary("libc.so.6") >>> libc.printf("hello world %i\n", 5) hello world 5 Wow, that was hard! =) > >>>6. scope guard (transactional processing); Python has the miserable > >>>try-catch-finally paradigm > > > >WRONG! See the with statement: http://www.python.org/dev/peps/pep-0343/ > > > >with lock: > > some_non_mt_function() > > > >with transaction: > > some_queries() > > > >with file(fname) as f: > > x = f.read(10) > > f.write(x) > > Looks like you're right, and it's a recently added new feature. I suggest it proves my point - Python had to add complexity to support another paradigm. Python's "with" doesn't look any simpler than scope guard. It's simpler, because you only have one obvious way to do things, in D you can use a struct, a scope class or a scope statement to achieve the same. Of course that gives you more flexibility, but adds complexity to the language. I'm not complaining or saying that D is wrong, I'm just saying that Python is a very expressive language without much complexity. I think the tradeoff is the speed. > >>>8. RAII > >>Ok. > >> > >>I think this could also be enforced dynamically. > > > >Again, the with statement. > > Yes, you can emulate RAII with the with statement, but with RAII (objects that destruct when they go out of scope) you can put this behavior in the object rather than explicitly in the code every time you use it. It's more complicated to have to remember to do it every time on use. Maybe you are right, but the with statement plays very well with the "explicit is better than implicit" of Python :) Again, is flexibility vs complexity. > >>>10. ability to manage resources directly > > > >What do you mean by resource? > > Garbage collection isn't appropriate for managing every resources. Scarce ones need handling manually. Even large malloc's often are better done outside of the gc. We are talking about performance again. If you need speed, I agree Python is worse than D. > >>>11. inline assembler > > > >You can do bytecode manipulation, which is the assembler of dynamic languages :) > > That doesn't help if you really need to do a little assembler. Right, but I don't think anyone uses assembler just for fun, you use it either for optimization (where I already said D is better than Python) or for doing some low-level stuff (where Python clearly is not a viable option). > >I really think the *only* *major* advantage of D over Python is speed. That's it. > > I probably place a lot more importance on static verification rather than relying on convention and tons of unit tests. There are static analyzers for Python: http://www.logilab.org/857 http://divmod.org/trac/wiki/DivmodPyflakes http://pychecker.sourceforge.net/ And again, judging from experience, I don't know why, but I really have a very small bug count when using Python. I don't work with huge teams of crappy programmers (which I think is the scenario that D tries to cover), that can be a reason ;) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- Creativity is great but plagiarism is faster |
December 01, 2009 Re: dynamic classes and duck typing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Andrei Alexandrescu, el 1 de diciembre a las 11:07 me escribiste: > Walter Bright wrote: > >Leandro Lucarella wrote: > >>with file(fname) as f: > >> x = f.read(10) > >> f.write(x) > > > >Looks like you're right, and it's a recently added new feature. I suggest it proves my point - Python had to add complexity to support another paradigm. Python's "with" doesn't look any simpler than scope guard. > > Actually "with" is an awful abstraction as defined in Java (the new version), C#, and Python. Scheme also has am unwind-protect function. I strongly believe all of the above are hopelessly misguided. Scope guard is the right thing, and I am convinced it will prevail. Good arguments! -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- Los pobres buscan su destino. Acá está; ¿no lo ven? -- Emilio Vaporeso. Marzo de 1914 |
December 01, 2009 Re: dynamic classes and duck typing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Andrei Alexandrescu, el 1 de diciembre a las 10:58 me escribiste: > >I really think the *only* *major* advantage of D over Python is speed. That's it. > > In wake of the above, it's actually huge. If you can provide comparable power for better speed, that's a very big deal. (Usually dynamic/scripting languages are significantly more powerful because they have fewer constraints.) I develop twice as fast in Python than in D. Of course this is only me, but that's where I think Python is better than D :) I think only not having a compile cycle (no matter how fast compiling is) is a *huge* win. Having an interactive console (with embedded documentation) is another big win. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- When I was a child I had a fever My hands felt just like two balloons. Now I've got that feeling once again I can't explain you would not understand This is not how I am. I have become comfortably numb. |
December 01, 2009 Re: dynamic classes and duck typing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Leandro Lucarella | Leandro Lucarella wrote:
> Andrei Alexandrescu, el 1 de diciembre a las 11:07 me escribiste:
>> Walter Bright wrote:
>>> Leandro Lucarella wrote:
>>>> with file(fname) as f:
>>>> x = f.read(10)
>>>> f.write(x)
>>> Looks like you're right, and it's a recently added new feature. I
>>> suggest it proves my point - Python had to add complexity to
>>> support another paradigm. Python's "with" doesn't look any simpler
>>> than scope guard.
>> Actually "with" is an awful abstraction as defined in Java (the new
>> version), C#, and Python. Scheme also has am unwind-protect
>> function. I strongly believe all of the above are hopelessly
>> misguided. Scope guard is the right thing, and I am convinced it
>> will prevail.
>
> Good arguments!
Yah, point taken :o). I probably haven't clarified enough that I'm talking about a mere belief. Arguments have been discussed here in the past (e.g. scalability of the language construct with multiple transactions). Time will tell, but one indicating factor is that programs don't deal well with exceptions and scope guards help that massively, whereas "with" seems to help much less. Besides, anyone may be a nut about something, and scope guard is something I'm a nut about.
Andrei
|
Copyright © 1999-2021 by the D Language Foundation