Re: std.signal : voting has begun
On Wed, Jan 15, 2014 at 9:35 PM, Russel Winder rus...@winder.org.uk wrote: We can, of course, now open the debate as to whether the Oxford Comma should be used. ;-) And does English mean American English, Canadian English, Australian English, South African English, New Zealand English, or proper English, i.e. that spoken in England. :-) -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder I vote: British English sentence construction with either American English or British English spelling. People are welcome to fix the documentation if the original writer's English is not 100% :) or if they just prefer the spelling to be from one of the other versions of English. Disclaimer: I speak South African English. P.S. I think Programming English is pretty much American English. For example is there any API that contains the English word Colour?
Re: std.signal : voting has begun
On Wednesday, 15 January 2014 at 15:59:20 UTC, qznc wrote: On Wednesday, 15 January 2014 at 07:46:29 UTC, Andrei Alexandrescu wrote: yada yada yada I just created a wiki page to document requirements. Hopefully, this helps people to decide on their vote and not to forget aspects. http://wiki.dlang.org/Phobos_Quality Should this be linked from http://wiki.dlang.org/Review/Process ? It will be great if we will have a list of English-speaking people that can help with documentation. For example, English is not my native language, so it will be great if somebody else read and correct my documentation. So, we need a list of people who interested to help with documentation for new modules with their contact information (e-mail should be enough).
Re: std.signal : voting has begun
Thanks for helping to keep voting threads clean from off-topic discussions.
Re: std.signal : voting has begun
On 1/15/14 11:35 AM, Russel Winder wrote: On Wed, 2014-01-15 at 13:42 -0500, John J wrote: […] Uses complete english sentences with correct syntax, grammar, and punctuation. Please capitalize the e in english. We can, of course, now open the debate as to whether the Oxford Comma should be used. ;-) At ACCU I attended talks by you, an awful speaker, and an incompetent chowderhead. Now you tell me whether we should use the Oxford comma or not :o). And does English mean American English, Canadian English, Australian English, South African English, New Zealand English, or proper English, i.e. that spoken in England. :-) We can always aspire... Andrei
Coming back, Unique, opDot and whatever else
Hello everyone! It's been a long time since I last posted here, I've been away from all things D, only being able to take an occasional peek from time to time. It's so good to be back. I'm now finding a bit of time to commit to learn D, more relearn as it would seem. I've started my rediscoveries with exploring of concurrency, parallelism, threading in D, and after some time I found myself thinking I need a unique encapsulator. Don't ask why, I may not even be able to answer it in a month. But that helped me solve some problems before in C++, so I thought why not try it here? In a couple of page views I came upon std.typecons and its Unique type. And I thought why that is exactly what I want!. And it was, too. But after taking a closer look at its general implementation I just couldn't help myself but think well, it seems it was done in a hurry, never finished, left as it was because this of that and whatnot. I mean, those sparse comments, things like doesn't work yet, etc... I thought well, since I'm learning the language again, why not make it an exercise and fill those blanks? It'd certainly help me, because it would improve the abstraction I'm using, and because it's a learning experience. So, here's what I came up with for now: http://codepad.org/S4TfIdxc Granted, not a complete implementation, keeping not very far from the original. But right now I think it's a good time to ask you guys what do you think? Where have I went wrong, what did I do incorrectly, what potential issues can you spot in this? I mean, I'm not asking about using opDot(), which, as I understand it, could be going away anytime now. At least I think I managed to fill in most of the blanks of the current implementation while keeping (almost?) to the same interface. In short, please destroy this with Big Fat Phazerz so I could take the remaining ashes and contemplate on the next iteration :)
Re: Coming back, Unique, opDot and whatever else
Oh woops, it seems I misclicked the links and ended up posing in .announce instead of .learn. Sorry about that! If this is in any way movable, I'd be obliged. Thanks!
Re: Coming back, Unique, opDot and whatever else
On Friday, 17 January 2014 at 01:12:04 UTC, Stanislav Blinov wrote: Hello everyone! It's been a long time since I last posted here, I've been away from all things D, only being able to take an occasional peek from time to time. It's so good to be back. I'm now finding a bit of time to commit to learn D, more relearn as it would seem. I've started my rediscoveries with exploring of concurrency, parallelism, threading in D, and after some time I found myself thinking I need a unique encapsulator. Don't ask why, I may not even be able to answer it in a month. But that helped me solve some problems before in C++, so I thought why not try it here? In a couple of page views I came upon std.typecons and its Unique type. And I thought why that is exactly what I want!. And it was, too. But after taking a closer look at its general implementation I just couldn't help myself but think well, it seems it was done in a hurry, never finished, left as it was because this of that and whatnot. I mean, those sparse comments, things like doesn't work yet, etc... I thought well, since I'm learning the language again, why not make it an exercise and fill those blanks? It'd certainly help me, because it would improve the abstraction I'm using, and because it's a learning experience. So, here's what I came up with for now: http://codepad.org/S4TfIdxc Granted, not a complete implementation, keeping not very far from the original. But right now I think it's a good time to ask you guys what do you think? Where have I went wrong, what did I do incorrectly, what potential issues can you spot in this? I mean, I'm not asking about using opDot(), which, as I understand it, could be going away anytime now. At least I think I managed to fill in most of the blanks of the current implementation while keeping (almost?) to the same interface. Improving Phobos code by filling in the blanks is usually a good idea and a good learning experience as well. Changing an interface in Phobos is a big deal and should be thoroughly justified. Does it break backwards compatibility? Why is it necessary? (btw moving to .learn is not possible, unfortunately)
Re: Coming back, Unique, opDot and whatever else
On 2014-01-17 02:12, Stanislav Blinov wrote: Hello everyone! It's been a long time since I last posted here, I've been away from all things D, only being able to take an occasional peek from time to time. It's so good to be back. I'm now finding a bit of time to commit to learn D, more relearn as it would seem. I've started my rediscoveries with exploring of concurrency, parallelism, threading in D, and after some time I found myself thinking I need a unique encapsulator. Don't ask why, I may not even be able to answer it in a month. But that helped me solve some problems before in C++, so I thought why not try it here? In a couple of page views I came upon std.typecons and its Unique type. And I thought why that is exactly what I want!. And it was, too. But after taking a closer look at its general implementation I just couldn't help myself but think well, it seems it was done in a hurry, never finished, left as it was because this of that and whatnot. I mean, those sparse comments, things like doesn't work yet, etc... I thought well, since I'm learning the language again, why not make it an exercise and fill those blanks? It'd certainly help me, because it would improve the abstraction I'm using, and because it's a learning experience. So, here's what I came up with for now: http://codepad.org/S4TfIdxc Granted, not a complete implementation, keeping not very far from the original. But right now I think it's a good time to ask you guys what do you think? Where have I went wrong, what did I do incorrectly, what potential issues can you spot in this? I mean, I'm not asking about using opDot(), which, as I understand it, could be going away anytime now. At least I think I managed to fill in most of the blanks of the current implementation while keeping (almost?) to the same interface. In short, please destroy this with Big Fat Phazerz so I could take the remaining ashes and contemplate on the next iteration :) opDot has been replaced with opDispatch [1] and alias this [2]. Why can't @safe be used, can you use @trusted instead? You should probably use template constraints for createUnique as well. As for coding style, especially if you're aiming for including in Phobos: * Function names never start with underscore and always starts with a lowercase letter * I would prefer the same for instance variables as well, but I know there are several cases in Phobos where instance variables starts with an underscore [1] http://dlang.org/operatoroverloading.html#Dispatch [2] http://dlang.org/class.html#AliasThis -- /Jacob Carlborg
Re: Componentizing D's garbage collector
On Tuesday, 14 January 2014 at 14:22:27 UTC, Timon Gehr wrote: On 01/14/2014 10:11 AM, Paulo Pinto wrote: On Monday, 13 January 2014 at 23:42:50 UTC, Timon Gehr wrote: On 01/13/2014 11:05 PM, Paulo Pinto wrote: Am 13.01.2014 22:31, schrieb Timon Gehr: On 01/13/2014 10:11 PM, Walter Bright wrote: Not to say there aren't other ways of doing things, but with random objects becoming pinnable puts a big damper on things unless you can identify all the objects that might be pinned and isolate them. But I doubt that's really knowable up front. The reason pinning doesn't particularly impede this is because pinning is rare. In Java or in D? Eg. there are no unions in Java. C# has unions. http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute%28v=vs.110%29.aspx The common language runtime controls the physical layout of the data fields of a class or structure in managed memory. However, ... Did you also read the remaining part of the page, Obviously. or just looked for something to paste? ... Look, you hadn't done anything besides pasting for backing up your point or making it precise. I'll be proven wrong if you are able to show us how you do the following in C#: union U{ int x; Object y; } You can control the layout, that is what matters. Not at what level you are expressing it. ... Obviously. Ignoring what such runtimes offer, only puts D at disadvantage when comparing feature lists, which many in the industry do. ... Every resource I have encountered indicates that C# does not offer this functionality because it is detrimental to GC, eg: http://stackoverflow.com/questions/17771902/struct-memory-hack-to-overlap-object-reference-is-it-possible Excuse me for being stupid. I just read MSDN without trying it out, so I wasn't aware that object references cannot be made to overllap with other data, even in unsafe structs. Me and my big mouth. Better test it properly next time. -- Paulo
Re: Graphics Library for D
You mentioned keyboard, mouse, and touch. Something that can't be forgot about is pen input. It is becoming more and more common for laptops to not only come with touch, but also a stylus+digitizer for pen input. Just something to think about.
Re: extend in to all array types
On Thursday, 16 January 2014 at 07:28:43 UTC, luka8088 wrote: On 15.1.2014. 16:30, pplantinga wrote: In python, I really like the ability to check if an element is in an array: if x in array: # do something D has this, but only for associative arrays. Is there any chance we could extend this to every kind of array? D array uses this operator for checking against array keys, not values. It makes sense for sorted arrays, as they make good sets. That said, it makes the most sense to limit opBinaryRight!in to SortedRange.
Access modifier for extensions
Hi there, I have an idea for an access modifier that I wanted to throw out there, in the hopes that it will resonate with someone. Basically I've found that in practice, when building a module, I always need to keep two kind of users in mind. Those who want to use it, and those who want to extend it. For extending, there is the 'protected' attribute, but it's specific for class overriding only. Very often, extensions are not merely limited to derived classes. What I find myself wanting is more like the 'package' attribute, except it needs to work outside of the package as well. So right now, the only viable choice is making all functionality for users and extenders 'public'. So let's imagine the 'extendable' attribute for a moment. Here's what I would like it to do: Let's say someone built a GUI library, and without access to the library, I want to add support for another platform. -- module buttoncontrol public class ButtonControl { public Event pressEvent; extendable void click(Point position); } -- Now, you don't want a user to be able to generate a click. But someone whose purpose it is to extend the library, should be able to do it. extender -- import extendable buttoncontrol; void click(Point position) { auto button = findButtonUnderCursor(position); button.click(position); } -- user -- import buttoncontrol; void createUi() { auto button = new ButtonControl(); button.click(Point(10,10)); // ERROR, no access to click function } -- So, that's the general idea. I haven't thought very hard about the syntax part, so ignore that. Let me know what you think. Is it useful? feasible? worth the effort? Cheers, Boyd
Re: Access modifier for extensions
Something that I have been doing quite heavily recently is a registration approach. I.e. in a module constructor (shared) you call a function giving it a class type that most likely inherits another class/interface. From there code is generated/executed at compile time for that function call. Very useful for registering e.g. routes. However an issue with this approach I've seen while porting glfw to D is that sure this works but how can I do e.g. new Window(640, 480, My title here); when it needs to hook into the registration system to grab the real window implementation that you have set to use by default (or overridable by adding the name to the call). This is essentially the factory pattern. Now something that allows me to say the function allocates this class but not its children would really be useful. As I could get it to go to the registration system and grab the allocated result from there. Based upon this what you're thinking of is essentially add/override methods on a class which is really isn't good D code. Too much like c++ and ugly. Perhaps what we could have to accomplish your part while making it obvious is a sorta like how c#'s event support is. Now we could implement this as a mixin template. I.e. it could generate: static void method_addHandler(T)(del) in { ... // check if del is a delegate with matching definition // first arg must be previous value } body { ... // add arg to list } T method(ARGS) { ... // run handlers while passing previous value } With this you could also pass e.g. a lambda or some delegate to the mixin to say this is my default output of this method. Can also do some checks for default return types ext. I don't know how to handle access modifiers for this. However pretty much everything else is doable without changing the front end specially for this use case. Will depend though on the allocation api and if it'll allow you to return a child class type. I don't see why it wouldn't though. But this is just my thoughts on the matter. I'm sure somebody will destroy it!
Re: Access modifier for extensions
On Thursday, 16 January 2014 at 09:28:18 UTC, Boyd wrote: Hi there, I have an idea for an access modifier that I wanted to throw out there, in the hopes that it will resonate with someone. Basically I've found that in practice, when building a module, I always need to keep two kind of users in mind. Those who want to use it, and those who want to extend it. For extending, there is the 'protected' attribute, but it's specific for class overriding only. Very often, extensions are not merely limited to derived classes. What I find myself wanting is more like the 'package' attribute, except it needs to work outside of the package as well. So right now, the only viable choice is making all functionality for users and extenders 'public'. So let's imagine the 'extendable' attribute for a moment. Here's what I would like it to do: Let's say someone built a GUI library, and without access to the library, I want to add support for another platform. -- module buttoncontrol public class ButtonControl { public Event pressEvent; extendable void click(Point position); } -- Now, you don't want a user to be able to generate a click. But someone whose purpose it is to extend the library, should be able to do it. extender -- import extendable buttoncontrol; void click(Point position) { auto button = findButtonUnderCursor(position); button.click(position); } -- user -- import buttoncontrol; void createUi() { auto button = new ButtonControl(); button.click(Point(10,10)); // ERROR, no access to click function } -- So, that's the general idea. I haven't thought very hard about the syntax part, so ignore that. Let me know what you think. Is it useful? feasible? worth the effort? Cheers, Boyd This can be achieved with traditional OOP design patterns and i have to agree with the above poster this is too much like C++ hacking and looks horrible.
Re: Graphics Library for D
On Thu, 2014-01-16 at 08:07 +, Tofu Ninja wrote: You mentioned keyboard, mouse, and touch. Something that can't be forgot about is pen input. It is becoming more and more common for laptops to not only come with touch, but also a stylus+digitizer for pen input. Just something to think about. Agreed. I have a Wacom which I use for all of my training courses. -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Re: DIP54 : revamp of Phobos tuple types
On Monday, 23 December 2013 at 01:39:26 UTC, Dicebot wrote: http://wiki.dlang.org/DIP54 This is follow-up of several hot discussion threads that have happened several months ago. It has become pretty clear that there is no good way out of existing situation and least bad needs to be picked just to move forward (because it still be better than current horrible one) Linked proposal was discussed in short e-mail conversation with Andrei (with silent observation with Walter) and is mostly pre-approved. I am interested in general opinion of community and suggestions for any smaller tweaks before starting to work on pull requests. Thanks for your attention. Small update on this. I have chosen to go route of investigating compiler enhancement possibilities first to allow cleaner argument pack implementation. After some tweaks it was relatively easy to make work these two samples: - struct X { static int opSlice(size_t l, size_t u) { return l + u; } } pragma(msg, X[1..2]); - and - struct X { // note the template args static auto opSlice(size_t l, size_t u)() { return l + u; } } pragma(msg, X[1..2]); - However I am still struggling with more practical example: - struct X(T...) { static auto opSlice(size_t l, size_t u)() { return X!(T[l..u]); } } alias Y = (X!(1, 2, 3))[1..2]; - It seems to take completely different processing path, one that does not allow obvious syntax rewriting before semantic pass. I think I'll throw few more weeks into trying this and proceed with crappy alternative upon failure.
Re: foreach thoughts
On Wednesday, 15 January 2014 at 01:28:26 UTC, Manu wrote: You can't step a -O build, or inspect the value of most variables. So you can't really debug. The problem with optimizations is that code mutates a lot. Can you expect the debugger to step through inlined functions? Loop merging can be even more evil in this regard.
Re: Graphics Library for D
On 01/06/2014 01:52 PM, bearophile wrote: Mike: * Break the library into loosely coupled pieces that can be used individually or aggregated by other projects to build things that we haven't even thought of * Geometric primitives should be their own library/package * Vector graphics (paths, line caps, etc...) should be their own library/package * Raster graphics should be their own library/package * Window management should be its own library/package * Font's are just data. Don't couple them to the rendering engine. (e.g Convert them to a vector/raster representation and then let those libraries handle the rest. * The rendering engine should be its own library/package, that should be easily replaced with whatever is suitable for the given platform. An independent color system module could be useful, even in Phobos. Part of the Geometric primitives (2D/3D vectors, rotation matrices, the most commonly useful geometry algorithms and formulas) could go in a Phobos module. And the graphics library could import and use this standard module. I wrote a vector graphics library quite a while ago. https://github.com/MartinNowak/graphics It contains a lot of Path and Bezier curve algorithms and uses a novel rasterization technique http://josiahmanson.com/research/wavelet_rasterization/. It's a little outdated and probably won't compile any longer. It also depends on a small GUI primitives library which contains Color, Point, Size and Rect. https://github.com/MartinNowak/guip
Re: [RFC] I/O and Buffer Range
On Tue, 07 Jan 2014 05:04:07 -0500, Dmitry Olshansky dmitry.o...@gmail.com wrote: 07-Jan-2014 11:59, Jason White пишет: On Monday, 6 January 2014 at 10:26:27 UTC, Dmitry Olshansky wrote: Ok, now I see. In my eye though serialization completely hides raw stream write. So: struct SomeStream{ void write(const(ubyte)[] data...); } struct Serializer(Stream){ void write(T)(T value); //calls stream.write inside of it private: Stream stream; } I was thinking it should also have alias stream this;, but maybe that's not the best thing to do for a serializer. I concede, I've s/(read|write)Data/\1/g on https://github.com/jasonwhite/io/blob/master/src/io/file.d and it now works on Windows with useful exception messages. Cool, got to steal sysErrorString too! :) Actually these objects do just fine, since OS does the locking (or makes sure of something equivalent). If your stream is TLS there is no need for extra locking at all (no interleaving of I/O calls is possible) regardless of its kind. Shared instances would need locking as 2 threads may request some operation, and as OS locks only on per sys-call basis something cruel may happen in the code that deals with buffering etc. Oh yeah, you're right. As a side note: I would love to get a kick-ass I/O stream package into Phobos. It could replace std.stream as well as std.stdio. Then our goals are aligned. Be sure to take a peek at (if you haven't already): https://github.com/schveiguy/phobos/blob/new-io/std/io.d Yes, I'm gearing up to revisit that after a long D hiatus, and I came across this thread. At this point, I really really like the ideas that you have in this. It solves an issue that I struggled with, and my solution was quite clunky. I am thinking of this layout for streams/buffers: 1. Unbuffered stream used for raw i/o, based on a class hierarchy (which I have pretty much written) 2. Buffer like you have, based on a struct, with specific primitives. It's job is to collect data from the underlying stream, and present it to consumers as a random-access buffer. 3. Filter that has access to transform the buffer data/copy it. 4. Ranges that use the buffer/filter to process/present the data. The problem I struggled with is the presentation of UTF data of any format as char[] wchar[] or dchar[]. 2 things need to happen. First is that the data needs to be post-processed to perform any necessary byte swapping. The second is to transcode the data into the correct width. In this way, you can process UTF data of any type (I even have code to detect the encoding and automatically process it), and then use it in a way that makes sense for your code. My solution was to paste in a processing delegate into the class hierarchy of buffered streams that allowed one read/write access to the buffer. But it's clunky, and difficult to deal with in a generalized fashion. But the idea of using a buffer in between the stream and the range, and possibly bolting together multiple transformations in a clean way, makes this problem easy to solve, and I think it is closer to the vision Andrei/Walter have. I also like the idea of pinning the data instead of my mechanism of using a delegate (which was similar but not as general). It also has better opportunities for optimization. Other ideas that came to me that buffer filters could represent: * compression/decompression * encryption I am going to study your code some more and see how I can update my code to use it. I still need to maintain the std.stdio.File interface, and Walter is insistent that the initial state of stdout/err/in must be synchronous with C (which kind of sucks, but I have plans on how to make it not be so bad). There is still a lot of work left to do, but I think one of the hard parts is done, namely dealing with UTF transcoding. The remaining sticky part is dealing with shared. But with structs, this should make things much easier. One question, is there a reason a buffer type has to be a range at all? I can see where it's easy to make it a range, but I don't see higher-level code using the range primitives when dealing with chunks of a stream. -Steve
another cool RTInfo trick - i want in runtime
Check this out. Modify your druntime slightly. In object.di, find template RTInfo(T) and add this bit: import core.config; alias checkResult = TypeCheck!T; Then, pop open import/core/config.d and put these contents in it: module core.config; template TypeCheck(T) { enum TypeCheck = true; } Compile a program, any program. Should be no difference in anything - no errors, no changes to the binary, no compile slowdown - from before the modifications. Now, create a file named anything you want with these contents: module core.config; template TypeCheck(T) { static if(T.stringof == Cool) static assert(0, No type named 'Cool' is allowed!); enum TypeCheck = true; } Compile your program, should still work. Then add struct Cool{} to it anywhere... and you get a compile error. Brothers and sisters, I've talked to you before about doing custom RTInfo using __traits(compiles) tricks to look for the config module, but my previous ways - while they worked - sucked because the compiler would look for the module over and over again, slowing things down a bit. This new method achieves success on all counts. By offering a file with druntime to be the module up front, the compiler does no special searching, it finds it. It is a trivial file, so impact on compile speed is negligible. But then, if you offer your own file with the same module name on the command line, dmd looks THERE first, finds your special code, and knows to skip searching the import path! Even true for object.d, since this is all in templates with local imports; the template still needs to be instantiated. Since this object.d doesn't actually store anything* in the RTInfo itself, there's no worry of binary incompatibilities resulting from separate compiliation with different rtinfo modules. It simply provides a hook into the types for checking. Using this, we can automatically check all kinds of per-project requirements. Don't want virtual functions in your class unless they are reviewed? Make your TypeCheck loop over them and look for a UDA, issuing a static assert if not there. Don't want references to un-owned mutable data? Ditto. Have a naming convention to check? Can do that too. I see lots of upsides, and the downsides from my last experiment with this I believe have been eliminated. Am I missing something? I wanna do a druntime pull request! * User data extensions could potentially be allowed if RTInfo stored a pointer to an interface, which may be null. Other modules may implement the interface differently, but as long as they implement it (or set it to null), it should still have consistent binary compatibility. You might make object.d's RTInfo create a static struct with information the GC needs first, then a pointer to the user defined data. The RTInfo template ultimately resolves to the pointer to that struct. The data itself is consistent - still defined in only one place, druntime itself, and the GC info is available right there, no added indirection, and we have the hook for user additions too, all under a consistent interface. You can also add runtime info about a type using static constructors: === module core.config; string[] types; template TypeCheck(T) { enum TypeCheck = true; shared static this() { types ~= T.mangleof; } } === module test500.d struct Cool {} void main() { import core.config, std.stdio; writeln(types); } === dmd test500.d rtinfo.d $ ./test500 [S7test5004Cool, S3std5array17__T8AppenderTAyaZ8Appender4Data, S3std5array17__T8AppenderTAyaZ8Appender] Run time info available about all the types used in that program! S yeah, this is pretty much a pure win all around to my eyes. Am I blind to the suck?
Re: another cool RTInfo trick - i want in runtime
On Thursday, 16 January 2014 at 15:57:05 UTC, Adam D. Ruppe wrote: Now, create a file named anything you want with these contents: I guess this won't work with rdmd, then?
Re: another cool RTInfo trick - i want in runtime
On Thursday, 16 January 2014 at 16:09:52 UTC, Vladimir Panteleev wrote: I guess this won't work with rdmd, then? That's due to a deficiency in rdmd: tt doesn't let you forward all the available module options to dmd, even though it would make sense to do it, for this kind of replaceable config module thing and also for replacing say one phobos file at a time for doing dev work on that . rdmd should be fixed to allow you to pass more than one explicit module (maybe just add an option like --additional-dmd-option=file.d).
Re: another cool RTInfo trick - i want in runtime
On Thursday, 16 January 2014 at 16:21:25 UTC, Adam D. Ruppe wrote: On Thursday, 16 January 2014 at 16:09:52 UTC, Vladimir Panteleev wrote: I guess this won't work with rdmd, then? That's due to a deficiency in rdmd: tt doesn't let you forward all the available module options to dmd, even though it would make sense to do it, for this kind of replaceable config module thing and also for replacing say one phobos file at a time for doing dev work on that . rdmd should be fixed to allow you to pass more than one explicit module (maybe just add an option like --additional-dmd-option=file.d). That sounds overcomplicated. Why not move the standard search paths to after the users' ones? So that users can override Phobos and Druntime modules simply by creating them within their search path.
Re: another cool RTInfo trick - i want in runtime
On Thursday, 16 January 2014 at 16:26:49 UTC, Vladimir Panteleev wrote: Why not move the standard search paths to after the users' ones? That might work too. Either way though, the compiler and language let you list additional modules and it all just works if you do, so rdmd should too... however it does. I don't use rdmd myself so the specific solution should probably be guided by people who do.
GDC Project Ideas wiki
Hi, I've started on a ProjectIdeas page, as the list of things that I'm currently working on, either actively, non-actively, on and off, and things that just went completely idle and no one has looked at for years. Some of these really need to start being distributed by anyone who wants to help out with the project. There's not just development work, so there should be plenty to do even for those who don't profess themselves as being a compiler dev. http://wiki.dlang.org/GDC/ProjectIdeas Regards Iain.
Re: another cool RTInfo trick - i want in runtime
On Thursday, 16 January 2014 at 16:37:16 UTC, Adam D. Ruppe wrote: I don't use rdmd myself so the specific solution should probably be guided by people who do. Well, the beauty of rdmd is that you don't need to mess with options in the general case. My setup is that generally I press Enter on a .d file and it is built into an .exe (if there is an entry point in any imported modules) - no other action required. If I had to modify the command line for every invocation, that would not work for my case, so I'd have to write a rdmd wrapper to look for additional command-line options in a configuration file in the current directory, or implement something like that in rdmd itself. If these requirements can be specified in the source code itself, that would be much better. In our case it would simply be the presence of a file in the project search path. An existing example of this is pragma(lib) - instead of telling the user to specify which libraries to add to the linker command line, or providing a makefile (with all its problems), a pragma(lib) can be used to pull in those libraries automatically.
DConf 2014 proposals: two weeks left!
There are two weeks left until the DConf 2014 proposals deadline, and time is running fast! We see great content in blogs and articles. This very group has contents worth distilling into a talk topic on literally a daily basis. (Just look at Adam's another cool RTInfo trick). So please consider submitting - people reading this will form the bulk of our speakers. (If you think your topic is uninteresting, consider it may seem that way because we all work on it so it's very familiar. But we're expecting a good number of n00bs this year, and it's always worth bringing new insight on an important and well-discussed theme.) Deadline is January 31st. Also don't forget reduced-cost ($250) pre-registration expires the same day. http://dconf.org Thanks, Andrei
Re: DConf 2014 proposals: two weeks left!
On 1/16/14 9:13 AM, Vladimir Panteleev wrote: On Thursday, 16 January 2014 at 17:07:55 UTC, Andrei Alexandrescu wrote: Deadline is January 31st. Also don't forget reduced-cost ($250) pre-registration expires the same day. Can I register but get a refund if my talk is accepted? ;) Thanks for asking. I'll ask Walter. Andrei
Re: another cool RTInfo trick - i want in runtime
On Thursday, 16 January 2014 at 16:26:49 UTC, Vladimir Panteleev wrote: Why not move the standard search paths to after the users' ones? So that users can override Phobos and Druntime modules simply by creating them within their search path. Never mind, this is already the case! It depends on how you write your own sc.ini (I had mine with Phobos/Druntime in front).
Re: DConf 2014 proposals: two weeks left!
On Thursday, 16 January 2014 at 17:07:55 UTC, Andrei Alexandrescu wrote: Deadline is January 31st. Also don't forget reduced-cost ($250) pre-registration expires the same day. Can I register but get a refund if my talk is accepted? ;)
Re: another cool RTInfo trick - i want in runtime
On Thursday, 16 January 2014 at 17:10:42 UTC, Vladimir Panteleev wrote: On Thursday, 16 January 2014 at 16:26:49 UTC, Vladimir Panteleev wrote: Why not move the standard search paths to after the users' ones? So that users can override Phobos and Druntime modules simply by creating them within their search path. Never mind, this is already the case! It depends on how you write your own sc.ini (I had mine with Phobos/Druntime in front). Probably we should pick one way or another as standard for packaging so that projects can rely on it.
Re: SHA-3 is KECCAK
I support the idea that it would be useful to have an implementation or binding for Keccak and may be other crypto hash functions. Now all what I found are pycrypto implementation an official implementation written with C at http://keccak.noekeon.org/. But I was unable to deal with the interface of this library. There are a little of comments in the code and I couldn't find concrete examples how to use it. Phobos simple interface like in std.digest.md would be more suitable for casual use. Very often in not needed to tweek all of these parameters for algorithm, but needed that it will just work. I will appreciate for some guidelines if someone tried to bind this C implementation for using in D.
Re: Programmer en D published on dlang-fr.org
On Wednesday, 15 January 2014 at 20:19:51 UTC, Raphaël Jakse wrote: Le 15/01/2014 21:18, Raphaël Jakse a écrit : Fixes can come from the ***support*** you are the most at ease, it's ok for me media might be a better word ;-) Le petit travail pour ce soir. :-) Appuyer avec le souris sur voir les passages http://dlang-fr.org/cours/programmer-en-d/compilateur.html http://dlang-fr.org/cours/programmer-en-d/types.html http://dlang-fr.org/cours/programmer-en-d/variables.html ifloat, cfloat ... needs to be removed from the original English version. I might have an issue with the following phrase where a verb equals a noun. Introducing a variable to the program is called its definition. http://dlang-fr.org/cours/programmer-en-d/es.html http://dlang-fr.org/cours/programmer-en-d/expression_logiques.html expressions logiques http://dlang-fr.org/cours/programmer-en-d/corrections/expressions_logiques.html Revenir au chapitre: Expressions logiques Oops! That page can’t be found.
Re: DConf 2014 proposals: two weeks left!
On Thursday, 16 January 2014 at 17:13:24 UTC, Vladimir Panteleev wrote: On Thursday, 16 January 2014 at 17:07:55 UTC, Andrei Alexandrescu wrote: Deadline is January 31st. Also don't forget reduced-cost ($250) pre-registration expires the same day. Can I register but get a refund if my talk is accepted? ;) Yep, also curious.
Re: Access modifier for extensions
On Thursday, 16 January 2014 at 11:18:07 UTC, Gary Willoughby wrote: This can be achieved with traditional OOP design patterns and i have to agree with the above poster this is too much like C++ hacking and looks horrible. I think I misrepresented my case by mucking up the example. I don't care about any individual use case. Ignore it. What I'm looking for is a way to represent this: class AThing { public void DoSomethingAnyoneCanDo(); public_ish void DoSomethingThatRequiresExpertise(); } The first method in the class, is something you want to expose to any user. The second is meant for the guy who wants access to the more advanced stuff, where you have to know what you are doing. Inheriting from the class is not an option, or at least unwanted. Basically I need the 'package' attribute, but for modules outside the package, even modules I have no control over, or know anything about. Am I really the only who ever found the need for such a thing? Because I see situations where this could be pretty damn handy, all the time.
Re: Programmer en D published on dlang-fr.org
On 01/16/2014 09:34 AM, sclytrack wrote: ifloat, cfloat ... needs to be removed from the original English version. That issue is a part of a long list of mostly trivial changes to make. I will get to those later. However, I am not sure whether removing ifloat and cfloat is the right thing to do yet because D boasts about getting complex floating point arithmetic right because of their presence. Last we discussed the library solution, that issue has not been addressed yet: http://forum.dlang.org/post/l6pmbs$1njo$1...@digitalmars.com Testing the program again with git head... Nope, ifloat and friends are still needed today for program correctness. foreach_reverse has been the reverse (ha! ;)): I had decided to not mention it in the book but I think people still find it useful in certain cases. I might have an issue with the following phrase where a verb equals a noun. Introducing a variable to the program is called its definition. Thank you; I will rephrase it. I will keep using the adjective variable as a noun though. ;) Ali
Re: another cool RTInfo trick - i want in runtime
On Thursday, 16 January 2014 at 15:57:05 UTC, Adam D. Ruppe wrote: Check this out. Modify your druntime slightly. In object.di, find template RTInfo(T) and add this bit: Suggestions: 1. I guess TypeCheck is a temporary name? I would suggest e.g. CustomRTInfo. 2. How about using a template mixin instead of a template? Then you can drop the dummy bool. I know that if you use a mixin, you can't refer to stuff that's in the scope where it's declared, but I think that's OK - because you probably don't want an object file for config.d anyway, since: 3. rdmd will not add config.d to the compiler's command line, since it lies in an excluded package core (so it's assumed it'll be in phobos.lib). But that's OK, since there will be no symbols in config.d to link against anyway! It all fits together quite nicely. You can access stuff in your main program by importing its modules within the template mixin.
Re: Access modifier for extensions
On Thursday, 16 January 2014 at 17:45:40 UTC, Boyd wrote: On Thursday, 16 January 2014 at 11:18:07 UTC, Gary Willoughby wrote: This can be achieved with traditional OOP design patterns and i have to agree with the above poster this is too much like C++ hacking and looks horrible. I think I misrepresented my case by mucking up the example. I don't care about any individual use case. Ignore it. What I'm looking for is a way to represent this: class AThing { public void DoSomethingAnyoneCanDo(); public_ish void DoSomethingThatRequiresExpertise(); } The first method in the class, is something you want to expose to any user. The second is meant for the guy who wants access to the more advanced stuff, where you have to know what you are doing. Inheriting from the class is not an option, or at least unwanted. Basically I need the 'package' attribute, but for modules outside the package, even modules I have no control over, or know anything about. Am I really the only who ever found the need for such a thing? Because I see situations where this could be pretty damn handy, all the time. By your example i'm getting the impression you want a standard interface for users of your class but want advanced behaviour of the same interface for other users while avoiding inheritance? If this is the case, your answer is delegation[1]. class A { private Delegate delegateObject; public void setDelegate(Delegate delegateObject) { this.delegateObject = delegateObject; } public value doSomethingAnyoneCanDo() { if (this.delegateObject) { return this.delegateObject.doSomethingThatRequiresExpertise(); } // Do something anyone can do. } } [1]: http://en.wikipedia.org/wiki/Delegation_pattern P.S. Don't confuse this with the D 'delegate' type.
Re: Access modifier for extensions
On Thursday, 16 January 2014 at 18:23:16 UTC, Gary Willoughby wrote: On Thursday, 16 January 2014 at 17:45:40 UTC, Boyd wrote: I think I misrepresented my case by mucking up the example. I don't care about any individual use case. Ignore it. What I'm looking for is a way to represent this: class AThing { public void DoSomethingAnyoneCanDo(); public_ish void DoSomethingThatRequiresExpertise(); } The first method in the class, is something you want to expose to any user. The second is meant for the guy who wants access to the more advanced stuff, where you have to know what you are doing. Inheriting from the class is not an option, or at least unwanted. Basically I need the 'package' attribute, but for modules outside the package, even modules I have no control over, or know anything about. Am I really the only who ever found the need for such a thing? Because I see situations where this could be pretty damn handy, all the time. By your example i'm getting the impression you want a standard interface for users of your class but want advanced behaviour of the same interface for other users while avoiding inheritance? If this is the case, your answer is delegation[1]. class A { private Delegate delegateObject; public void setDelegate(Delegate delegateObject) { this.delegateObject = delegateObject; } public value doSomethingAnyoneCanDo() { if (this.delegateObject) { return this.delegateObject.doSomethingThatRequiresExpertise(); } // Do something anyone can do. } } [1]: http://en.wikipedia.org/wiki/Delegation_pattern P.S. Don't confuse this with the D 'delegate' type. No, I'm talking about two different functions with different functionalities. The desktop PC is probably a good analogy. The normal user just turns it on and off. Others might open up the case, change the CPU multiplier, add some memory, maybe turn down the fans so they make less noise. class DesktopPC { public void turnOn(); public void turnOff(); expertMode void setCpuMultiplier(int value); }
Re: another cool RTInfo trick - i want in runtime
On Thursday, 16 January 2014 at 15:57:05 UTC, Adam D. Ruppe wrote: Check this out. Modify your druntime slightly. In object.di, find template RTInfo(T) and add this bit: import core.config; alias checkResult = TypeCheck!T; Then, pop open import/core/config.d and put these contents in it: module core.config; template TypeCheck(T) { enum TypeCheck = true; } Compile a program, any program. Should be no difference in anything - no errors, no changes to the binary, no compile slowdown - from before the modifications. Now, create a file named anything you want with these contents: module core.config; template TypeCheck(T) { static if(T.stringof == Cool) static assert(0, No type named 'Cool' is allowed!); enum TypeCheck = true; } Compile your program, should still work. Then add struct Cool{} to it anywhere... and you get a compile error. Brothers and sisters, I've talked to you before about doing custom RTInfo using __traits(compiles) tricks to look for the config module, but my previous ways - while they worked - sucked because the compiler would look for the module over and over again, slowing things down a bit. This new method achieves success on all counts. By offering a file with druntime to be the module up front, the compiler does no special searching, it finds it. It is a trivial file, so impact on compile speed is negligible. But then, if you offer your own file with the same module name on the command line, dmd looks THERE first, finds your special code, and knows to skip searching the import path! Even true for object.d, since this is all in templates with local imports; the template still needs to be instantiated. Since this object.d doesn't actually store anything* in the RTInfo itself, there's no worry of binary incompatibilities resulting from separate compiliation with different rtinfo modules. It simply provides a hook into the types for checking. Using this, we can automatically check all kinds of per-project requirements. Don't want virtual functions in your class unless they are reviewed? Make your TypeCheck loop over them and look for a UDA, issuing a static assert if not there. Don't want references to un-owned mutable data? Ditto. Have a naming convention to check? Can do that too. I see lots of upsides, and the downsides from my last experiment with this I believe have been eliminated. Am I missing something? I wanna do a druntime pull request! * User data extensions could potentially be allowed if RTInfo stored a pointer to an interface, which may be null. Other modules may implement the interface differently, but as long as they implement it (or set it to null), it should still have consistent binary compatibility. You might make object.d's RTInfo create a static struct with information the GC needs first, then a pointer to the user defined data. The RTInfo template ultimately resolves to the pointer to that struct. The data itself is consistent - still defined in only one place, druntime itself, and the GC info is available right there, no added indirection, and we have the hook for user additions too, all under a consistent interface. You can also add runtime info about a type using static constructors: === module core.config; string[] types; template TypeCheck(T) { enum TypeCheck = true; shared static this() { types ~= T.mangleof; } } === module test500.d struct Cool {} void main() { import core.config, std.stdio; writeln(types); } === dmd test500.d rtinfo.d $ ./test500 [S7test5004Cool, S3std5array17__T8AppenderTAyaZ8Appender4Data, S3std5array17__T8AppenderTAyaZ8Appender] Run time info available about all the types used in that program! S yeah, this is pretty much a pure win all around to my eyes. Am I blind to the suck? I guess that could work pretty well for a C++ friend emulation with UDA's! Were not you the one who wanted to show me an example for that with using RTInfo? Offer your way the possibility to check automatically for null references? With an UDA e.g. @safe_ref or @not_null
Re: [RFC] I/O and Buffer Range
16-Jan-2014 19:55, Steven Schveighoffer пишет: On Tue, 07 Jan 2014 05:04:07 -0500, Dmitry Olshansky dmitry.o...@gmail.com wrote: Then our goals are aligned. Be sure to take a peek at (if you haven't already): https://github.com/schveiguy/phobos/blob/new-io/std/io.d Yes, I'm gearing up to revisit that after a long D hiatus, and I came across this thread. At this point, I really really like the ideas that you have in this. It solves an issue that I struggled with, and my solution was quite clunky. I am thinking of this layout for streams/buffers: 1. Unbuffered stream used for raw i/o, based on a class hierarchy (which I have pretty much written) 2. Buffer like you have, based on a struct, with specific primitives. It's job is to collect data from the underlying stream, and present it to consumers as a random-access buffer. The only interesting thing I'd add here s that some buffer may work without underlying stream. Best examples are arrays and MM-files. 3. Filter that has access to transform the buffer data/copy it. 4. Ranges that use the buffer/filter to process/present the data. Yes, yes and yes. I find it surprisingly good to see our vision seems to match. I was half-expecting you'd come along and destroy it all ;) The problem I struggled with is the presentation of UTF data of any format as char[] wchar[] or dchar[]. 2 things need to happen. First is that the data needs to be post-processed to perform any necessary byte swapping. The second is to transcode the data into the correct width. In this way, you can process UTF data of any type (I even have code to detect the encoding and automatically process it), and then use it in a way that makes sense for your code. My solution was to paste in a processing delegate into the class hierarchy of buffered streams that allowed one read/write access to the buffer. But it's clunky, and difficult to deal with in a generalized fashion. But the idea of using a buffer in between the stream and the range, and possibly bolting together multiple transformations in a clean way, makes this problem easy to solve, and I think it is closer to the vision Andrei/Walter have. In essence a transcoding filter for UTF-16 would wrap a buffer of ubyte and itself present a buffer interface (but of wchar). My own stuff currently deals only in ubyte and the limited decoding is represented by a decode function that takes a buffer of ubyte and decodes UTF-8. I think typed buffers/filters is the way to go. I also like the idea of pinning the data instead of my mechanism of using a delegate (which was similar but not as general). It also has better opportunities for optimization. Other ideas that came to me that buffer filters could represent: * compression/decompression * encryption I am going to study your code some more and see how I can update my code to use it. I still need to maintain the std.stdio.File interface, and Walter is insistent that the initial state of stdout/err/in must be synchronous with C (which kind of sucks, but I have plans on how to make it not be so bad). I seriously not seeing how interfacing with C runtime could be fast enough. There is still a lot of work left to do, but I think one of the hard parts is done, namely dealing with UTF transcoding. The remaining sticky part is dealing with shared. But with structs, this should make things much easier. I'm thinking a generic locking wrapper is possible along the lines of: shared Locked!(GenericBuffer!char) stdin; //usage struct Locked(T){ shared: private: T _this; Mutex mut; public: //forwarded methods } The wrapper will introduce a lock, and implement every method of wrapped struct roughly like this: mut.lock(); scope(exit) mut.unlock(); (cast(T*)_this).method(args); I'm sure it could be pretty automatic. One question, is there a reason a buffer type has to be a range at all? I can see where it's easy to make it a range, but I don't see higher-level code using the range primitives when dealing with chunks of a stream. Lexers/parsers enjoy it - i.e. they work pretty much as ranges especially when skipping spaces and the like. As I said the main reason was: if it fits as range why not? After all it makes one-pass processing of data trivial as it rides on top of foreach: foreach(octect; mybuffer) { if(intersting(octect)) do_cool_stuff(); } Things like countUntil make perfect sense when called on buffer (e.g. to find matching sentinel). -- Dmitry Olshansky
Re: Access modifier for extensions
On Thursday, 16 January 2014 at 09:28:18 UTC, Boyd wrote: For extending, there is the 'protected' attribute, but it's specific for class overriding only. Very often, extensions are not merely limited to derived classes. What I find myself wanting is more like the 'package' attribute, except it needs to work outside of the package as well. You can make class members accessible to a module by reintroducing them in a derived class using an alias. It even works for static and final methods, and field variables. Example: /// module library; class Button { protected void click() {} } /// module user; import library; void main() { auto button = new Button(); button.click(); // NG } /// module extender; import library; class ExtendedButton : Button { // reintroduce protected member as private to this scope private alias Button.click click; } void main() { auto button = new ExtendedButton(); button.click(); // OK } /// HTH.
Re: another cool RTInfo trick - i want in runtime
On Thursday, 16 January 2014 at 18:15:39 UTC, Vladimir Panteleev wrote: 1. I guess TypeCheck is a temporary name? I would suggest e.g. CustomRTInfo. My first thought when writing this was the TypeCheck would just contain a bunch of static asserts to ensure the type matches whatever your project's special requirements are; it would act kinda like a plugin to the compiler's semantic check. (Actually, it does the bool because my first try was to use it as a template constraint, but if that fails, ti just stops the RTInfo from instantiating; it doesn't actually fail the compile like static assert inside does.) But CustomRTInfo is a good name too, especially if we are adding data. 2. How about using a template mixin instead of a template? If we actually mix it in that could change the binary layout of the thing though. We don't need the dummy bool btw, I just tried and it works the same without it. It all fits together quite nicely. You can access stuff in your main program by importing its modules within the template mixin. yes
Re: Graphics Library for D
On Thu, 16 Jan 2014 07:51:26 -0800, Martin Nowak c...@dawg.eu wrote: On 01/06/2014 01:52 PM, bearophile wrote: Mike: * Break the library into loosely coupled pieces that can be used individually or aggregated by other projects to build things that we haven't even thought of * Geometric primitives should be their own library/package * Vector graphics (paths, line caps, etc...) should be their own library/package * Raster graphics should be their own library/package * Window management should be its own library/package * Font's are just data. Don't couple them to the rendering engine. (e.g Convert them to a vector/raster representation and then let those libraries handle the rest. * The rendering engine should be its own library/package, that should be easily replaced with whatever is suitable for the given platform. An independent color system module could be useful, even in Phobos. Part of the Geometric primitives (2D/3D vectors, rotation matrices, the most commonly useful geometry algorithms and formulas) could go in a Phobos module. And the graphics library could import and use this standard module. I wrote a vector graphics library quite a while ago. https://github.com/MartinNowak/graphics It contains a lot of Path and Bezier curve algorithms and uses a novel rasterization technique http://josiahmanson.com/research/wavelet_rasterization/. It's a little outdated and probably won't compile any longer. It also depends on a small GUI primitives library which contains Color, Point, Size and Rect. https://github.com/MartinNowak/guip This is awesome! What's the license on it and can we use it in Aurora? -- Adam Wilson IRC: LightBender Aurora Project Coordinator
Re: DIP54 : revamp of Phobos tuple types
On Monday, 23 December 2013 at 23:24:30 UTC, Andrei Alexandrescu wrote: On 12/23/13 4:25 AM, Dicebot wrote: On Monday, 23 December 2013 at 12:03:05 UTC, ilya-stromberg wrote: Can we add alias for `auto-expansion TypeTuple` and add link to the previous documentation like this: alias ExpandedTemplateArgumentList(T) = TemplateArgumentList!(T).expand; It looks like it can fix all objections here. What is this supposed to give over just using .expand directly? I have not seen a good rationale that justifies it among existing objections, probably have missed it. I also think that implicit expansion should not be frequent enough to justify its own abstraction. Andrei The thing is that you can build non expanding tuples on top of expanding ones, not the other way around. So I think the language should have buitin expanding tuples (and renamed something else than tuple).
Re: Graphics Library for D
On Thu, 16 Jan 2014 03:22:08 -0800, Russel Winder rus...@winder.org.uk wrote: On Thu, 2014-01-16 at 08:07 +, Tofu Ninja wrote: You mentioned keyboard, mouse, and touch. Something that can't be forgot about is pen input. It is becoming more and more common for laptops to not only come with touch, but also a stylus+digitizer for pen input. Just something to think about. Agreed. I have a Wacom which I use for all of my training courses. We'll try to support as much input as we can, but to some extent we'll be at the mercy of what the Operating System can give us. -- Adam Wilson IRC: LightBender Aurora Project Coordinator
Re: another cool RTInfo trick - i want in runtime
All right, it wasn't you, it was Andrej Mitrovic on my thread http://forum.dlang.org/thread/pdshwedjqgquoibxh...@forum.dlang.org#post-mailman.1977.1381065059.1719.digitalmars-d-learn:40puremagic.com The problem on a library NotNull struct is: nobody will use it, because it requires NotNull on both sides, by the caller and by the callee: class A { } void safe_foo(NotNull!A na) { } void main() { NotNull!A na = NotNull!A(new A()); safe_foo(na); } Which is a lot more effor than: class A { } void safe_foo(@safe_ref A na) { } void main() { A a = new A(); safe_foo(a); } because it moves the check to the callee. Also it is far more readable and easier to write as a contract like: void safe _foo(A a) in { assert(a !is null); } body { }
Re: another cool RTInfo trick - i want in runtime
On Thursday, 16 January 2014 at 19:13:42 UTC, Adam D. Ruppe wrote: On Thursday, 16 January 2014 at 18:44:54 UTC, Namespace wrote: I guess that could work pretty well for a C++ friend emulation with UDA's! Were not you the one who wanted to show me an example for that with using RTInfo? I've played with rtinfo a lot before, but I don't remember doing C++ friend emulation... Offer your way the possibility to check automatically for null references? With an UDA e.g. @safe_ref or @not_null I think those would be better done with the type info, like NotNull!t. What's cool about the RTInfo thing though is it is checked on everything, so it can check for the *absence* of a UDA as well as for the presence. You might say something must not have any nullable references unless specially marked. The rtinfo checker can confirm that: loop over all members, if it is potentially nullable and isn't marked with either NotNull or @i_know_this_is_nullable_and_that_is_ok, it can throw an error. It is possible to do that kind of thing with static assert on the module level too sort of. See, the module level one for one can be forgotten and it can't access nested things in functions: void foo() { struct InnerStruct {} } // can't see foo.InnerStuct here! static assert(ModulePassesCheck!(mixin(this_module))); But RTInfo *does* see InnerStruct, and you don't have to remember to add the check to your module too. All right, it wasn't you, it was Andrej Mitrovic on my thread http://forum.dlang.org/thread/pdshwedjqgquoibxh...@forum.dlang.org#post-mailman.1977.1381065059.1719.digitalmars-d-learn:40puremagic.com The problem on a library NotNull struct is: nobody will use it, because it requires NotNull on both sides, by the caller and by the callee: class A { } void safe_foo(NotNull!A na) { } void main() { NotNull!A na = NotNull!A(new A()); safe_foo(na); } Which is a lot more effor than: class A { } void safe_foo(@safe_ref A na) { } void main() { A a = new A(); safe_foo(a); } because it moves the check to the callee.
Re: [RFC] I/O and Buffer Range
On Thu, 16 Jan 2014 13:44:08 -0500, Dmitry Olshansky dmitry.o...@gmail.com wrote: 16-Jan-2014 19:55, Steven Schveighoffer пишет: On Tue, 07 Jan 2014 05:04:07 -0500, Dmitry Olshansky dmitry.o...@gmail.com wrote: Then our goals are aligned. Be sure to take a peek at (if you haven't already): https://github.com/schveiguy/phobos/blob/new-io/std/io.d Yes, I'm gearing up to revisit that after a long D hiatus, and I came across this thread. At this point, I really really like the ideas that you have in this. It solves an issue that I struggled with, and my solution was quite clunky. I am thinking of this layout for streams/buffers: 1. Unbuffered stream used for raw i/o, based on a class hierarchy (which I have pretty much written) 2. Buffer like you have, based on a struct, with specific primitives. It's job is to collect data from the underlying stream, and present it to consumers as a random-access buffer. The only interesting thing I'd add here s that some buffer may work without underlying stream. Best examples are arrays and MM-files. Yes, but I would stress that for convenience, the buffer should forward some of the stream primitives (such as seeking) in cases where seeking is possible, at least in the case of a buffer that wraps a stream. That actually is another point that would have sucked with my class-based solution -- allocating a class to use an array as backing. 3. Filter that has access to transform the buffer data/copy it. 4. Ranges that use the buffer/filter to process/present the data. Yes, yes and yes. I find it surprisingly good to see our vision seems to match. I was half-expecting you'd come along and destroy it all ;) :) I've been preaching for a while that ranges don't make good streams, and that streams should be classes, but I hadn't considered splitting out the buffer. I think it's the right balance. The problem I struggled with is the presentation of UTF data of any format as char[] wchar[] or dchar[]. 2 things need to happen. First is that the data needs to be post-processed to perform any necessary byte swapping. The second is to transcode the data into the correct width. In this way, you can process UTF data of any type (I even have code to detect the encoding and automatically process it), and then use it in a way that makes sense for your code. My solution was to paste in a processing delegate into the class hierarchy of buffered streams that allowed one read/write access to the buffer. But it's clunky, and difficult to deal with in a generalized fashion. But the idea of using a buffer in between the stream and the range, and possibly bolting together multiple transformations in a clean way, makes this problem easy to solve, and I think it is closer to the vision Andrei/Walter have. In essence a transcoding filter for UTF-16 would wrap a buffer of ubyte and itself present a buffer interface (but of wchar). My intended interface allows you to specify the desired type per read. Think of the case of stdin, where the clients will be varied and written by many different people, and its interface is decided by Phobos. But a transcoding buffer may make some optimizations. For instance, reading a UTF32 file as utf-8 can re-use the same buffer, as no code unit uses more than 4 code points (did I get that right?). I am going to study your code some more and see how I can update my code to use it. I still need to maintain the std.stdio.File interface, and Walter is insistent that the initial state of stdout/err/in must be synchronous with C (which kind of sucks, but I have plans on how to make it not be so bad). I seriously not seeing how interfacing with C runtime could be fast enough. It's not. But an important stipulation in order for this to all be accepted is that it doesn't break existing code that expects things like printf and writef to interleave properly. However, I think we can have an opt-in scheme, and there are certain cases where we can proactively switch to a D-buffer scheme. For example, if you get a ByLine range, it expects to exhaust the data from stream, and may not properly work with C printf. The idea is that stdio.File can switch at runtime from FILE * to D streams as needed or directed. There is still a lot of work left to do, but I think one of the hard parts is done, namely dealing with UTF transcoding. The remaining sticky part is dealing with shared. But with structs, this should make things much easier. I'm thinking a generic locking wrapper is possible along the lines of: shared Locked!(GenericBuffer!char) stdin; //usage struct Locked(T){ shared: private: T _this; Mutex mut; public: //forwarded methods } The wrapper will introduce a lock, and implement every method of wrapped struct roughly like this: mut.lock(); scope(exit) mut.unlock(); (cast(T*)_this).method(args); I'm sure it could be pretty automatic. This would be a key addition
Re: another cool RTInfo trick - i want in runtime
On 2014-01-16 16:57, Adam D. Ruppe wrote: Brothers and sisters, I've talked to you before about doing custom RTInfo using __traits(compiles) tricks to look for the config module, but my previous ways - while they worked - sucked because the compiler would look for the module over and over again, slowing things down a bit. This new method achieves success on all counts. By offering a file with druntime to be the module up front, the compiler does no special searching, it finds it. It is a trivial file, so impact on compile speed is negligible. But then, if you offer your own file with the same module name on the command line, dmd looks THERE first, finds your special code, and knows to skip searching the import path! Even true for object.d, since this is all in templates with local imports; the template still needs to be instantiated. Does this only work once? Say I have two libraries that use this technique, would that work? This seems somewhat complicated, depending on the orders of modules passed to the compiler. Since this object.d doesn't actually store anything* in the RTInfo itself, there's no worry of binary incompatibilities resulting from separate compiliation with different rtinfo modules. It simply provides a hook into the types for checking. No, not yet. As far as I know, the idea was to use RTInfo to collect and store type info for a precise GC. Using this, we can automatically check all kinds of per-project requirements. Don't want virtual functions in your class unless they are reviewed? Make your TypeCheck loop over them and look for a UDA, issuing a static assert if not there. Don't want references to un-owned mutable data? Ditto. Have a naming convention to check? Can do that too. I see lots of upsides, and the downsides from my last experiment with this I believe have been eliminated. Am I missing something? I wanna do a druntime pull request! I have had a different idea for a solution to this problem for a while. That is, add a new manifest constant to object.d, called rtInfo. This will act like a UDA. Any template with the object.rtInfo UDA attached to itself will behave just as RTInfo does today. module object; enum rtInfo; @rtInfo template RTInfo (T) { enum RTInfo = null; } module foo.check_virtual_methods; @rtInfo template CheckVirtualMethods (T) { static if (!containsVirtualMethods!(T)) static assert(false, Error, contains virtual methods); enum CheckVirtualMethods = null; } An idea for storing data in TypeInfo is to create an associative array. The keys would be the fully qualified name of the template, in this case foo.check_virtual_methods.CheckVirtualMethods. The values would be whatever the template evaluates to. There's one problem with this, the associative array would need to be built at runtime due to separate compilation. -- /Jacob Carlborg
Re: another cool RTInfo trick - i want in runtime
Am Thu, 16 Jan 2014 15:57:04 + schrieb Adam D. Ruppe destructiona...@gmail.com: Check this out. Modify your druntime slightly. In object.di, find template RTInfo(T) and add this bit: import core.config; alias checkResult = TypeCheck!T; Then, pop open import/core/config.d and put these contents in it: module core.config; template TypeCheck(T) { enum TypeCheck = true; } Compile a program, any program. Should be no difference in anything - no errors, no changes to the binary, no compile slowdown - from before the modifications. Now, create a file named anything you want with these contents: module core.config; template TypeCheck(T) { static if(T.stringof == Cool) static assert(0, No type named 'Cool' is allowed!); enum TypeCheck = true; } Compile your program, should still work. Then add struct Cool{} to it anywhere... and you get a compile error. Brothers and sisters, I've talked to you before about doing custom RTInfo using __traits(compiles) tricks to look for the config module, but my previous ways - while they worked - sucked because the compiler would look for the module over and over again, slowing things down a bit. This new method achieves success on all counts. By offering a file with druntime to be the module up front, the compiler does no special searching, it finds it. It is a trivial file, so impact on compile speed is negligible. But then, if you offer your own file with the same module name on the command line, dmd looks THERE first, finds your special code, and knows to skip searching the import path! Even true for object.d, since this is all in templates with local imports; the template still needs to be instantiated. Since this object.d doesn't actually store anything* in the RTInfo itself, there's no worry of binary incompatibilities resulting from separate compiliation with different rtinfo modules. It simply provides a hook into the types for checking. Using this, we can automatically check all kinds of per-project requirements. Don't want virtual functions in your class unless they are reviewed? Make your TypeCheck loop over them and look for a UDA, issuing a static assert if not there. Don't want references to un-owned mutable data? Ditto. Have a naming convention to check? Can do that too. I see lots of upsides, and the downsides from my last experiment with this I believe have been eliminated. Am I missing something? I wanna do a druntime pull request! * User data extensions could potentially be allowed if RTInfo stored a pointer to an interface, which may be null. Other modules may implement the interface differently, but as long as they implement it (or set it to null), it should still have consistent binary compatibility. You might make object.d's RTInfo create a static struct with information the GC needs first, then a pointer to the user defined data. The RTInfo template ultimately resolves to the pointer to that struct. The data itself is consistent - still defined in only one place, druntime itself, and the GC info is available right there, no added indirection, and we have the hook for user additions too, all under a consistent interface. You can also add runtime info about a type using static constructors: === module core.config; string[] types; template TypeCheck(T) { enum TypeCheck = true; shared static this() { types ~= T.mangleof; } } === module test500.d struct Cool {} void main() { import core.config, std.stdio; writeln(types); } === dmd test500.d rtinfo.d $ ./test500 [S7test5004Cool, S3std5array17__T8AppenderTAyaZ8Appender4Data, S3std5array17__T8AppenderTAyaZ8Appender] Run time info available about all the types used in that program! S yeah, this is pretty much a pure win all around to my eyes. Am I blind to the suck? This solve quite a few issues at once! It looks like stuff that could only be done with compiler extensions or AST manipulations and yet it works with a simple template. Just for the neat once in a lifetime idea it should be accepted. :) -- Marco
Re: [RFC] I/O and Buffer Range
On 12/29/2013 2:02 PM, Dmitry Olshansky wrote: The BufferRange concept itself (for now called simply Buffer) is defined here: http://blackwhale.github.io/datapicked/dpick.buffer.traits.html I am confused because there are 4 terms conflated here: BufferRange Buffer InputStream Stream
Re: another cool RTInfo trick - i want in runtime
On Thursday, 16 January 2014 at 15:57:05 UTC, Adam D. Ruppe wrote: S yeah, this is pretty much a pure win all around to my eyes. Am I blind to the suck? Wow, great trick! I'd love to see this merged.
Re: DMD can implicitly convert class pointer to the bool. Is it bug or terrible feature?
On Sun, 24 Nov 2013 16:38:19 -0500, Ary Borenszweig a...@esperanto.org.ar wrote: On 11/24/13 11:18 AM, ilya-stromberg wrote: DMD output: Error: use 'is' instead of '==' when comparing with null Error: use '!is' instead of '!=' when comparing with null Ugh, if the compiler disallows comparison of reference with == and != and tells you to use is and !is, can't compiler just allow you to write == and understand it as is? What's the big deal? The reason for this was a long fought battle with Walter. f == null would crash if f actually WAS null (compiler did blind rewrite to f.opEquals(null), which is a virtual call). This was the solution we could get Walter to implement, and that was a pretty big accomplishment after his opposition :) The rewrite could be done too, but this implementation is actually how Walter was convinced -- it flagged several cases in Phobos where he had done that and didn't realize it. However, x == y has since been changed to forward to object.opEquals(x, y), which can handle null parameters in either position, so this error is actually unneeded, and could be removed (I'd recommend removing it). -Steve
Re: Access modifier for extensions
On Thursday, 16 January 2014 at 18:50:26 UTC, Vladimir Panteleev wrote: On Thursday, 16 January 2014 at 09:28:18 UTC, Boyd wrote: For extending, there is the 'protected' attribute, but it's specific for class overriding only. Very often, extensions are not merely limited to derived classes. What I find myself wanting is more like the 'package' attribute, except it needs to work outside of the package as well. You can make class members accessible to a module by reintroducing them in a derived class using an alias. It even works for static and final methods, and field variables. Example: /// module library; class Button { protected void click() {} } /// module user; import library; void main() { auto button = new Button(); button.click(); // NG } /// module extender; import library; class ExtendedButton : Button { // reintroduce protected member as private to this scope private alias Button.click click; } void main() { auto button = new ExtendedButton(); button.click(); // OK } /// HTH. While it would work in this case, extending the class is not always an option. Plus it seems quite a big and dirty-looking work around for something that should, in my opinion, be quite simple.
Re: [RFC] I/O and Buffer Range
17-Jan-2014 00:18, Walter Bright пишет: On 12/29/2013 2:02 PM, Dmitry Olshansky wrote: The BufferRange concept itself (for now called simply Buffer) is defined here: http://blackwhale.github.io/datapicked/dpick.buffer.traits.html I am confused because there are 4 terms conflated here: BufferRange Buffer One and the same fr the moment. You even quoted it: BufferRange .. (for now called simply Buffer)... InputStream Stream One and the same as I dealt with the input side of the problem only. -- Dmitry Olshansky
Re: [RFC] I/O and Buffer Range
17-Jan-2014 00:00, Steven Schveighoffer пишет: On Thu, 16 Jan 2014 13:44:08 -0500, Dmitry Olshansky dmitry.o...@gmail.com wrote: 16-Jan-2014 19:55, Steven Schveighoffer пишет: On Tue, 07 Jan 2014 05:04:07 -0500, Dmitry Olshansky dmitry.o...@gmail.com wrote: [snip] In essence a transcoding filter for UTF-16 would wrap a buffer of ubyte and itself present a buffer interface (but of wchar). My intended interface allows you to specify the desired type per read. Think of the case of stdin, where the clients will be varied and written by many different people, and its interface is decided by Phobos. But a transcoding buffer may make some optimizations. For instance, reading a UTF32 file as utf-8 can re-use the same buffer, as no code unit uses more than 4 code points (did I get that right?). The other way around :) 4 code units - 1 code point. I am going to study your code some more and see how I can update my code to use it. I still need to maintain the std.stdio.File interface, and Walter is insistent that the initial state of stdout/err/in must be synchronous with C (which kind of sucks, but I have plans on how to make it not be so bad). I seriously not seeing how interfacing with C runtime could be fast enough. It's not. But an important stipulation in order for this to all be accepted is that it doesn't break existing code that expects things like printf and writef to interleave properly. However, I think we can have an opt-in scheme, and there are certain cases where we can proactively switch to a D-buffer scheme. For example, if you get a ByLine range, it expects to exhaust the data from stream, and may not properly work with C printf. The idea is that stdio.File can switch at runtime from FILE * to D streams as needed or directed. There is still a lot of work left to do, but I think one of the hard parts is done, namely dealing with UTF transcoding. The remaining sticky part is dealing with shared. But with structs, this should make things much easier. I'm thinking a generic locking wrapper is possible along the lines of: shared Locked!(GenericBuffer!char) stdin; //usage struct Locked(T){ shared: private: T _this; Mutex mut; public: //forwarded methods } The wrapper will introduce a lock, and implement every method of wrapped struct roughly like this: mut.lock(); scope(exit) mut.unlock(); (cast(T*)_this).method(args); I'm sure it could be pretty automatic. This would be a key addition for ANY type in order to properly work with shared. BUT, I don't see how it works safely generically because you necessarily have to cast away shared in order to call the methods. You would have to limit this to only working on types it was intended for. The requirement may be that it's pure or should I say well-contained. In other words as long as it doesn't smuggle references somewhere else it should be fine. That is to say it's 100% fool-proof, nor do I think that essentially simulating a synchronized class is a always a good thing to do... I've been expecting to have to do something like this, but not looking forward to it :( One question, is there a reason a buffer type has to be a range at all? I can see where it's easy to make it a range, but I don't see higher-level code using the range primitives when dealing with chunks of a stream. Lexers/parsers enjoy it - i.e. they work pretty much as ranges especially when skipping spaces and the like. As I said the main reason was: if it fits as range why not? After all it makes one-pass processing of data trivial as it rides on top of foreach: foreach(octect; mybuffer) { if(intersting(octect)) do_cool_stuff(); } Things like countUntil make perfect sense when called on buffer (e.g. to find matching sentinel). I think I misstated my question. What I am curious about is why a type must be a forward range to pass isBuffer. Of course, if it makes sense for a buffer type to also be a range, it can certainly implement that interface as well. But I don't know that I would need those primitives in all cases. I don't have any specific use case for having a buffer that doesn't implement a range interface, but I am hesitant to necessarily couple the buffer interface to ranges just because we can't think of a counter-case :) Convenient to work with does ring good to me. I simply see no need to reinvent std.algorithm on buffers especially the ones that just scan left-to-right. Example would be calculating a checksum of a stream (say data comes from a pipe or socket i.e. buffered). It's a trivial application of std.algorithm.reduce and there no need to reinvent that wheel IMHO. -- Dmitry Olshansky
Re: [RFC] I/O and Buffer Range
On Thu, 16 Jan 2014 17:28:31 -0500, Dmitry Olshansky dmitry.o...@gmail.com wrote: The other way around :) 4 code units - 1 code point. I knew that was going to happen :) This would be a key addition for ANY type in order to properly work with shared. BUT, I don't see how it works safely generically because you necessarily have to cast away shared in order to call the methods. You would have to limit this to only working on types it was intended for. The requirement may be that it's pure or should I say well-contained. In other words as long as it doesn't smuggle references somewhere else it should be fine. That is to say it's 100% fool-proof, nor do I think that essentially simulating a synchronized class is a always a good thing to do... I think you meant *not* 100% :) But yeah, regardless of how generalized it is, this is likely the best path. I think this is the tack that std.stdio.File takes anyway, except it's using FILE *'s locking mechanism. Convenient to work with does ring good to me. I simply see no need to reinvent std.algorithm on buffers especially the ones that just scan left-to-right. Example would be calculating a checksum of a stream (say data comes from a pipe or socket i.e. buffered). It's a trivial application of std.algorithm.reduce and there no need to reinvent that wheel IMHO. I again think I am being misunderstood. Example might be appropriate: struct Buffer {...} // implements BOTH forward range and Buffer primitives struct OtherBuffer {...} // only implements Buffer primitives. If isBuffer is modified to not require isForwardRange, then both Buffer and OtherBuffer will work as buffers, but only Buffer works as a range. But as you have it now, isBuffer!OtherBuffer is false. Is this necessary? So we can implement buffers that are both ranges and buffers, and will work with std.algorithm without modification (and that's fine and expected by me), but do we need to *require* that? Are we over-specifying? Is there a possibility that someone can invent a buffer that satisfies the primitives of say a line-by-line reader, but cannot possibly be a forward range? -Steve
Re: DConf 2014 proposals: two weeks left!
On 1/16/14 9:13 AM, Vladimir Panteleev wrote: On Thursday, 16 January 2014 at 17:07:55 UTC, Andrei Alexandrescu wrote: Deadline is January 31st. Also don't forget reduced-cost ($250) pre-registration expires the same day. Can I register but get a refund if my talk is accepted? ;) Yes, we allow that. Register away, and we'll refund your check if you get one or more talks accepted. Andrei
Re: [RFC] I/O and Buffer Range
On 1/16/2014 2:30 PM, Dmitry Olshansky wrote: 17-Jan-2014 00:18, Walter Bright пишет: On 12/29/2013 2:02 PM, Dmitry Olshansky wrote: The BufferRange concept itself (for now called simply Buffer) is defined here: http://blackwhale.github.io/datapicked/dpick.buffer.traits.html I am confused because there are 4 terms conflated here: BufferRange Buffer One and the same fr the moment. You even quoted it: BufferRange .. (for now called simply Buffer)... I know. But using two names for the same thing makes for confusing documentation. There also appears to be no rationale for for the moment. InputStream Stream One and the same as I dealt with the input side of the problem only. Same problem with multiple names for the same thing, also there's no definition of either name.
Re: another cool RTInfo trick - i want in runtime
This is a bit of a side discussion because the RTInfo can't *change* the type, it can only look at it. It is more like a centralized place to static asserts or maybe static data than an AST macro. But... On Thursday, 16 January 2014 at 19:32:10 UTC, Namespace wrote: The problem on a library NotNull struct is: nobody will use it, because it requires NotNull on both sides, by the caller and by the callee: That's a lot of the benefit: the type system forces you to handle it sooner rather than later, so you can see where the invalid state came from. NotNull!A na = NotNull!A(new A()); This could be easily automated though with a helper function: NotNull!T create(T, Args...)(Args args) { return assumeNotNull(new T(args)); } // use it! notice that it is notnull already auto na = create!A(); And then you can just use it. Also it is far more readable and easier to write as a contract That's what I tend to do now but the advantage of NotNull!() is catching it earlier.
Re: another cool RTInfo trick - i want in runtime
On Thursday, 16 January 2014 at 23:56:14 UTC, Adam D. Ruppe wrote: // use it! notice that it is notnull already auto na = create!A(); That's neat. Didn't Andrei mention something about wanting new to be removed from the language and replaced with a library solution using allocators? If that were the case, it'd be pretty easy to enforce that class allocators return NotNull!T. It'd get rid of nullable references without needing a breaking language change.
Re: another cool RTInfo trick - i want in runtime
On Thursday, 16 January 2014 at 20:13:29 UTC, Jacob Carlborg wrote: Does this only work once? Say I have two libraries that use this technique, would that work? No, then you'd get complaints about the module being defined in two files. This would be a once-per-project thing. Libraries however could provide helper functions with instructions for the user to call them in their project file. For example module my.serialization; mixin template SerializationAdditionToTypeInfo(T) { Whatever serialize() { . } } and then the user would open up their magic file module core.config; // BTW this name is just because it was on my mind from another discussion with it for enabled features template CustomRtInfo(T) { import my.serialization; mixin SerializationAdditionToTypeInfo!T; // you can also do other library's stuff here } hmmm Vladimir might be right that the custom info thing would be better done as a mixin template, then we could throw all this right in there and maybe build the whole class. I've gotta try it, I'm not sure yet. No, not yet. As far as I know, the idea was to use RTInfo to collect and store type info for a precise GC. Yeah, RTInfo is one of the most potentially cool things that has sat untapped for a long time. I have had a different idea for a solution to this problem for a while. That is, add a new manifest constant to object.d, called rtInfo. This will act like a UDA. Any template with the object.rtInfo UDA attached to itself will behave just as RTInfo does today. I think that would need compiler support though and might not work as well when compiling two files separately since then part of the rtinfo wouldn't get checked. True, here you'd have to include the config file each time you compile a file, but at least that bit is centralized so easier to manage. An idea for storing data in TypeInfo is to create an associative array. The keys would be the fully qualified name of the template, in this case foo.check_virtual_methods.CheckVirtualMethods. The values would be whatever the template evaluates to. There's one problem with this, the associative array would need to be built at runtime due to separate compilation. Yeah, I've played with this idea before too, it is definitely doable today.
Re: another cool RTInfo trick - i want in runtime
On Thursday, 16 January 2014 at 20:16:59 UTC, Marco Leise wrote: It looks like stuff that could only be done with compiler extensions or AST manipulations and yet it works with a simple template. Yeah, though remember that it can't actually manipulate the type, it just looks and can build up other data or issue errors, but not change the code it is looking at.
Re: another cool RTInfo trick - i want in runtime
On Friday, 17 January 2014 at 00:03:21 UTC, Meta wrote: Didn't Andrei mention something about wanting new to be removed from the language and replaced with a library solution using allocators? I'm not sure if he's on board, but that's something I've been wanting for a while. Probably won't happen though, the new operator has a lot of fans (I kinda like it myself and fear the massive amount of code breakage removing it would cause). But we could still use specialized alternatives - new being there doesn't prohibit using a create function.
Re: another cool RTInfo trick - i want in runtime
On 2014-01-17 00:03:19 +, Meta jared...@gmail.com said: On Thursday, 16 January 2014 at 23:56:14 UTC, Adam D. Ruppe wrote: // use it! notice that it is notnull already auto na = create!A(); That's neat. Didn't Andrei mention something about wanting new to be removed from the language and replaced with a library solution using allocators? If that were the case, it'd be pretty easy to enforce that class allocators return NotNull!T. It'd get rid of nullable references without needing a breaking language change. In one C++ project of mine I have a make_new T (args...) template function that does exactly that. Pretty neat. The biggest downside to such an approach is that you're creating your own meta-language on top of the regular language (replacing the language syntax with your own). But it cannot really be avoided if you want NotNull to be usable. The next language facility you might have to duplicate is the cast (to keep the not-null qualifier when casting). Then maybe you'll want it to play nice with other the other qualifier type template Rebindable. -- Michel Fortin michel.for...@michelf.ca http://michelf.ca
Re: DConf 2014 proposals: two weeks left!
On 1/16/14 2:57 PM, Andrei Alexandrescu wrote: On 1/16/14 9:13 AM, Vladimir Panteleev wrote: On Thursday, 16 January 2014 at 17:07:55 UTC, Andrei Alexandrescu wrote: Deadline is January 31st. Also don't forget reduced-cost ($250) pre-registration expires the same day. Can I register but get a refund if my talk is accepted? ;) Yes, we allow that. Register away, and we'll refund your check if you get one or more talks accepted. Updated website to reflect the message. Andrei
Non-null objects, the Null Object pattern, and T.init
Walter and I were talking today about the null pointer issue and he had the following idea. One common idiom to replace null pointer exceptions with milder reproducible errors is the null object pattern, i.e. there is one object that is used in lieu of the null reference to initialize all otherwise uninitialized references. In D that would translate naturally to: class Widget { private int x; private Widget parent; this(int y) { x = y; } ... // Here's the interesting part static Widget init = new Widget(42); } Currently the last line doesn't compile, but we can make it work if the respective constructor is callable during compilation. The compiler will allocate a static buffer for the newed Widget object and will make init point there. Whenever a Widget is to be default-initialized, it will point to Widget.init (i.e. it won't be null). This beautifully extends the language because currently (with no init definition) Widget.init is null. So the init Widget will satisfy: assert(x == 42 parent is Widget.init); Further avenues are opened by thinking what happens if e.g. init is private or @disable-d. Thoughts? Andrei
Re: Non-null objects, the Null Object pattern, and T.init
On Friday, 17 January 2014 at 01:42:38 UTC, Andrei Alexandrescu wrote: static Widget init = new Widget(42); The problem here is if it is in a mutable data segment: Widget i; // implicitly set to init assert(i is Widget.init); // uh oh i.mutate(); Widget i2; // set to widget init... assert(i is i2); // oh dear // i2 now reflects the mutation done above! And if the init is put in a read-only segment similar to a string buffer, we still get a segmentation fault when we try to mutate it. I'm not necessarily against having the option, but I think it would generally be more trouble than it is worth. If you have an object that you want to guarantee is not null, make the nullable implementation class Widget_impl {} then define alias Widget = NotNull!Widget_impl; and force initialization that way.
Re: Non-null objects, the Null Object pattern, and T.init
On Friday, 17 January 2014 at 01:42:38 UTC, Andrei Alexandrescu wrote: Walter and I were talking today about the null pointer issue and he had the following idea. One common idiom to replace null pointer exceptions with milder reproducible errors is the null object pattern, i.e. there is one object that is used in lieu of the null reference to initialize all otherwise uninitialized references. In D that would translate naturally to: class Widget { private int x; private Widget parent; this(int y) { x = y; } ... // Here's the interesting part static Widget init = new Widget(42); } Currently the last line doesn't compile, but we can make it work if the respective constructor is callable during compilation. The compiler will allocate a static buffer for the newed Widget object and will make init point there. Whenever a Widget is to be default-initialized, it will point to Widget.init (i.e. it won't be null). This beautifully extends the language because currently (with no init definition) Widget.init is null. So the init Widget will satisfy: assert(x == 42 parent is Widget.init); Further avenues are opened by thinking what happens if e.g. init is private or @disable-d. Thoughts? Andrei I am assuming init will be a property static function. So essentially we would be removing .init support for classes in compiler and pushing it out into Object. I would rather if that is an option an init static function, that it would be required to have override otherwise it would be too 'magical' for me atleast. The default can still be null.
Re: Non-null objects, the Null Object pattern, and T.init
On 1/16/14 5:53 PM, Adam D. Ruppe wrote: On Friday, 17 January 2014 at 01:42:38 UTC, Andrei Alexandrescu wrote: static Widget init = new Widget(42); The problem here is if it is in a mutable data segment: Widget i; // implicitly set to init assert(i is Widget.init); // uh oh i.mutate(); Widget i2; // set to widget init... assert(i is i2); // oh dear // i2 now reflects the mutation done above! Yah, that would be expected. I'm not necessarily against having the option, but I think it would generally be more trouble than it is worth. If you have an object that you want to guarantee is not null, make the nullable implementation class Widget_impl {} then define alias Widget = NotNull!Widget_impl; and force initialization that way. Noted. Andrei
Re: Non-null objects, the Null Object pattern, and T.init
On Friday, 17 January 2014 at 01:42:38 UTC, Andrei Alexandrescu wrote: Whenever a Widget is to be default-initialized, it will point to Widget.init (i.e. it won't be null). This beautifully extends the language because currently (with no init definition) Widget.init is null. Hmm, what about derived classes? How do you check for a valid Widget given a DerivedWidget.init? class DerivedWidget : Widget { static DerivedWidget init = new DerivedWidget(...); } bool valid(Widget w) { return w !is Widget.init; } DerivedWidget foo; assert(!valid(foo)); // doesn't fire, foo is valid? The nice thing about null is that it is the bottom type, so it is a universal sentinel value. Also, what about interfaces? You cannot define an init for an interface. Obviously that could just be a known and accepted limitation of this proposal, but I'm not a huge fan of solutions that only work in a subset of situations. Perhaps there is a solution that I haven't thought of. assert(x == 42 parent is Widget.init); Is that meant to say x is Widget.init?
Re: Non-null objects, the Null Object pattern, and T.init
On Friday, 17 January 2014 at 01:57:24 UTC, Rikki Cattermole wrote: I am assuming init will be a property static function. So essentially we would be removing .init support for classes in compiler and pushing it out into Object. I don't think a function would work without major work since that would mean adding non-blit* default construction to the language - which isn't present at all right now.
Re: Non-null objects, the Null Object pattern, and T.init
On Friday, 17 January 2014 at 02:07:08 UTC, deadalnix wrote: Most object don't have a sensible init value. That is just hiding the problem under the carpet. That's true. class Widget { Widget parent; static Widget init = ??? } How do you define init?
Re: Non-null objects, the Null Object pattern, and T.init
On Friday, 17 January 2014 at 01:42:38 UTC, Andrei Alexandrescu wrote: Walter and I were talking today about the null pointer issue and he had the following idea. One common idiom to replace null pointer exceptions with milder reproducible errors is the null object pattern, i.e. there is one object that is used in lieu of the null reference to initialize all otherwise uninitialized references. In D that would translate naturally to: class Widget { private int x; private Widget parent; this(int y) { x = y; } ... // Here's the interesting part static Widget init = new Widget(42); } Currently the last line doesn't compile, but we can make it work if the respective constructor is callable during compilation. The compiler will allocate a static buffer for the newed Widget object and will make init point there. Whenever a Widget is to be default-initialized, it will point to Widget.init (i.e. it won't be null). This beautifully extends the language because currently (with no init definition) Widget.init is null. So the init Widget will satisfy: assert(x == 42 parent is Widget.init); Further avenues are opened by thinking what happens if e.g. init is private or @disable-d. Thoughts? Andrei Most object don't have a sensible init value. That is just hiding the problem under the carpet.
Re: Non-null objects, the Null Object pattern, and T.init
On 1/16/14 5:57 PM, Rikki Cattermole wrote: I am assuming init will be a property static function. In the example above it's just a static data member. So essentially we would be removing .init support for classes in compiler and pushing it out into Object. I would rather if that is an option an init static function, that it would be required to have override otherwise it would be too 'magical' for me atleast. The default can still be null. Override only works for nonstatic methods. Andrei
Re: Non-null objects, the Null Object pattern, and T.init
On 1/16/14 6:02 PM, Peter Alexander wrote: On Friday, 17 January 2014 at 01:42:38 UTC, Andrei Alexandrescu wrote: Whenever a Widget is to be default-initialized, it will point to Widget.init (i.e. it won't be null). This beautifully extends the language because currently (with no init definition) Widget.init is null. Hmm, what about derived classes? How do you check for a valid Widget given a DerivedWidget.init? class DerivedWidget : Widget { static DerivedWidget init = new DerivedWidget(...); } bool valid(Widget w) { return w !is Widget.init; } DerivedWidget foo; assert(!valid(foo)); // doesn't fire, foo is valid? The nice thing about null is that it is the bottom type, so it is a universal sentinel value. This is a good point. Also, what about interfaces? You cannot define an init for an interface. Obviously that could just be a known and accepted limitation of this proposal, but I'm not a huge fan of solutions that only work in a subset of situations. Perhaps there is a solution that I haven't thought of. assert(x == 42 parent is Widget.init); Is that meant to say x is Widget.init? To clarify: assert(Widget.init.x == 42 Widget.init.parent is Widget.init); Andrei
Re: Non-null objects, the Null Object pattern, and T.init
On 1/16/14 6:11 PM, Adam D. Ruppe wrote: On Friday, 17 January 2014 at 02:04:27 UTC, Andrei Alexandrescu wrote: Yah, that would be expected. Yeah, but I think people would find it weird. This kind of thing is actually possible today: class Foo { } class Bar { Foo foo = new Foo(); // this gets a static reference into the typeinfo.init (since new Foo is evaluated at compile time!) which is blitted over... } That wouldn't be allowed. Andrei
Re: Non-null objects, the Null Object pattern, and T.init
On Friday, 17 January 2014 at 02:04:27 UTC, Andrei Alexandrescu wrote: Yah, that would be expected. Yeah, but I think people would find it weird. This kind of thing is actually possible today: class Foo { } class Bar { Foo foo = new Foo(); // this gets a static reference into the typeinfo.init (since new Foo is evaluated at compile time!) which is blitted over... } void main() { auto bar = new Bar(); // bar.foo is blitted to point at the static Foo auto bar2 = new Bar(); // and same thing assert(bar.foo is bar2.foo); // passes, but that's kinda weird } Granted, maybe the weirdness here is because the variable isn't static, so people expect it to be different, but I saw at least one person on the chat room be very surprised by this - and I was too, until I thought about how CTFE and Classinfo.init is implemented, then it made sense, but at first glance it was a bit weird. I think people would be a bit surprised if it was Foo foo; as well using the proposed .init thingy.
Re: Non-null objects, the Null Object pattern, and T.init
On 1/16/14 6:09 PM, Peter Alexander wrote: On Friday, 17 January 2014 at 02:07:08 UTC, deadalnix wrote: Most object don't have a sensible init value. That is just hiding the problem under the carpet. That's true. class Widget { Widget parent; static Widget init = ??? } How do you define init? Depends on what you want. Could be null or could have itself as a parent. The null object pattern is what it is. Andrei
Re: Non-null objects, the Null Object pattern, and T.init
On Friday, 17 January 2014 at 02:08:07 UTC, Andrei Alexandrescu wrote: assert(x == 42 parent is Widget.init); Is that meant to say x is Widget.init? To clarify: assert(Widget.init.x == 42 Widget.init.parent is Widget.init); Ah right, missed the parent parameter... Also ignore my previous comment in that case :-) However, I'm not sure this is good. Those kinds of reference cycles can easily lead to infinite loops. Is that really an improvement on a null-pointer dereference?
Re: Non-null objects, the Null Object pattern, and T.init
On Friday, 17 January 2014 at 02:06:03 UTC, Andrei Alexandrescu wrote: I would rather if that is an option an init static function, that it would be required to have override otherwise it would be too 'magical' for me atleast. The default can still be null. Override only works for nonstatic methods. I know it doesn't. Its more for making it nicer to read than anything. An actual property as you've shown would be nice. But having another place which can be abused, which you can write code for is nice.
Re: Non-null objects, the Null Object pattern, and T.init
On 1/16/14 6:13 PM, Peter Alexander wrote: However, I'm not sure this is good. Those kinds of reference cycles can easily lead to infinite loops. Is that really an improvement on a null-pointer dereference? You don't have to use the null object pattern for all classes. It's opt-in. Andrei
Re: Non-null objects, the Null Object pattern, and T.init
deadalnix: Most object don't have a sensible init value. That is just hiding the problem under the carpet. If there's desire to solve this problem I think that improving the type system to avoid nulls where they are not desired is better than having an init object. So aren't not-nullable pointers and references a better solution? Bye, bearophile
Re: Non-null objects, the Null Object pattern, and T.init
On Friday, 17 January 2014 at 02:52:15 UTC, bearophile wrote: deadalnix: Most object don't have a sensible init value. That is just hiding the problem under the carpet. If there's desire to solve this problem I think that improving the type system to avoid nulls where they are not desired is better than having an init object. So aren't not-nullable pointers and references a better solution? Bye, bearophile This! Also, if anything, it's better to turn `init` into a method rather than an object. The following would work all of a sudden: class Foo { Bar bar = new Bar(); int i = 42; Foo() { assert(bar !is null); assert(i == 42); } // auto-generated private final void init(Foo foo) { foo.bar = new Bar(); foo.i = 42; } }
Re: Non-null objects, the Null Object pattern, and T.init
On 2014-01-17 01:42:37 +, Andrei Alexandrescu seewebsiteforem...@erdani.org said: Walter and I were talking today about the null pointer issue and he had the following idea. [...] Thoughts? Which null pointer issue were you discussing exactly? The one I'm mostly concerned about is the propagation of a null value from point A to point B in a program, where you only detect the null value at point B through a null dereference making it hard to figure out from where this unexpected null value comes from. Replace 'null' with 'sentinel' and it's no easier to figure out where the invalid value comes from. Except now instead of checking for null you have to check for null *and* for T.init *and* for all the various Sublcass.init you might get. The idea is interesting, but I see it creating more problems than it would solve. I'm not even sure I understand what problem it tries to solve. -- Michel Fortin michel.for...@michelf.ca http://michelf.ca
Re: Non-null objects, the Null Object pattern, and T.init
On Thu, Jan 16, 2014 at 11:00:24PM -0500, Michel Fortin wrote: On 2014-01-17 01:42:37 +, Andrei Alexandrescu seewebsiteforem...@erdani.org said: Walter and I were talking today about the null pointer issue and he had the following idea. [...] Thoughts? Which null pointer issue were you discussing exactly? The one I'm mostly concerned about is the propagation of a null value from point A to point B in a program, where you only detect the null value at point B through a null dereference making it hard to figure out from where this unexpected null value comes from. Replace 'null' with 'sentinel' and it's no easier to figure out where the invalid value comes from. Except now instead of checking for null you have to check for null *and* for T.init *and* for all the various Sublcass.init you might get. The idea is interesting, but I see it creating more problems than it would solve. I'm not even sure I understand what problem it tries to solve. [...] AFAICT the null object pattern is intended to prevent dereferencing a null pointer (i.e., prevent a segfault on Posix), by providing a dummy object that has no-op stubs for methods and default values for fields. But from what I've been observing, what people have been asking for on this forum has been more a way of *preventing* null (or a sentinel, as here) from being assigned to a reference to begin with. So as far as that is concerned, this proposal doesn't really address the issue. Now, if we modify this sentinel to instead record the location of the code that first initialized it (via __FILE__ and __LINE__ default parameters perhaps), then we can set it up to print out this information at a convenient juncture, so that the source of the uninitialized reference can be determined. *Then* perhaps it will be a start of a solution to this issue. (Though it still has limitations in the sense that the problem can only be caught at runtime, whereas some cases of null dereference preferably should be caught at compile-time.) T -- Music critic: That's an imitation fugue!
Re: Non-null objects, the Null Object pattern, and T.init
On 1/16/2014 5:42 PM, Andrei Alexandrescu wrote: Walter and I were talking today about the null pointer issue and he had the following idea. One common idiom to replace null pointer exceptions with milder reproducible errors is the null object pattern, i.e. there is one object that is used in lieu of the null reference to initialize all otherwise uninitialized references. In D that would translate naturally to: class Widget { private int x; private Widget parent; this(int y) { x = y; } ... // Here's the interesting part static Widget init = new Widget(42); } I was thinking of: @property static Widget init() { ... }
Re: Non-null objects, the Null Object pattern, and T.init
On 1/16/2014 6:11 PM, Adam D. Ruppe wrote: I think people would be a bit surprised if it was Foo foo; We really don't want any foo-foo stuff in D.
Re: Non-null objects, the Null Object pattern, and T.init
On 01/17/2014 03:11 AM, Adam D. Ruppe wrote: On Friday, 17 January 2014 at 02:04:27 UTC, Andrei Alexandrescu wrote: Yah, that would be expected. Yeah, but I think people would find it weird. This kind of thing is actually possible today: class Foo{ int x = 2; } class Bar{ auto foo = new Foo(); } void main(){ auto ibar = new immutable(Bar)(); auto bar = new Bar(); static assert(is(typeof(ibar.foo.x)==immutable)); assert(ibar.foo.x==2); bar.foo.x=3; assert(ibar.foo.x==3); // uh-oh! }
Re: Non-null objects, the Null Object pattern, and T.init
On 01/17/2014 02:42 AM, Andrei Alexandrescu wrote: class Widget { private int x; private Widget parent; this(int y) { x = y; } ... // Here's the interesting part static Widget init = new Widget(42); } Currently the last line doesn't compile, but we can make it work if the respective constructor is callable during compilation. The compiler will allocate a static buffer for the newed Widget object and will make init point there. immutable(Widget) iwidget; // ?
Re: another cool RTInfo trick - i want in runtime
Am Fri, 17 Jan 2014 00:15:51 + schrieb Adam D. Ruppe destructiona...@gmail.com: On Thursday, 16 January 2014 at 20:16:59 UTC, Marco Leise wrote: It looks like stuff that could only be done with compiler extensions or AST manipulations and yet it works with a simple template. Yeah, though remember that it can't actually manipulate the type, it just looks and can build up other data or issue errors, but not change the code it is looking at. Right. It did get me interested in how UDAs work though, since I never really looked at them when they were introduced. The compiler can cope with a lot of template magic I throw at it now. I'm sure I would have had a dozen errors already with 2.063. I'm investigating data driven library bindings. E.g. some template contains function pointers with UDAs that describe how wrappers are to be generated that turn getError() calls into D exceptions and turn D strings into C char* and similar tricks, like handling API changes from one version to the next. -- Marco
Re: another cool RTInfo trick - i want in runtime
Am Fri, 17 Jan 2014 00:17:58 + schrieb Adam D. Ruppe destructiona...@gmail.com: On Friday, 17 January 2014 at 00:03:21 UTC, Meta wrote: Didn't Andrei mention something about wanting new to be removed from the language and replaced with a library solution using allocators? I'm not sure if he's on board, but that's something I've been wanting for a while. Probably won't happen though, the new operator has a lot of fans (I kinda like it myself and fear the massive amount of code breakage removing it would cause). But we could still use specialized alternatives - new being there doesn't prohibit using a create function. The state of NotNull without it being a language feature would still be a bit silly. A good implementation allows promotion to NotNull like this: void foo(Object o) { if (o !is null) { bar(o); } } void bar(NotNull!Object) {} Maybe it could be implemented like if (__ctfe). -- Marco
Array of pointers
Hi. I started my first program in D (I have a little experience in c). I wanted to create an array of pointers for creating a node with multiple connections. In C you can make one directly (node *nedePtr[]). What is the equivalent for the D's syntax?? Regards Arjan
Re: Array of pointers
On Thursday, 16 January 2014 at 09:00:18 UTC, Namespace wrote: On Thursday, 16 January 2014 at 08:55:43 UTC, Arjan Fetahu wrote: Hi. I started my first program in D (I have a little experience in c). I wanted to create an array of pointers for creating a node with multiple connections. In C you can make one directly (node *nedePtr[]). What is the equivalent for the D's syntax?? Regards Arjan node*[] nedePtr; Ok. Thank You!
Re: Array of pointers
On Thursday, 16 January 2014 at 09:03:00 UTC, Arjan Fetahu wrote: On Thursday, 16 January 2014 at 09:00:18 UTC, Namespace wrote: On Thursday, 16 January 2014 at 08:55:43 UTC, Arjan Fetahu wrote: Hi. I started my first program in D (I have a little experience in c). I wanted to create an array of pointers for creating a node with multiple connections. In C you can make one directly (node *nedePtr[]). What is the equivalent for the D's syntax?? Regards Arjan node*[] nedePtr; Ok. Thank You! Keep in mind that, unlike in c++, D classes are reference types: class Node { Node[] nodes; // This is valid } Structs are value types though, so using a struct in the above example is illegal.
Re: Array of pointers
On Thursday, 16 January 2014 at 09:47:21 UTC, Rene Zwanenburg wrote: On Thursday, 16 January 2014 at 09:03:00 UTC, Arjan Fetahu wrote: On Thursday, 16 January 2014 at 09:00:18 UTC, Namespace wrote: On Thursday, 16 January 2014 at 08:55:43 UTC, Arjan Fetahu wrote: Hi. I started my first program in D (I have a little experience in c). I wanted to create an array of pointers for creating a node with multiple connections. In C you can make one directly (node *nedePtr[]). What is the equivalent for the D's syntax?? Regards Arjan node*[] nedePtr; Ok. Thank You! Keep in mind that, unlike in c++, D classes are reference types: class Node { Node[] nodes; // This is valid } Structs are value types though, so using a struct in the above example is illegal. You mean: struct Node { Node[] nodes; } or struct Node { Node*[] nodes; } ? Works both. What's not working is this: struct Node { Node node; }
Re: A little of coordination for Rosettacode
qznc: This sounds somewhat paradox to me. How can a new feature have a regression? A regression means it has worked before, but new feature did not exist before. Regressions on older betas; or to see if using the new features breaks other apparently unrelated parts of old code. In practice the difference between the uses is not that important I think, because the sheer number of code snippets and release frequency means that most examples can be compiled with the latest release no matter what bearophile does. ;) Right. The percentage of future compilable entries is small, usually much less than 5%. And this was even more true in past, when the frequency of D releases was higher. Btw are your scripts public, bearophile? They are the common kind of little scripts that you prefer to rewrite on your own. Bye, bearophile
Re: Compile/link Win64
On Wednesday, 15 January 2014 at 22:21:18 UTC, Nick Sabalausky wrote: \Program Files (x86)\Windows Kits\ doesn't exist :( As I suspected, it must not have installed correctly. Nick, did you notice my reply from 4 days ago? http://forum.dlang.org/post/lumcuftlvokawuneq...@forum.dlang.org I believe that under certain conditions, the MS linker will just skip over libraries of certain bitness, so I suspect that might be your problem. I don't think the platform/Windows SDK is related to the problem in your first post because Visual Studio 2005 (VS8), which is what you had in your paths, comes with its own copy (the PlatformSDK directory).
Re: Compile/link Win64
On Friday, 10 January 2014 at 20:32:53 UTC, Brad Anderson wrote: Hmm, that's strange, %WindowsSdkDir% isn't set. I thought vcvarsall.bat was supposed to set up all of that. Appears to be a common problem with VC2008: http://stackoverflow.com/questions/1102689/windowssdkdir-is-not-set-correctly-in-visual-studio-2008 According to this post[1], he is using VC2005 (VS8), not 2008. 2005 comes with its own copy of the SDK, under VC/PlatformSDK. http://forum.dlang.org/post/lapkjf$pio$1...@digitalmars.com