Re: Fibers and async io stuff for beginners
On Friday, 24 April 2015 at 12:38:39 UTC, Jens Bauer wrote: On Friday, 24 April 2015 at 09:15:21 UTC, Chris wrote: I was more thinking of the audio thread. But the audio is probably better off in a separate thread. I think you could do this too. In fact, this is very similar to how the audio from a MOD file is decoded. (I only mentioned an interrupt, because I'm used to putting audio in interrupts, since I work very close to the hardware; meaning that interrupts will normally be much more efficient) I might give it a shot.
multiSort for sorting AA by value
The following works great. It sorts an AA by value: 1. by frequency of word 2. by alphabetic order (if two or more words have the same value) import std.stdio : writefln; import std.algorithm.sorting : multiSort; void main() { size_t[string] wcount = [ hamster:5, zorro:80, troll:90, algorithm:80, beer:80 ]; struct Word { string word; size_t count; } Word[] sorter; foreach (ref k, ref v; wcount) sorter ~= Word(k, v); assert(wcount.length == sorter.length); sorter.multiSort!(a.count b.count, a.word b.word); assert(sorter[2].word == beer); foreach (ref it; sorter) writefln(%s : %d, it.word, it.count); } I'm happy with it, but maybe there is a more concise implementation?
Re: [dvm] Can't install compilers on Mac
On Wednesday, 29 April 2015 at 06:41:30 UTC, Jacob Carlborg wrote: On 2015-04-28 19:46, Chris wrote: I keep getting this message. Why? Fetching: http://ftp.digitalmars.com/dmd.2.067.0.zip [] 56256/54884 KB Installing: dmd-2.067.0 An unknown error occurred: tango.core.Exception.IOException@/Users/doob/development/d/tango/tango/core/Exception.d(59): /Users/name/.dvm/bin/dmd-2.067.0 :: No such file or directory OS X Version 0.4.3 Have you installed DVM itself, running ./dvm install dvm? Can you please add the verbose flag, -v, when installing a compiler and posting the output. Yes. Doesn't work. Maybe I should just download it and compile it myself?
Re: Factory pattern in D
On Friday, 1 May 2015 at 10:04:46 UTC, Namespace wrote: How about this: struct A { int x = 42; } struct B { int x = 7; } T factory(T)() { return T(); } void main() { auto a = factory!(A); } That's what I was looking for, I just couldn't get it right. Thanks. Rikki: I wanted to avoid classes and interfaces.
Factory pattern in D
What would be the D equivalent of the factory pattern? This obviously doesn't work: struct A { int x = 42; } struct B { int x = 7; } auto factory(string type) { if (type == A) return A(); else if (type == B) return B(); else return A(); // default } void main() { auto a = factory(A); } Error: mismatched function return type inference of B and A (dmd 2.067.1)
[dvm] Can't install compilers on Mac
I keep getting this message. Why? Fetching: http://ftp.digitalmars.com/dmd.2.067.0.zip [] 56256/54884 KB Installing: dmd-2.067.0 An unknown error occurred: tango.core.Exception.IOException@/Users/doob/development/d/tango/tango/core/Exception.d(59): /Users/name/.dvm/bin/dmd-2.067.0 :: No such file or directory OS X Version 0.4.3
Re: Factory pattern in D
On Friday, 1 May 2015 at 10:46:20 UTC, Chris wrote: On Friday, 1 May 2015 at 10:27:16 UTC, biozic wrote: On Friday, 1 May 2015 at 10:12:36 UTC, Chris wrote: On Friday, 1 May 2015 at 10:04:46 UTC, Namespace wrote: How about this: struct A { int x = 42; } struct B { int x = 7; } T factory(T)() { return T(); } void main() { auto a = factory!(A); } That's what I was looking for, I just couldn't get it right. Thanks. Rikki: I wanted to avoid classes and interfaces. This might be a bit more useful: --- struct A { int x = 42; } struct B { int x = 7; } auto factory(string type = )() { static if (type == A) return A(); else static if (type == B) return B(); else return A(); // default } void main() { auto a = factory!A; auto b = factory!B; auto x = factory; } --- Duh, I tried `static if` yesterday and I still got Error: mismatched function return type inference of B and A. Now it works! Sure, I must have overlooked something. Sometimes it's better to go home and call it a day than to try to get something to work. And thanks, by the way!
Re: Factory pattern in D
On Friday, 1 May 2015 at 10:27:16 UTC, biozic wrote: On Friday, 1 May 2015 at 10:12:36 UTC, Chris wrote: On Friday, 1 May 2015 at 10:04:46 UTC, Namespace wrote: How about this: struct A { int x = 42; } struct B { int x = 7; } T factory(T)() { return T(); } void main() { auto a = factory!(A); } That's what I was looking for, I just couldn't get it right. Thanks. Rikki: I wanted to avoid classes and interfaces. This might be a bit more useful: --- struct A { int x = 42; } struct B { int x = 7; } auto factory(string type = )() { static if (type == A) return A(); else static if (type == B) return B(); else return A(); // default } void main() { auto a = factory!A; auto b = factory!B; auto x = factory; } --- Duh, I tried `static if` yesterday and I still got Error: mismatched function return type inference of B and A. Now it works! Sure, I must have overlooked something. Sometimes it's better to go home and call it a day than to try to get something to work.
Re: Factory pattern in D
On Friday, 1 May 2015 at 10:47:22 UTC, Chris wrote: On Friday, 1 May 2015 at 10:46:20 UTC, Chris wrote: On Friday, 1 May 2015 at 10:27:16 UTC, biozic wrote: On Friday, 1 May 2015 at 10:12:36 UTC, Chris wrote: On Friday, 1 May 2015 at 10:04:46 UTC, Namespace wrote: How about this: struct A { int x = 42; } struct B { int x = 7; } T factory(T)() { return T(); } void main() { auto a = factory!(A); } That's what I was looking for, I just couldn't get it right. Thanks. Rikki: I wanted to avoid classes and interfaces. This might be a bit more useful: --- struct A { int x = 42; } struct B { int x = 7; } auto factory(string type = )() { static if (type == A) return A(); else static if (type == B) return B(); else return A(); // default } void main() { auto a = factory!A; auto b = factory!B; auto x = factory; } --- Duh, I tried `static if` yesterday and I still got Error: mismatched function return type inference of B and A. Now it works! Sure, I must have overlooked something. Sometimes it's better to go home and call it a day than to try to get something to work. And thanks, by the way! Thinking about it, T factory(T)() { return T(); } is better suited for a factory (with static type checks). This aside, how would I get something to load dynamically? It's either mismatched function return type or (with type check) variable X cannot be read at compile time: void main(string[] args) { auto type = args[1]; auto myType = factory!type(); } So it's back to classes/interfaces again? H.
Re: Factory pattern in D
On Friday, 1 May 2015 at 11:11:28 UTC, biozic wrote: On Friday, 1 May 2015 at 11:01:29 UTC, Chris wrote: Thinking about it, T factory(T)() { return T(); } is better suited for a factory (with static type checks). But then I don't know what factory!X() provides that X() alone doesn't. Just cleaner code with type checks T factory(T)() { static if (is (T == A) || (is (T == B))) return T(); else assert(0, Type ~T.stringof~ is not supported); } and then you could have auto getType(string type = )() { static if (type == A) return factory!A(); else static if (type == B) return factroy!B(); else return factory!A(); // default } in order to separate the logic, i.e. the factory produces the type and performs all the type checks, whereas `getType` is the interface for the user. This aside, how would I get something to load dynamically? It's either mismatched function return type or (with type check) variable X cannot be read at compile time: void main(string[] args) { auto type = args[1]; auto myType = factory!type(); } So it's back to classes/interfaces again? H. Indeed. Runtime polymorphism is based on classes and interfaces. The struct and template solutions can only make compile-time factories. Yep. Only that compile-time factories kinda defeat the purpose.
Re: vibed: how to use pure HTML instead of template engine?
On Wednesday, 6 May 2015 at 13:32:48 UTC, Suliman wrote: By default vibed use Diet. Maybe it's cool, but for me it's easier to write in pure HTML. What is the best way to do it? You want to serve html files instead of templates, right? It should be something like router.get(*, serveStaticFiles(./public/)); Put your html stuff into the folder public.
Re: vibed: how to use pure HTML instead of template engine?
On Wednesday, 6 May 2015 at 13:50:04 UTC, Chris wrote: On Wednesday, 6 May 2015 at 13:32:48 UTC, Suliman wrote: By default vibed use Diet. Maybe it's cool, but for me it's easier to write in pure HTML. What is the best way to do it? You want to serve html files instead of templates, right? It should be something like router.get(*, serveStaticFiles(./public/)); Put your html stuff into the folder public. Cf. http://vibed.org/docs#http-routing
Re: vibed: how to use pure HTML instead of template engine?
On Wednesday, 6 May 2015 at 14:28:26 UTC, Adam D. Ruppe wrote: On Wednesday, 6 May 2015 at 14:23:27 UTC, Chris wrote: Especially this: http://vibed.org/templates/diet#embedded-code I think that's a misfeature... if I used vibe.d, I'd want to avoid the diet too. I have never used the templates. Usually I generate the HTML myself, if its dynamic stuff, and send it back to the user as via res.writeBody: auto html = someStringActions(); res.writeBody(cast(ubyte[])html); For static pages I route to serverStaticFiles.
Re: vibed: how to use pure HTML instead of template engine?
On Wednesday, 6 May 2015 at 14:21:24 UTC, Chris wrote: On Wednesday, 6 May 2015 at 14:07:09 UTC, Suliman wrote: I mean that I know that template can be changes dynamically, but I thought that 99% of dynamic is javascript code... Templates are like PHP, JSP, LSP etc. They can do stuff on the server side via embedded D code, load files for example. With JS you cannot do this. I think you should also be able to access variables set in query strings (?email=m...@mail.com ...) and process them. But I'm not 100% sure about the latter. The user variables you get like this: void customHandler(HTTPServerRequest req, HTTPServerResponse res) { auto fields = req.query; // = [email:m...@mail.com]; } The drawback of templates is that you have to recompile them after each change atm, which is not very dynamic. Just have a look at http://vibed.org/templates/diet. Especially this: http://vibed.org/templates/diet#embedded-code
Re: vibed: how to use pure HTML instead of template engine?
On Wednesday, 6 May 2015 at 14:07:09 UTC, Suliman wrote: I mean that I know that template can be changes dynamically, but I thought that 99% of dynamic is javascript code... Templates are like PHP, JSP, LSP etc. They can do stuff on the server side via embedded D code, load files for example. With JS you cannot do this. I think you should also be able to access variables set in query strings (?email=m...@mail.com ...) and process them. But I'm not 100% sure about the latter. The user variables you get like this: void customHandler(HTTPServerRequest req, HTTPServerResponse res) { auto fields = req.query; // = [email:m...@mail.com]; } The drawback of templates is that you have to recompile them after each change atm, which is not very dynamic. Just have a look at http://vibed.org/templates/diet.
Re: vibed: how to use pure HTML instead of template engine?
On Thursday, 7 May 2015 at 09:27:39 UTC, Chris wrote: On Thursday, 7 May 2015 at 08:25:30 UTC, Suliman wrote: You're not setting a port. add: settings.port = 8080; before listenHTTP(); then it'll work. It's do not help :( This should work, put it in your `app.d` file: import vibe.d; shared static this() { auto settings = new HTTPServerSettings; settings.port = 8080; settings.bindAddresses = [::1, 127.0.0.1]; auto router = new URLRouter; router.get(*, serveStaticFiles(./public/)); listenHTTP(settings, router); logInfo(Please open http://127.0.0.1:8080/ in your browser.); } Mind you, don't forget the `.` before the forward slash in serveStaticFiles(./public/). Any file in the folder `public` should now be navigate-able to via: http://127.0.0.1:8080/index.html or http://localhost/index.html For starters, don't make your own custom main method. Just create a vibe.d project and paste the above code into app.d. Later you can have a more sophisticated handling of requests. Do this 1. dub init suliman vibe.d 2. You might see an info message like this Deprecated use of init type. Use --type=[vibe.d | deimos | minimal] in future. Successfully created an empty project in '/home/christoph/D/vibed/Tests/suliman'. 3. Now you have a small project. Go to the folder `suliman/source` and open the file app.d 4. Replace the whole code in there with import vibe.d; shared static this() { auto settings = new HTTPServerSettings; settings.port = 8080; settings.bindAddresses = [::1, 127.0.0.1]; auto router = new URLRouter; router.get(*, serveStaticFiles(./public/)); listenHTTP(settings, router); logInfo(Please open http://127.0.0.1:8080/ in your browser.); } 5. Save an build the project 6. Create a file called `index.html` in the (sub)folder `public` that is in the folder `suliman`, i.e. `suliman/public/` 7. Paste this code into it: html p Hello, Suliman! /p /html 8. Save it and navigate in your browser to http://127.0.0.1:8080/index.html You should see Hello, Suliman! in your browser window now. Hope this helped you. C.
Re: vibed: how to use pure HTML instead of template engine?
On Thursday, 7 May 2015 at 08:25:30 UTC, Suliman wrote: You're not setting a port. add: settings.port = 8080; before listenHTTP(); then it'll work. It's do not help :( This should work, put it in your `app.d` file: import vibe.d; shared static this() { auto settings = new HTTPServerSettings; settings.port = 8080; settings.bindAddresses = [::1, 127.0.0.1]; auto router = new URLRouter; router.get(*, serveStaticFiles(./public/)); listenHTTP(settings, router); logInfo(Please open http://127.0.0.1:8080/ in your browser.); } Mind you, don't forget the `.` before the forward slash in serveStaticFiles(./public/). Any file in the folder `public` should now be navigate-able to via: http://127.0.0.1:8080/index.html or http://localhost/index.html For starters, don't make your own custom main method. Just create a vibe.d project and paste the above code into app.d. Later you can have a more sophisticated handling of requests.
Re: vibed: how to use pure HTML instead of template engine?
Later you can have more sophisticated methods, e.g. if you want to handle query strings you could do something like this: import vibe.d; shared static this() { auto settings = new HTTPServerSettings; settings.port = 8080; settings.bindAddresses = [::1, 127.0.0.1]; auto router = new URLRouter; router.get(*, serveStaticFiles(./public/)); /* This is the new bit */ router.any(*, handleRequest); listenHTTP(settings, router); logInfo(Please open http://127.0.0.1:8080/ in your browser.); } void handleRequest(HTTPServerRequest req, HTTPServerResponse res) { if (!req.query.length) return; auto request = req.query; // Do something fancy with the request // ... // Create a result string result; // ... // Return the result to the client res.writeBody(cast(ubyte[])result); // The client will receive this. }
Re: vibed: how to use pure HTML instead of template engine?
On Friday, 8 May 2015 at 10:20:35 UTC, Rikki Cattermole wrote: On 8/05/2015 10:17 p.m., Chris wrote: On Thursday, 7 May 2015 at 19:51:20 UTC, yawniek wrote: On Thursday, 7 May 2015 at 18:59:13 UTC, Suliman wrote: 1. Do I need write ./public/ ? In examples often simply public/ will work too. even public it goes trough Path struct, see: https://github.com/rejectedsoftware/vibe.d/blob/11578aa956a9b3b0e305d655f9668a867fdd89bd/source/vibe/inet/path.d 2. What incoming parameters (HTTPServerRequest req, HTTPServerResponse res) mean? Why I should to specify them? HTTPServerRequest contains all data that the client sends, e.g. headers, cookies, source ip etc. see: https://github.com/rejectedsoftware/vibe.d/blob/11578aa956a9b3b0e305d655f9668a867fdd89bd/source/vibe/http/server.d#L584 HTTPServerResponse is the response you send back. https://github.com/rejectedsoftware/vibe.d/blob/11578aa956a9b3b0e305d655f9668a867fdd89bd/source/vibe/http/server.d#L788 you woud want to set at least its body, as you do below 3. Why code with: res.writeBody(Hello, World!, text/plain); and router.get(*, serveStaticFiles(./public/)); also work, but my variant (see code above) do not load say that page not found? what exactely does not work? please link code (ideally https://gist.github.com/ ) 4. How to specify page that I need to load, why in examples there is only link to folder like public? But what if I want to load public/foo.html? public servers public files, its more or less a static webserver which checks if a file exists and then serves that. if you want to dynamically modify content you send you need to use the templating or do your own string magic. generally it seems you do not fully understand the concept of how these web frameworks work. i think you should either read vibe.d's source code or more read how other such frameworks work e.g. http://www.sinatrarb.com/documentation.html has pretty good documentations and books that explain the inner workings (but mind, ruby is a dynamically typed language). then i also can recommend that you check out vibe.d's github repositories and read trough all the example projects that come with it. e.g. https://github.com/rejectedsoftware/vibe.d/tree/11578aa956a9b3b0e305d655f9668a867fdd89bd/examples/app_skeleton I'd say it is a bit hard to get into vibe.d just like that. I had to work out a lot of things myself simply because it's web server technology cast in D. Most of the difficulties are not D but understanding the whole web server thing. But I have to say vibe.d is very very good once you know your way around. Maybe we should set up some tutorials with common tasks so developers can concentrate on D instead of the web. I was thinking maybe a vibe.d manual using leanpub's systems. Assuming it was hosted on Github and set to be free. It would work out rather well and because you can embed other files into the book, examples can be made kinda like they are now in vibe.d's repo runnable. But also contained in the manual inline. All syntax highlighted and all. Yeah, I think we need a dedicated page with tutorials (covering most use cases) for vibe.d. It's great, I love it, but nobody knows about it and it's hard to use. You have to go through all the examples/source code to do simple things - and things keep changing. Maybe even powerful vibe.d boilerplate projects you can set up with dub, e.g. a project that already contains `serveStaticFiles` and stuff like that. dub init myproject vibe.d --server=[minimal | query | noui] Stuff like that. Maybe with DlangIDE support. And stubs with explanations, e.g. How do I handle queries? (req.query) etc. A one stop shop for vibe.d. I'd hate to see it ignored only because it's not accessible. Maybe it's time to bundle things up anyway. dub/dvm/dlangIDE/dlangUI/vibe.d. It's right there in front of us and we all speak the same language :-)
Chaining input
I have the following code that converts input like blah, blub, gobble, dygook to string[] auto f = File(file.txt, r); auto words = f.byLine .map!( a = a.to!(string) .splitter(, ) .filter!(a = a.length) ) .copy(appender!(string[])).data; I'm sure there is room for improvement. D is pretty cool in this way. Once you get used to this kind of code, you're spoiled forever.
Re: vibed: how to use pure HTML instead of template engine?
On Thursday, 7 May 2015 at 19:51:20 UTC, yawniek wrote: On Thursday, 7 May 2015 at 18:59:13 UTC, Suliman wrote: 1. Do I need write ./public/ ? In examples often simply public/ will work too. even public it goes trough Path struct, see: https://github.com/rejectedsoftware/vibe.d/blob/11578aa956a9b3b0e305d655f9668a867fdd89bd/source/vibe/inet/path.d 2. What incoming parameters (HTTPServerRequest req, HTTPServerResponse res) mean? Why I should to specify them? HTTPServerRequest contains all data that the client sends, e.g. headers, cookies, source ip etc. see: https://github.com/rejectedsoftware/vibe.d/blob/11578aa956a9b3b0e305d655f9668a867fdd89bd/source/vibe/http/server.d#L584 HTTPServerResponse is the response you send back. https://github.com/rejectedsoftware/vibe.d/blob/11578aa956a9b3b0e305d655f9668a867fdd89bd/source/vibe/http/server.d#L788 you woud want to set at least its body, as you do below 3. Why code with: res.writeBody(Hello, World!, text/plain); and router.get(*, serveStaticFiles(./public/)); also work, but my variant (see code above) do not load say that page not found? what exactely does not work? please link code (ideally https://gist.github.com/ ) 4. How to specify page that I need to load, why in examples there is only link to folder like public? But what if I want to load public/foo.html? public servers public files, its more or less a static webserver which checks if a file exists and then serves that. if you want to dynamically modify content you send you need to use the templating or do your own string magic. generally it seems you do not fully understand the concept of how these web frameworks work. i think you should either read vibe.d's source code or more read how other such frameworks work e.g. http://www.sinatrarb.com/documentation.html has pretty good documentations and books that explain the inner workings (but mind, ruby is a dynamically typed language). then i also can recommend that you check out vibe.d's github repositories and read trough all the example projects that come with it. e.g. https://github.com/rejectedsoftware/vibe.d/tree/11578aa956a9b3b0e305d655f9668a867fdd89bd/examples/app_skeleton I'd say it is a bit hard to get into vibe.d just like that. I had to work out a lot of things myself simply because it's web server technology cast in D. Most of the difficulties are not D but understanding the whole web server thing. But I have to say vibe.d is very very good once you know your way around. Maybe we should set up some tutorials with common tasks so developers can concentrate on D instead of the web.
Re: vibed: how to use pure HTML instead of template engine?
On Wednesday, 6 May 2015 at 18:52:41 UTC, Suliman wrote: auto html = someStringActions(); res.writeBody(cast(ubyte[])html); Thanks, but how to attach to html css file? Now page is loading, but do not handle css that also placed in this folder. CSS should be exported automatically when you use serveStaticFiles. I don't understand what exactly you mean. If you send a string html ... /htm the browser automatically detects the CSS file you link to and will get it from vibe.d If the CSS is embedded in the HTML (via style/style the browser will recognize this.
Re: Moving from Python to D
Moving from Python to D always a good idea ;-)
Re: Moving from Python to D
On Friday, 8 May 2015 at 14:13:43 UTC, Chris wrote: Moving from Python to D always a good idea ;-) You might be interested in this: http://wiki.dlang.org/Programming_in_D_for_Python_Programmers http://d.readthedocs.org/en/latest/examples.html#plotting-with-matplotlib-python
Re: Why .dup not work with multidimensional arrays?
On Friday, 8 May 2015 at 06:30:46 UTC, Ali Çehreli wrote: On 05/07/2015 07:39 PM, Dennis Ritchie wrote: On Friday, 8 May 2015 at 02:23:23 UTC, E.S. Quinn wrote: It's because arrays are references types, and .dup is a strictly shallow copy, so you're getting two outer arrays that reference the same set of inner arrays. You'll have to duplicated each of the inner arrays yourself if you need to make a deep copy. Thank you. It really works :) - import std.stdio; void main() { auto c = [[[1, 2, 3], [4, 5, 6, 7, 8]], [[9, 10], [11, 12, 13]]]; auto d = [[c[0][0].dup, c[0][1].dup], [c[1][0].dup, c[1][1].dup]]; d[0][1][1 .. $ - 1] *= 3; writeln(c = , c); // [[[1, 2, 3], [4, 5, 6, 7, 8]], // [[9, 10], [11, 12, 13]]] // OK writeln(d = , d); // [[[1, 2, 3], [4, 15, 18, 21, 8]], // [[9, 10], [11, 12, 13]]] // OK } - http://ideone.com/kJVUhd Maybe there is a way to create .globalDup for multidimensional arrays? In D, everything is possible and very easy. :p I called it deepDup: import std.stdio; import std.traits; import std.range; import std.algorithm; auto deepDup(A)(A arr) if (isArray!A) { static if (isArray!(ElementType!A)) { return arr.map!(a = a.deepDup).array; } else { return arr.dup; } } void main() { auto c = [[[1, 2, 3], [4, 5, 6, 7, 8]], [[9, 10], [11, 12, 13]]]; auto d = c.deepDup; d[0][1][1 .. $ - 1] *= 3; writeln(c = , c); // [[[1, 2, 3], [4, 5, 6, 7, 8]], // [[9, 10], [11, 12, 13]]] // OK writeln(d = , d); // [[[1, 2, 3], [4, 15, 18, 21, 8]], // [[9, 10], [11, 12, 13]]] // OK } Ali Nice one. I have the same problem in one of my modules. I might use the above code henceforth.
Re: Chaining input
On Friday, 8 May 2015 at 11:14:43 UTC, Robert burner Schadek wrote: On Friday, 8 May 2015 at 11:00:01 UTC, Chris wrote: I'm sure there is room for improvement. It looks like your reading some kind of comma seperated values (csv). have a look at std.csv of phobos ``` foreach(record; file.byLine.joiner(\n).csvReader!(Tuple!(string, string, int))) { writefln(%s works as a %s and earns $%d per year, record[0], record[1], record[2]); } ``` Yeah, I actually wanted to have a closer look at std.csv. But in this case the input format may change (comments, keywords etc.), so I might need a customized parser anyway.
Re: Weird OSX issue
On Monday, 27 April 2015 at 13:54:42 UTC, Steven Schveighoffer wrote: On 4/25/15 3:07 AM, Dan Olson wrote: Jacob Carlborg d...@me.com writes: On 2015-04-24 20:37, Steven Schveighoffer wrote: So am I going crazy? Or is dmd doing things differently depending on where its environment is? Any compiler gurus out there understand why the symbol is different? I don't want to file a bug with this, because it seems dependent on installation location, would possibly not be reproducible. I can't reproduce this with DMD from DVM (compiler is installed in the user home directory). I have lots of version laying around and they all worked fine on the posted code. But maybe a clue here... $ ~/dmd2.066.0/osx/bin/dmd mod1.d $ nm mod1.o | grep start U _D4core6thread6Thread5startMFZv $ dmd mod1.d $ nm mod1.o | grep start U _D4core6thread6Thread5startMFNbZC4core6thread6Thread --- a/src/core/thread.d +++ b/src/core/thread.d @@ -587,7 +587,7 @@ class Thread * Throws: * ThreadException if the thread fails to start. */ -final Thread start() +final Thread start() nothrow in { assert( !next !prev ); I wonder if dmd -v will show where its picking up stuff. Thank you. It is something I missed. Lo and behold: dmd -v mod1.d: ... import core.thread (/usr/share/dmd/src/druntime/import/core/thread.di) ... ~/Downloads/dmd2/osx/bin/dmd -v mod1.d: ... importcore.thread (/Users/steves/Downloads/dmd2/osx/bin/../../src/druntime/import/core/thread.d) ... Hm... thread.di vs thread.d (and I didn't notice before because all the other imports were .d, I just glanced over that detail). And so, let's see here: ls -l /usr/share/dmd/src/druntime/import/core/thread.* -rw-rw-r-- 1 steves staff 157781 Mar 24 10:44 thread.d -rw-rw-r--+ 1 steves staff 31382 Feb 24 2014 thread.di Hey, looky there :) So, looking at time machine (love that feature), I found that when I installed 2.066, back in October, we had switched to using thread.d instead of thread.di. But the installer did not erase the old thread.di. BTW, found this: https://github.com/D-Programming-Language/druntime/pull/865 So I think the issue here is that the pkg installer on OSX does not clean up the target directory if it already exists (or at least purposely remove thread.di). Will look into fixing that. At least now, it works properly, thanks (did a rm -rf /usr/share/dmd and reinstall). -Steve Now that you mention it, I had similar issues on my Linux distro at work (Ubuntu, alas!). The installer for 2.067.0 (or 2.066.0?) didn't erase old files and I got compiler errors for no apparent reason. What I did was to use dvm to install and manage my dmd versions. This is much cleaner. I just didn't have the patience to go through all the /dmd/ directories and clean them up. dvm installs its own copy, it's not a system wide installation, so you never have any issues with old files. I wouldn't want to miss it now. dvm install 2.067.1 later in your shell you just type dvm use 2.067.1 https://github.com/jacob-carlborg/dvm
Re: -vgc Info ok?
On Monday, 18 May 2015 at 14:34:38 UTC, ketmar wrote: On Mon, 18 May 2015 14:30:42 +, Chris wrote: The following string[string] myarray = [key:value]; string entry; entry = myarray[key]; // = vgc: indexing an associative array may cause GC allocation Why is _accessing_ an assoc treated as indexing it? it can throw out of range error, which is `new`ed. But shouldn't it read accessing an associative array may cause GC allocation? And maybe a hint to the exception that may be thrown. It's not the same as myarray[key1] = some value; myarray[key2] = some other value; A bit confusing.
-vgc Info ok?
The following string[string] myarray = [key:value]; string entry; entry = myarray[key]; // = vgc: indexing an associative array may cause GC allocation Why is _accessing_ an assoc treated as indexing it?
Re: -vgc Info ok?
On Monday, 18 May 2015 at 18:40:15 UTC, ketmar wrote: On Mon, 18 May 2015 14:41:19 +, Chris wrote: On Monday, 18 May 2015 at 14:34:38 UTC, ketmar wrote: On Mon, 18 May 2015 14:30:42 +, Chris wrote: The following string[string] myarray = [key:value]; string entry; entry = myarray[key]; // = vgc: indexing an associative array may cause GC allocation Why is _accessing_ an assoc treated as indexing it? it can throw out of range error, which is `new`ed. But shouldn't it read accessing an associative array may cause GC allocation? not any access may cause allocation. `auto e = key in myarray;` will not allocate, for example. yet it's still accessing the array. it's *indexing* which may end in allocation. Yes, that's exactly what was driving at. Accessing is not indexing, and yet I get a warning for _indexing_, while the real reason is that a wrong access can cause an exception (which allocates). I.e. it should be accessing an associative array may cause GC allocation on error Maybe the message with indexing for accessing is merely reusing the message for indexing, or all assoc array operations are lumped together as indexing. I dunno. It seems wrong to me, because it's inaccurate. And maybe a hint to the exception that may be thrown. i believe that such explanation is a work for lint-like tool. burden compiler with special cases can lead too far. ;-) It's not the same as myarray[key1] = some value; myarray[key2] = some other value; A bit confusing. yes, it requires some knowledge of language and libraries. -vgc is not a linter, though, it was made with some assumptions about user's knowledge. yet you can open ER in bugzilla, maybe DMD developers will implement it. i'm not a developer, and i can be wrong in reasons behind -vgc.
Re: -vgc Info ok?
On Tuesday, 19 May 2015 at 09:10:50 UTC, Namespace wrote: On Monday, 18 May 2015 at 14:30:43 UTC, Chris wrote: The following string[string] myarray = [key:value]; string entry; entry = myarray[key]; // = vgc: indexing an associative array may cause GC allocation Why is _accessing_ an assoc treated as indexing it? No error if you use myarray.get(key, null); or string* entry = key in myarray; What are the advantages / disadvantages of the two methods?
Re: -vgc Info ok?
On Tuesday, 19 May 2015 at 11:08:52 UTC, thedeemon wrote: On Monday, 18 May 2015 at 14:30:43 UTC, Chris wrote: Why is _accessing_ an assoc treated as indexing it? Are you sure you understand indexing as we do? It's not like indexing of databases, it's just accessing by index i.e. using myarray[some_index]. I understood indexing as assigning an index to something myarray[Index1] = First Entry; As in https://en.wiktionary.org/wiki/indexing https://en.wiktionary.org/wiki/index#Verb
Re: GC: Memory keeps growing
On Wednesday, 15 April 2015 at 11:48:26 UTC, Rikki Cattermole wrote: On 15/04/2015 11:44 p.m., Chris wrote: My garbage collected app starts with ~10 MB in memory, however with every execution of code it grows by at least 0.2 MB (or more depending on the input). Although I can see memory being freed (say it goes up to 32 MB and drops to 14 MB), it keeps on growing slowly but surely. I use structs for the most part [1] and reuse arrays at critical points, clearing them with destroy() after use. Maybe this is the problem? I dunno. I'd be grateful for any hints. [1] The few classes I use are either singletons or instantiated only once and cached when the programs starts. Sounds like you are doing a LOT of allocations. Try with -vgc during compilation to find out where you are allocating. Just did that, for the most part it's: - indexing an associative array may cause GC allocation - operator ~= may cause GC allocation - operator ~ may cause GC allocation Whereas 'new' causes GC allocation is rare and applies only to classes that are instantiated only once. I use appender a lot, too. There might be some low-hanging fruit there. However, before I change anything, maybe you guys have some suggestions.
[dub]
I get the following message from dub when using --build=release: Linking... .dub/build/myprogram-release-linux.posix-x86_64-dmd_2067-C1A5273464ACE9961E3F3BA6AC04084B/abairtts.o:(.data._D65TypeInfo_xC3std5range10interfaces18__T10InputRangeTiZ10InputRange6__initZ+0x10): undefined reference to `_D64TypeInfo_C3std5range10interfaces18__T10InputRangeTiZ10InputRange6__initZ' collect2: error: ld returned 1 exit status --- errorlevel 1 DUB version 0.9.23, built on Apr 3 2015 dmd 2.067.0 Also, if I set the flags manually (dlfags[1]), they are ignored and dub build in debug mode. [1] now -boundscheck=off, instead of -noboundscheck
[dub] Release build fails with 2.067.0
Sorry, I forgot the title the first time around! I get the following message from dub when using --build=release: Linking... .dub/build/myprogram-release-linux.posix-x86_64-dmd_2067-C1A5273464ACE9961E3F3BA6AC04084B/abairtts.o:(.data._D65TypeInfo_xC3std5range10interfaces18__T10InputRangeTiZ10InputRange6__initZ+0x10): undefined reference to `_D64TypeInfo_C3std5range10interfaces18__T10InputRangeTiZ10InputRange6__initZ' collect2: error: ld returned 1 exit status --- errorlevel 1 DUB version 0.9.23, built on Apr 3 2015 dmd 2.067.0 Also, if I set the flags manually (dlfags[1]), they are ignored and dub build in debug mode. [1] now -boundscheck=off, instead of -noboundscheck
Re: GC: Memory keeps growing
On Thursday, 16 April 2015 at 18:51:25 UTC, Kagamin wrote: On Wednesday, 15 April 2015 at 12:03:49 UTC, Chris wrote: There might be some low-hanging fruit there. However, before I change anything, maybe you guys have some suggestions. See if switching to 64-bit mode changes anything. 64bit is the default. I've monitored the program for a while and it seems that it is not growing indefinitely. It might go up from 10 MB to 20 MB, but then it is happy with 20 MB for ages. It might even go down to 14 MB again, only to increase to 16 or 18 MB later. It's a bit weird. I analyzed it step by step but I couldn't find a culprit. Sometimes it stays constant for ages like 15.2 MB no matter what I put through it. Then I put one word through it and it goes up to 15.4 MB. It's a bit odd. However, I don't know the exact behavior of the GC, but it's a good time to start looking into it.
Templates: Array slices not recognized
The following: import std.stdio : writefln; import std.range.primitives : isInputRange, hasLength; void main() { size_t[] a = [1, 2, 3, 4, 5, 6, 7, 8, 9]; doSomething(a); // works doSomething(a[0..5]); // --- Error: template slices.doSomething cannot deduce function from argument types !()(ulong[]), candidates are: // slices.d(11): slices.doSomething(R)(ref R r) if (isInputRange!R hasLength!R) doSomething!(size_t[])(a[0..5]); // --- Error: doSomething (ref ulong[] r) is not callable using argument types (ulong[]) } void doSomething(R)(ref R r) if (isInputRange!R hasLength!R) // etc.. { foreach (ref n; r) { writefln(%d * 2 = %d, n, n * 2); } } //EOF a[0..5] is not recognized as size_t[]. If I give the compiler a hint with !(size_t[]), it complains again, i.e. I can not pass the slice as a reference. A workaround is size_t[] b = a[0..5]; doSomething(b); However, this comes with a serious performance penalty in for loops (even if I predefine b and reuse it in the loop). to!(size_t[])(a[0..5]) is even worse. Any thoughts or tips?
Re: Templates: Array slices not recognized
On Saturday, 18 April 2015 at 16:26:57 UTC, Max Klyga wrote: On 2015-04-18 13:46:19 +, Chris said: The following: import std.stdio : writefln; import std.range.primitives : isInputRange, hasLength; void main() { size_t[] a = [1, 2, 3, 4, 5, 6, 7, 8, 9]; doSomething(a); // works doSomething(a[0..5]); // --- Error: template slices.doSomething cannot deduce function from argument types !()(ulong[]), candidates are: // slices.d(11): slices.doSomething(R)(ref R r) if (isInputRange!R hasLength!R) doSomething!(size_t[])(a[0..5]); // --- Error: doSomething (ref ulong[] r) is not callable using argument types (ulong[]) } void doSomething(R)(ref R r) if (isInputRange!R hasLength!R) // etc.. { foreach (ref n; r) { writefln(%d * 2 = %d, n, n * 2); } } //EOF a[0..5] is not recognized as size_t[]. If I give the compiler a hint with !(size_t[]), it complains again, i.e. I can not pass the slice as a reference. A workaround is size_t[] b = a[0..5]; doSomething(b); However, this comes with a serious performance penalty in for loops (even if I predefine b and reuse it in the loop). to!(size_t[])(a[0..5]) is even worse. Any thoughts or tips? a[0..5] is an R-value, and cannot be passed by reference. As you noticed, once you use a variable - everything works because only L-values can be passed by reference. Also why are you passing slices by reference? Slices do not copy the memory they point to when passed by value. Doh! You're right! My bad. However, this makes the function less generic, but it doesn't matter here.
Re: [dub] Release build fails with 2.067.0
On Wednesday, 15 April 2015 at 10:26:55 UTC, John Colvin wrote: On Wednesday, 15 April 2015 at 10:11:17 UTC, Chris wrote: On Tuesday, 14 April 2015 at 15:58:18 UTC, Chris wrote: Sorry, I forgot the title the first time around! I get the following message from dub when using --build=release: Linking... .dub/build/myprogram-release-linux.posix-x86_64-dmd_2067-C1A5273464ACE9961E3F3BA6AC04084B/abairtts.o:(.data._D65TypeInfo_xC3std5range10interfaces18__T10InputRangeTiZ10InputRange6__initZ+0x10): undefined reference to `_D64TypeInfo_C3std5range10interfaces18__T10InputRangeTiZ10InputRange6__initZ' collect2: error: ld returned 1 exit status --- errorlevel 1 DUB version 0.9.23, built on Apr 3 2015 dmd 2.067.0 Also, if I set the flags manually (dlfags[1]), they are ignored and dub build in debug mode. [1] now -boundscheck=off, instead of -noboundscheck Update: I tried to compile the code with a script and I still have the same problem: dmd -release -boundscheck=off -O -inline (or any combination of these) When I use dmd file1.d, file2.d ... it also fails. Only when I use dmd -debug file1.d file2.d ... does it work. Isn't that weird. I've made sure that the latest version of dmd is now installed system wide (Ubuntu) and not just locally with dvm (which is a cool tool). I have no clue what causes this problem. How about with -allinst? This did the trick, thanks a million! But why would I have to do this now (it wasn't necessary with 2.066)? Also, if you run dub --build=profile you'll get src/phobos/std/getopt.d(438): Warning: statement is not reachable src/phobos/std/getopt.d(577): Warning: statement is not reachable The plot thickens ... :-)
Re: [dub] Release build fails with 2.067.0
On Tuesday, 14 April 2015 at 15:58:18 UTC, Chris wrote: Sorry, I forgot the title the first time around! I get the following message from dub when using --build=release: Linking... .dub/build/myprogram-release-linux.posix-x86_64-dmd_2067-C1A5273464ACE9961E3F3BA6AC04084B/abairtts.o:(.data._D65TypeInfo_xC3std5range10interfaces18__T10InputRangeTiZ10InputRange6__initZ+0x10): undefined reference to `_D64TypeInfo_C3std5range10interfaces18__T10InputRangeTiZ10InputRange6__initZ' collect2: error: ld returned 1 exit status --- errorlevel 1 DUB version 0.9.23, built on Apr 3 2015 dmd 2.067.0 Also, if I set the flags manually (dlfags[1]), they are ignored and dub build in debug mode. [1] now -boundscheck=off, instead of -noboundscheck Update: I tried to compile the code with a script and I still have the same problem: dmd -release -boundscheck=off -O -inline (or any combination of these) When I use dmd file1.d, file2.d ... it also fails. Only when I use dmd -debug file1.d file2.d ... does it work. Isn't that weird. I've made sure that the latest version of dmd is now installed system wide (Ubuntu) and not just locally with dvm (which is a cool tool). I have no clue what causes this problem.
GC: Memory keeps growing
My garbage collected app starts with ~10 MB in memory, however with every execution of code it grows by at least 0.2 MB (or more depending on the input). Although I can see memory being freed (say it goes up to 32 MB and drops to 14 MB), it keeps on growing slowly but surely. I use structs for the most part [1] and reuse arrays at critical points, clearing them with destroy() after use. Maybe this is the problem? I dunno. I'd be grateful for any hints. [1] The few classes I use are either singletons or instantiated only once and cached when the programs starts.
Re: -vgc Info ok?
On Tuesday, 19 May 2015 at 12:41:29 UTC, ketmar wrote: On Tue, 19 May 2015 11:36:32 +, Chris wrote: On Tuesday, 19 May 2015 at 11:08:52 UTC, thedeemon wrote: On Monday, 18 May 2015 at 14:30:43 UTC, Chris wrote: Why is _accessing_ an assoc treated as indexing it? Are you sure you understand indexing as we do? It's not like indexing of databases, it's just accessing by index i.e. using myarray[some_index]. I understood indexing as assigning an index to something myarray[Index1] = First Entry; As in https://en.wiktionary.org/wiki/indexing https://en.wiktionary.org/wiki/index#Verb and that's wrong. ;-) most programmers in this case read indexing as accesing by index. it's a common term for such access. Is that so. I don't remember having come across this meaning. It is usually called access or indexing access (cf. http://dlang.org/hash-map.html). I still think that saying just indexing is not correct in -vgc, since it can be both assignment and access. tbh, i didn't even understand you fully until i read the post i'm answering to.
AMD Windows 7
Has anyone run into problems with D on AMD processors? I'm talking about Windows 7 on a HP625 laptop in particular.
Re: AMD Windows 7
On Friday, 12 June 2015 at 14:55:15 UTC, Benjamin Thaut wrote: On Friday, 12 June 2015 at 14:39:55 UTC, Chris wrote: I wish it were an error in the Python code so I could fix it, but it works on all other machines (at least those with Intel). It's only on the HP625 with AMD that this error occurs. Another DLL (which isn't mine) also failed to load, although with a different error message. It might be just this particular model, or AMD, I dunno. I couldn't find anything about it on the internet. Atm I'm using dmd 2.067.1, maybe compiling with GDC or LDC will fix it. That sounds more like its the software installed on the machine and not the processor. Are you sure that all microsoft runtime libraries are installed? If you did use the vs 2012 linker to create the D-dll you need to install this redistributable package: http://www.microsoft.com/en-US/download/details.aspx?id=30679 Did you run Depends on the dll? Usually depends will tell you why the dll does not load: http://www.dependencywalker.com/ Kind Regards Benjamin Thaut Thanks, I will look into it. The problem is that I don't have the machine anymore (had to return it to user). The weird thing is that the DLL loads correctly (else there would be an error message in the log file), but is a NoneType (i.e. null) when methods are called (e.g. mydll.getSomething()). If it were not loaded, it wouldn't even come to the point at which it calls functions in the DLL.
Re: AMD Windows 7
On Friday, 12 June 2015 at 14:20:58 UTC, Alex Parrill wrote: On Friday, 12 June 2015 at 13:16:32 UTC, Chris wrote: On Friday, 12 June 2015 at 12:41:23 UTC, weaselcat wrote: On Friday, 12 June 2015 at 10:54:46 UTC, Chris wrote: Has anyone run into problems with D on AMD processors? I'm talking about Windows 7 on a HP625 laptop in particular. Can you be any more specific? What kind of problems? A DLL in D is loaded into a Python program, but not recognized later. It says: NoneType doesn't have method called... It's only on this machine (or processor?). I recompiled it on the machine, but I still get the same error. Unfortunately, we only have Intel processors, so I cannot test it on other AMD processors. That's an error in your Python code. I wish it were an error in the Python code so I could fix it, but it works on all other machines (at least those with Intel). It's only on the HP625 with AMD that this error occurs. Another DLL (which isn't mine) also failed to load, although with a different error message. It might be just this particular model, or AMD, I dunno. I couldn't find anything about it on the internet. Atm I'm using dmd 2.067.1, maybe compiling with GDC or LDC will fix it.
Re: AMD Windows 7
On Friday, 12 June 2015 at 12:41:23 UTC, weaselcat wrote: On Friday, 12 June 2015 at 10:54:46 UTC, Chris wrote: Has anyone run into problems with D on AMD processors? I'm talking about Windows 7 on a HP625 laptop in particular. Can you be any more specific? What kind of problems? A DLL in D is loaded into a Python program, but not recognized later. It says: NoneType doesn't have method called... It's only on this machine (or processor?). I recompiled it on the machine, but I still get the same error. Unfortunately, we only have Intel processors, so I cannot test it on other AMD processors.
Concurrency in DLL
Would anyone know off the top of the head why a std.concurrency.send() message can fail in a DLL? The DLL is loaded into Python and works (including the threading) when in a test program or mine and loaded via cytpes.CDLL() etc. However, embedded in a third party package, where it is loaded in the same way, the thread is never called (the DLL as such is loaded and available and works fine). The thread is generated like this in the DLL: import std.concurrency; extern(C) { export void methodCalledFromPython(const char* message) { // convert message to string etc. // now spawn thread in order to be able to return to // main thread asap auto dothis = spawn(doSomething, thisTid); send(dothis, message.idup); } } // Method in same module private void doSomething(Tid tid) { receive( (string input) { // Do something with input } ); } Is it to do with thisTid that conflicts with the main program somehow? However, in my test program it works fine. Anything I'm forgetting here?
Regex-Fu
I'm a bit at a loss here. I cannot get the longest possible match. I tried several versions with eager operators and stuff, but D's regex engine(s) always seem to return the shortest match. Is there something embarrassingly simple I'm missing? void main() { import std.regex : regex, matchFirst; import std.stdio : writeln; auto word = blablahula; auto m = matchFirst(word, regex(^([a-z]+)(hula|ula)$)); writeln(m); // prints [blablahula, blablah, ula] } I want it to return hula not ula.
Re: Regex-Fu
On Monday, 25 May 2015 at 11:20:46 UTC, novice2 wrote: I cannot get the longest possible it match longest for first group ([a-z]+) try ^([a-z]+?)(hula|ula)$ Namespace, novice2: Ah, I see. The problem was with the first group that was too greedy, not with the second. I was focusing on the latter. Thanks, this works now!
Re: flush MessageBox
On Thursday, 20 August 2015 at 15:57:47 UTC, John Colvin wrote: On Thursday, 20 August 2015 at 15:25:57 UTC, Chris wrote: Is there a way to flush a thread's message box other than aborting the thread? MailBox is private: https://github.com/D-Programming-Language/phobos/blob/master/std/concurrency.d#L1778 flush from inside the thread? You could call receiveTimeout with a 0 timer in a loop until it returns false. Yes, from inside the thread. I have a worker thread (with receiveTimeout) that is started when the program starts and sits there waiting for input. I naively thought this was a great idea, until I noticed that when input comes fast the mailbox grows and the bloody thread won't stop until all the items in the mailbox are processed. I was looking for something like `if (abort) { mailbox.flush(); }`
Re: flush MessageBox
On Friday, 21 August 2015 at 12:59:09 UTC, John Colvin wrote: On Friday, 21 August 2015 at 10:43:22 UTC, Chris wrote: On Thursday, 20 August 2015 at 15:57:47 UTC, John Colvin wrote: On Thursday, 20 August 2015 at 15:25:57 UTC, Chris wrote: Is there a way to flush a thread's message box other than aborting the thread? MailBox is private: https://github.com/D-Programming-Language/phobos/blob/master/std/concurrency.d#L1778 flush from inside the thread? You could call receiveTimeout with a 0 timer in a loop until it returns false. Yes, from inside the thread. I have a worker thread (with receiveTimeout) that is started when the program starts and sits there waiting for input. I naively thought this was a great idea, until I noticed that when input comes fast the mailbox grows and the bloody thread won't stop until all the items in the mailbox are processed. I was looking for something like `if (abort) { mailbox.flush(); }` void flushMailbox() { bool r; do { r = receiveTimeout(Duration.zero, (Variant _){}); } while(r); } You could optimise that to more efficiently deal with the actual types you're receiving, instead of making a Variant every time, but it's probably not worth it. The compiler might even optimise it away anyway. Wouldn't it be easier to have a library function that can empty the mailbox immediately? It's a waste of time to have all items in the mailbox crash against a wall, before you can go on as in [ item1 // cancel item2 === do nothing return; item3 === do nothing return; ] In parts I find std.concurrency lacking. Simple things sometimes need workarounds.
Re: flush MessageBox
On Friday, 21 August 2015 at 14:35:53 UTC, Chris wrote: On Friday, 21 August 2015 at 12:59:09 UTC, John Colvin wrote: On Friday, 21 August 2015 at 10:43:22 UTC, Chris wrote: On Thursday, 20 August 2015 at 15:57:47 UTC, John Colvin wrote: On Thursday, 20 August 2015 at 15:25:57 UTC, Chris wrote: Is there a way to flush a thread's message box other than aborting the thread? MailBox is private: https://github.com/D-Programming-Language/phobos/blob/master/std/concurrency.d#L1778 flush from inside the thread? You could call receiveTimeout with a 0 timer in a loop until it returns false. Yes, from inside the thread. I have a worker thread (with receiveTimeout) that is started when the program starts and sits there waiting for input. I naively thought this was a great idea, until I noticed that when input comes fast the mailbox grows and the bloody thread won't stop until all the items in the mailbox are processed. I was looking for something like `if (abort) { mailbox.flush(); }` void flushMailbox() { bool r; do { r = receiveTimeout(Duration.zero, (Variant _){}); } while(r); } Thanks by the way. This does the trick.
Re: flush MessageBox
On Friday, 21 August 2015 at 17:05:56 UTC, John Colvin wrote: On Friday, 21 August 2015 at 14:35:53 UTC, Chris wrote: On Friday, 21 August 2015 at 12:59:09 UTC, John Colvin wrote: [...] Wouldn't it be easier to have a library function that can empty the mailbox immediately? It's a waste of time to have all items in the mailbox crash against a wall, before you can go on as in [ item1 // cancel item2 === do nothing return; item3 === do nothing return; ] In parts I find std.concurrency lacking. Simple things sometimes need workarounds. yes, it would be better. Please file an enhancement request: https://issues.dlang.org Done. https://issues.dlang.org/show_bug.cgi?id=14953
flush MessageBox
Is there a way to flush a thread's message box other than aborting the thread? MailBox is private: https://github.com/D-Programming-Language/phobos/blob/master/std/concurrency.d#L1778
Struct vs. Class
I have still some classes lying around in my code. As threading is becoming more and more of an issue, classes and OOP in general turn out to be a nuisance. It's not so hard to turn the classes into structs, a lot of classes are in fact singletons (yes, I've been kinda fading out classes for a while now). My question is now, what do I have to keep in mind if I turn a cached class into a cached struct, i.e. initProgram() { auto myClass = new AwesomeDoEverything.instance(); // lives for the rest of the program, is a singleton } // ... myClass.call(input); initProgram() { auto myStruct = AwesomeDoEverything(); // lives for the rest of the program } // ... myStruct.call(input); // Can live in different threads without reinitializing it. Or is there a way I can make a singleton class thread-able? I cannot afford to re-initialize certain classes / structs because I don't wanna hit the file system every time I do so.
Re: Struct vs. Class
On Friday, 26 June 2015 at 11:28:38 UTC, Daniel Kozák wrote: On Fri, 26 Jun 2015 11:11:15 + Chris via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: I have still some classes lying around in my code. As threading is becoming more and more of an issue, classes and OOP in general turn out to be a nuisance. It's not so hard to turn the classes into structs, a lot of classes are in fact singletons (yes, I've been kinda fading out classes for a while now). My question is now, what do I have to keep in mind if I turn a cached class into a cached struct, i.e. initProgram() { auto myClass = new AwesomeDoEverything.instance(); // lives for the rest of the program, is a singleton } // ... myClass.call(input); initProgram() { auto myStruct = AwesomeDoEverything(); // lives for the rest of the program } // ... myStruct.call(input); // Can live in different threads without reinitializing it. Or is there a way I can make a singleton class thread-able? I cannot afford to re-initialize certain classes / structs because I don't wanna hit the file system every time I do so. bad link: http://dlang.org/phobos/std_concurrency.html#.initOnce Thanks a million! This might do the trick and my classes can live happily ever after :-)
Re: Yes or No Options
On Monday, 27 July 2015 at 15:50:11 UTC, Alex wrote: Hey guys! I am super new to programming and still trying to learn the very basics via a book that I bought. Out of interest: what made you start with D? It's not the most obvious choice for a programming novice.
Re: Yes or No Options
On Thursday, 30 July 2015 at 14:20:41 UTC, Alex wrote: My father owns a small software company, specialized in market data products. www.bccgi.com (in case anyone is interested) So programming was basically around all my life. I do a small job in his company and my next task was to learn D. There are two trainees and the three of us have to learn D. Ofc the two trainees have to learn other languages as well. My dad said the reason why we learn this language is that he personally finds it to be a very intuitive language that produces machine code. If he just wanted us to teach programming he said he'd just told us to learn C#. In addition to that he wants to keep up and always have new languages and features in the company (only 8 people). And since we have experts for almost any language here but not a single one for D, it was time for someone to start! Once I started I found it to be really interesting and challenging plus I like solving problems. Thank you for being so nice! I have seen very few communities where beginners are welcomed so well! Very interesting indeed! Care to write an article about it one day? Learning D as an absolute beginner or something like that. I wonder, is your father's company listed among those using D? I think there's a list somewhere on Wiki, if not we should have one :-)
Thread communication
Is there a good way to stop work-intensive threads via thread communication (instead of using a shared variable)? The example below is very basic and naive and only meant to exemplify the basic problem. I want to stop (and abort) the worker as soon as new input arrives. However, while executing the function that contains the foreach-loop the worker thread doesn't listen, because it's busy, of course. I've tried a few solutions with send and receive in this block, but somehow none of them work perfectly. //=== import std.stdio : readln, writefln, writeln; import std.string : strip; import std.concurrency; import core.thread; Tid thread1; struct Exit {} void main() { string input; bool exists; while ((input = readln.strip) != null) { if (exists) { thread1.send(Exit()); } thread1 = spawn(worker); exists = true; thread1.send(input.idup); } } void worker() { bool run = true; while (run) { receive( (string input) { foreach (ref i; 0..10) { writefln(%d.\tDoing something with input %s, i+1, input); Thread.sleep(500.msecs); } run = false; }, (Exit exit) { run = false; } ); } writeln(End of thread worker); } //===
Re: Thread communication
On Tuesday, 4 August 2015 at 18:15:08 UTC, Ali Çehreli wrote: On 08/04/2015 09:19 AM, Dicebot wrote: receiveTimeout I think the problem here is that the worker is busy, not even able to call that. This sounds like sending a signal to the specific thread (with pthread_kill()) but I don't know the details of it nor whether Phobos supports it. Ali The problem is that it works up to a certain extent with receiveTimeout. However, if the input arrives in very short intervals, all the solutions I've come up with so far (including data sharing) fail sooner or later. New threads are spawned faster than old ones can be given the abort signal. There are ways to wait, till a given thread dies, say with a shared variable isAlive `while (isAlive) {}`, but even here I've come across problems when the input comes very fast. I don't know how to solve this problem, because message passing follows a linear protocol (as far as I understand it) and shared variables give rise to data races. Something like pthread_kill() would indeed be useful, to terminate a thread at random. I wonder if fibers would be an option. D-threads seem to be based on the assumption that there is no need to abort threads at random, any time. Or am I mistaken?
Re: Yes or No Options
On Thursday, 30 July 2015 at 17:48:51 UTC, Ali Çehreli wrote: On 07/30/2015 08:14 AM, Chris wrote: I wonder, is your father's company listed among those using D? I think there's a list somewhere on Wiki, if not we should have one :-) I don't think they use D yet but the page is here: http://wiki.dlang.org/Current_D_Use Ali That's the link. Thanks! I find the reasons Alex gave for using D very interesting. It's beyond all hype and reddit and stuff like that. It shows that D attracts users for what it is, without any hype or sh*t like that.
Re: Thread communication
On Thursday, 6 August 2015 at 08:40:58 UTC, Kagamin wrote: } AFAIK, boost does it by integrating support for interruption into various functions, so IO, waits and locks reply to interrupt requests appropriately. You can do something similar. I understand the philosophy behind D-threads. However, I have a situation where waiting for a thread to react to an abort signal (if it reacts at all) and finish according to a protocol can cause a delay that may not be acceptable to the user or cause inconsistencies. Instant abortion works best with data sharing. However, then I have the ugly situation where I have to place the abort flag at strategical places in several functions/blocks to make sure the task will not be pursued, because you never know when exactly the new input will arrive. In this way it can be intercepted. Unfortunately, this is messy and it is not easy to avoid data races. A possible solution would be to halt all threads except for the main thread, spawn a new thread, and end the old thread silently behind the scenes. I'm not sure, if this is possible though. I also wonder, if it would be possible to use some sort of observer that never sleeps.
std.stream.MemoryStream deprecated, range is the alternative?
class Test { MemoryStream m_stream; this(MemoryStream stream) { m_stream = stream; } void write(byte val) { m_stream.write(val); } byte read() { byte val; m_stream.read(val); return val; } } void main() { byte[] read = [0, 2, 4, 6, 8, 10, 12]; auto t = new Test(read); byte val = t.read(); t.write(1); byte val1 = t.m_stream.data; writeln(val, val1); } since memorystream is deprecated how do i do something like this with Input and Output ranges? How can i fill up an array with ranges like you can do with streams? Thanks.
Re: Concurrency Confusion
On Thursday, 6 August 2015 at 21:17:15 UTC, 岩倉 澪 wrote: On Tuesday, 4 August 2015 at 08:35:10 UTC, Dicebot wrote: // in real app use `receiveTimeout` to do useful stuff until // result message is received auto output = receiveOnly!(immutable(Bar)[]); New question: how would I receive a immutable value with receiveTimeout? I need the results from my worker thread outside of the delegate that receiveTimeout takes. Also: what is the best way to kill off the worker thread when I close the application, without having to wait for the worker thread to complete? My first thought was to use receiveTimeout in the worker thread, but the work is being done in a parallel foreach loop, and I am not sure if there is a way to safely use receiveTimeout in a parallel situation... I also found Thread.isDaemon in core.thread. I tried doing auto thread = Thread.getThis(); thread.isDaemon = true; at the start of the worker thread, but it still seems to wait for it to complete before closing. Thanks again! receiveTimeout can be used like this: void main() { spawn(workerFunc); writeln(Waiting for a message); bool received = false; while (!received) { received = receiveTimeout(600.msecs, (string message) { // === Receiving a value writeln(received: , message); }); if (!received) { writeln(... no message yet); /* ... other operations may be executed here ... */ } } } (cf. http://ddili.org/ders/d.en/concurrency.html) To stop threads immediately, I've found that the best way is to use a shared variable, typically a bool, that is changed only in one place. I hope I'll find the time on Monday to post a simple example. 1. shared bool ABORT; 2. 3.// in owner thread 4. ABORT = true; // The only place where you do this. 5. bool res; 6. while ((res = receiveOnly!bool()) == false) { debug writeln(waiting for abort ...); } // in worker thread(s) foreach () { if (ABORT) break; // working away } // ... ownerTid.send(true); If you have more than one thread to abort, you'll have to adapt lines 5 and 6 accordingly. Unfortunately, sending an abort message to a thread as in `send(thread, true)` takes too long. Setting a global flag like ABORT is instantaneous. Beware of data races though. You might want to have a look at: http://ddili.org/ders/d.en/concurrency_shared.html Especially `synchronized` and atomicOp.
Re: Concurrency Confusion
On Friday, 7 August 2015 at 15:55:33 UTC, Chris wrote: Using a shared boolean is probably not the best way, I should have said the most efficient and reliable way.
Re: Concurrency Confusion
On Saturday, 8 August 2015 at 00:39:57 UTC, 岩倉 澪 wrote: On Friday, 7 August 2015 at 22:13:35 UTC, 岩倉 澪 wrote: message is local to the delegate that receiveTimeout takes. I want to use message outside of the delegate in the receiving thread. However, if you send an immutable value from the worker thread, afaict there would be no way to assign it to a global/outer variable without making a mutable copy (expensive!) I haven't really spent much time trying to pass my message as mutable via shared yet, but hopefully that could work... Found the answer to this :) http://forum.dlang.org/post/mailman.1706.1340318206.24740.digitalmars-d-le...@puremagic.com I send the results from my worker thread with assumeUnique, and then simply cast away immutable in the receiving thread like so: (in module scope) Bar[] baz; (in application loop) import std.array if(baz.empty) { import std.concurrency, std.datetime; receiveTimeout(0.msecs, (immutable Bar[] bar){ baz = cast(Bar[])bar; }); } Note aside: if you only import what you need (say `import std.concurrency : receiveTimeout; std.datetime : msecs`), you can reduce the size of the executable considerably as your program grows.
Re: Thread pools
On Wednesday, 22 July 2015 at 15:41:06 UTC, Alex Parrill wrote: On Wednesday, 22 July 2015 at 14:28:48 UTC, Chris wrote: What would be the best way to manage different threads (spawned via std.concurrency), e.g. to tell them to stop at once, once a new command comes in? A thread pool? How would that look like in D? I feel my knowledge of D threads is still a bit limited. `std.parallelism` includes a TaskPool class [1] and a taskPool property [2], but they spawn their own threads. I'm not sure why you need a thread pool to tell std.concurrency threads to stop; why not send a stop message to each of them? [1]: http://dlang.org/phobos/std_parallelism.html#.TaskPool [2]: http://dlang.org/phobos/std_parallelism.html#.taskPool Thanks. I'm dealing with nested threads at the moment. main { spawn(thread1) { // Does some processing spawn(thread2) { // Plays audio } } } If main receives a signal, all threads should stop immediately (thread1 and thread2).
Re: Thread pools
On Wednesday, 22 July 2015 at 17:01:52 UTC, Marc Schütz wrote: You can probably simply terminate the main thread, which will send an OwnerTerminated message to all dependent threads. The threads need to `receive()` this message and terminate. Not possible here. Main has to run the all the time, it's waiting for input and spawns threads accordingly.
Re: Thread pools
On Wednesday, 22 July 2015 at 16:16:36 UTC, John Colvin wrote: I would send a message to terminate to thread1, which would in turn send a similar message to any threads it has started, wait until they've all stopped (maybe with a time-out), then return. I.e. every thread knows how to cleanly terminate itself when instructed, so you just send a terminate message down the tree of threads and then wait for the effects to bubble back up to main. Thanks. I was thinking the same when I gave it a second thought on my way home. Instead of having a central pool, every thread is responsible for its own threads. So main only needs to care about the initial thread. That's the theory, I'll have to see how this works in reality.
Thread pools
What would be the best way to manage different threads (spawned via std.concurrency), e.g. to tell them to stop at once, once a new command comes in? A thread pool? How would that look like in D? I feel my knowledge of D threads is still a bit limited.
Re: Invalid foreach aggregate
On Monday, 16 November 2015 at 16:49:19 UTC, Marc Schütz wrote: On Monday, 16 November 2015 at 16:44:27 UTC, Chris wrote: Updating my code from 2.067.1 to 2.069.1 (I skipped 2.068, because I was too busy). I get this error: invalid foreach aggregate, define opApply(), range primitives, or use .tupleof for code like foreach (ref it; myArray.doSomething) {} Probably not the best idea anyway. What's the best fix for this? Thanks. Well, what does `doSomething` return? It returns a range that modifies individual items in myArray, i.e. it assigns values to fields in each item of the array.
Invalid foreach aggregate
Updating my code from 2.067.1 to 2.069.1 (I skipped 2.068, because I was too busy). I get this error: invalid foreach aggregate, define opApply(), range primitives, or use .tupleof for code like foreach (ref it; myArray.doSomething) {} Probably not the best idea anyway. What's the best fix for this? Thanks.
Re: Invalid foreach aggregate
On Monday, 16 November 2015 at 17:57:53 UTC, opla wrote: On Monday, 16 November 2015 at 16:55:29 UTC, Chris wrote: On Monday, 16 November 2015 at 16:49:19 UTC, Marc Schütz wrote: On Monday, 16 November 2015 at 16:44:27 UTC, Chris wrote: Updating my code from 2.067.1 to 2.069.1 (I skipped 2.068, because I was too busy). I get this error: invalid foreach aggregate, define opApply(), range primitives, or use .tupleof for code like foreach (ref it; myArray.doSomething) {} Probably not the best idea anyway. What's the best fix for this? Thanks. Well, what does `doSomething` return? It returns a range that modifies individual items in myArray, i.e. it assigns values to fields in each item of the array. have you... tried without ref tried by adding a pair of parens after doSomething ? tried std.algorithm.each or map on doSomething ? checked the primitives ? checked that isInputRange!(ReturnType!doSomething) == true? I think ref is necessary, else the items are not changed. I will try the other options tomorrow (Tuesday). Thanks. I wonder was the change overdue (and I got away with it till 2.068.1) or is it a new policy due to changes in D?
Re: Invalid foreach aggregate
On Tuesday, 17 November 2015 at 11:58:22 UTC, Chris wrote: Sorry that should be: @property void popFront() { r = r[1..$]; cnt++; }
Re: Invalid foreach aggregate
I've checked several options now and it doesn't work. Here (http://dlang.org/statement.html#foreach-with-ranges) it is stated that it suffices to have range primitives, if opApply doesn't exist. My code worked up to 2.068.0, with the introduction of 2.068.1 it failed. I wonder why that is. I have empty, front and popFront in my range which is a struct, and it used to work.
Re: Invalid foreach aggregate
On Tuesday, 17 November 2015 at 12:22:22 UTC, Marc Schütz wrote: Ok, that's a strange implementation of opIndex(). Usually, a parameter-less opIndex() is supposed to return a slice into the full range, but yours returns a size_t, which of course can't be iterated over. The change that made this stop working is: https://github.com/D-Programming-Language/dmd/pull/4948 This contains, among others a fix for issue 14625 "opIndex() doesn't work on foreach container iteration": https://issues.dlang.org/show_bug.cgi?id=14625 This allows to iterate directly over containers, without needing to slice them first. I guess it's a bit too eager, because if the object is already iterable without slicing (as in your example), it could just do that. On the other hand, it's a corner case, and it might actually be preferable to slice always, if the iterable supports it... In any case, I'd suggest you fix your opIndex(), except if there's a really good reason it is as it is. I see. Thanks for the explanation. What would be the easiest fix for this example?
Re: Invalid foreach aggregate
On Tuesday, 17 November 2015 at 11:26:19 UTC, Marc Schütz wrote: That really depends on the details, that's why I asked. It could be a regression, or it could be that the compiler now does stricter checking than before, and your implementation wasn't completely correct, or it could be a bug in Phobos if you use that to create the range. If you can post a minimal example that works in 2.067.1, but doesn't with the current version, I can try to find the change that broke it. I did just that and I could find the culprit. It's opIndex(). It works up until 2.068.0, with 2.068.1 I already get this error: "primitives.d(7): Error: invalid foreach aggregate doSomething(items).opIndex()" Here's the example: = import std.stdio : writeln; import std.range.primitives; void main() { string[] items = ["a", "b", "c"]; foreach (ref it; items.doSomething()) { writeln(it); } } auto doSomething(InputRange)(ref InputRange r) { struct DoSomething { private { InputRange r; size_t cnt; } this(InputRange r) { this.r = r; } @property bool empty() { return r.length == 0; } @property auto front() { return r[0]; } @property void popFront() { r = r[1..$]; } @property size_t length() const { return r.length; } @property size_t opIndex() { return cnt; } @property auto save() const { return this; } } return DoSomething(r); }
Re: bearophile is back! :) was: Re: conver BigInt to string
On Thursday, 5 November 2015 at 19:38:23 UTC, Ali Çehreli wrote: Good one! ;) I'm really happy that he is still around. Ali So am I! The more, the merrier!
Re: bearophile is back! :) was: Re: conver BigInt to string
On Thursday, 5 November 2015 at 19:30:02 UTC, Ali Çehreli wrote: On 11/05/2015 09:40 AM, bearophile wrote: Bye, bearophile Were you immersed in another language? Rust? Ali His D doesn't seem to be Rusty though!
Re: good reasons not to use D?
On Friday, 30 October 2015 at 10:35:03 UTC, Laeeth Isharc wrote: Interesting. Two points suggest that you should use D only for serious programming: "cases where you want to write quick one-off scripts that need to use a bunch of different libraries not yet available in D and where it doesn't make sense to wrap or port them" - quick and dirty "where you have many inexperienced programmers and they need to be productive very quickly." - quick and awkward [what does this tell us about financial programming ...] This reason is true of any other language: "where you have a lot of code in another language (especially non C, non Python) and defining an interface is not so easy;" In fact, the reasons you give (apart from the point about GUI) are true of C++, C#, Java etc. too. It's a bit generic. I was thinking of D specific reasons like lack of support for mobile platforms (not 100% yet). So your average stock broker couldn't calculate some bogus numbers on his iPad while having a latte and a Pelegrino in a posh cafe off Wallstreet. He he he. GC and lack of mobile are real reasons not to use D.
Re: OT: why do people use python when it is slow?
On Thursday, 15 October 2015 at 09:47:56 UTC, Ola Fosheim Grøstad wrote: On Thursday, 15 October 2015 at 09:24:52 UTC, Chris wrote: Yep. This occurred to me too. Sorry Ola, but I think you don't know how sausages are made. I most certainly do. I am both doing backend programming and we have a farm... :-) Well, you know how gourmet sausages are made (100% meat), because you make them yourself apparently. But I was talking about the sausages you get out there ;) A lot of websites are not "planned". They are quickly put together to promote an idea. The code/architecture is not important at that stage. The idea is important. The website has to have dynamic content that can be edited by non-programmers (Not even PHP! HTML at most!). If you designed a website from a programming point of view first, you'd never get the idea out in time.
Re: OT: why do people use python when it is slow?
On Wednesday, 14 October 2015 at 18:17:29 UTC, Russel Winder wrote: The thing about Python is NumPy, SciPy, Pandas, Matplotlib, IPython, Jupyter, GNU Radio. The data science, bioinformatics, quant, signal provessing, etc. people do not give a sh!t which language they used, what they want is to get their results as fast as possible. Most of them do not write programs that are to last, they are effectively throw away programs. This leads them to Python (or R) and they are not really interested in learning anything else. Scary, but I agree with you again. In science this is exactly what usually happens. Throw away programs, a list here, a loop there, clumsy, inefficient code. And that's fine, in a way that's what scripting is for. The problems start to kick in when the same guys get the idea to go public and write a program that everyone can use. Then you have a mess of slow code (undocumented) in a slow language. This is why I always say "Use C, C++ or D from the very beginning" or at least document your code in a way that it can easily be rewritten in D or C. But well, you know, results, papers, conferences ... This is why many innovations live in an eternal Matlab or Python limbo.
Re: OT: why do people use python when it is slow?
On Wednesday, 14 October 2015 at 18:37:40 UTC, Mengu wrote: On Wednesday, 14 October 2015 at 05:42:12 UTC, Ola Fosheim Grøstad wrote: On Tuesday, 13 October 2015 at 23:26:14 UTC, Laeeth Isharc wrote: https://www.quora.com/Why-is-Python-so-popular-despite-being-so-slow Andrei suggested posting more widely. That's flaimbait: «Many really popular websites use Python. But why is that? Doesn't it affect the performance of the website?» No. Really popular websites use pre-generated content / front end caches / CDNs or wait for network traffic from distributed databases. really popular portals, news sites? yes. really popular websites? nope. like booking.com, airbnb.com, reddit.com are popular websites that have many parts which have to be dynamic and responsive as hell and they cannot use caching, pre-generated content, etc. using python affect the performance of your website. if you were to use ruby or php your web app would be slower than it's python version. and python version would be slower than go or d version. Yep. This occurred to me too. Sorry Ola, but I think you don't know how sausages are made. Do you really think that all the websites out there are performance tuned by network programming specialists? You'd be surprised!
Re: LuaD: creating a flexible data filter system
On Friday, 16 October 2015 at 09:01:57 UTC, yawniek wrote: hi, i'm reading in a stream of data that is deserialized into individual frames. a frame is either of: a) a specific D datastructure ( struct with a few ulong,string,string[string] etc members), known at compile time b) json (preferably stdx.data.json) i now want to implement something where i can dynamically add lua filters that then get data out of these frames, create a new lua object send it back to D code where its either sent to another lua filter or at last being serialized again to json und then being processed further. ideally i would not like to copy all the data into a lua object but directly access it from lua. is there an elegant approach to do this and support both a and b cases? so far i did some benchmarks, mainly with string comparisons and it turned out that luaD is about 10x faster than mruby and python D bridges. You could use the Lua C API directly. I have a small project where I use DerelictLua[1] and access the Lua C API directly for fast processing (cf. http://www.lua.org/manual/5.3/ or http://www.lua.org/manual/5.2/ "C API"). Another performance trick is to compile lua functions and store them in memory, rather than having lua read and execute everything. lua_State* L = luaL_newstate(); auto func = luaL_loadstring(L, "Lua code as C-string\0"); // Lua file compiled as a function Later you call the function with the Lua C API like "lua_pcall(L, 0, 1, 0);". It's a bit tricky to move things around on the Lua stack, but you'll get there! ;) [1] https://github.com/DerelictOrg/DerelictLua
Re: LuaD: creating a flexible data filter system
On Saturday, 17 October 2015 at 02:02:16 UTC, Jakob Ovrum wrote: On Friday, 16 October 2015 at 10:45:52 UTC, Chris wrote: Later you call the function with the Lua C API like "lua_pcall(L, 0, 1, 0);". It's a bit tricky to move things around on the Lua stack, but you'll get there! ;) Or you could use LuaD which doesn't require you to mess around with the relatively unproductive, bug-prone C API :) I've used both, LuaD and DerelictLua + my own smaller D library that wraps all these nasty Lua stack operations (e.g. creating, accessing and adding to tables). The better I got to know the Lua C API while writing my own wrappers, the more I came to appreciate LuaD :-) However, LuaD is still 5.1 and I didn't want to be stuck with 5.1. So I rolled my own. It's not as comprehensive as LuaD but did the trick. The purpose was to experiment with Lua server pages + vibe.d which worked fine. Rikki gave me the idea to compile each page as a Lua function into memory for faster execution (etLua style[1]). It works fine with both LuaD and my own wrappers. In my own version I use the Lua C API directly in some places, though I don't know, if that's really a big speedup. If I set up my own homepage, I'd probably give vibe.d + Lua a shot. No more PHP and sh*t like that. [1] https://github.com/leafo/etlua
Re: Lazy sort
On Friday, 11 September 2015 at 10:41:16 UTC, ixid wrote: Does sort have to be eager or would it be possible to have a lazy version? It's messy to always have to use array and leap in and out of lazy operations within a UFCS chain. Surely as many functions as possible should be optionally lazy. Are you the lazy sort? ;) Sorry, I couldn't resist the pun.
Bloat with std.(string.)format?
If I have code like this: auto builder = appender!string; builder ~= "Hello, World!"; builder ~= "I'm here!"; builder ~= "Now I'm there!"; the object file grows by 10-11 lines with each call to `builder ~=`. If I use this: builder ~= format("%s", "Hello, World!"); builder ~= format("%s", "I'm here!"); builder ~= format("%s", "Now I'm there!"); The object file is more than twice as big and it grows by 20 lines with each call to `format`. If I use builder ~= format("%s %s %s", "Hello, World!", "I'm here!", "Now I'm there!"); the code bloat is even worse. There are many situation where a formatting string is preferable to concatenation, however it adds _a lot_ of bloat. Would a custom formatter be preferable to reduce code bloat or should std/format.d be optimized? (Or both?) dmd 2.067.1 -release -boundscheck=off -inline -O
Re: Bloat with std.(string.)format?
On Thursday, 17 September 2015 at 10:33:44 UTC, John Colvin wrote: Some initial bloat is expected, format is pretty big (although twice as big is a lot, unless your original code was quite small?). It was in a test program. Only a few lines. But it would still add a lot of bloat in a program that uses it in different modules, wouldn't it? The extra bloat per call is likely due to inlining. I would hope that dmd would spot consecutive inlining of the same function and merge them, but perhaps it doesn't. You could certainly make a less feature complete implementation of format that is smaller. Don't know if it's worth the trouble. Have you tried with ldc or gdc. In particular, have you tried using ldc with --gc-sections on linux? Not yet. GDC and LDC always lag behind (this time considerably), so I'm usually stuck with DMD for development.
Re: Bloat with std.(string.)format?
On Thursday, 17 September 2015 at 15:17:21 UTC, John Colvin wrote: On Thursday, 17 September 2015 at 13:42:15 UTC, Chris wrote: On Thursday, 17 September 2015 at 12:49:03 UTC, John Colvin wrote: [...] Thanks. That's up to date enough now. Is it stable, though? Reasonably so in my testing, but expect more bugs than in a full release. For version 2.067.1 it took a long time this time. Maybe we should focus some of our efforts on LDC and GCD being up to date faster. It would be great to have more people working on them, yes. I suppose it's an area most people (including myself) shy away from. I know next to nothing about compiler implementation.
Re: Bloat with std.(string.)format?
On Thursday, 17 September 2015 at 12:49:03 UTC, John Colvin wrote: On Thursday, 17 September 2015 at 10:53:17 UTC, Chris wrote: On Thursday, 17 September 2015 at 10:33:44 UTC, John Colvin wrote: Some initial bloat is expected, format is pretty big (although twice as big is a lot, unless your original code was quite small?). It was in a test program. Only a few lines. But it would still add a lot of bloat in a program that uses it in different modules, wouldn't it? The upfront cost is paid only once per unique template arguments per binary. So no, it doesn't scale badly there. Inlining, on the other hand, will - roughly speaking - increase binary sizes linearly with the number of calls. That's the cost you pay for (hopefully) better performance. The extra bloat per call is likely due to inlining. I would hope that dmd would spot consecutive inlining of the same function and merge them, but perhaps it doesn't. You could certainly make a less feature complete implementation of format that is smaller. Don't know if it's worth the trouble. I would say not worth it, unless you have a real problem with binary sizes for an actual finished product. Even then, I'd say you could get bigger, easier gains by messing around with -fvisibility settings, --gc-sections, strip etc. on GDC and LDC Have you tried with ldc or gdc. In particular, have you tried using ldc with --gc-sections on linux? Not yet. GDC and LDC always lag behind (this time considerably), so I'm usually stuck with DMD for development. That's a shame. https://github.com/ldc-developers/ldc/releases/tag/v0.16.0-alpha3 is at 2.067.1, is that not up-to-date enough? Thanks. That's up to date enough now. Is it stable, though? For version 2.067.1 it took a long time this time. Maybe we should focus some of our efforts on LDC and GCD being up to date faster.
Linker error with dmd
Why do I get this error msg with dmd 2.067.1 and 2.068.0 in release mode: $ dub --build=release (.data._D65TypeInfo_xC3std5range10interfaces18__T10InputRangeTiZ10InputRange6__initZ+0x10): undefined reference to `_D64TypeInfo_C3std5range10interfaces18__T10InputRangeTiZ10InputRange6__initZ' collect2: error: ld returned 1 exit status --- errorlevel 1 dmd failed with exit code 1. It works fine with the latest version of ldc2.
What's wrong with this code?
This crashes when triggered: voxel_vec [string] move_buttons = [ "button_xp" : voxel_vec ([ 1, 0, 0 ]), "button_xm" : voxel_vec ([ -1, 0, 0 ]), "button_yp" : voxel_vec ([ 0, 1, 0 ]), "button_ym" : voxel_vec ([ 0, -1, 0 ]), "button_zp" : voxel_vec ([ 0, 0, 1 ]), "button_zm" : voxel_vec ([ 0, 0, -1 ]) ]; foreach (bname, vec; move_buttons) { Button bmove = cast (Button) g.getObject (bname); bmove.addOnClicked (delegate void (Button aux) { if (!glw.sel_active) return; glw.vf.move (3, vec, glw.sel_limits); glw.set_mesh (glw.vf.polygonize); } ); } I get: First-chance exception at 0x754fc42d in 3dprinterapp.exe: 0xE0440001: 0xe0440001. Unhandled exception at 0x754fc42d in 3dprinterapp.exe: 0xE0440001: 0xe0440001. Inspection with the debugger reveals the var glw is "out of scope" at the location of the if (!glw... and single stepping past that line triggers the exception. The variable glw is in scope however, this code just above it works: b.addOnValueChanged (delegate void (SpinButton aux) { for (int i = 0; i < 6; i++) sellimits [i] = selwidgets [i].getValueAsInt (); glw.set_sel_box (sellimits); glw.sel_active = 1; glw.actual_queue_draw (); }); (works) Could this be a compiler bug? I have no idea what could be wrong. Bringing it out of the loop produces the same error: Button xmove = cast (Button) g.getObject ("button_xp"); xmove.addOnClicked (delegate void (Button aux) { if (!glw.sel_active) return; glw.vf.move (3, voxel_vec ([ 1, 0, 0 ]), glw.sel_limits); glw.set_mesh (glw.vf.polygonize); }); (same error) This is with DMD 2.067.1 under Windows, I'm stuck with it because if I upgrade to 2.068 then GtkD doesn't work anymore. Also using GtkD 3.0.0, version 3.1.4 doesn't work with either version of DMD. Thanks in advance for any help.
Re: What's wrong with this code?
On Saturday, 19 September 2015 at 02:45:54 UTC, Adam D. Ruppe wrote: On Saturday, 19 September 2015 at 02:30:39 UTC, Chris wrote: bmove.addOnClicked (delegate void (Button aux) { What's the context of this call? If it is inside a struct and you are accessing local variables you can get in trouble because the context pointer may not be correct. You are using `vec` there, if `glw` is a struct/class member too, then the compiler can sometimes be a bit stupid about bringing in the correct `this` reference to the delegate. Hi thanks for the response. The context is inside a try block in the program's main() function. Glw is indeed a class but it doesn't look like it quite configures the problem you describe. I think #3 will work for you here. Right above that loop, try something like auto glw = this.glw; There's no "this", it's the main() function. I stuck a "auto glw2 = glw" in there but it didn't help. I found more funny stuff. If I move the code around and change the order of that snippet to before the other one I posted earlier, the first line (if (!glw...) now works *despite* the debugger saying the variable glw is "not found". So now as long as the condition evaluates to true it will work as expected. However when the condition is made to eval to false then the *next* line of code will trigger the exception as I first encountered. So I'm going to go ahead and say I found a compiler bug.
Re: What's wrong with this code?
Update: If I add *also* a auto vec2 = vec; now the code works. So it looks like this now: voxel_vec [string] move_buttons = [ "button_xp" : voxel_vec ([ 1, 0, 0 ]), "button_xm" : voxel_vec ([ -1, 0, 0 ]), "button_yp" : voxel_vec ([ 0, 1, 0 ]), "button_ym" : voxel_vec ([ 0, -1, 0 ]), "button_zp" : voxel_vec ([ 0, 0, 1 ]), "button_zm" : voxel_vec ([ 0, 0, -1 ]) ]; foreach (bname, vec; move_buttons) { Button bmove = cast (Button) g.getObject (bname); bmove.addOnClicked (delegate void (Button aux) { auto glw2 = glw; auto vec2 = vec; if (!glw2.sel_active) return; glw2.vf.move (3, vec2, glw2.sel_limits); glw2.set_mesh (glw2.vf.polygonize); } ); } and works as expected. I'm going to leave it like that in the belief it's a compiler bug, if someone wants to take a look at the full source I'm willing to disclose it. Thanks again for the help and the idea of the work around.
Re: Linker error with dmd
On Friday, 2 October 2015 at 14:03:08 UTC, John Colvin wrote: On Friday, 2 October 2015 at 09:43:54 UTC, Chris wrote: Why do I get this error msg with dmd 2.067.1 and 2.068.0 in release mode: $ dub --build=release (.data._D65TypeInfo_xC3std5range10interfaces18__T10InputRangeTiZ10InputRange6__initZ+0x10): undefined reference to `_D64TypeInfo_C3std5range10interfaces18__T10InputRangeTiZ10InputRange6__initZ' collect2: error: ld returned 1 exit status --- errorlevel 1 dmd failed with exit code 1. It works fine with the latest version of ldc2. What is it that you are building? An executable. I mainly use a code base that compiles perfectly well in release mode. I couldn't find the reason for this error message, plus, ldc2 has no problem with it.
What's wrong with my debugger?
Please see the linked screenshot: http://i.imgur.com/SpkXu5m.png As you can see, the inside, outside and collision arrays don't seem to work with the debugger. They show a bogus lenght and a bogus memory address. Extracting the lenghts to separate variables outl, insl and coll show that the arrays actually behave properly, though. Is that a debugger bug? Or maybe something I can fix? Thanks in advance. DMD 2.069.2, Mago debugger, VisualD 3.43, compiling for 32 bits if that makes a difference (can't get either 64 bit compilation or LDC to work)
Re: What's wrong with my debugger?
On Thursday, 24 December 2015 at 09:30:24 UTC, Rainer Schuetze wrote: In the locals window, mago displays all instances of variables, but with the same value (which might be some uninitialized value of a different declaration than expected). The Visual Studio debug engine shows different values, though. Hi, thanks for the reply but not actually, no, if I change the debug engine to VS and rebuild I get the same behaviour.
Re: Linker error
On Friday, 10 June 2016 at 12:12:17 UTC, ketmar wrote: On Friday, 10 June 2016 at 12:04:50 UTC, Chris wrote: I get the error below with code like this: auto res = ['1', '2'].map!(a => a.to!string); dmd 2.071.0 What's wrong here? I import std.algorithm, std.range, std.array, std.conv in the module. (.data._D65TypeInfo_xC3std5range10interfaces18__T10InputRangeTiZ10InputRange6__initZ+0x10): undefined reference to `_D64TypeInfo_C3std5range10interfaces18__T10InputRangeTiZ10InputRange6__initZ' collect2: error: ld returned 1 exit status post the whole code and command line, please. it looks like you doing separate compilation, and forgot to put something to command line, or there is some conflict between installed compiler versions (for example, dmd and ldc, and one somehow is trying to use libphobos from another). The whole code would be too much. This, however compiles and links perfectly well: ` import std.algorithm; import std.conv : to; void main() { auto res = [1, 2, 3].map!(a => a.to!string); } ` I use dub and `dvm use 2.071.0`. The code compiled perfectly well until I used `map!` I have no clue what causes it. I even used `dub clean`
Linker error
I get the error below with code like this: auto res = ['1', '2'].map!(a => a.to!string); dmd 2.071.0 What's wrong here? I import std.algorithm, std.range, std.array, std.conv in the module. (.data._D65TypeInfo_xC3std5range10interfaces18__T10InputRangeTiZ10InputRange6__initZ+0x10): undefined reference to `_D64TypeInfo_C3std5range10interfaces18__T10InputRangeTiZ10InputRange6__initZ' collect2: error: ld returned 1 exit status
Re: What's wrong with my usage of std.algorithm.map in this code example?
On Wednesday, 25 May 2016 at 14:32:11 UTC, ag0aep6g wrote: On 05/25/2016 03:27 PM, Chris wrote: Why can the tuple be iterated with foreach, as in my quick fix, and indexed with tuple[0..], but is not accepted as a range? What are the differences? popFront doesn't make sense with a tuple (aka expression list). When you remove the first element of a tuple, you get another tuple of a different type, but popFront can't change the type of the range. In code: void main() { import std.meta: AliasSeq; AliasSeq!(int, int, int) tuple = AliasSeq!(1, 2, 3); tuple.popFront(); /* How would this be implemented? Would have to change tuple's type to AliasSeq!(int, int). */ } Is there a way to rangify a tuple? std.range.only: void main() { import std.meta: AliasSeq; import std.range: only; AliasSeq!(int, int, int) tuple = AliasSeq!(1, 2, 3); auto range = only(tuple); range.popFront(); /* ok */ } I see. Maybe it would be worth adding a wrapper to typecons.Tuple or std.range that helps to rangify tuples. I cannot think of any use case right now. I never needed this and in the example that started this thread, it would keep the function from converting mixed tuples (cf. my example above).