Re: Cannot compile program with DMD built from source
On Wednesday, 9 March 2016 at 16:13:38 UTC, Minas Mina wrote: Hello, I have followed the instructions here (http://wiki.dlang.org/Starting_as_a_Contributor#POSIX) to install DMD, druntime and phobos from source. My platform is Ubuntu 15.10 x64. This is the error I get: http://pastebin.com/kWCv0ymn Sorry I didn't explain well. All 3 components (DMD, druntime and phobos) were built successfully. The error I posted above is when trying to compile this code: import std.stdio; import std.experimental.logger; void main() { auto logger = new FileLogger("log"); logger.info("test"); }
Cannot compile program with DMD built from source
Hello, I have followed the instructions here (http://wiki.dlang.org/Starting_as_a_Contributor#POSIX) to install DMD, druntime and phobos from source. My platform is Ubuntu 15.10 x64. This is the error I get: http://pastebin.com/kWCv0ymn
Re: Application with WinMain does not start
On Saturday, 5 March 2016 at 14:08:28 UTC, Mike Parker wrote: On Saturday, 5 March 2016 at 14:01:11 UTC, Mike Parker wrote: If you use WinMain, you do not need that flag. Actually, I need to amend that. It isn't needed with WinMain when using the Microsoft linker, but it is when using OPTLINK. The MS linker recognizes WinMain and treats it as /SUBSYSTEM:WINDOWS by default. Thanks. I removed the WinMain and it worked.
Application with WinMain does not start
I added a WinMain function to my application because I don't want it to open a console when running on windows. But now it doesn't even start... extern (Windows) int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { bool b = true; while (b) { sync(Clock.currTime(utcTimeZone())); Thread.sleep(getNextTimeToRun() - Clock.currTime(utcTimeZone())); } return 0; } And this is my DUB configuration: name "..." description "..." copyright "..." authors "..." targetType "executable" lflags "/SUBSYSTEM:windows" "/EXETYPE:NT" platform="windows" I got those flags from here: http://wiki.dlang.org/D_for_Win32 Any ideas:
Re: efficient and safe way to iterate on associative array?
On Friday, 4 March 2016 at 13:53:22 UTC, aki wrote: Is it okay to modify associative array while iterating it? import std.stdio; void main() { string[string] hash = [ "k1":"v1", "k2":"v2" ]; auto r = hash.byKeyValue(); while(!r.empty) { auto key = r.front.key; auto value = r.front.value; r.popFront(); writefln("key=%s, value=%s", key, value); // may not modify 'hash' here ? hash = null; } } I guess probably it's not. Then, my question is are there an efficient and safe way to iterate on an associative array even if there are possibility to be modified while iterating? I'm writing interpreter and want to make my language to be safe; even malicious script cannot fall it in 'core dump' state. It is okay if it causes undefined behavior like throw or instant exit from loop, but not crash. Thanks, Aki. I think what you can do is extract its contents to an array, iterate it and modify it as you like, and then insert back to another associative array. I don't think it's efficient but I don't know if it's possible to do something else.
Trouble installing DCD on Windows
Hello. I'm trying to install DCD on windows 8.1 using DUB but I get an error. When executing "dub build --build=release --config=client" I get the following error: => Root package dcd contains reference to invalid package libdparse >=0.5.0 <0.6.0 <=
Re: std.experimental.logger.Logger writeLogMsg is @safe?
On Monday, 22 February 2016 at 23:03:38 UTC, Jonathan M Davis wrote: On Monday, February 22, 2016 22:22:01 Minas Mina via Digitalmars-d-learn wrote: [...] Short answer: [...] Great, thanks.
std.experimental.logger.Logger writeLogMsg is @safe?
I'm trying to inherit from Logger, and I my custom logger to print to stdout using writeln(). But I can't because writeLogMsg is @safe, whereas writeln() is @system. Why is writeLogMsg @safe? This is too restrictive.
Re: is increment on shared ulong atomic operation?
On Sunday, 7 February 2016 at 19:43:23 UTC, rsw0x wrote: On Sunday, 7 February 2016 at 19:39:27 UTC, rsw0x wrote: On Sunday, 7 February 2016 at 19:27:19 UTC, Charles Hixson wrote: If I define a shared ulong variable, is increment an atomic operation? E.g. shared ulong t; ... t++; It seems as if it ought to be, but it could be split into read, increment, store. I started off defining a shared struct, but that seems silly, as if the operations defined within a shared struct are synced, then the operation on a shared variable should be synced, but "+=" is clearly stated not to be synchronized, so I'm uncertain. https://dlang.org/phobos/core_atomic.html#.atomicOp Just noticed that there's no example. It's used like shared(ulong) a; atomicOp!"+="(a, 1); Wow, that syntax sucks a lot.
Re: Proper Use of Assert and Enforce
On Wednesday, 14 March 2012 at 05:44:24 UTC, Chris Pons wrote: I'm new, and trying to incorporate assert and enforce into my program properly. My question revolves around, the fact that assert is only evaluated when using the debug switch. I read that assert throws a more serious exception than enforce does, is this correct? I'm trying to use enforce in conjunction with several functions that initialize major components of the framework i'm using. However, i'm concerned with the fact that my program might continue running, while I personally would like for it to crash, if the expressions i'm trying to check fail. Here is what i'm working on: void InitSDL() { enforce( SDL_Init( SDL_Init_Everything ) > 0, "SDL_Init Failed!"); SDL_WN_SetCaption("Test", null); backGround = SDL_SetVideoMode( xResolution, yResolution, bitsPerPixel, SDL_HWSURFACE | SDL_DOUBLEBUF); enforce( backGround != null, "backGround is null!"); enforce( TTF_Init() != -1, "TTF_Init failed!" ); } Is it proper to use in this manner? I understand that I shouldn't put anything important in an assert statement, but is this ok? Use assertions when a variable's value should not depend on external factors. For example, let's say you want to write a square root function. The input must be >= 0, and because this depends on external factors (e.g. user input), you must check it with `enforce()`. The output of the function must should always be >= 0 as well, but this does not depend on any external factor, so use assert for it (a negative square root is a program bug). auto sqrt(float val) { enfore(val >= 0f); float result = ... assert(result >= 0f); return result; }
Re: Most performant way of converting int to string
On Wednesday, 23 December 2015 at 22:29:31 UTC, Andrew Chapman wrote: On Wednesday, 23 December 2015 at 11:46:37 UTC, Jakob Ovrum wrote: On Wednesday, 23 December 2015 at 11:21:32 UTC, Jakob Ovrum wrote: Dynamic memory allocation is expensive. If the string is short-lived, allocate it on the stack: See also std.conv.toChars[1] for stringifying lazily/on-demand. http://dlang.org/phobos/std_conv#toChars Thanks Jakob! I did try toChars but I couldn't quite figure out a syntax of calling it that the compiler was happy with. From memory I tried things along the lines of: string v = toChars!(16,char,LetterCase.lower)(i); to convert an integer to Hex for example, but the compiler wasn't happy with it. How would I convert an int to a string using this? Cheers. I haven't tested it, but: `toChars` doesn't return a string -- that's the whole point :) It returns a range, so you have to call it something like: auto v = toChars!(16,char,LetterCase.lower)(i);
Re: Using executeShell in multiple thread causes access violation error
bump
Using executeShell in multiple thread causes access violation error
I have written a script that visits all directories in the current directory and executes a command. In my case, "git pull". When running the script serially, everything is fine. All git repositories are pulled. But I'd like to pull multiple repositories in parallel to speed things up. So I've changed my loop from foreach(entry; dirs) to foreach(entry; parallel(dirs)) After a while that the program is running I get: std.exception.ErrnoException@std\stdio.d(638): Could not close file `HANDLE(C0)' (No error) 0x00411E5C 0x0040B8AB 0x0040A146 0x00402288 0x00403A99 0x00413B95 0x004095FC 0x00439AA0 0x770992B2 in RtlInitializeExceptionChain 0x77099285 in RtlInitializeExceptionChain object.Error@(0): Access Violation 0x00439429 0x0043A277 0x00411ECD 0x763A9B2C in GetFileAttributesW Here is the code: http://pastebin.com/Tk0TBGxs
Re: How do I use dub?
Oh and another thing: The program compiles right now but I can't execute it because for some reason: Failed to create a child process. Cannot run program "/home/minas/Projects/eclipse_workspace/DTest/dtest" (in directory "/home/minas/Projects/eclipse_workspace/DTest"): error=13, Permission denied Running from terminal yields the same error.
How do I use dub?
I intent to use D to make a small 2D game. I have downloaded eclipse, DDT plugin and dub. I also set the path to dub in eclipse. So I made a new project, tested a writeln and it worked. The next step was to add some dependencies for derelict. I need SFML for now (and DerelictUtils of course). So this is what I've done: { "name" : "DTest", "description" : "A minimal D bundle.", "dependencies" : { "derelict-util": ">=1.0.3", "derelict-sfml2": "~2.1" }, "versions-x86_64": ["UseAmd64Impl"], "lflags": ["-I/home/minas/.dub/packages/derelict-sfml2-2.1/lib", "-LDerelictSFML2"] } The way I specified the library seems very ugly to me. Essentially it's a full path... How can I tell dub to use it by locating it automatically from its local repository?
Re: Global const variables
On Tuesday, 21 October 2014 at 08:02:52 UTC, bearophile wrote: Currently this code gets rejected: const int[] a = [1]; void main() pure { auto y = a[0]; } test2.d(3,14): Error: pure function 'D main' cannot access mutable static data 'a' test2.d(3,14): Error: pure function 'D main' cannot access mutable static data 'a' But is this a good idea? Isn't it better to accept it? Bye, bearophile Aren't pure functions supposed to return the same result every time? If yes, it is correct to not accept it.
Re: and/or/not/xor operators
On Thursday, 30 May 2013 at 16:48:33 UTC, bearophile wrote: Shriramana Sharma: Hello. I have always loved the readability of C++'s and/or/not/xor word-like logical operators but It doesn't seem to be available in D. and/or/not are less visually noisy, they look better than the ugly &&/||/! of C/C++/D, and it's much less easy to write & when you need && or vice versa, so they are also less bug-prone, as Python shows. On this Python syntax got it better than D. But Walter refused them time ago on the basis that no one uses them in C++. So you can ask for them in the main D newsgroup, but I don't think you will see them in D... Bye, bearophile They are more noisy for non-English talking persons.
Re: Deallocate array?
On Tuesday, 7 May 2013 at 23:09:29 UTC, Matic Kukovec wrote: Hi I'm running Windows Vista 64 with dmd 2.062. I have a simple program: import std.stdio, core.memory, std.cstream; void main() { string[] temp_array; for(int i=0;i<500;i++) { ++temp_array.length; temp_array[temp_array.length - 1] = "a"; } temp_array = null; GC.collect(); writeln("end"); din.getc(); } When the program waits at "din.getc();", memory usage in the Task Manager is 150MB. Why isn't the memory deallocating? P.S.; I tried temp_array.clear() and destroy(temp_array), but nothing changed. I guess the memory isn't freed because there is no need to do so. A garbage collector kicks in when there is not enough memory. In this case there is no need to.
Re: immutable string
On Saturday, 27 April 2013 at 18:14:11 UTC, Michael wrote: According to http://dlang.org/const3.html The simplest immutable declarations use it as a storage class. It can be used to declare manifest constants. So, immutable string s = "..."; should be a manifest constant. If it is a constant that it can be used in switch(...). switch(someStr) { case s: ...; // Error: case must be a string or an integral constant, not s. }, but string s = "..."; works good. Why? Because maybe string is already (immutable)char[]?
Re: Direlect3 with Mono-D
If you aren't comfortable with either C++ or D I would suggest to do the tutorials with C++, as there are no OpenGL tutorials for D. Don't try to learn two things at the same time.
Re: Direlect3 with Mono-D
On Saturday, 20 April 2013 at 15:49:47 UTC, Dementor561 wrote: I have all the needed files to use Direlect3, and I have Mono-D installed on Xamarin, I was wondering how I could put it all together in a project. 1) Do you use windows or linux? 2) Have you built derelict3? 3) If you are using linux, have you moved the .d files to /usr/include and the .lib files to /usr/lib ?
Re: operator +=
On Monday, 8 April 2013 at 12:37:34 UTC, Simen Kjaeraas wrote: On 2013-04-08, 14:23, Minas Mina wrote: How can I define operator += for a struct? http://dlang.org/operatoroverloading.html In short: struct S { auto opOpAssign( string op : "+" )( S other ) { // Do stuff here. } } Thanks a lot.
operator +=
How can I define operator += for a struct?
Re: Question about auto ref
auto in? in ref?
Re: Question about auto ref
Why is "const ref" not a good choice?
Re: Segfault in "_d_dynamic_cast ()"
On Friday, 25 January 2013 at 16:19:15 UTC, Maxim Fomin wrote: On Friday, 25 January 2013 at 15:15:32 UTC, Minas Mina wrote: I found what the root of all evil was - The GC. After disabling it, the program runs fine. Perhaps you was working with C code, GC + legacy code sometimes lead to logical memory errors. However GC per se is unlikely to cause any errors (I remember Walter was telling that neither he nor anybody faced issues with GC). Also your code may still have errors but absence of GC hides them. I have written the same program in C++ -- and I get no seg-fault. Well I don't know for sure that something isn't wrong with my code, but I suspect it is the GC that is messing things up.
Re: Segfault in "_d_dynamic_cast ()"
Maybe. I am re-writing the code in C++ to see, and also to compare the performance.
Re: Segfault in "_d_dynamic_cast ()"
I found what the root of all evil was - The GC. After disabling it, the program runs fine.
Re: Segfault in "_d_dynamic_cast ()"
On Thursday, 24 January 2013 at 13:22:20 UTC, Maxim Fomin wrote: On Thursday, 24 January 2013 at 10:14:29 UTC, Minas Mina wrote: I am trying to create a BVH tree structure to speed up raytracing. So far it has been fine. I have created the BVH tree. It works for 202 triangles/spheres. Thanks. Requests for debugging help without source code are likely to be buried in archives silently. Perhaps you can look at _d_dynamic_cast source code (https://github.com/D-Programming-Language/druntime/blob/master/src/rt/cast_.d#L69) and figure out the exact statement which produces segfault. The code can be found here: https://github.com/minas1/D_Raytracing The code that creates the BVH tree is in bvh.d. The code that prints the tree is in main.d.
Segfault in "_d_dynamic_cast ()"
I am trying to create a BVH tree structure to speed up raytracing. So far it has been fine. I have created the BVH tree. It works for 202 triangles/spheres. However, when the scene has more spheres/triangles, I get a segmentation fault when the rays are traces, not when the tree is being built. To let you understand, there is a Surface class, from which "BVHNode", "Sphere" and "Triangle" inherit. I have written a small function that prints the BVH tree recursively. Here it is: void printBVH(Surface root, int i = 0, string str = "") { if( root is null ) return; writeln("--PRINT()--"); writeln("icy");//writeln(root.boundingBox()); writeln("name = ", root.name, " depth = ", i, " [", str, "]"); writeln("--~~~--\n"); if( (cast(BVHNode)root) !is null ) // OOPS! SEG FAULT HERE { printBVH((cast(BVHNode)(root)).left, i+1, "left"); printBVH((cast(BVHNode)(root)).right, i+1, "right"); } } And I pass to printBVH() the root node that the function that builds the tree has returned. // replaces every two Surfaces with one that is their parent. Proceeds until there is only one surface, which is the root. BVHNode createBVHTree2(Surface[] objects, ubyte axis = 0, int depth = 0) { import std.algorithm, std.stdio; BVHNode root; // sort left out for now until the seg fault is fixed //sort!("(a.boundingBox().min.x + a.boundingBox().max.x) * 0.5f < (b.boundingBox().min.x + b.boundingBox().max.x) * 0.5f", SwapStrategy.unstable)(objects); while( objects.length > 1 ) { writeln("--- Level ---"); foreach(o; objects) write("[", o.name, "] "); writeln(); auto temp = new Surface[objects.length/2 + 1]; auto sz = 0UL; for(auto i = 0UL; i < objects.length; i += 2) { writeln("i = ", i, " sz = ", sz+1); BVHNode parent = new BVHNode(); parent.name = "p"; parent.left = objects[i]; if( i + 1 < objects.length ) { parent.right = objects[i+1]; auto box1 = objects[i].boundingBox(), box2 = objects[i+1].boundingBox(); parent.box = combine(box1, box2); } else { parent.right = null; parent.box = objects[i].boundingBox(); } temp[sz++] = parent; } temp.length = sz; objects = temp; } root = cast(BVHNode)objects[0]; return root; } Ok, so when I print the scene using printBVH(), I get a segfault in the line: if( (cast(BVHNode)root) !is null ) GDB says: Program received signal SIGSEGV, Segmentation fault. 0x004b55fc in _d_dynamic_cast () Note that I have written the createBVHTree() and printBVH() functions in Java to see if it would be different. The code works in Java. I guess something is wrong with the compiler here and the way it handles recursion(?) -- By the way the code seg faults at the 11 depth level. Are there any know bugs for this? Thanks.
Re: tiny std.datetime question
On Wednesday, 16 January 2013 at 14:15:46 UTC, n00b wrote: Nevermind, found it myself. SysTime* sys = new SysTime(standardTime, UTC()); sys.hour; Le 16/01/2013 08:07, n00b a écrit : Hello, I'm kinda ashamed to ask that here, but std.datetime documentation is so complex... I only want to get hour/minute from a t_time (no timezone). I'm moving to D2, the equivalent code in D1 was: std.date.Date date; date.parse(std.date.toUTCString(time)); date.hour; This is a better way, that doesn't allocate memory: auto clock = Clock.currTime(); writeln(clock.hour); :)
Re: structs are now lvalues - what is with "auto ref"?
So when it will be fixed I will be able to write: void foo(auto ref Vector3 v); and it will pass copies or references depending on the situation?
Re: structs are now lvalues - what is with "auto ref"?
On Friday, 28 December 2012 at 12:47:03 UTC, Namespace wrote: On Friday, 28 December 2012 at 12:28:01 UTC, bearophile wrote: Namespace: How likely is it that "auto ref" will implemented in this release? Walter wants to release 2.061 "soon". So maybe that's for the successive (unstable?) version of the compiler. Bye, bearophile As long as it is implemented soon, I'm so satisfied. But an official statement that it will be implemented soon, would be nice. This feature is really very important and useful. +1
Re: structs are now lvalues - what is with "auto ref"?
On Sunday, 23 December 2012 at 23:59:55 UTC, Jonathan M Davis wrote: On Monday, December 24, 2012 00:48:01 Namespace wrote: but Andrei is dead set against - Jonathan M Davis Why?
Re: Passing rvalues to functions expecting const ref
On Sunday, 23 December 2012 at 20:40:09 UTC, Namespace wrote: Minas Mina: Show me the whole code, I think that your opBinary functions returns rvalues. This would be a good and important case for "auto ref". But until now it is only for template paramters... struct Vector3 { float x, y, z; this(float _x, float _y, float _z) { x = _x; y = _y; z = _z; } // negate operator Vector3 opUnary(string s)() const if( s == "-" ) { Vector3 temp = this; temp.x = -temp.x; temp.y = -temp.y; temp.z = -temp.z; return temp; } // + operator for completeness Vector3 opUnary(string s)() const if( s == "+" ) { return this; } // binary operators Vector3 opBinary(string op) (float val) const { static if( op == "+" ) { Vector3 temp = this; temp.x += val; temp.y += val; temp.z += val; } else static if( op == "-" ) { Vector3 temp = this; temp.x -= val; temp.y -= val; temp.z -= val; } else static if( op == "*" ) { Vector3 temp = this; temp.x *= val; temp.y *= val; temp.z *= val; } else static if( op == "/" ) { Vector3 temp = this; temp.x /= val; temp.y /= val; temp.z /= val; } return temp; } Vector3 opBinary(string op) (Vector3 v) const { static if( op == "+" ) { Vector3 temp = this; temp.x += v.x; temp.y += v.y; temp.z += v.z; } static if( op == "-" ) { Vector3 temp = this; temp.x -= v.x; temp.y -= v.y; temp.z -= v.z; } static if( op == "*" ) { Vector3 temp = this; temp.x *= v.x; temp.y *= v.y; temp.z *= v.z; } return temp; } } /// dot product of two Vector3 vectors @safe pure float dot(Vector3 u, Vector3 v) { return u.x * v.x + u.y * v.y + u.z * v.z; } dot is making copies now because what I have shown earlier does not work... It's what I'm using now.
Re: Passing rvalues to functions expecting const ref
On Sunday, 23 December 2012 at 12:08:47 UTC, Namespace wrote: As long as you use structs this should work, as you can see here: http://dpaste.dzfl.pl/03adf3d1 But if you use classes, it does not work anymore. So I like it a lot, that it works with structs. :) Thank you. I had forgotten to supply the constructor to the struct :/
Re: Static compiling with dmd
On Wednesday, 12 December 2012 at 14:28:48 UTC, Zardoz wrote: How I can compile with static linking with dmd ? I try with dmd -L-static but i get this error : /usr/bin/ld: cannot find -lgcc_s I used before gdc with -static options and owrked well on it, but I need to use now dmd. Try using -L-lyourlib
Re: Check for ctfe
Why is it "if( __ctfe )" and not static if.. ?
types of ranges
Is there n article that explains the different types of Ranges? (InputRange, ForwardRange, etc) and their usage?
struct with @disable(d) default constructor doesn't work with arrays?
I have this struct: struct S { int[] t; @disable this(); this(int sz) { t = new int[sz]; t[] = 1; } S opCall(int sz) { S s = S(sz); return s; } this(this) { t = t.dup; } } Naturally, this doesn't work: S s; // compiler error However this does compile. S[100] s; S[100] s; writeln(s[0].t[0]); // range violation error! I think it's a bug, what do you think?
Re: stdlib.exit()
On Sunday, 19 August 2012 at 23:48:01 UTC, Minas Mina wrote: That's what I do: import std.c.stdlib; void main(string[] args) { if( args.length == 1 ) { writeln("Some arguments, please!"); exit(-1); } } Sorry, forgot to import std.stdio.
Re: stdlib.exit()
That's what I do: import std.c.stdlib; void main(string[] args) { if( args.length == 1 ) { writeln("Some arguments, please!"); exit(-1); } }
Re: Link .s file with dmd?
On Monday, 13 August 2012 at 22:06:08 UTC, Namespace wrote: Can i link an assembler file .s with dmd like gcc with "gcc out.s any.c -o out.exe"? If so, how? .s, .c, .d files (source files), are not linked. What is linked, are object files (.obj or .o). GCC either compiles the .s file to an object file, or passes it to assembler to do it - I don't know. I think what you need to is to create an object file from the .s file and link it to your D executable. To do it: gcc out.s -c The -c switch stops after compiling. It doesn't do the linking. A .o file will be created, out.o Then dmd your_source_file.d out.o
Re: Function that calculates in compile time when it can
On Monday, 6 August 2012 at 15:56:52 UTC, Namespace wrote: Take a look into std.math: https://github.com/D-Programming-Language/phobos/blob/master/std/math.d I found this: real sin(real x) @safe pure nothrow; /* intrinsic */ And these: creal sin(creal z) @safe pure nothrow { creal cs = expi(z.re); creal csh = coshisinh(z.im); return cs.im * csh.re + cs.re * csh.im * 1i; } /** ditto */ ireal sin(ireal y) @safe pure nothrow { return cosh(y.im)*1i; } I don't see anything about ctfe. Maybe I didn't understand well and sin is not evaluated at compile time. Can someone clarify this?
Re: Function that calculates in compile time when it can
On Monday, 6 August 2012 at 15:21:38 UTC, Philippe Sigaud wrote: On Mon, Aug 6, 2012 at 3:54 PM, Minas Mina wrote: Something like this: template fib(ulong n) { static if( n < 2 ) const fib = n; else const fib = fib!(n-1) + fib!(n-2); if( n < 2) return n; return fib(n-1) + fib(n-2); } It doesn't work of course, as I am in a template and trying to "return" something. CTFE? Is that "compile time function evaluation"? If yes, it's really slow... If I try: static x = fib(40); // fib is a normal function it takes forever and makes my pc run really slowly. Well, you're using the worst possible algorithm to calculate Fibonacci (exponential time), so it's no wonder it's taking foverer :) Then, you've to know that CT calculation is far slower than runtime calculation. My experience on this is about an order of magnitude slower, and even more. On the machine I'm currently on, fib(30) is calculated instantaneously at runtime, but it takes 4-6s at CT. Fib(40) aloready takes 4-6 s at runtime, so I won't test at CT :) To come back to your question. __ctfe should be used with a standard (non-static) if. Here I implement to Fibonacci algos, one linear in n at CT, one exponential ar RT. That's just to show that a good algo at CT can run circles around a bad algo at RT. At compile-time, getting fib(100) is instantaneous, while getting only fib(40) at RT takes a few seconds on my machine. import std.conv: to; import std.stdio; long fib(size_t n) { if(__ctfe) // compile-time, linear, sustained development { long[] temp = new long[](n+1); // dynamic array during CTFE, D rox temp[0] = 1; temp[1] = 1; size_t p = 1; while (p < n) { ++p; temp[p] = temp[p-1]+temp[p-2]; } return -temp[p]; // '-' as an indication that this indeed took place at CT } else // runtime, exponential, woohoo baby! { if (n == 0 || n == 1) return 1; else return fib(n-1)+fib(n-2); } } void main() { enum f1 = fib(100); // CT pragma(msg, "At CT, fib(100) = " ~to!string(f1)); // will be < 0 as a flag auto f2 = fib(40); // RT writeln("At RT, fib(40) = ", f2); } Don't try fib(100) at runtime! Thank you for your reply! Haha, yeah, I knew I was using the worst possible algorithm. It was just for testing... I'm never going to use ctfe with algorithms of that complexity again! Ok, so I can use if(__ctfe) to define different behaviour(or not) at compile time than at runtime. The way I want to use it, however, I don't have to: import std.stdio; void main() { ulong f1 = fibonacci(50); // calculated at runtime static f2 = fibonacci(50); // calculated at compile time writeln(f); } // calcuated at O(1) woohoo! ulong fibonacci(ulong n) { import std.math; double r0 = (1 + sqrt(5.0)) / 2.0, r1 = (1 - sqrt(5.0)) / 2.0, a = 1.0 / sqrt(5.0), b = -1.0 / sqrt(5.0); // fn = a*r0 + b*r1 return cast(ulong)(a * pow(r0, cast(double)n) + b * pow(r1, cast(double)n)); } What I was really looking for was to do something like the way std.math.sin works. I read somewhere that if the argument is available at compile time, it evaluates the result at compile time. So, if I do: double f = sin(0.5); // calculated at compile time or not? If it is calculated at compile time, how do I do it for my own functions? If not, I guess the only way is to use static or enum like you guys showed me.
Re: Function that calculates in compile time when it can
On Monday, 6 August 2012 at 15:21:38 UTC, Philippe Sigaud wrote: On Mon, Aug 6, 2012 at 3:54 PM, Minas Mina wrote: Something like this: template fib(ulong n) { static if( n < 2 ) const fib = n; else const fib = fib!(n-1) + fib!(n-2); if( n < 2) return n; return fib(n-1) + fib(n-2); } It doesn't work of course, as I am in a template and trying to "return" something. CTFE? Is that "compile time function evaluation"? If yes, it's really slow... If I try: static x = fib(40); // fib is a normal function it takes forever and makes my pc run really slowly. Well, you're using the worst possible algorithm to calculate Fibonacci (exponential time), so it's no wonder it's taking foverer :) Then, you've to know that CT calculation is far slower than runtime calculation. My experience on this is about an order of magnitude slower, and even more. On the machine I'm currently on, fib(30) is calculated instantaneously at runtime, but it takes 4-6s at CT. Fib(40) aloready takes 4-6 s at runtime, so I won't test at CT :) To come back to your question. __ctfe should be used with a standard (non-static) if. Here I implement to Fibonacci algos, one linear in n at CT, one exponential ar RT. That's just to show that a good algo at CT can run circles around a bad algo at RT. At compile-time, getting fib(100) is instantaneous, while getting only fib(40) at RT takes a few seconds on my machine. import std.conv: to; import std.stdio; long fib(size_t n) { if(__ctfe) // compile-time, linear, sustained development { long[] temp = new long[](n+1); // dynamic array during CTFE, D rox temp[0] = 1; temp[1] = 1; size_t p = 1; while (p < n) { ++p; temp[p] = temp[p-1]+temp[p-2]; } return -temp[p]; // '-' as an indication that this indeed took place at CT } else // runtime, exponential, woohoo baby! { if (n == 0 || n == 1) return 1; else return fib(n-1)+fib(n-2); } } void main() { enum f1 = fib(100); // CT pragma(msg, "At CT, fib(100) = " ~to!string(f1)); // will be < 0 as a flag auto f2 = fib(40); // RT writeln("At RT, fib(40) = ", f2); } Don't try fib(100) at runtime! Thank you for your reply! Haha, yeah, I knew I was using the worst possible algorithm. I
Re: Function that calculates in compile time when it can
On Monday, 6 August 2012 at 14:25:29 UTC, Eyyub wrote: On Monday, 6 August 2012 at 13:46:14 UTC, Tobias Pankrath wrote: You can check for compile time with static if(__ctfe) No, you can't. __ctfe is a "CTFE-ed"(?) value. But you can do something like that : http://dpaste.dzfl.pl/e3f26239 Minas : I don't know if your PC is outdated, but it's weird. :/ It's Ubuntu 12.04 running on an Intel i5. That's what I tried to calculate: static x = fib(40); ulong fib(ulong n) { if(n < 2) return n; else return fib(n-1) + fib(n-2); } Maybe because it has a lot of recursion?
Re: Function that calculates in compile time when it can
Something like this: template fib(ulong n) { static if( n < 2 ) const fib = n; else const fib = fib!(n-1) + fib!(n-2); if( n < 2) return n; return fib(n-1) + fib(n-2); } It doesn't work of course, as I am in a template and trying to "return" something. CTFE? Is that "compile time function evaluation"? If yes, it's really slow... If I try: static x = fib(40); // fib is a normal function it takes forever and makes my pc run really slowly.
Re: Error while trying to allocate memory (malloc)
Maybe you need a cast before malloc to convert it to a "s_blockInfo*"?
Function that calculates in compile time when it can
I want to write a fibonacci(n) function that calculates the result. a) if n is known at compile time, use a template b) if not, use a normal function I know how to write a template version: template fib(ulong n) { static if( n < 2 ) const fib = n; else const fib = fib!(n-1) + fib!(n-2); } But how can I 'know' if n is known at compile time to make it use the other version? (which I won't post 'cause it is fairly easy).
Re: How to define a constructor in a struct?
On Sunday, 5 August 2012 at 16:42:16 UTC, Adam D. Ruppe wrote: On Sunday, 5 August 2012 at 16:30:48 UTC, Minas Mina wrote: Thank you. Is it the way it is to have compatibility with C structs? I'm not sure... I think so in part, but I think another part of it is to make sure that struct constructors can't bring a hidden cost to generic code. I see. Thank you a lot for your help!
Re: How to define a constructor in a struct?
Thank you. Is it the way it is to have compatibility with C structs?
How to define a constructor in a struct?
I want to make a struct that defines a constructor: struct Point { this() { } } However I get a compiler error: "constructor main.Point.this default constructor for structs only allowed with @disable and no body" I wrote a @disable next to it but same error. I don't understand what the "no body" part means.
Re: Is "delete" really going away?
Thanks for the answers. So clear() or destroy() in 2.060 be used to call the destructor, but the actual memory of the object won't be freed, right? Is this is true, why wasn't "delete" changed to behave like destroy()?
Is "delete" really going away?
I think having the delete keyword for classes was a very good thing, altough I don't know the problems it has for the GC and probably other things. Consider this scenario: class Base { // ... } class Derived : Base { // ... FILE *f; this() { f = fopen(...); } ~this() { fclose(f); } } void main() { Base *b = new Derived(); delete b; // call the copy constructor b = // something else... } Having a destructor and that you know when is going to be called is VERY useful! So by removing the "delete" keyword, what happens? We won't have a way to destroy objects in a predictable way anymore? (I'm not talking about structs in any way). Thanks
Implementing a Monitor
I'm using condition variables to implement a monitor that simulates the producer-consumer(unbounded buffer) scenario. Note: monitor is __gshared and is initialized in main(). Then the other threads are created and run. There is one producer thread, and 5 consumer threads. void producer() { while( 1 ) { monitor.produce(); } } void consumer() { while( 1 ) { monitor.consume(); } } class Monitor { Cond cond; char[] buffer; ulong sz; this() { // necessary: The condition variable constructor requires a mutex passed to it cond = new Cond(new Mutex()); } void produce() { // produce a letter a-z char c = 'a' + rand() % 26; writeln("* Producer: Produced a '", c, "' buffer.length = ", buffer.length, "\n"); // put it into the buffer ++buffer.length; buffer[buffer.length - 1] = c; //if( buffer.length > 1 ) notify(cond); // calls condition.notify() //Thread.sleep(dur!"msecs"(1000)); } void consume() { if( buffer.length == 0 ) { writeln("put to sleep"); cwait(cond); // calls Condition.wait() } // take char c = buffer[buffer.length-1]; --buffer.length; writeln("# Consumer has taken a '", c, "' buffer = [", buffer, "] (", buffer.length, " elements)\n"); } } The output is something like: put to sleep put to sleep put to sleep put to sleep * Producer: Produced a 'n' buffer.length = 0 put to sleep * Producer: Produced a 'w' buffer.length = 1 * Producer: Produced a 'l' buffer.length = 2 * Producer: Produced a 'r' buffer.length = 3 * Producer: Produced a 'b' buffer.length = 4 * Producer: Produced a 'b' buffer.length = 5 * Producer: Produced a 'm' buffer.length = 6 * Producer: Produced a 'q' buffer.length = 7 ... Even though the producer calls notify() when he finishes, none of the consumer threads is ever resumed... (I ran the program for a while and redirected output to a file. Then I searched for "#" that the consumer prints but nothing). Why is that happening? Is there something wrong with Condition.notify()? Also, is there a function that I can call to immediatly suspend the running thread? Thanks
profiling with -profile
I have this code: import std.stdio; void main() { f(); g(); } void f() { writeln("f()"); } void g() { writeln("g()"); } I compile with the command: dmd test.d -profile Then I execute it. It prints: f() g() as expected. Shouldn't it print profiling information as well?
Re: profiling with -profile
Sorry, I just saw the generated file... :p
Re: deimos libX11 undefined reference
Try -L-lX11
Re: Creating a shared reference type
On Saturday, 14 July 2012 at 09:21:27 UTC, David Nadlinger wrote: On Saturday, 14 July 2012 at 09:15:55 UTC, Minas Mina wrote: Isn't this the way shared is used (or should be used)? Should be used: probably yes. But functions/methods which are able to act on shared data must be marked so, and unfortunately, the druntime primitives are not yet annotated with shared, so you need to manually cast shared() away first (or just use __gshared instead of shared). David Thank you, __gshared was actually what I was looking for!
Re: Creating a shared reference type
Thanks, I've got another problem: void f() { sema.wait(); ++x; sema.notify(); } sema is the global shared Semaphore (as above) main.d(29): Error: function core.sync.semaphore.Semaphore.wait () is not callable using argument types () shared main.d(29): Error: expected 1 function arguments, not 0 main.d(33): Error: function core.sync.semaphore.Semaphore.notify () is not callable using argument types () shared Why isn't it working as I am expecting it to? Isn't this the way shared is used (or should be used)?
Creating a shared reference type
I'm want to "play" a bit with thread syncronization... So this is a (big) part of my code. The other is the imports, the thread starting and the printing of x. shared int x; shared Semaphore sema; void main(string[] args) { auto t1 = new Thread(&f); auto t2 = new Thread(&g); sema = new Semaphore(1); // error here The error is: Error: cannot implicitly convert expression (new Semaphore(1u)) of type core.sync.semaphore.Semaphore to shared(Semaphore) I understand what the error means, I just don't know how to fix it (to make it explicit). I tried new shared (Semaphore(1)) but doesn't work.
Re: Immutable array initialization in shared static this
I guess it's because you have an array of constants (immutables). The array is not immutable though. I could be wrong, I'm not an expert or D syntax :)
Re: immutability and constness
On Thursday, 12 July 2012 at 14:42:17 UTC, Ali Çehreli wrote: On 07/12/2012 07:13 AM, Minas wrote: Thanks a lot! So what is the problem with (logical)const? Is it needed that much? And why some methods (toString(), toHash()) HAVE to be const? I mean, what's the problem if they aren't? Here is the problem: (That is why I almost never make abstract member functions 'const' in my C++ coding. Base can't know mutability needs of the derived.) Ali I see. Just because toString() in object is const, so must be in the derived classes thus limiting them. So now I understand the solution that Andrei is considering (removing those from object). I think this is a good thing to do, those functions don't belong there (I have had some experience with Java's equals(Object o). All I say is that it sucks.) In C++, I would use a templated function. If the type didn't provide those methods it would be a compile error. Nice and clean :) Thanks for the reply :)
immutability and constness
I'm fairly new to D, but I have been using C++ for a while now (about 5 years, selftaught). From what I have learned, const in C++ is inconsistent. For example: int main() { const int x = 0; // could be placed in ROM because it's known at compile time } void f(int x) { const int y = x * x; // logical const // blah blah blah } const can be also cast away (const_cast if I remember correctly - I wasn't doing it often :) ) and mess everything. From what I understand, immutable in D is truly immutable. But I have seen some code here on the forum that casts aways immutability... (Is that even defined behaviour? What if that thing was in ROM?) D has const as well... This is were it becomes a bit tricky for me. To be honest, I haven't got the book about D - it should(does it?) have information about that. Can someone explain what are D's goal about immutable, const - and why it is bitwise const and not logical? How does it benefit programs? I have read something about that in the "general discussions" forum but posted the question here because it's for me (and others) to learn about that. Thanks.
Re: Concurrency in D
On Wednesday, 27 June 2012 at 23:50:17 UTC, Ali Çehreli wrote: On 06/27/2012 04:05 PM, Adam Burton wrote: >> For example I would like to >> have a thread calculate the sum of the first half of an array >> while another thread would calculate the other half, and I could >> add the two results at the end. > For this task there is another concurrency module called std.parallelism > that is designed for this type of thing (afaik). > http://dlang.org/phobos/std_parallelism.html TDPL predates std.parallelism, so it's not in the book. Although the module's documentation is straightforward, I have the following page which may be more accessible for some: http://ddili.org/ders/d.en/parallelism.html Clicking [Next] on that pages goes to Message Passing Concurrency: http://ddili.org/ders/d.en/concurrency.html Ali P.S. Both of those pages are incomplete in some ways, which I will address soon. Much better than the library reference :)
Re: Concurrency in D
You all helped, thank you :) I will read the concurrency part tomorrow!
Concurrency in D
I have been "playing" latetly with std.concurrency and core.thread. I like both, but they are entirely different approaches to concurrency. std.concurrency: Uses message passing. Does not allow passing of mutable types. core.thread: Essentially the same as the approach taken by Java. 1) Is one favoured over the other? I guess std.concurrency would be, because it uses messages (and I recently read somewhere that immutability + message passing = good thing). Well, my problem about is, how can send mutable data to another thread? _Can_ I do it? If not, how am I supposed to share data between them? Not everything can be immutable right? For example I would like to have a thread calculate the sum of the first half of an array while another thread would calculate the other half, and I could add the two results at the end. 2) What about core.thread? To do proper sync between threads in core.thread, semaphore, mutexes and stuff like that are needed. Are those "good practice" in D? 3) I have also read a bit about syncronized classes and shared classes/structs, altough I didn't understand it too much (well I didn't try too much to be honest). For all those appoaches, which is the preffered? For all those appoaches, which is the preffered for game programming? Thank you.
Re: Removing from SList (std.container)...
Doesn't Andrei plan to do something about this module?
Re: Removing from SList (std.container)...
Thank you for your reply. Yes, std.container really sucks. Anyway, I made my program using C++ and STL
Re: Removing from SList (std.container)...
On Wednesday, 27 June 2012 at 09:52:14 UTC, Tobias Pankrath wrote: On Wednesday, 27 June 2012 at 09:37:01 UTC, Minas Mina wrote: How can I do that? Why not list.remove(x); like in STL? std.container encodes the complexity of operations in the method names. There is no way to remove a range in constant time in SList, so you only get linearRemove. And you always need a range to remove something. Can you show me an example or removing a number?
Removing from SList (std.container)...
How can I do that? Why not list.remove(x); like in STL?
Re: Strange exception using threads
Thank you very much :) I like the "you are done :)" approach!
Re: Writing .di files
I'm sorry, what I meant was "how to interface to C code". Sorry for writing it in a bad way. Do I just declare the C code as extern and then link together with the C .lib/.o/.so file? (I'm in Ubuntu) What about the stuff that is in header files?