Compiler optimization breaks multi-threaded code
There is one question on SO which seems like a serious problem for atomic ops. http://stackoverflow.com/questions/4165149/compiler-optimization-breaks- multi-threaded-code in short: shared uint cnt; void atomicInc ( ) { uint o; while ( !cas( &cnt, o, o + 1 ) ) o = cnt; } is compiled with dmd -O to something like: shared uint cnt; void atomicInc ( ) { while ( !cas( &cnt, cnt, cnt + 1 ) ) { } } see the web page for details.
Re: Proposal: User Code Bug Tracking
V Thu, 25 Nov 2010 01:32:36 +, dsimcha wrote: > The root cause of my last D2 bug was closest to: Signed/unsigned comparison and arithmetic see http://www.digitalmars.com/d/archives/digitalmars/D/learn/ Mixing_operations_with_signed_and_unsigned_types_20347.html to work around this bug, and get error at compile time you can create template for built in operators (< + - /): as 'lt' mentioned in the archived post, and use: lt(a, b) instead of a < b. If it were not possible to make such templates, I would be hunting bugs in my sometime wrong/sometime not calculations to this day. It is quite hard to avoid using unsigned types, especially when you are using auto.
Re: uniqueness
V Fri, 10 Dec 2010 11:53:04 +0100, Don wrote: > Any mutable object returned from a strongly pure function, is guaranteed > to be unique. the function should be probably be safe too, to guarentee to not cast const away.
Re: memoize (is this a fix for overloading?)
On Tue, 04 Jan 2011 22:49:11 +, %u wrote: > (An unrelated side note: I'm new to newsgroups, and I was wondering, > what program do people mainly use for communication? I'm using the web > interface, but do most people use Thunderbird or something? Thank you!) Also outlook express, omea reader, pan and there many more nntp new readers; any is much better than the web interface (which is used mainly as a temp solution or to make web links to posts).
Re: C# Interop
On Mon, 31 Jan 2011 21:25:11 +, Eelco Hoogendoorn wrote: > Do I just create a D DLL with a bunch of free extern(C) function for > communication? Yes, why not. You can pass struts in extern(C) functions... > What about marshalling? Is using unsafe pointers back and > forth the best I can do? No. > C# can read from a pointer allocated by D in > unsafe mode, and D can read from a pinned C# pointer, right? Yes. Just an idea, but have you considered using COM. C# interoperates with it seamlessly and heard of some D projects using it. one starter link: http://www.dsource.org/projects/juno/wiki/ComProgramming
Re: d-m-l.org rendering error?
V Mon, 28 Nov 2011 12:42:13 +0100, Andrea Fontana wrote: > On this page: > http://d-programming-language.org/class.html I can confirm this (in Firefox).
Re: Program size, linking matter, and static this()
On 21. 12. 2011 14:22, so wrote: Supporting module nesting in single file wouldn't hurt, would it? module main; module nested { } Kind of... template MyNamespaceImpl () { int i; } alias MyNamespaceImpl!() MyNamespace; void main () { MyNamespace.i = 1; with (MyNamespace) { i = 2; } writeln(MyNamespace.i); readln(); }
Re: Inheritance of purity
V Thu, 16 Feb 2012 18:49:40 -0800, Walter Bright wrote: > Given: > > class A { void foo() { } } > class B : A { override pure void foo() { } } > > This works great, because B.foo is covariant with A.foo, meaning it can > "tighten", or place more restrictions, on foo. Will the 'inheritance' of attributes work for interfaces too? interface I { void foo() @safe pure nothrow const; } class B : I { void foo() { } } // is it @safe pure nothrow const ?
Re: Dynamic language
http://rigaux.org/language-study/scripting-language/
Re: compiler support added for precise GC
On Wednesday, 18 April 2012 at 10:07:59 UTC, Robert Clipsham wrote: // a.d class Base { /* whatever magic to get derived classes */ } // b.d import a; class Derived : Base {} void main() {} to find derived classes at runtime: http://forum.dlang.org/thread/mailman.1052.1292505452.21107.digitalmars-d-le...@puremagic.com#post-op.vns7nfjpvxi10f:40biotronic-pc.lan
Re: D folk in London 2013-05-28
On Wednesday, 24 April 2013 at 18:56:10 UTC, Russel Winder wrote: I will be doing an "In the Brain" session at Skills Matter 2013-05-28 18:30+01:00: Are Go and D threats to Python? http://skillsmatter.com/podcast/nosql/are-go-and-d-threats-to-python/mh-7066 http://www.meetup.com/skillsmatter/events/115928192/confirm/ Anyone in London at that time is most welcome to come and heckle. Interesting topic. Will a recoding be available online ?
Re: Value Range Propagation
V Tue, 22 Feb 2011 22:23:32 -0800, Walter Bright wrote: > http://ddj.com/blog/archives/2011/02/value_range_pro.html This case is missed. The result must be always in range of ubyte. ubyte ub; ubyte a = 255 - ub; // Error: cannot implicitly convert expression // (255 - cast(int)ub) of type int to ubyte
Re: Which D features to emphasize for academic review article
On Tuesday, 14 August 2012 at 10:31:30 UTC, Mehrdad wrote: Note to Walter: You're obviously correct that you can make an arbitrarily complex program to make it too difficult for the compiler to enforce initialization, the way C# does (and gives up in some cases). What you seem to be missing is that the issue you're saying is correct in theory, but too much of a corner case in practice. C#/Java programmers ___rarely___ run into the sort of issue you're mentioning, and even when they do, they don't have nearly as much of a problem with fixing it as you seem to think. Completely agree. I find it quite useful in C#. It helps a lot in hairy code (nested if/foreach/try) to make sure all cases are handled when initializing variable. Compilation errors can be simply dismissed by assigning a 'default' value to variable at the beginning the functions, but is generally a sloppy programing and you loose useful help of the compiler. The rules in C# are very simple and almost verbatim can be applied to D http://msdn.microsoft.com/en-us/library/aa691172%28v=vs.71%29.aspx
Re: Fixing enum names in Phobos
On Mon, 01 Aug 2011 05:56:22 +, %u wrote: > How do you plan on camelCasing pure, nothrow, out, ref, etc? simply add exception to the camelCase rule: if word is keyword, use PascalCase. IMO, easier to remember and to the eyes than any kind of ad-hoc pre/sufix.
Re: Allocators/region allocator proposal overhaul
V Sun, 11 Sep 2011 19:25:41 +, dsimcha wrote: > Is there any easy way to getDDoc to document that a mixin template has > been mixed into a class/struct? I.e.: > > struct Foo { > /// Document that this is mixed in. > mixin SomeMixin; > } Currently none. http://d.puremagic.com/issues/show_bug.cgi?id=648
Re: The design principles of D (aka The D Manifesto)
On Sun, 13 Jun 2010 18:01:23 +, dsimcha wrote: > The one that seems to resonate most strongly throughout the design of D > is "thou shalt not need to write boilerplate code". The inclusion of > features such as mixins, properties, ranges, highly streamlined operator > overloading and a template system much more powerful than C++'s means > that if you're writing lots boilerplate code in D, there's probably a > template function, struct or class of some kind that you need to write > that will do it for you. Contrast this to Java, where boilerplate code > is so prevalent that IDE features are designed specifically to write it > for you, or to C++, where people insist that having to write tons of > boilerplate to do even the simplest thing is just the price you pay for > flexibility. Very good point IMO. By using opposite word "DRY", it could be said that D is designed to you keep you programs DRY, and makes it very easy and natural thing to do. If one finds himself repeating code, he should consult docs, or ask on NG. One important thing I can think out right now is that it is natural for D to have safe abstractions. Either by creating them upon built-in types like arrays and strings or by using compile time techniques for advanced type checking. Also, it might be good remind C programmers that exceptions are generally preferred error handling mechanism in D.
Re: Is the declaration grammar definition of 'Parameter' correct?
On Sun, 13 Jun 2010 20:15:46 +, BCS wrote: > The first thing to do is put all of the description of the grammar in > the docs into one place. If we are at it, it would be good to enhance visual representation of docs by generate syntax diagram, similarly as on http://www.json.org/ it not only helps to learn and understand grammar, but also lowers the barrier to just looking at it. When I first saw this kind of diagrams on JSON site, it made good impression on me. Tool used for this is. http://dotnet.jku.at/applications/Visualizer/ Another important point is - having it visually really help find and enhance specs. This tools accepts EBNF syntax that is specified on the page. D syntax is specified in BNF, and uses different syntax, but (E)BNF is so simple, it should be possible to adjust different syntaxes just using regex (I think/ hope). If there is interest in such diagrams, and there is one file syntax file, I would be willing to make changes to this tool (C#) to be able to batch- generate these images. (It would be also a good idea to look at first if BNF diagrams look good, and if EBNF isn't necessary.)
Re: immutable singleton pattern with static opCall
On Sun, 27 Jun 2010 09:36:04 +0930, Justin Johansson wrote: > immutable class Foo > { > static private Foo instance; > > static this() { // line 9 >instance = new Foo; > } > > static Foo opCall() { // line 13 >return instance; > } > } > > test.d(9): Error: function test.Foo._staticCtor2 without 'this' cannot > be const/immutable > test.d(13): Error: function test.Foo.opCall without 'this' cannot be > const/immutable there is bug report on this subject http://d.puremagic.com/issues/show_bug.cgi?id=3598 Your example also uses static variable, which was not considered in the bug report. This makes things more complex to design properly, because it seems now that one does not want static functions to be affected by immutable attribute of class, but it should affect static data...
Re: Why don't other programming languages have ranges?
maybe this will give some pointers http://lambda-the-ultimate.org/node/3520
Re: Alias parameters for templates does not accept built-in types
On Sat, 14 Aug 2010 04:03:15 +, Deokjae Lee wrote: > template T(alias X) { > Error: template instance T!(int) does not match template declaration T > (alias X) > However, I got a reply that the behavior is intended. I think the > limitation that the built-in types are not accepted as alias parameters > for templates is not beautiful :( That's a kind of lack of symmetry and > practice :) I'd like to know the reason of such a limitation. I would guess that it is because name of built-in types are keywords, while other names are not. But it is possible to overload templates with and without alias: template T(alias X) { pragma(msg, "alias X ->"~ X.stringof); } template T(X) { pragma(msg, "X ->" ~ X.stringof); } ...given the ability to send keyword aliases to template, templates would come closer to macros.
Re: The Status of Const
On Tue, 17 Aug 2010 12:05:55 +0200, Pelle wrote: > class C { } > class D : C { } > class E : C { } > > void append_to(ref const(C)[] cs, const(C) c) { cs ~= c; } > > D[] ds; > append_to(ds, new E); > > > *ahem* > D[] can not be converted to const(C). That it works today is pretty > terrible. Rewrite the append_to to work with Objects, and well. :-) what about appending instance of C? Doing this, you would end up with arrays of Ds, where one item will be instance of C! D[] ds; append_to(ds, new C);
[OT]
Hi, could somebody please approve my email to phobos mailing list. I received message: ...Is being held until the list moderator can review it for approval. The reason it is being held: Post to moderated list... I suppose the moderation is only for first message... Thank you.
Re: Please comment on http://d-programming-language.org/
On Thu, 02 Sep 2010 02:03:33 -0500, Andrei Alexandrescu wrote: > Time to zero in on the overall design and start working on the content. > Please give the design one more round of comments. > > Thanks, > > Andrei Few opinions and observations: 1. It is common practice that clicking on site logo links to site root. In this case it goes to digitalmars.com. This should be fixed and separate link to digitalmars.com should be provided in header 2. Flare is good, without it the design would look boring. 3. Many headers have smaller font than the normal text font. Look for instance at the overview page (chromium / linux). 4. I like the size of the basic text and code font. - chromium / linux But I would preffer the code font to be slight larger than text font (now is the slightly smaller) - the browser uses curier new or similar for code - firefox / linux text and code font seems to be the same size. - the browser uses Monospace font for code 5. The page reacts very well to zooming in and out in browser, which is a very good thing
Re: do D support something like C# 4.0 co/contra-variance?
On Thu, 02 Sep 2010 07:38:24 -0400, bearophile wrote: > dennis: >> http://blog.t-l-k.com/dot-net/2009/c-sharp-4-covariance-and- contravariance > > I think D2 doesn't support those things yes. But they are useful and may > be added to D3. > > Bye, > bearophile I did not explored this area much, but it seems thanks to duck typed D templates, in some cases template covariance and contravariance is achievable implicitly (see the code example). It is also worth noting that C# does not support more simple OO feature - covariant return types [1], which I really miss when programming in C#. The variance of D templates may be quite hard to specify and implement, given the genericity and complexity of templates. But I'm sure at least some effects are implementable right now - like safe contra/variant cast; and it should be also possible to add variable to types as variance annotations, which are checkable at ct...I might look closer at this some time.. [1] http://www.digitalmars.com/d/2.0/function.html import std.stdio; class Rect { void draw () { writeln ("Rect"); } } class RoundedRect : Rect { override void draw () { writeln ("RoundedRect"); } } class UltraRect : RoundedRect { override void draw () { writeln ("UltraRect"); } } class List (T) { private T[] items; void add (T item) { items ~= item; } T[] getAll () { return items.dup; } } void fill (T) (List!(T) list) { // list.add (new Rect); // errors here: // function List!(RoundedRect).List.add (RoundedRect item) is not callable using argument types (Rect) // cannot implicitly convert expression (new Rect) of type Rect to RoundedRect list.add (new RoundedRect); list.add (new UltraRect); } void drawAll (T) (List!(T) items) { foreach (item; items.getAll()) item.draw(); } void main () { auto l = new List!(RoundedRect); fill (l); drawAll (l); }
Re: do D support something like C# 4.0 co/contra-variance?
On Thu, 02 Sep 2010 07:38:24 -0400, bearophile wrote: > dennis: >> http://blog.t-l-k.com/dot-net/2009/c-sharp-4-covariance-and- contravariance > > I think D2 doesn't support those things yes. But they are useful and may > be added to D3. > > Bye, > bearophile I just found... http://digitalmars.com/d/2.0/phobos/std_traits.html#isCovariantWith
Re: dmd 2.063 generated code a lot slower then dmd 2.062
On Monday, 14 October 2013 at 11:34:06 UTC, Benjamin Thaut wrote: Visual Studio requests CRLF file endings... But I fully agree CRLF should die. Kind Regards Benjamin Thaut Visual Studio (at least 2010) keeps whatever original CR / LF or CRLF line endings were in file when you opened it. Even warns you when file contains mixed line endings and keeps each line as it were. You can change/normalize them in men File/Advance Save Options.
Re: Eloquently sums up my feelings about the disadvantages of dynamic typing
On Wednesday, 16 October 2013 at 17:27:54 UTC, H. S. Teoh wrote: some default error handler somewhere that swallows all JS errors That would be function bound to window.onerror event. Remove it, or put breakpoint in it; Also "use strict"; on new code. But it might be valuable to find out if it pays of putting it to use on old code (if it isn't too much warnings -> refactoring needed). One benefit, among few others, is that assignment to undeclared variable throws exception.
Re: Slow performance compared to C++, ideas?
On Friday, 31 May 2013 at 04:06:58 UTC, deadalnix wrote: I don't think going as far as making thing final by default make sense at this point. But we sure need a way to be able to finalize methods. We had an extensive discussion with Don and Manu at DConf, here are some idea that came out : - Final by default [..] - Introduce a virtual keyword. [..] C# has final by default, and mandatory virtual keyword. Barely anyone complained. Mostly is considered a good thing to be explicit. As for the D, since the override keyword is mandatory, it would be a compiler error to omit a virtual keyword on base method, and thus easily fixable. As for the methods that are supposed to be virtual but never actual overridden - there you must know which ones that should be, and make that explicit. This applies only for libraries, and only the ones that use lot of methods intend to be overridden (generally questionable design) have some work to do on being explicit about virtual.
Re: Slow performance compared to C++, ideas?
On Monday, 3 June 2013 at 17:18:55 UTC, Andrei Alexandrescu wrote: override is not comparable because it improves code correctness and maintainability, for which there is ample prior evidence. It's also a matter for which, unlike virtual/final, there is no reasonable recourse. Virtual by default makes it simpler to call method on object that is not initialized yet (constructor not called yet). This situation is possible regardless if virtual is default or not (it can just happen more easily). I think this calling virtual function in constructor should generate a warning. (I wouldn't be surprised if there is enhancement request filed for this already) module test; import std.stdio; class Base { this () { writeln("Base.this"); foo(); } void foo () { writeln("Base.foo"); } } class Derived : Base { this () { writeln("Derived.this"); } override void foo () { writeln("Derifed.foo"); } } void main () { auto d = new Derived; } Program output: Base.this Derifed.foo // Derived.foo is called before object constructor Derived.this
Re: Slow performance compared to C++, ideas?
On Wednesday, 5 June 2013 at 14:08:46 UTC, Regan Heath wrote: With virtual by default, could D statically verify/deny these? What about with static by default? Does it get easier or harder to detect/deny these in either case? Without understanding dmd internals, the implementation effort should be exactly the same regardless of default. And it should be easy too, like checking a flag on function call expression: walk each ast tree item in constructor if funcApplicattion.isVirtual then emit warning ... The bug reports regarding this issue are http://d.puremagic.com/issues/show_bug.cgi?id=5056 http://d.puremagic.com/issues/show_bug.cgi?id=3393
Re: Slow performance compared to C++, ideas?
On Thursday, 6 June 2013 at 05:52:28 UTC, Jonathan M Davis wrote: 1. 'virtual' means a method is an "introducing" one. 2. 'override' means override with a non-final function. 3. 'final override' means a method overrides a base virtual function with a final function. 4. 'final' by itself and none both mean final and non-overriding. I like the 'final override', it is more natural. What about case when you want to introduce new final method of the same name as already existing final method in base (c# uses 'new' for this) class Base { final void foo () } class Derived : Base { new void foo () } what would be in place of 'new' in D?
Re: Slow performance compared to C++, ideas?
On Thursday, June 06, 2013 10:42:26 Michal Minich wrote: On Thursday, 6 June 2013 at 05:52:28 UTC, Jonathan M Davis What about case when you want to introduce new final method of the same name as already existing final method in base (c# uses 'new' for this) class Base { final void foo () } class Derived : Base { new void foo () } what would be in place of 'new' in D? We could probably use new to mean the same thing, but I confess that even allowing this seems incredibly bad to me. You end up with a base class function which isn't being overidden looking like it's being overriden in a derived class. And even if it's obvious when look at Derived's declaration thanks to the new, anything which is derived from Derived would just be marked with override. So, it would be incredibly easy to think that calling Base.foo would call Derived.foo or the foo function of the class derived from Derived. So, certainly my initial reaction is to say that because Base.foo was marked with final, it shouldn't be possible for any of its derived classes to have a function with the same signature. That can cause problem for author of base class - if he add any final method, he can break derived classes he may not know of. Example - if you update your external lib you are using in your project, and it happens that new version of some base has 'search' final function added, and you happen to have fn with same name in in your derived, you must now rename all your usages of 'search' function... (i would be preferable if you could just add new on in your derived class 'search'). This problems are more common in languages as C# where OOP is more frequently used as in D. Also this issue will be more frequent in D with final as default, because to this time virtual method were more common - and they don't have this issue as they have 'override' behavior. 'new' would be orthogonal to 'override' for final functions. virutals can be overridden finals can be newed I think it is very clearly explained in pasted specification in comment http://forum.dlang.org/post/op.wx8biyx7eav7ka@stevens-macbook-pro.local
Re: std.compress
On Thursday, 13 June 2013 at 11:36:16 UTC, Daniel Murphy wrote: Ok, how exactly is the data compressed in the following snippet? No scrolling up to the top of the module to see what's imported! newdata = data.compress(); You can have that argument for any single overload and virtual call. At least you know it statically; with virtual you don't know until runtime... In many languages you would have interface ICompressor { Stream compress (Stream s) }...
Re: With statement become like C#'s using?
On Monday, 5 August 2013 at 12:40:26 UTC, Bosak wrote: In C# there is this using construct: just declare variable as scope, and ti will be destructed as son as function exits. void foo () { scope obj = new Object; } // obj will be destructed here you can also use it together with anonymous scope (same as c#) more generally, there is a "scope" statement http://dlang.org/exception-safe.html that can be used where normally try/finally (without catch) would be used, to achieve cleaner code.
Re: With statement become like C#'s using?
On Monday, 5 August 2013 at 13:11:44 UTC, bearophile wrote: Michal Minich: void foo () { scope obj = new Object; } // obj will be destructed here That usage of scope has being deprecated... Why it is deprecated? I follow newsgroups, but that I miss... I like it use together with scope classes: scope class C {} - are they too deprecated?
Re: With statement become like C#'s using?
On Monday, 5 August 2013 at 13:33:28 UTC, Adam D. Ruppe wrote: On Monday, 5 August 2013 at 12:40:26 UTC, Bosak wrote: with(Bitmap image = open("filename.bmp")) { I think this shoudl be allowed simply for consistency with this: if(auto a = getfoo()) { use a } This is good. I think it should too. But what Bosak proposes is that when "with" statements ends, the object should be destructed, which is large violation what with statements if for. Not mentioning breaking all the existing code...
Re: Enums - probably an old subject
On Thursday, 21 November 2013 at 07:42:48 UTC, Craig Dillabaugh wrote: I should also mention, this post likely better belongs in: digitalmars.D.learn I don't entirely think so. I think the OP is arguing that D should be able to identify symbol as specific enum's field when used: - in place of function argument when the fn parameters is of enum type - and when comparing for equality with variable of enum type. ie. the lookup of the symbol should be first inside the enum, and the continue normally. There was plan long long time ago to implement it, but I don't remember for which reason it was not. In order to consider this again for implementation I think proper DIP should be written where complete semantics of this should be described. For one I don't know how it should be have if you would have variable of the same name as enum field i.e: enum State { on, off } auto State s; auto on = 1; if (on == on) ? And I think it would be especially confusing when enum which is function parameters has the same field name as local variable on call site: void change (State s) {} void main () { State on = State.off, change (on) }
Re: declaration/expression
> import tango.io.Stdout; > void main(){ > int[4] i = [1,2,3,4]; > T(t); // compiler: I think this is an expression *barf* t(i[])(i[]); > //compiler: I think this is a declaration *barf* > } > > class T{ > public T opCall(int[] i){ > Stdout(i).newline; > return this; > } > } In your example are at least two errors. T(t); -- the "t" is not defined there public T opCall(int[] i) { -- it should be called as t(i), if you want call T(i), make this method static. I personally do not encounter problem you are writing about. But you should be aware of: Expressions that have no effect, like (x + x), are illegal in expression statements. If such an expression is needed, casting it to void will make it legal. http://www.digitalmars.com/d/1.0/statement.html#ExpressionStatement
Re: overloading functions against function templates
bearophile wrote: > import std.stdio: writeln; > double foo(int x) { return x * 2; } > double foo(float x) { return x * 3; } double foo(T)(T x) { return x * 4; > } > double foo(T : double)(T x) { return x * 5; } void main() { > writeln(foo(10));// prints: > writeln(foo(10.5)); // prints: > writeln(foo(10.5f)); // prints: > writeln(foo(10U)); // prints: > } > > What's the output? > I think functions have to be used first, when possible, to reduce > "template bloat". I'm not sure by choosing function first, code size will be lower. I'm not sure how dmd works, but I think by choosing template foo, code will be generated only once for both Point and size classes. (correct me if I'm wrong) Thus I agree the functions should be chosen first, because functions are more specific. class Point { int x, y; } class Size { int width, height; } void foo (Point P) { ... } void foo (Size s) { ... } void foo (T) (T t) { ... } void main () { foo (new Point()); foo (new Point()); }
Re: override(T)
So I was thinking of this: class LotterySimulation : Lottery, Figure { override(Lottery) void draw(); override(Figure) void draw(); } This is easy to implement, scales well, and has good real world uses. What say you? Andrei I think this is well solved in C# http://msdn.microsoft.com/en-us/library/aa664591%28VS.71%29.aspx The syntax is simpler. Members implemented explicitly are not accessible thru variable of concrete class instance - they are only accessible thru variables of interface type (or when explicitly casted). If I understand you correctly, this is the same way as you propose for D.
Re: dmd support for IDEs
Eclipse is heavy, slow and often unresponsive. I use poseidon myself because it is light and fast and I don't require much more from an IDE at the moment. You can try to download just bare Eclipse platform (which is just text editor) and install descent into it using Eclipse software updates. It starts up faster than C or Java version Eclipse and there is only D related stuff in the UI. http://download.eclipse.org/eclipse/downloads/drops/R-3.5.1-200909170800/index.php Under "Platform runtime binary"
Re: dmd support for IDEs
Hello Ary, Don wrote: Ary Borenszweig wrote: Michal Minich wrote somewhere else: --- You can try to download just bare Eclipse platform (which is just text editor) and install descent into it using Eclipse software updates. It starts up faster than C or Java version Eclipse and there is only D related stuff in the UI. http://download.eclipse.org/eclipse/downloads/drops/R-3.5.1-20090917 0800/index.php Under "Platform runtime binary" --- I tried it and it's true, it feels much lighter this way and you don't a lot of bloat in menus and other things. It would be great to put this on the Descent front page. I put it on the "Installing the plugin" page as soon as I saw it here. Thanks Michal Minich! You are welcome :) I use it this way from the beginning on both Windows and Ubuntu. I first installed Descent into Java Eclipse, but it was also first time I saw Java and Eclipse :) so I was quite overwhelmed by the lot functionality available and could not find which is for D and which for Java. This way it is more beginner friendly. Thank you for your hard work on Descent.
Re: safety model in D
Hello Michel, module (system) name; // interface: unsafe impl.: unsafe module (safe) name; // interface: safe impl.: safe I thought that first (unsafe-unsafe) case is currently available just by: module name; // interface: unsafe impl.: unsafe separating modules to unsafe-unsafe and safe-safe has no usefulness - as those modules could not interact, specifically you need modules that are implemented by unsafe means, but provides only safe interface, so I see it as: module name; // interface: unsafe impl.: unsafe module (system) name; // interface: safe impl.: unsafe module (safe) name; // interface: safe impl.: safe so you can call system modules (io, network...) from safe code.
Re: safety model in D
Hello Andrei, Michal Minich wrote: Hello Michel, module (system) name; // interface: unsafe impl.: unsafe module (safe) name; // interface: safe impl.: safe I thought that first (unsafe-unsafe) case is currently available just by: module name; // interface: unsafe impl.: unsafe separating modules to unsafe-unsafe and safe-safe has no usefulness - as those modules could not interact, specifically you need modules that are implemented by unsafe means, but provides only safe interface, so I see it as: module name; // interface: unsafe impl.: unsafe module (system) name; // interface: safe impl.: unsafe module (safe) name; // interface: safe impl.: safe so you can call system modules (io, network...) from safe code. That's a pretty clean design. How would it interact with a -safe command-line flag? Andrei When compiling with -safe flag, you are doing it because you need your entire application to be safe*. Safe flag would just affect modules with no safety flag specified - making them (safe): module name; --> module (safe) name; and then compile. It would not affect system modules, because you already *belive* that the modules are *safe to use* (by using or not using -safe compiler flag). *note: you can also partially compile only some modules/package.
Re: safety model in D
Hello Michel, I'm not sure this works so well. Look at this: module memory; // unsafe interface - unsafe impl. extern (C) void* malloc(int); extern (C) void free(void*); module (system) my.system; // safe interface - unsafe impl. import memory; void test() { auto i = malloc(10); free(i); } // ok: unsafe impl. allowed module (safe) my.safe; // safe interface - safe impl. import memory; void test() { auto i = malloc(10); free(i); } // error: malloc, free are unsafe How is this supposed to work correctly with and without the "-safe" compiler flag? The way you define things "-safe" would make module memory safe for use while it is not. I'm saying the module memory would not compile when compiler is called with -safe switch. the compiler would try to compile each module without safety specification, as if they were *marked* (safe) - which will not succeed for module memory in this case. In this setting, the reasons to have -safe compiler switch are not so important, they are more like convenience, meaning more like -forcesafe. You would want to use this flag only when you *need* to make sure your application is safe, usually when you are using other libraries. By this switch you can prevent compilation of unsafe application in case some other library silently changes safe module to unsafe in newer version.
Re: safety model in D
Hello Don, Michal Minich wrote: Hello Michel, I'm not sure this works so well. Look at this: module memory; // unsafe interface - unsafe impl. extern (C) void* malloc(int); extern (C) void free(void*); module (system) my.system; // safe interface - unsafe impl. import memory; void test() { auto i = malloc(10); free(i); } // ok: unsafe impl. allowed module (safe) my.safe; // safe interface - safe impl. import memory; void test() { auto i = malloc(10); free(i); } // error: malloc, free are unsafe How is this supposed to work correctly with and without the "-safe" compiler flag? The way you define things "-safe" would make module memory safe for use while it is not. I'm saying the module memory would not compile when compiler is called with -safe switch. the compiler would try to compile each module without safety specification, as if they were *marked* (safe) - which will not succeed for module memory in this case. In this setting, the reasons to have -safe compiler switch are not so important, they are more like convenience, meaning more like -forcesafe. You would want to use this flag only when you *need* to make sure your application is safe, usually when you are using other libraries. By this switch you can prevent compilation of unsafe application in case some other library silently changes safe module to unsafe in newer version. Doesn't work. There are system modules which CANNOT safely be called from safe modules -- eg extern(C) functions. They MUST have unsafe interfaces. Hello Don, Michal Minich wrote: Hello Michel, I'm not sure this works so well. Look at this: module memory; // unsafe interface - unsafe impl. extern (C) void* malloc(int); extern (C) void free(void*); module (system) my.system; // safe interface - unsafe impl. import memory; void test() { auto i = malloc(10); free(i); } // ok: unsafe impl. allowed module (safe) my.safe; // safe interface - safe impl. import memory; void test() { auto i = malloc(10); free(i); } // error: malloc, free are unsafe How is this supposed to work correctly with and without the "-safe" compiler flag? The way you define things "-safe" would make module memory safe for use while it is not. I'm saying the module memory would not compile when compiler is called with -safe switch. the compiler would try to compile each module without safety specification, as if they were *marked* (safe) - which will not succeed for module memory in this case. In this setting, the reasons to have -safe compiler switch are not so important, they are more like convenience, meaning more like -forcesafe. You would want to use this flag only when you *need* to make sure your application is safe, usually when you are using other libraries. By this switch you can prevent compilation of unsafe application in case some other library silently changes safe module to unsafe in newer version. Doesn't work. There are system modules which CANNOT safely be called from safe modules -- eg extern(C) functions. They MUST have unsafe interfaces. then they are not (system) modules. they are just modules with no specification. When not using -safe switch, you cannot call from (safe) to module with no safety specification (you can only call (safe) and (system)) When using -safe switch, there does not exists module with not safety specification, all plain modules will be marked (safe), and (system) modules are unchanged. You will not be able to call extern(C) functions from (safe) module, because module in which they are defined will be marked (safe), and will not compile itself. There is the problem I think you are referring to: (system) modules should not be affected by -safe flag. User of module believes (system) is safe, so the (system) module can call anything anytime. So I would suggest such update: when -safe switch is not used: module name;// interface: unsafe impl: unsafe module (system) name; // interface: safe impl: unsafe module (safe) name; // interface: safe impl: safe when -safe switch is used: module name;// interface: unsafe impl: unsafe -- when imported from system module module name;// interface: safe impl: safe -- when imported from safe modules module (system) name; // interface: safe impl: unsafe module (safe) name; // interface: safe impl: safe this means, that when -safe switch is used, that modules with no specification would be marked (safe) only when imported by modules marked as (safe). When they are imported from (system) modules, they will not be marked (safe). There is no need to another check if both (safe) and (system) nodules imports given module, because import from (safe) modules is stronger check, which is always fulfils by import from (system module). In other words, (system) module does not need to perform any more checking when -safe flag is used, it is same as if it not used.
Re: safety model in D
On Wed, 04 Nov 2009 14:03:42 -0300, Leandro Lucarella wrote: > I think safe should be the default, as it should be the most used flavor > in user code, right? What about: > > module s; // interface: safe impl.: safe > module (trusted) t; // interface: safe impl.: unsafe > module (unsafe) u;// interface: unsafe impl.: unsafe > > * s can import other safe or trusted modules (no unsafe for s). * t can > import any kind of module, but he guarantee not to corrupt your > memory if you use it (that's why s can import it). > * u can import any kind of modules and makes no guarantees (C bindings > use this). > >> That's a pretty clean design. How would it interact with a -safe >> command-line flag? > > I'll use safe by default. If you want to use broken stuff (everything > should be correctly marked as safe (default), trusted or unsafe) and let > it compile anyway, add a compiler flag -no-safe (or whatever). > > But people should never use it, unless you are using some broken library > or you are to lazy to mark your modules correctly. > > > Is this too crazy? I have no problem with safe as default, most of my code is safe. I also like the module (trusted) - it really pictures it meanings, better than "system". But I think there is no reason no use -no-safe compiler flag ... for what reason one would want to force safer program to compile as less safer :) As I'm thinking more about it, I don't see any reason to have any compiler flag for safety at all.
Re: safety model in D
On Wed, 04 Nov 2009 13:12:54 -0600, Andrei Alexandrescu wrote: >> But I think there is no reason no use -no-safe compiler flag ... for >> what reason one would want to force safer program to compile as less >> safer :) > > Efficiency (e.g. remove array bounds checks). > >> As I'm thinking more about it, I don't see any reason to have any >> compiler flag for safety at all. > > That would be a great turn of events!!! > > > Andrei Memory safety is pretty specific thing, If you want it, you want it all, not just some part of it - then you cannot call it memory safety. The idea of safe module, which under some compiler switch is not safe does not appeal to me. But efficiency is also important, and if you want it, why not move the code subjected to bounds checks to trusted/system module - I hope they are not checked for bounds in release mode. Moving parts of the code to trusted modules is more semantically describing, compared to crude tool of ad-hoc compiler switch. One thing I'm concerned with, whether there is compiler switch or not, is that module numbers will increase, as you will probably want to split some modules in two, because some part may be safe, and some not. I'm wondering why the safety is not discussed on function level, similarly as pure and nothrow currently exists. I'm not sure this would be good, just wondering. Was this topic already discussed?
Re: safety model in D
On Wed, 04 Nov 2009 14:24:47 -0600, Andrei Alexandrescu wrote: >> But efficiency is also important, and if you want it, why not move the >> code subjected to bounds checks to trusted/system module - I hope they >> are not checked for bounds in release mode. Moving parts of the code to >> trusted modules is more semantically describing, compared to crude tool >> of ad-hoc compiler switch. > > Well it's not as simple as that. Trusted code is not unchecked code - > it's code that may drop redundant checks here and there, leaving code > correct, even though the compiler cannot prove it. So no, there's no > complete removal of bounds checking. But a trusted module is allowed to > replace this: > > foreach (i; 0 .. a.length) ++a[i]; > > with > > foreach (i; 0 .. a.length) ++a.ptr[i]; > > The latter effectively escapes checks because it uses unchecked pointer > arithmetic. The code is still correct, but this time it's the human > vouching for it, not the compiler. > >> One thing I'm concerned with, whether there is compiler switch or not, >> is that module numbers will increase, as you will probably want to >> split some modules in two, because some part may be safe, and some not. >> I'm wondering why the safety is not discussed on function level, >> similarly as pure and nothrow currently exists. I'm not sure this would >> be good, just wondering. Was this topic already discussed? > > This is a relatively new topics, and you pointed out some legit kinks. > One possibility I discussed with Walter is to have version(safe) vs. > version(system) or so. That would allow a module to expose different > interfaces depending on the command line switches. > > > Andrei Sorry for the long post, but it should explain how safety specification should work (and how not). Consider these 3 ways of specifying memory safety: safety specification at module level (M) safety specification at function level (F) safety specification using version switching (V) I see a very big difference between these things: while the M and F are "interface" specification, V is implementation detail. This difference applies only to library/module users, it causes no difference for library/module writer - he must always decide if he writes safe, unsafe or trusted code Imagine scenario with M safety for library user: Library user wants to make memory safe application. He marks his main module as safe, and can be sure (and/or trust), that his application is safe from this point on; because safety is explicit in "interface" he cannot import and use unsafe code. scenario with V safety: Library user wants to make memory safe application. He can import any module. He can use -safe switch on compiler so compiler will use safe version of code - if available! User can be never sure if his application is safe or not. Safety is implementation detail! For this reason, I think V safety is very unsuitable option. Absolutely useless. But there are also problems with M safety. Imagine module for string manipulation with 10 independent functions. The module is marked safe. Library writer then decides add another function, which is unsafe. He can now do following: Option 1: He can mark the module trusted, and implement the function in unsafe way. Compatibility with safe clients using this module will remain. Bad thing: there are 10 provably safe functions, which are not checked by compiler. Also the trust level of module is lower in eyes of user. Library may end us with all modules as trusted (no safe). Option 2: He will implement this in separate unsafe module. This has negative impact on library structure. Option 3: He will implement this in separate trusted module and publicly import this trusted module in original safe module. The thirds options is transparent for module user, and probably the best solution, but I have a feeling that many existing modules will end having their unsafe twin. I see this pattern to emerge: module(safe) std.string module(trusted) std.string_trusted // do not import, already exposed by std.string Therefore I propose to use F safety. It is in fact the same beast as pure and nothrow - they also guarantee some kind of safety, and they are also part of function interface (signature). Compiler also needs to perform stricter check as normally. Just imagine marking entire module pure or nothrow. If certainly possible, is it practical? You would find yourself splitting your functions into separate modules with specific check, or not using pure and nothrow entirely. This way, if you mark your main function safe, you can be sure(and/or trust) your application is safe. More usually - you can use safe only for some functions and this requirement will propagate to all called functions, the same way as for pure or nothrow. One think to figure out remains how to turn of runtime bounds checking for trusted code (and probably safe too). This is legitimate requirement, because probably all the s
Re: Safety, undefined behavior, @safe, @trusted
I agree if the flag is called "-release". But if the "disable bounds checking" flag is renamed to -unsafe or similar, I can't see any impact on reputation. Ditto.
Re: Safety, undefined behavior, @safe, @trusted
Hello Andrei, Walter Bright wrote: Jason House wrote: I posted in the other thread how casting to immutable/shared can be just as bad. A leaked reference prior to casting to immutable/shared is in effect the same as casting away shared. No matter how you mix thread local and shared, or mutable and immutable, you still have the same undefined behavior Not undefined, it's just that the compiler can't prove it's defined behavior. Hence, such code would go into a trusted function. Are we in agreement that @safe functions have bounds checking on regardless of -release? Andrei I think there are two cases: User would want max performance from a some library, but he does not care about performance. User should have the right to override intentions of library writer, making his code less safe, to achieve speed. Compiler flag -unsafe (or -unsafe-no-bounds-checking) should do this. The user will know that he is *overriding* the original safety to lower level. Also, when a library writer wants his code to appeal and be usable to most users, he should mark it @safe or @trusted. But in situation, when he knows that safe code would be always bounds-checked (there is no -unsafe compiler switch), he may rather mark his code @trusted, even if it would be safe, in order to appeal to user that don't want slow (bounds-checked) library. If the library writer knows that users can override safety (bounds-checking), he would not hesitate to use @safe where appropriate. the -unsafe-no-bounds-checking flag is essential for properly working of safeness in D.
Re: Any IDEs or editors that are compatible with D 2.0?
Hello Kagamin, Matt Nawrocki Wrote: Hi... are there any IDEs or editors out there that support DMD 2.0 yet? I am having a hard time finding a good one. Thanks! Notepad can understand any characters. PSPad would be better choice than notepad :) http://www.pspad.com/ At least it has syntax highlighting (although you will need to fine tune it) project management, and can invoke compiler and go to line with error To my knowledge there is unfortunately no editor supporting D 2 syntax parsing (and code completion) You may look at page http://prowiki.org/wiki4d/wiki.cgi?EditorSupport if you did not already
Re: Should masked exceptions be an error?
Andrei Alexandrescu wrote: Consider: try { ... } catch (Exception) { ... } catch (StdioException) { ... } The second handler never matches because StdioException is a subclass of Exception, so the first handler will always match whatever the second matches. Should that be a compile-time error? I think so. Andrei Yes, it works like that in Java. Yes, it works like that in C#.
Re: dynamic classes and duck typing
Hello retard, Tue, 01 Dec 2009 14:24:01 -0800, Walter Bright wrote: dsimcha wrote: My biggest gripe about static verification is that it can't help you at all with high-level logic/algorithmic errors, only lower level coding errors. Good unit tests (and good asserts), on the other hand, are invaluable for finding and debugging high-level logic and algorithmic errors. Unit tests have their limitations as well. Unit tests cannot prove a function is pure, for example. Sure, unit tests can't prove that. Both unit tests and static verification are needed. But it doesn't lead to this conclusion. Static verification is sometimes very expensive and real world business applications don't need those guarantees that often. It's ok if a web site or game crashes every now and then. If I need serious static verification, I would use tools like Coq, not D.. Static verification in Coq is very expensive, but who really does that for real world programs. I think we are talking about automatic static verification with none or minimal programmer assistance - it will get you assurances for larger project with multiple programmers - that various parts plug in correctly (typecheck) and that they do not affect other parts of program in unexpected ways (const/pure/safe) - then you are at good ground to verify yours program logic by yourself (debugging/pre(post)conditions/unittests/asserts/invariants).
Re: dynamic classes and duck typing
Hello bearophile, But in dynamic code you don't almost never assert that a variable is an int; you assert that 'a' is able to do its work where it's used. So 'a' can often be an int, decimal, a multiprecision long, a GMP multiprecision, or maybe even a float. What you care of it not what a is but if does what it has to, so you care if it quacks :-) That's duck typing. Yes that's duck typing: "assert that 'a' is able to do its work where it's used" (function with required signature exists) Interfaces in OOP, or type classes in Haskell are here to "assert that 'a' is intended to work where it's used" (type is some implementation of the required concept (int/long/bigint)) both have its place :) Note that duck typing need not to be only dynamic, it can also happen at compile time - ranges in D checks if some functions are specified for "object" at compile time.
Re: should postconditions be evaluated even if Exception is thrown?
Hello Andrei, The way I was thinking of it is: int f() out(result) { } out(Exception e) { } body { } So you have a chance to assert what the world looks like in case you plan on returning a result, and what the world looks like if an exception is emerging from the function. So checked exceptions - this is not. Andrei if the function which throws exception is pure, then there is no world invariant to hold on after function exits (only return value is to be checked on success). Is there reason to have out(Exception ex) {} postcondition for pure function, or it should be compile time error to specify one? Similarly, when function is nothrow or when is not marked pure but does not make any side effect either.
Re: should postconditions be evaluated even if Exception is thrown?
Hello Michel, if the function which throws exception is pure, then there is no world invariant to hold on after function exits (only return value is to be checked on success). Is there reason to have out(Exception ex) {} postcondition for pure function, or it should be compile time error to specify one? Well you could still assert something about the exception: out (LoginException ex) { assert(ex.errorDescription != ""); } So, although I can't really find an example that looks useful, someone might and I don't think it should be disallowed. Yes, you could provide more specific error message (or maybe throw more specific exception), but I'm not sure how useful is this. I'm also not sure about how some specifics should work: currently, it is not allowed to throw Exception from postcondition, it is only possible to throw Error (assert). Should it be possible to throw Exception from error handling postcondition or not? If exception handling postcondition is empty (or does not throw any Error or Exception), should the exception throw in body be suppressed or not? If you throw in postcondition, what to do with Exception throw in body ? Similarly, when function is nothrow or when is not marked pure but does not make any side effect either. In a nothrow function it certainly does not make sense have contracts for exceptions since none can be thrown. The only reasonable thing you could do in one is this: out (Exception e) { assert(false); } But since the compiler can statically check that no exception can be thrown it's dead code anyway... unless someone cast a function that throws as nothrow. but function and it contracts are defined at compile time anyway. (Such nothrow cast could only badly affect callers of this function.)
Re: should postconditions be evaluated even if Exception is thrown?
Hello Leandro, I think postconditions should only be able to inspect (in a read-only manner) the exception; once the postcondition finished executing, the exception should be propagated as is. heating up the processor for no effect whatsoever?! Note also that it is possible, and desired, to use assert statement in conditions; this statement can throw Error (it is corner case of changing behavior of program, but we can consider that it is not changing anything, because it should end the program very fast anyway).
Re: lazy redux
Hello Andrei, Should we sack lazy? I'd like it to have a reasonable replacement. Ideas are welcome! Andrei there are 3 sides from which to look at lazy function parameter. 1. Usage - being able to send expressions to function is very important for writing clear and nice looking code. I think just by requiring enclosure in curly braces "fun({gun();})" would make this feature quite less appealing and used. This syntactic feature is very pleasing - by whichever feature at definition side it is achieved (macro/expression type), it should stay here. 2. Writing - On the function definition side, I don't see much difference in *writing* "lazy int dg" or "int delegate () dg". The functions that take lazy parameter are not written daily - their usage is much more frequent (enforce, logging). One problem I see currently with "lazy" that by specification it can be evaluated zero or more times. For me, "lazy" means zero or one time (compiler should handle this internally). This is not particularly important, because it is probably not so hard for programmer to write correct function - evaluation as many times as needed (which I think is usually 0 or 1 anyway). Just, the name "lazy" does not seems correct to me. 3. Contract - It was mentioned that programmer may expect "foo" to be always called in "bar (foo())". In case bar takes lazy argument, it may not be called. We need to have function which takes expression as parameter, while being able to separately express that function takes delegate. This should minimize cases of possible mismatched parameters. If we would replace "lazy" with explicit delegate parameter specification in function declaration, we would lost this possibility, and I think there would be more bugs cased by mismatched parameters. So I think we should leave "lazy" in, until we have macros. But introduction "{ epx }" as delegate/function literal for functions with no arguments, which implicitly returns result of the expression, seems to me as a good idea.
Re: lazy redux
Hello Michel, void logIfFalse(bool condition, pure lazy string message); logIfFalse(i == 1, createMessage()); I like the idea that of restricting what is passed into function; void logIfFalse(bool condition, lazy pure nothrow @safe string message); In wich case, expression passed needs to be checked for these restrictions. But I would leave the semantics of current lazy as is, or with one adjustment: It would be better if the compiler could make sure it is executed only zero or one time (but I don't think it has much practical advantage).
Re: lazy redux
Hello bearophile, Michal Minich: But introduction "{ epx }" as delegate/function literal for functions with no arguments, which implicitly returns result of the expression, seems to me as a good idea. It's a special case, and special cases help to kill languages. It's not important enough. But a general shorter syntax for lambdas is possible, like the C# one. Evaluations lazy arguments only 0 or 1 times sounds like a nice idea. Bye, bearophile Yes, it works well in C#, and it is one of the best extension of this language (only adding generics was better). Consider how it works in C#, and how it could in D // 1. lambda with no parameter int a; var t = new Thread ( () => a=42 ); // 2. lambda with one parameter string[] arr; Array.FindAll (arr, item => item.Contains ("abc")); // 3. lambda with more parameters Foo ( (a, b) => a + b ); // 4. lambda with statement (previous examples were expressions) Array.FindAll (arr, item => { return item.Contains ("abc"); } ); // curly braces, semicolon and return are required when statement is used. D could use: 1. auto t = new Thread ( { a=42 } ); or auto t = new Thread ( () { a=42 } ); 2. array.findAll (arr, (item) { item.contains ("abc") } ); 3. foo ( (a, b) { a + b } ); 4. array.findAll (arr, (item) { return item.contains ("abc"); } ); I'm not proposing this syntax (maybe I probably should, but I have feeling I would not be first). It may not even be possible to parse it, but seems to me more similar to how currently functions are written. In this setting {exp} or {stm} is not *special* case.
Re: lazy redux
Hello Denis, 1. auto t = new Thread ( { a=42 } ); or auto t = new Thread ( () { a=42 } ); It already works, just try it (but don't forget to put a semicolon at the end). 2. array.findAll (arr, (item) { item.contains ("abc") } ); 3. foo ( (a, b) { a + b } ); 4. array.findAll (arr, (item) { return item.contains ("abc"); } ); I'm not proposing this syntax (maybe I probably should, but I have feeling I would not be first). It may not even be possible to parse it, but seems to me more similar to how currently functions are written. In this setting {exp} or {stm} is not *special* case. I believe it would work. And yes, it was already proposed by many others. it works with two differences: 1. the semicolon is required, even if the body consist only of one expression. This is a minor detail. 2. more importantly - parameter types must be specified explicitly. I don't understand why type of b cannot be inferred in this example: void foo (void delegate (int a) dg) { dg(1); } void main () { foo ( (int b) { writeln (b); } ); } Does the type inference has problem with template code or some other combination of features...?
Re: lazy redux
Hello Andrei, Michal Minich wrote: Hello Andrei, Should we sack lazy? I'd like it to have a reasonable replacement. Ideas are welcome! Andrei there are 3 sides from which to look at lazy function parameter. 1. Usage - being able to send expressions to function is very important for writing clear and nice looking code. I think just by requiring enclosure in curly braces "fun({gun();})" would make this feature quite less appealing and used. This syntactic feature is very pleasing - by whichever feature at definition side it is achieved (macro/expression type), it should stay here. I think the same. But I seem to recall that at least one person on reddit thought it's a major loss of a guarantee. what he would think of Lisp then :-) 2. Writing - On the function definition side, I don't see much difference in *writing* "lazy int dg" or "int delegate () dg". The functions that take lazy parameter are not written daily - their usage is much more frequent (enforce, logging). Nononono. There's a huge difference. If you have "lazy int x", then that's perceived as an int with some sort of storage class. Then a putative user would expect auto y = x; to define another int. In fact it's unclear whether y should be an int or a delegate. The presence of the delegate type clarifies what's going on. I could come up with several other examples that reveal "lazy int x" to be a complete crock. You are right, I didn't noticed that. I always perceived "()" in "foo()" as forcing of computation. Properties or real lazy evaluation could solved this maybe, but ... Yank it. Although the possibility to specify if delegate accept expression or just function pointer really should be retained. How about: void fun (@expr int delegate () dg) {...} instead of lazy. While normal delegate parameters will work as they are now. One problem I see currently with "lazy" that by specification it can be evaluated zero or more times. For me, "lazy" means zero or one time (compiler should handle this internally). This is not particularly important, because it is probably not so hard for programmer to write correct function - evaluation as many times as needed (which I think is usually 0 or 1 anyway). Just, the name "lazy" does not seems correct to me. I agree. That's why I say we yank it and at most allow function and delegate parameters to accept expressions. That approach has its own problems. Consider: void fun(int delegate() dg) { ... } int delegate() gun() { ... } fun(gun()); In this case gun does get evaluated :o). @expr above does not have this prob. Andrei I think @expr delegate is it. Another possible ussage could be: @expr int delegate () x = 1 + 1; @expr auto y = 1 + 1; // y has type "int delegate ()"
Static member functions
Discussion with Tomek Sowiński and Steven Schveighoffer moved from digitalmars.D.learn: Currently it is impossible to have static member function in struct or class; this does not compile: struct S2 { static void foo () immutable { } } Error: function main.S.foo without 'this' cannot be const/immutable The problem I see is in definition of immutable member function: from D specs: "Immutable member functions are guaranteed that the object and anything referred to by the this reference is immutable." -- I think this rule is wrong, because it mentions *this* and at the same time it applies to static member functions, which obviously doesn't have *this* reference. I propose changing this rule 2 to: "Immutable *non-static* member functions are guaranteed that the object and anything referred to by the this reference is immutable." and adding this one: "Immutable static member functions are guaranteed that the static variables of object and anything referred to by these variables is immutable" And I'm asking if this is reasonable, useful, implementable and/or desired - Or how should be defined semantics of static immutable member function? Currently there are none. Consider this example: struct S { static int x; static void foo () immutable { x = 3; // should be error, because immutable static member function cannot change mutable static data members. } static void bar () { x = 3; // ok } } There is already bugzilla entry: http://d.puremagic.com/issues/ show_bug.cgi?id=3598
Re: Static member functions
Hello Denis, OTOH, if you want to protect yourself from (accidental) global state mutation, you are free to declare your static function as pure: struct X { static int x; static void foo() pure { // x = 3; // error } static void bar() { x = 3; // okay } } I was thinking about providing contract to function, that it does not *modify* state, something as half-pure. Anyway, this would be hard to define correctly.
Re: Static member functions
Hello Tomek, Dnia 08-12-2009 o 20:09:10 Tomek Sowiński napisał(a): I think immutable static member functions don't make sense and rightly so. On functions immutable is about "this" and there's no "this". Currently everything inside an immutable struct/class is tagged with "immutable". I say, tag everything but static functions. You should probably specify it in the bug report http://d.puremagic.com/issues/show_bug.cgi?id=3598 This resolution is, at least for me, not obvious. Let immutable types define them like anyone else. Tomek For clarity, I'm not commenting any of Michal's examples, I'm talking about this: immutable struct Strukt { static void funkcja() { } // now doesn't compile } We both agree it is a bug. You want to fix it not marking static function as immutable when the they are inside immutable type. I was trying to fix it by giving some meaning to static immutable functions, which seems to be not so good idea…
Re: @disable
On Sat, 16 Jan 2010 00:58:36 -0600, Andrei Alexandrescu wrote: > I'd also like to see other keywords (nothrow, pure, override come to > mind) transferred into the attribute space. I'd welcome if that happens. My personal favorite is "align", it is common, hard to replace word when one works with text/graphics/forms/ layout stuff, and as D keyword, it is rarely used. Some other candidates are at http://www.digitalmars.com/d/2.0/ attribute.html, maybe except "auto", it feels more like command to me than attribute. What about immutable/const - are they @attributes?. Also function parameter attributes = in/inout/ref - will it be possible to apply attribute to fn parameters? (It seems that what should be @attribute and what not is for big discussion.)
Will D 2.0 concurrency be supported between processes?
Will the currently-being-designed message-passing concurrency be supported between OS processes? Or only OS threads supported is planned? Others may be probably interested in: light-weight threads, cooperative concurrency and communication through network? If the implementation is not planned for initial release, is it planned for foreseeable future? Thank you for answer.
Re: Static attributes & immutability, static attributes seen from instances
On Fri, 05 Mar 2010 16:33:40 -0500, bearophile wrote: > A bit later in the discussion div0 and Pelle M. have said/suggested that > accessing static vars through an instance can be a bad thing, and it's > better to allow the programmer to access them only through the > class/struct name. I think that calling static members through an instance should be disallowed. In my opinion this is serious misfeature. It causes semantic un-clearness on usage - As you shown with the example with immutable static member. Here is one with mutable member: consider: struct S { static int s; int i } and usage in some other module: S s1, s2; s1.s += 1; s1.i += 1; now s2.s == 1, s2.i == 0. from usage is not apparent that 's' is a static member, in fact it seems it is instance member. This just makes program less clear. When one is presented with new code base and want to understand it, he must allays check if the member is not static - it should be apparent from usage and compiler should force it. This would allow an additional feature: two "namespaces" in the class/ struct - one for static names and one for instance names, giving ability to "overload" members - i.e. have two opCall in struct - one for type and one for instance. But I cannot think of any example use case of this feature right now.
Re: Static attributes & immutability, static attributes seen from instances
On Sat, 06 Mar 2010 11:30:45 -0500, Adam D. Ruppe wrote: > On Sat, Mar 06, 2010 at 11:33:02AM +0000, Michal Minich wrote: >> This would allow an additional feature: two "namespaces" in the class/ >> struct - one for static names and one for instance names, giving >> ability to "overload" members - i.e. have two opCall in struct - one >> for type and one for instance. But I cannot think of any example use >> case of this feature right now. > > I'd really like for opCall to be separated out, so you can initialize > structs from various types and treat it like a function object without > hassle. I've tried to do this now, but it keeps calling static opcall > when I wanted the other one, and sometimes vice versa. > > In a perfect world, all three of these would be workable: > > Variant a = 10; > Variant b = { writefln("Hello, world!"); }; b(); > > But, last time I tried, I could get line 2 or line 3 to work, but not > both. Separating static from instance should do the trick. I never used opAssign, but doesn't it solves this problem? Considering that both opCall and opAssign work with "=" their interaction must be probably quite complex...
Re: functional
what mostly functional programmers think about it: What are the properties of "Functional Programming Languages"? http://lambda-the-ultimate.org/node/2539 What are the real benefits of FP? http://lambda-the-ultimate.org/node/1578 from the discussion it seems there may be no straight answer. it might be interesting to see discussion to second question about D on this group - if it did't already happened?
.NET - Heap Allocations Viewer plugin
This is how variation on theme of @nogc or @noalloc can look in IDE. New plugin for Resharper from one of JetBrains developers. http://blog.jetbrains.com/dotnet/2014/06/06/heap-allocations-viewer-plugin/ I for sure will try it.