Re: implicit conversions to/from shared
On Sunday, 10 July 2016 at 13:02:17 UTC, ag0aep6g wrote: While messing with atomicLoad [1], I noticed that dmd lets me implicitly convert values to/from shared without restrictions. It's in the spec [2]. This seems bad to me. [...] Atomic loading and storing, from what I understand, is usually limited to about a word on most architectures. I don't think it would be good to implicitly define assignment and referencing as atomic operations, since it would be limited. IMO concurrent access is better off being explicit anyway. I don't think there is an issue with converting unshared reference types to shared (ex. ref T -> ref shared(T) or T* -> shared(T)*); worst you get is some extra synchronization.
Re: Endiannes & Splitting Values
On Wednesday, 6 July 2016 at 21:44:37 UTC, BitGuy wrote: I'm trying to implement a feistel cipher that'll give the same results regardless of the endianness of the machine it runs on. To make the cipher I need to split a 64bit value into two 32bit values, mess with them, and then put them back together. I can think of a few ways to split a 64bit value with versions or the endianness functions in bitmanip but it all seems pretty messy for just wanting to split a value... I'm thinking maybe I can just cast and bitshift so I can forget about the endianness but I'm not really sure about the casting down rules and if that'd work? Bitshifts and binary operators work the same regardless of endianness. Just shift by 32/mask with 0x and cast. It's only if you are accessing a value as a byte array that you have to worry about endianness.
Re: Dynamic array of objects
On Monday, 27 June 2016 at 22:00:15 UTC, gummybears wrote: Hi, Today thought lets learn D. I am writing a compiler for a language and read D compiles very fast. Switched my compiler from C++ to D and ran my test suite to use D. Doing somethin wrong as creating array of objects gives me a segmentation fault Example import std.stdio; class Pair { float x; float y; this() { x = 0; y = 0; } } void main() { Pair[] arr; // segmentation fault on next line arr = new Pair[](10); arr[0].x = 3; arr[0].y = 4; writef("arr[0] = (%f,%f)",arr[0].x,arr[0].y); } You've allocated an array of 10 objects but didn't put any objects into it, so each of the entries is null (since classes are reference types in D). The line after the allocation fails as you try to access a null object. Either fill out the array with new objects (`arr[0] = new Pair()`), or convert Pair to a struct (structs are value types).
Re: arsd png bug
On Monday, 20 June 2016 at 21:39:45 UTC, Joerg Joergonson wrote: 1810: case 3: auto arr = data.dup; foreach(i; 0 .. arr.length) { auto prev = i < bpp ? 0 : arr[i - bpp]; if (i >= previousLine.length) break; arr[i] += cast(ubyte) /*std.math.floor*/( cast(int) (prev + previousLine[i]) / 2); } adding if (i >= previousLine.length) break; prevents some crashes and seems to work. You'd probably get better results by filing an issue with the project's bug tracker [1]. Also by including a sample image that causes the crash. [1]: https://github.com/adamdruppe/arsd/issues
Re: Strange Issues regarding aliases
On Tuesday, 14 June 2016 at 17:37:40 UTC, Joerg Joergonson wrote: On Tuesday, 14 June 2016 at 17:34:42 UTC, Joerg Joergonson wrote: This is how derelict does it, I simply moved them in to the class for simplicity. I mean glad: http://glad.dav1d.de/ It seems that a loader is required for some reason and that possibly could be one or both of the problems. You absolutely need a loader to load most opengl functions. They are not usually exposed in the shared object, as gl function pointers are tied to a specific opengl context. You are trying to call function pointer types, which is invalid. You need to declare some variable with the type, load the function pointer into the variable (platform specific; there are plenty of tutorials on how to do this in C), and call that variable. (Also I disagree that separating the opengl API based on what the symbol is is a step up from the "ancient and backwards flat access" way. Functions are, by neccessity, coupled to the types and enums they take. A better categorization would be based on version introduced or extension, iirc jogl does that)
Re: Fibers, what for?
On Sunday, 12 June 2016 at 08:38:03 UTC, chmike wrote: Fibers don't need synchronization to access shared data. This removes the overhead of synchronization and simplifies "multitheaded" programming greatly. This is misleading. Any sort of cooperative system needs synchronization when two or more tasks try to access the same data, whether those "tasks" are OS threads, fibers, different machines on a network, etc. Fibers do make it easier, as no task can run in parallel with the current one and switching tasks is done explicitly via yield, effectively giving the current fiber exclusive access to the entire program state in between yields. But if you need to hold onto a resource across a yield, you will need the usual set of concurrency primitives, like locks. (A practical example: making a commit using the Node.js libgit bindings involves several asynchronous steps, during which other tasks may access it. If you don't want anyone else messing with the Git repo while you are making a commit, you must protect the repo with a lock.) Also note that Vibe.d, the largest fiber-based framework D has to offer, is capable of running several coroutines in parallel on multiple threads, meaning you must use the same level of synchronization as if you were using threads.
Re: Why can't I assign a mixin to an alias?
On Saturday, 11 June 2016 at 02:46:00 UTC, Adam D. Ruppe wrote: On Saturday, 11 June 2016 at 02:33:46 UTC, Alex Parrill wrote: Mixins are statements. No, they're not. Well, yes they are [1], but there are also mixin expressions [2]. Not to be confused with the TemplateMixin[3], which is indeed always a statement. 1: http://dlang.org/spec/grammar.html#MixinExpression 2: http://dlang.org/spec/grammar.html#MixinStatement 3: http://dlang.org/spec/grammar.html#TemplateMixin Huh, every time I've used mixins, I've always run into the issue in the OP, so I assumed they were statements. It definitely seems like a bug then.
Re: Why can't I assign a mixin to an alias?
On Friday, 10 June 2016 at 22:38:29 UTC, Dechcaudron wrote: I have the following code: private string getVariableSignalWrappersName(VarType)() { return VarType.stringof ~ "SignalWrappers"; } void addVariableListener(VarType)(int variableIndex, void delegate(int, VarType)) { alias typeSignalWrappers = mixin(getVariableSignalWrappersName!VarType); } On compilation, the following error is issued: Error: basic type expected, not mixin Why should it be like that? I believe the compiler should not impose restrictions on what mixins can or cannot do :/ Mixins are statements. They cannot be a part of an expression. The other two posts have demonstrated how to get around this.
Re: Parse File at compile time, but not embedded
On Thursday, 9 June 2016 at 22:02:44 UTC, Joerg Joergonson wrote: On Tuesday, 7 June 2016 at 22:09:58 UTC, Alex Parrill wrote: Accessing a SQL server at compile time seems like a huge abuse of CTFE (and I'm pretty sure it's impossible at the moment). Why do I need to install and set up a MySQL database in order to build your software? Lol, who says you have access to my software? You know, the problem with assumptions is that they generally make no sense when you actually think about them. By "I" I meant "someone new coming into the project", such as a new hire or someone that will be maintaining your program while you work on other things. In any case, this is impossible. D has no such concept as "compile-time-only" values, so any usage of a value risks embedding it into the binary.
Re: I implemented delegates in D
On Thursday, 9 June 2016 at 21:02:26 UTC, maik klein wrote: Has this been done before? Well, yes, the entire point of delegates is to be able to capture variables (as opposed to function pointers, which cannot). auto createADelegate(int captured) { return (int a) => captured + a; } void main() { auto dg1 = createADelegate(5); auto dg2 = createADelegate(32); assert(dg1(5) == 10); assert(dg1(10) == 15); assert(dg2(8) == 40); assert(dg2(32) == 64); } https://dpaste.dzfl.pl/90ebc29651f6 (Unfortunately template delegates, like the ones used with map, don't keep their captured variables alive after the captured variables go out of scope, but it doesn't sound like you need those)
Re: Parse File at compile time, but not embedded
On Monday, 6 June 2016 at 21:57:20 UTC, Pie? wrote: On Monday, 6 June 2016 at 21:31:32 UTC, Alex Parrill wrote: But reading sensitive data at compile-time strikes me as dangerous, depending on your use case. If you are reading sensitive information at compile time, you are presumably going to include that information in your binary (otherwise why would you read it?), and your binary is not secure. Not necessarily, You chased that rabbit quite far! The data your reading could contain sensitive information only used at compile time and not meant to embed. For example, the file could contain login and password to an SQL database that you then connect, at compile time and retrieve that information the disregard the password(it is not needed at run time). Accessing a SQL server at compile time seems like a huge abuse of CTFE (and I'm pretty sure it's impossible at the moment). Why do I need to install and set up a MySQL database in order to build your software?
Re: Error: mutable method isolated.graphics.g3d.model.Model.begin is not callable using a const object
On Monday, 6 June 2016 at 21:55:00 UTC, ag0aep6g wrote: On 06/06/2016 11:25 PM, Alex Parrill wrote: You might be able to get away with casting the const away, if you are sure it won't modify the hash or equality check. Casting away const and then mutating has undefined behavior. The compiler is free to assume that it doesn't happen. Be aware that you're working outside of the specified language if you do it. You rely on the compiler producing code that works in your favor when it has no obligation to do so. I don't think we should ever suggest relying on undefined behavior here in D.learn. Yes, you are correct. I was mixing up C const rules with D. Unfortunately there does not seem to be an easy solution to this problem. The best solution might be to use an array of pairs instead of a hash table, but that may have a performance impact.
Re: Enum that can be 0 or null
On Tuesday, 7 June 2016 at 04:31:56 UTC, ParticlePeter wrote: On Monday, 6 June 2016 at 20:32:23 UTC, Alex Parrill wrote: They'd be the same type, since you would define the vulkan functions to take these structures instead of pointer or integer types. It relies on a lot of assumptions about the ABI that make a raw pointer work the same as a structure containing just one pointer, which is why I did not give it much consideration. Is there a way to use opCast (just an idea, not working code) ? private struct VK_HANDLE_HELPER { const void * handle = null; alias handle this; T opCast(T)() if( is( T == uint64_t )) { return 0uL; } } const VK_NULL_HANDLE = VK_HANDLE_HELPER(); I don't think opCast gets called for implicit conversions; it only gets called for explicit casts. I'll test it later.
Re: Parse File at compile time, but not embedded
On Monday, 6 June 2016 at 17:31:52 UTC, Pie? wrote: Is it possible to parse a file at compile time without embedding it into the binary? I have a sort of "configuration" file that defines how to create some objects. I'd like to be able to read how to create them but not have that config file stick around in the binary. e.g., (simple contrived example follows) Config.txt x, my1 y, my1 z, my2 class my1 { } class my2 { } void parseConfig(A) { } void main() { parseConfig('Config.txt') // Effectively creates a mixin that mixes in auto x = new my1; auto y = new my1; auto z = new my2; } If parseConfig uses import('Config.txt') then config.txt will end up in the binary which I do not want. It would be easier to be able to use import and strip it out later if possible. Config.txt may contain secure information, which is why is doesn't belong in the binary. Most compilers, I believe, will not embed a string if it is not used anywhere at runtime. DMD might not though, I'm not sure. But reading sensitive data at compile-time strikes me as dangerous, depending on your use case. If you are reading sensitive information at compile time, you are presumably going to include that information in your binary (otherwise why would you read it?), and your binary is not secure.
Re: Error: mutable method isolated.graphics.g3d.model.Model.begin is not callable using a const object
On Monday, 6 June 2016 at 20:40:12 UTC, Begah wrote: I have a pretty weird error : Error: mutable method isolated.graphics.g3d.model.Model.begin is not callable using a const object [...] It may infer const from the type of `this.instance`, which may be further modified if the method you are running this in is `const`. If you explicitly specify the type of the foreach loop variables, does it work?
Re: Enum that can be 0 or null
On Monday, 6 June 2016 at 18:43:33 UTC, ParticlePeter wrote: On Saturday, 21 May 2016 at 06:36:53 UTC, tsbockman wrote: ... As an example, if VK_NULL_HANDLE only ever needs to be assigned to opaque types on the D side (that is, types that serve only as an ID or address for communicating with the C side), you could do this: private struct VkNullHandle { } enum VK_NULL_HANDLE = VkNullHandle.init; mixin template VkHandle(bool dispatchable) { static if (dispatchable || (size_t.sizeof == 8)) void* bits = null; else ulong bits = 0; this(typeof(this) that) { this.bits = that.bits; } this(VkNullHandle that) { this.bits = typeof(this.bits).init; } ref typeof(this) opAssign(typeof(this) that) { this.bits = that.bits; return this; } ref typeof(this) opAssign(VkNullHandle that) { this.bits = typeof(this.bits).init; return this; } } struct VkDevice { mixin VkHandle!true; } struct VkInstance { mixin VkHandle!true; } struct VkFence { mixin VkHandle!false; } struct VkSemaphore { mixin VkHandle!false; } void main() { VkInstance a = VK_NULL_HANDLE; VkFence b = VK_NULL_HANDLE; } (DPaste: https://dpaste.dzfl.pl/8f4ce39a907f ) The above is typesafe, and can easily be made compatible with a typical C API, since C does no parameter-related name mangling. In this case I don't see how it would be possible to use your VkDevice, etc. as argument to the C functions, as they are of different type, no? They'd be the same type, since you would define the vulkan functions to take these structures instead of pointer or integer types. It relies on a lot of assumptions about the ABI that make a raw pointer work the same as a structure containing just one pointer, which is why I did not give it much consideration.
Re: Emulate C's (polymorphic) NULL type
On Monday, 6 June 2016 at 18:33:36 UTC, ParticlePeter wrote: On Monday, 6 June 2016 at 16:19:02 UTC, Alex Parrill wrote: On Monday, 6 June 2016 at 09:43:23 UTC, ParticlePeter wrote: In C NULL can be used as integer as well as null pointer. Is there a way to create such a type in D? The type should have only one value which is obviously (0/null). A extern( C ) function should be able to take it as either one. Overloaded enum pops into my mind as example: enum NULL = 0; enum NULL = null; Is this possible somehow? I already asked about this: https://forum.dlang.org/post/bnkqevhyxwdjjxsct...@forum.dlang.org Tldr; doesn't seem to be possible without multiple alias this or using ABI hacks. O.k., my web search didn't find that topic. The last reply looks promising, wouldn't that work? That's the ABI hack I mentioned. It abuses the fact that on most hardware and compiled, a pointer and a structure containing a single pointer have the same binary representation. It will likely work, but it isn't guarenteed.
Re: Emulate C's (polymorphic) NULL type
On Monday, 6 June 2016 at 09:43:23 UTC, ParticlePeter wrote: In C NULL can be used as integer as well as null pointer. Is there a way to create such a type in D? The type should have only one value which is obviously (0/null). A extern( C ) function should be able to take it as either one. Overloaded enum pops into my mind as example: enum NULL = 0; enum NULL = null; Is this possible somehow? I already asked about this: https://forum.dlang.org/post/bnkqevhyxwdjjxsct...@forum.dlang.org Tldr; doesn't seem to be possible without multiple alias this or using ABI hacks.
Re: Shared, but synchronisation is not desired for multithreading
On Saturday, 4 June 2016 at 15:11:51 UTC, tcak wrote: If you ignore the discouraged __gshared keyword, to be able to share a variable between threads, you need to be using "shared" keyword. While designing your class with "shared" methods, the compiler directly assumes that objects of this class must be protected against threading problems. There can be three USAGEs of a class object: 1. It will be non-shared. So, it is stored in TLS, and only one thread can access it. 2. It will be shared. But programmer knows that the object is designed as "shared" with the purpose of reading its value from multiple threads. 3. It will be shared. But the object must be synchronised. Because programmer knows that multiple threads will be reading from and writing to object. Currently, in a normal coding environment (I am not talking about using extra parameters, increasing complexity etc), distinguishing between 2 and 3 does not seem like possible. You prepare your shared class, and its methods are designed to be either sycnhronised or not synchronised. There is no middle point unless you define the same method with different names, or use a flag like "bool run_this_method_synchronised_please". So, what I did is using UDA for this with the name @ThreadSafe. e.g. @ThreadSafe auto myObject = new shared MyClass(); In a method of the class, I make the declaration as following: public void foo() shared{ static if( std.traits.hasUDA!( this, ThreadSafe ) ){ // lock mutex scope(exit){ // unlock mutex } } // do your normal operations } This way, if the object is desired to be doing synchronisation, you only add an attribute to it. There are some small problems here, those are related to D's implementation right now: 1. There is no standard way of saying @ThreadSafe. You are supposed to be defining it. If language was to be defining a standard attribute as @ThreadSafe, it could be used everywhere for this purpose. 2. If a method is defined as shared, compiler immediately warns the programmer to use core.atomic.atomicOp. If codes are already being designed as thread-safe by the programmer, normal variable operations could be used without any concern. 3. As far as I remember, there were some talks about synchronized keyword not being used much. Maybe its usage could be changed to support this @ThreadSafe system. If the method is thread-safe, it should be marked as shared. Otherwise, it should not be shared. I think you're trying to mark functions that aren't actually thread safe but you call in a `synchronized` context as shared, when they should not be. If you've made guarantees that the shared object you are modifying can only be accessed by one thread, you can cast it to unshared, and call its thread-unsafe methods (which are now safe). I think there were plans to get `synchronized` to do this for you, but it doesn't, which makes it fairly unwieldy. (It also doesn't help that many "thread-safe" functions in D aren't marked as shared where they really ought to be, ex. all the functions in core.sync.mutex)
Re: Code security: "auto" / Reason for errors
On Wednesday, 1 June 2016 at 14:52:29 UTC, John Nixon wrote: On Wednesday, 2 March 2016 at 21:37:56 UTC, Steven Schveighoffer wrote: Pointer copying is inherent in D. Everything is done at the "head", deep copies are never implicit. This is a C-like language, so one must expect this kind of behavior and plan for it. I sympathise with Ozan. What is the best reference you know that explains this fully? Slices/dynamic arrays are literally just a pointer (arr.ptr) and a length (arr.length). Assigning a slice simply copies the ptr and length fields, causing the slice to refer to the entire section of data. Slicing (arr[1..2]) returns a new slice with the ptr and length fields updated. (This also means you can slice arbitrary pointers; ex. `(cast(ubyte*) malloc(1024))[0..1024]` to get a slice of memory backed by C malloc. Very useful.) The only magic happens when increasing the size of the array, via appending or setting length, which usually allocates a new array from the GC heap, except when D determines that it can get away with not doing so (i.e. when the data points somewhere in a GC heap and there's no data in-use after the end of the array. capacity also looks at GC metadata).
Re: Free the DMD backend
On Tuesday, 31 May 2016 at 20:18:34 UTC, default0 wrote: I have no idea how licensing would work in that regard but considering that DMDs backend is actively maintained and may eventually even be ported to D, wouldn't it at some point differ enough from Symantecs "original" backend to simply call the DMD backend its own thing? The way I understand it is that no matter how different a derivative work (such as any modification to DMD) gets, it's still a derivative work, and is subject to the terms of the license of the original work.
Re: Why do some T.init evaluate to true while others to false?
On Friday, 27 May 2016 at 15:49:16 UTC, ArturG wrote: On Friday, 27 May 2016 at 15:24:18 UTC, Adam D. Ruppe wrote: On Friday, 27 May 2016 at 15:19:50 UTC, ArturG wrote: yes but i have to check for that when some one does Why? This is no different than if they set any of the other four billion possible values. What do you mean? operation on float.nan gives you a float.nan so why does the shortcut evaluate to true and not false wouldnt that make more sense? NaN in IEEE 754 floating-point numbers (the floating-point number system most languages and processors use) is defined as a number with all exponent bits set and a non-zero mantissa. The mantissa value is the "NaN payload", and can be any value. `is` does a binary comparison on floating-point numbers, so NaNs with different payloads will not be considered equal, as you have found out with `float.init !is float.nan`.
Re: Why simple code using Rebindable doesn't compile ?
On Monday, 30 May 2016 at 10:09:19 UTC, chmike wrote: This code compile, but array appending doesn't work alias Rebindable!(immutable(InfoImpl)) Info; class InfoImpl { void foo() {} static immutable(InfoImpl) info() { __gshared immutable InfoImpl x = new immutable InfoImpl; return x; } } void main() { Info t = Info.info; Info[] a; //a ~= Info.info; <-- KO Compiler Error a ~= rebindable(Info.info); // Ok } - Why can't info() return a Rebindable!(immutable(InfoImpl)) ? What do you mean? `info` returns an `immutable(InfoImpl)`, not a `Rebindable!(immutable(InfoImpl))`. Rebindable doesn't apply itself to the return types of the methods of the return types (there's no reason to).
Re: Transient ranges
On Monday, 30 May 2016 at 12:53:07 UTC, Steven Schveighoffer wrote: On 5/30/16 5:35 AM, Dicebot wrote: On Sunday, 29 May 2016 at 17:25:47 UTC, Steven Schveighoffer wrote: What problems are solvable only by not caching the front element? I can't think of any. As far as I know, currently it is done mostly for performance reasons - if result is fitting in the register there is no need to allocate stack space for the cache, or something like that. One of most annoying examples is map which calls lambda on each `front` call : https://github.com/dlang/phobos/blob/master/std/algorithm/iteration.d#L587-L590 Maybe my understanding of your post is incorrect. You said "It is impossible to correctly define input range without caching front which may not be always possible and may have negative performance impact." I'm trying to figure out which cases caching makes the solution impossible. One case is wrapping a network stream: a TCP input range that yields ubyte[] chunks of data as they are read from the socket, a joiner to join the blocks together, a map that converts the bytes to characters, and take to consume each message. The issue is that, in a naive implementation, creating the TCP range requires reading a chunk from the socket to populate front. Since I usually set up my stream objects, before using them, the receiver range will try to receive a chunk, but I haven't sent a request to the server yet, so it would block indefinitely. Same issue with popFront: I need to pop the bytes I've already used for the previous request, but calling popFront would mean waiting for the response for the next request which I haven't sent out yet. The solution I used was to delay actually receiving the chunk until front was called, which complicates the implementation a bit.
Re: Transient ranges
On Sunday, 29 May 2016 at 17:45:00 UTC, Steven Schveighoffer wrote: On 5/27/16 7:42 PM, Seb wrote: So what about the convention to explicitely declare a `.transient` enum member on a range, if the front element value can change? enum isTransient(R) = is(typeof(() { static assert(isInputRange!R); static assert(hasIndirections(ElementType!R)); static assert(!allIndrectionsImmutable!(ElementType!R)); // need to write this })); -Steve allIndrectionsImmutable could probably just be is(T : immutable) (ie implicitly convertible to immutable). Value types without (or with immutable only) indirections should be convertible to immutable, since the value is being copied.
Re: A ready to use Vulkan triangle example for D
On Sunday, 29 May 2016 at 00:42:56 UTC, maik klein wrote: On Sunday, 29 May 2016 at 00:37:54 UTC, Alex Parrill wrote: On Saturday, 28 May 2016 at 19:32:58 UTC, maik klein wrote: Btw does this even work? I think the struct initializers have to be Foo foo = { someVar: 1 }; `:` instead of a `=` I didn't do this because I actually got autocompletion for `vertexInputStateCreateInfo.` and that meant less typing for me. No, its equals. In C it's a colon, which is a tad confusing. https://dpaste.dzfl.pl/bd29c970050a Gah, I got them backwards. Colon in D, equals in C. Could have sworn I checked before I posted that...
Re: A ready to use Vulkan triangle example for D
On Saturday, 28 May 2016 at 10:58:05 UTC, maik klein wrote: derelict-vulcan only works on windows, dvulkan doesn't have the platform dependend surface extensions for xlib, xcb, w32 and wayland. Without them Vulkan is unusable for me. I really don't care what I use, I just wanted something that works. Platform extension support will be in the next release of d-vulkan. It doesn't include platform extensions now because I wanted to find a way to implement it without tying d-vulkan to a specific set of bindings, though I can't seem to find a good solution unfortunately... I personally use the git version of GLFW, which handles the platform-dependent surface handling for me. As for the demo itself... It might help explain things more if the separate stages (instance creation, device creation, setting up shaders, etc) were split into their own functions, instead of stuffing everything into `main`. Struct initializers are also useful when dealing with Vulkan info structs, since you don't have to repeat the variable name each time. Ex this: VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = {}; vertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vertexInputStateCreateInfo.vertexBindingDescriptionCount = 1; vertexInputStateCreateInfo.pVertexBindingDescriptions = vertexInputStateCreateInfo.vertexAttributeDescriptionCount = 1; vertexInputStateCreateInfo.pVertexAttributeDescriptions = Can become: VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = { sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // also sType is pre-set with erupted or d-derelict vertexBindingDescriptionCount = 1, pVertexBindingDescriptions = , vertexAttributeDescriptionCount = 1, pVertexAttributeDescriptions = , };
Re: Testing array ptr for offset 0...
On Thursday, 26 May 2016 at 07:51:46 UTC, Era Scarecrow wrote: ... This smells like an XY problem [0]. Why exactly do you need the internal layout of the array structure? The line "not having to make another array to keep track of lengths and then shorten them" is fairly vague. "Shortening" an array via slicing is basically free (it's just some integer arithmetic), but I'm not sure if that's what you meant. [0]: http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem
Re: A technique to mock "static interfaces" (e.g. isInputRange)
On Wednesday, 25 May 2016 at 21:38:23 UTC, Atila Neves wrote: There was talk in the forum of making it easier to come up instantiations of say, an input range for testing purposes. That got me thinking of how mocking frameworks make it easy to pass in dependencies without having to write a whole new "test double" type oneself. How would one do that for what I've started calling "static interfaces"? How would one mock an input range? There's no way to inspect the code inside the lambda used in isInputRange or any other similar template constraint (.codeof would be awesome, but alas it doesn't exist), but a regular OOP interface you can reflect on... and there's even one called InputRange in Phobos... hmmm. The result is in the link below. The implementation is a bit horrible because I cowboyed it. I should probably figure out how to make it more template mixin and less of the string variety, but I was on a roll. Anyway, take a look at the unit test at the bottom first and complain about my crappy implementation later: https://gist.github.com/atilaneves/b40c4d030c70686ffa3b8543018f6a7e If you have an interface already I guess you could just mock that, but then you wouldn't be able to test templated code with it. This technique would fix that problem. Interesting? Crazy? Worth adding to unit-threaded? Phobos (after much cleaning up)? Atila Have you looked at std.typecons.AutoImplement at all? http://dlang.org/phobos/std_typecons.html#.AutoImplement It seems to do something similar to what you're doing, though it generates a subclass rather than a struct (for the purposes of testing contracts and stuff, I don't think it matters too much).
Re: d-vulkan, automatically generated D bindings for Vulkan
On Saturday, 19 March 2016 at 01:12:08 UTC, Alex Parrill wrote: https://github.com/ColonelThirtyTwo/dvulkan I've updated the bindings to Vulkan 1.0.13, and added a few fixes. Platform support will come in a bit. I'm going to use void* pointers for most of the platform-specific types, so you can use whatever bindings you want to use with them (whether they are full bindings or just one little opaque struct alias to use with, say, glfw).
Re: Enum that can be 0 or null
On Saturday, 21 May 2016 at 02:04:23 UTC, Mike Parker wrote: On Saturday, 21 May 2016 at 01:09:42 UTC, Alex Parrill wrote: Looks like my best bet is to mark it as deprecated and point them to Vk(Type).init instead. I would prefer to do something like this: enum VK_NULL_HANDLE_0 = 0; enum VK_NULL_HANDLE_PTR = null; Then document it clearly. Alias VK_NULL_HANDLE to one of them and keep it deprecated forever. Many users are not going to read the documentation on their own initiative, so the deprecation message telling them how to solve the problem will save you from responding to the same issue again and again and again. Hm, I could do `VK_NULL_DISPATCHABLE_HANDLE = null` for the types that are always pointers and `VK_NULL_NONDISPATCHABLE_HANDLE = null ? IS_64BIT : 0` for types that are either pointers are integers depending on arch, but those names are a bit long. Your specific example wouldn't work.
Re: Enum that can be 0 or null
On Friday, 20 May 2016 at 22:10:51 UTC, tsbockman wrote: Why do you need to? Just use null for pointer types, and 0 for integers. D is not C; you aren't *supposed* to be able to just copy-paste any random C snippet into D and expect it to work without modification. If that's not a satisfactory answer, please show some specific examples of code that you don't know how to make work without VK_NULL_HANDLE so that I can propose a workaround. Because, as I mentioned in the OP, for VK_NULL_HANDLE to work like it does in C on 32-bit systems, it needs to be compatible with both pointer types (VkDevice, VkInstance, etc) and 64-bit integer types (VkFence, VkSemaphore, many others). There is of course a workaround: since VK_NULL_HANDLE is always zero/null, Vk(Type).init will work as a replacement as long as you match up the types. But then people will try to use VK_NULL_HANDLE (as every C or C++ Vulkan tutorial or reference will instruct) and find out that either a) it doesn't work or b) it works fine on their 64 bit development system, but then cause a ton of errors when they try to compile their project for a 32-bit system. Looks like my best bet is to mark it as deprecated and point them to Vk(Type).init instead.
Enum that can be 0 or null
(How) can I make a constant that is either zero or null depending on how it is used? Vulkan has a VK_NULL_HANDLE constant which in C is defined to be zero. It is used as a null object for several types of objects. In D however, zero is not implicitly convertible to a null pointer, and vice versa. On 64 bit platforms, those types are all pointers, so there I can define VK_NULL_HANDLE as null. But on 32 bit platforms, some of the types are pointers and others are ulongs, and my definition of VK_NULL_HANDLE should be compatible with both. Anyone have an idea on how to make this work?
Re: ErrorException thrown when errno is modified ?
On Thursday, 19 May 2016 at 13:05:19 UTC, chmike wrote: Hello, I'm planning to call some posix functions core.sys.posix that may set the errno value in case of error. e.g. read() or write(). Checking the std.exception documentation I see that ErrnoException may be thrown when errors setting errno may occur. Does this affect the posix calls ? From what I saw in the code, it doesn't seam the case. Just making sure I'm correct. ErrnoException is the exception thrown by errnoEnforce, which is a convenient function for checking system calls. D links to the same Posix functions that C does; their behavior is exactly the same (ie they don't throw).
Re: Discuss vulkan erupted, the other auto-generated vulkan binding
On Monday, 16 May 2016 at 12:10:58 UTC, ParticlePeter wrote: This is in respect to announce thread: https://forum.dlang.org/post/mdpjqdkenrnuxvruw...@forum.dlang.org Please let me know if you had the chance to test the functionality as requested in the announce thread. All other question are welcome here as well of course. Cheers, ParticlePeter Apparently GitHub didn't add my own repo to my list of watch repos, meaning no notifications for them... I'll look over the pull request. Let's not split this project.
Re: Single-Allocation Variable-Sized Array
On Wednesday, 18 May 2016 at 21:28:56 UTC, Nordlöw wrote: What's the preferred way in D to implement single-allocation variable-sized arrays such as /** Single-Allocation Array. */ struct ArrayN { ubyte length; // <= maxLength size room; // allocated length ubyte[0] data; // `room` number of bytes follows } where insertion/deletion typically is done via ArrayN* pushBack(ArrayN*, ubyte element); ArrayN* popBack(ArrayN*); which, when needed, will reallocate a new larger/smaller `ArrayN` ? Further, what's the official name for this structure? In C it's called a variable-length struct or object. I don't think D implements them, but this could probably work: struct Foo { size_t len; ubyte[] data() @property { auto thisptr = cast(ubyte*)(); return thisptr[Foo.sizeof..(Foo.sizeof+len)]; } }
Re: parameter pack to inputRange
On Sunday, 8 May 2016 at 14:11:31 UTC, Ali Çehreli wrote: I like Alex Parrill's only() solution but it allocates a dynamic array as well by doing the equivalent of [args] in the guts of its implementation. No it does not. The constructor does `this.data = [values];`, but `this.data` is a fixed-sized array, which is stored in the structure itself. No allocation needs to happen (it should be the same as the foreach loop in your implementation). You guys are just re-inventing `only`.
Re: parameter pack to inputRange
On Friday, 6 May 2016 at 05:00:48 UTC, Erik Smith wrote: Is there an existing way to adapt a parameter pack to an input range? I would like to construct an array with it. Example: void run(A...) (A args) { Array!int a(toInputRange(args)); } Use std.range.only: http://dlang.org/phobos/std_range.html#only void run(A...)(A args) { auto rng = only(args); // ... }
Re: what's the right way to get char* from string?
On Thursday, 5 May 2016 at 07:49:46 UTC, aki wrote: extern (C) int strcmp(char* string1, char* string2); This signature of strcmp is incorrect. strcmp accepts const char* arguments [1], which in D would be written as const(char)*. The immutable(char)* values returned from toStringz are implicitly convertible to const(char)* and are therefore useable as-is as arguments to strcmp. import std.string; extern (C) int strcmp(const(char)* string1, const(char)* string2); auto v = strcmp(somestring1.toStringz, somestring2.toStringz); [1] http://linux.die.net/man/3/strcmp
Re: what is equivalent to template template
On Tuesday, 3 May 2016 at 21:31:35 UTC, Erik Smith wrote: C++ has template templates. I'm not sure how to achieve the same effect where (in example below) the template function myVariadic is passed to another function. void myVaridatic(A...)(A a) {} static void call(alias F,A...)(F f,A a) { f(a); } void foo() { call(myVaridatic,1,2,3); } You're close. An `alias` template parameter can be any symbol, including a template. But you can't pass in a template as a runtime parameter, so having `F f` in your parameters list is wrong (there's nothing to pass anyway; you already have the template, which is F). static void call(alias F, A...)(A a) { F(a); } Then instantiate and call the `call` function with the template you want: call!myVariadict(1,2,3);
Re: constructed variadic call
On Monday, 2 May 2016 at 18:22:52 UTC, Erik Smith wrote: Is there way to construct an "argument pack" from a non-static array (like the switch below)? I need to transport a variadic call through a void*. switch (a.length) { case 1: foo(a[1]); break; case 2: foo(a[1], a[2]); break; case 3: foo(a[1], a[2], a[3]); break; ... } I don't think it's possible to call a vararg function whose number of arguments is only known at runtime, for the same reasons it is impossible in C [1]. Your switch statement is probably the best you can do, other than rewriting the API to not use varargs (which, depending on what the function is doing, I would recommend). You can possibly use string mixins or static foreach to avoid repeating the case clauses. [1] Populating a va_list: http://stackoverflow.com/questions/988290/populating-a-va-list
Re: Threads
On Monday, 2 May 2016 at 16:39:13 UTC, vino wrote: Hi All, I am a newbie for D programming and need some help, I am trying to write a program using the example given in the book The "D Programming Language" written by "Andrei Alexandrescu" with few changes such as the example program read the input from stdin and prints the data to stdout, but my program reads the input from the file(readfile.txt) and writes the output to another file(writefile.txt), and I am getting the below errors while compiling Error: [root@localhost DProjects]# dmd readwriteb.d readwriteb.d(7): Error: cannot implicitly convert expression (__aggr2859.front()) of type ubyte[] to immutable(ubyte)[] readwriteb.d(15): Error: cannot implicitly convert expression (receiveOnly()) of type immutable(ubyte)[] to std.outbuffer.OutBuffer [root@localhost DProjects]# Version: DMD64 D Compiler v2.071.0 Code: import std.algorithm, std.concurrency, std.stdio, std.outbuffer, std.file; void main() { enum bufferSize = 1024 * 100; auto file = File("readfile.txt", "r"); auto tid = spawn(); foreach (immutable(ubyte)[] buffer; file.byChunk(bufferSize)) { send(tid, buffer); } } void fileWriter() { auto wbuf = new OutBuffer(); for (;;) { wbuf = receiveOnly!(immutable(ubyte)[])(); write("writefile.txt", wbuf); } } From, Vino.B File.byChunks iirc returns a mutable ubyte[] range, not an immutable(ubyte)[]. The easiest way to fix this would be to change the foreach variable to ubyte[] and make an immutable duplicate of it when sending via idup. wbuf is inferred to be an OutBuffer but then you assign an immutable(ubyte)[] to it in your foreach loop; a type error.
Re: Garbage Collector : Ignoring a reference
On Tuesday, 26 April 2016 at 09:07:59 UTC, Begah wrote: I am trying to create an asset manager for my textures. I had the idea ( it may be a wrong idea ) to create a hashmap of my textures with a string as the key. When the program request a texture, it firts check if it is in the hashmap and then returns if it is : [...] What you want are "weak references". I don't think D supports them yet.
Re: std.experimental.allocator.make should throw on out-of-memory
On Thursday, 21 April 2016 at 13:42:50 UTC, Era Scarecrow wrote: On Thursday, 21 April 2016 at 09:15:05 UTC, Thiez wrote: On Thursday, 21 April 2016 at 04:07:52 UTC, Era Scarecrow wrote: I'd say either you specify the amount of retries, or give some amount that would be acceptable for some background program to retry for. Say, 30 seconds. Would that actually be more helpful than simply printing an OOM message and shutting down / crashing? Because if the limit is 30 seconds *per allocation* then successfully allocating, say, 20 individual objects might take anywhere between 0 seconds and almost (but not *quite*) 10 minutes. In the latter case the program is still making progress but for the user it would appear frozen. Good point. Maybe having a global threshold of 30 seconds while it waits and retries every 1/2 second. In 30 seconds a lot can change. You can get gigabytes of memory freed from other processes and jobs. In the end it really depends on the application. A backup utility that you run overnight gives you 8+ hours to do the backup that probably takes up to 2 hours to actually do. On the other hand no one (sane anyways) wants to wait if they are actively using the application and would prefer it to die quickly and restart it when there's fewer demands on the system. I'm proposing that make throws an exception if the allocator cannot satisfy a request (ie allocate returns null). How the allocator tries to allocate is it's own business; if it wants to sleep (which I don't believe would be helpful outside of specialized cases), make doesn't need to care. Sleeping would be very bad for certain workloads (you mentioned games), so having make itself sleep would be inappropriate.
Re: Handling arbitrary char ranges
On Wednesday, 20 April 2016 at 22:44:37 UTC, ag0aep6g wrote: On 20.04.2016 23:59, Alex Parrill wrote: On Wednesday, 20 April 2016 at 17:09:29 UTC, Matt Kline wrote: [...] First, you can't assign anything to a void[], for the same reason you can't dereference a void*. This includes the slice assignment that you are trying to do in `buf[0..minLen] = remainingData[0..minLen];`. Not true. You can assign any dynamic array to a void[]. That's not assigning the elements of a void[]; it's just changing what the slice points to and adjusting the length, like doing `void* ptr = someOtherPtr;` Regarding vector notation, the spec doesn't seem to mention how it interacts with void[], but dmd accepts this no problem: int[] i = [1, 2, 3]; auto v = new void[](3 * int.sizeof); v[] = i[]; It only seems to work on arrays, not arbitrary ranges, sliceable or not. Though see below. [...] Second, don't use slicing on ranges (unless you need it). Not all ranges support it... As far as I see, the slicing code is guarded by `static if (isArray!T)`. Arrays support slicing. [...] Instead, use a loop (or maybe `put`) to fill the array. That's what done in the `else` path, no? Yes, I did not see the static if condition, my bad. Third, don't treat text as bytes; encode your characters. auto schema = EncodingScheme.create("utf-8"); auto range = chain("hello", " ", "world").map!(ch => cast(char) ch); auto buf = new ubyte[](100); auto currentPos = buf; while(!range.empty && schema.encodedLength(range.front) <= currentPos.length) { auto written = schema.encode(range.front, currentPos); currentPos = currentPos[written..$]; range.popFront(); } buf = buf[0..buf.length - currentPos.length]; You're "converting" chars to UTF-8 here, right? That's a nop. char is a UTF-8 code unit already. It can be either chars, wchars, or dchars. (PS there ought to be a range in Phobos that encodes each character, something like map maybe) std.utf.byChar and friends: https://dlang.org/phobos/std_utf.html#.byChar byChar would work. byWChar and byDChar might cause endian-ness issues.
Re: Handling arbitrary char ranges
On Wednesday, 20 April 2016 at 17:09:29 UTC, Matt Kline wrote: [...] First, you can't assign anything to a void[], for the same reason you can't dereference a void*. This includes the slice assignment that you are trying to do in `buf[0..minLen] = remainingData[0..minLen];`. Cast the buffer to a `ubyte[]` buffer first, then you can assign bytes to it. auto bytebuf = cast(ubyte[]) buf; bytebuf[0] = 123; Second, don't use slicing on ranges (unless you need it). Not all ranges support it... auto buf = [1,2,3]; auto rng = filter!(x => x != 1)(buf); pragma(msg, hasSlicing!(typeof(rng))); // false ... and even ranges that support it don't support assigning to an array by slice: auto buf = new int[](3); buf[] = only(1,2,3)[]; // cannot implicitly convert expression (only(1, 2, 3).opSlice()) of type OnlyResult!(int, 3u) to int[] Instead, use a loop (or maybe `put`) to fill the array. Third, don't treat text as bytes; encode your characters. auto schema = EncodingScheme.create("utf-8"); auto range = chain("hello", " ", "world").map!(ch => cast(char) ch); auto buf = new ubyte[](100); auto currentPos = buf; while(!range.empty && schema.encodedLength(range.front) <= currentPos.length) { auto written = schema.encode(range.front, currentPos); currentPos = currentPos[written..$]; range.popFront(); } buf = buf[0..buf.length - currentPos.length]; (PS there ought to be a range in Phobos that encodes each character, something like map maybe)
Re: std.experimental.allocator.make should throw on out-of-memory
On Wednesday, 20 April 2016 at 20:23:53 UTC, Era Scarecrow wrote: The downside though is the requirement to throw may not be necessary. Having a failed attempt at getting memory and sleeping the program for 1-2 seconds before retrying could succeed on a future attempt. For games this would be a failure to have the entire game pause and hang until it acquires the memory it needs, while non critical applications (say compressing data for a backup) having it be willing to wait wouldn't be a huge disadvantage (assuming it's not at the start and already been busy for a while). This would be best implemented in a "building block" allocator that wraps a different allocator and uses the `allocate` function, making it truly optional. It would also need a timeout to fail eventually, or else you possibly wait forever. This also heavily depends on what type of memory you're allocating. A stack based allocator (with fixed memory) wouldn't ever be able to get you more memory than it has fixed in reserve so immediately throwing makes perfect sense True, if you are allocating from small pools then OOM becomes more likely. But most programs do not directly allocate from small pools; rather, they try to allocate from a small pool (ex. a freelist) but revert to a larger, slower pool when the smaller pool cannot satisfy a request. That is implemented using the building block allocators, which use the `allocate` method, not `make`. Although IF the memory could be arranged and a second attempt made before deciding to throw could be useful (which assumes not having direct pointers to the memory in question and rather having an offset which is used. The more I think about it though the less likely this would be). This is the mechanism used for "copying" garbage collectors. They can only work if they can know about and alter all references to the objects that they have allocated, which makes them hard to use for languages with raw pointers like D.
Re: std.experimental.allocator.make should throw on out-of-memory
On Wednesday, 20 April 2016 at 19:18:58 UTC, Minas Mina wrote: On Tuesday, 19 April 2016 at 22:28:27 UTC, Alex Parrill wrote: I'm proposing that std.experimental.allocator.make, as well as its friends, throw an exception when the allocator cannot satisfy a request instead of returning null. [...] I believe it was designed this way so that it can be used in @nogc code, although I might be wrong. This is IMO a separate issue: that you cannot easily throw an exception without allocating it on the GC heap, making it too painful to use in nogc code. I've heard mentions of altering exception handling to store the exception in a static memory space instead of allocating them on the heap; I'd much rather see that implemented than the bandage solution of ignoring exception handling.
Re: VariantPointer
On Wednesday, 20 April 2016 at 13:41:27 UTC, Nordlöw wrote: At https://github.com/nordlow/phobos-next/blob/master/src/variant_pointer.d I've implemented a pointer-only version of Variant called VariantPointer. I plan to use it to construct light-weight polymorphism in trie containers for D I'm currently writing. VariantPointer uses the top N-bits (N currently 8) to encode the type pointed to be the untyped-pointer encoded in the 64-N bits lower bits. My question is: It safe to assume that `typeBits` most significant bits of a pointer on a 64-bit system are always zero? Note that I didn't want to use the lower bits because I'm currently unsure whether I need to represent stack-pointers aswell. Linux seems to reject mmap requests at or above 0x800, though the vsyscall page is at 0xff60 near the end of the virtual memory space. So it might work on Linux. As for the GC, you're probably out of luck. Adding a global mask option is unlikely to work well if multiple libraries use it.
Re: Shallow copy object when type is know
On Wednesday, 20 April 2016 at 12:32:48 UTC, Tofu Ninja wrote: Is there a way to shallow copy an object when the type is known? I cant seem to figure out if there is a standard way. I can't just implement a copy function for the class, I need a generic solution. A generic class copy function would require accessing private fields, so a clean per-attribute class copy is impossible. Doing a bitwise copy might work except for the synchronization mutex pointer. Can you elaborate on why you need this?
Re: Handling arbitrary char ranges
On Wednesday, 20 April 2016 at 17:09:29 UTC, Matt Kline wrote: I'm doing some work with a REST API, and I wrote a simple utility function that sets an HTTP's onSend callback to send a string: [...] IO functions usually work with octets, not characters, so an extra encoding step is needed. For encoding character arrays to UTF-#, there's std.string.representation, and std.encoding might have something for arbitrary ranges. Avoid slicing ranges; not all ranges support it. If you absolutely need it (you don't here) then add hasSlicing to the constraint. isSomeChar can tell you if a type (like the ranges element type) is a character.
Re: std.experimental.allocator.make should throw on out-of-memory
On Wednesday, 20 April 2016 at 18:07:05 UTC, Alex Parrill wrote: Yes, enforce helps (and I forgot it reruns its argument), but its still boilerplate, and it throws a generic "enforcement failed" exception instead of a more specific "out of memory" exception unless you remember to specify your own exception or message. s/rerun/return/
Re: std.experimental.allocator.make should throw on out-of-memory
On Wednesday, 20 April 2016 at 01:59:31 UTC, Vladimir Panteleev wrote: On Tuesday, 19 April 2016 at 22:28:27 UTC, Alex Parrill wrote: * It eliminates the incredibly tedious, annoying, and easy-to-forget boilerplate after every allocation to check if the allocation succeeded. FWIW, you can turn a false-ish (!value) function call result into an exception by sticking .enforce() at the end. Perhaps this is the use case for a Maybe type. Yes, enforce helps (and I forgot it reruns its argument), but its still boilerplate, and it throws a generic "enforcement failed" exception instead of a more specific "out of memory" exception unless you remember to specify your own exception or message.
std.experimental.allocator.make should throw on out-of-memory
I'm proposing that std.experimental.allocator.make, as well as its friends, throw an exception when the allocator cannot satisfy a request instead of returning null. These are my reasons for doing so: * It eliminates the incredibly tedious, annoying, and easy-to-forget boilerplate after every allocation to check if the allocation succeeded. * Being unable to fulfill an allocation is an exceptional case [1], thus exceptions are a good tool for handling it. Performance on the out-of-memory case isn't a big issue; 99% of programs, when out of memory, either exit immediately or display an "out of memory" message to the user and cancel the operation. * It fails faster and safer. It's better to error out immediately with a descriptive "out of memory" message instead of potentially continuing with an invalid pointer and potentially causing an invalid memory access, or worse, a vulnerability, if the developer forgot to check (which is common for boilerplate code). * Creating a standard out-of-memory exception will make it easier to catch, instead of catching each library's own custom exception that they will inevitably define. Hopefully, since std.experimental.allocator is experimental, we'll be allowed to make such backwards-incompatible changes. What are other peoples thoughts on this? Or has this brought up before and I missed the discussion? [1] It may not be very exceptional for "building-block" allocators that start with small but fast allocators that may fail a lot, in which case returning null is appropriate. However, AFAIK allocators internally use the `allocate` method of the allocator, not make, et al., so they should be unaffected by this change.
Re: .opAssign disabled without @disable
On Saturday, 16 April 2016 at 11:48:56 UTC, denizzzka wrote: Hi! DMD and LDC2 complain about disabled opAssign, but I am not used @disable and depend package "gfm" also isn't uses @disable. ... Try removing the const from this line: debug private const bool isLeafNode = false; I suspect that D is disabling whole-structure assignment since allowing it would mean that the constant `isLeafNode` could be changed.
Re: Recursive vs. iterative constraints
On Saturday, 16 April 2016 at 02:42:55 UTC, Andrei Alexandrescu wrote: So the constraint on chain() is: Ranges.length > 0 && allSatisfy!(isInputRange, staticMap!(Unqual, Ranges)) && !is(CommonType!(staticMap!(ElementType, staticMap!(Unqual, Ranges))) == void) Noice. Now, an alternative is to express it as a recursive constraint: (Ranges.length == 1 && isInputRange!(Unqual!(Ranges[0]))) || (Ranges.length == 2 && isInputRange!(Unqual!(Ranges[0])) && isInputRange!(Unqual!(Ranges[1])) && !is(CommonType!(ElementType!(Ranges[0]), ElementType!(Ranges[1])) == void)) || is(typeof(chain(rs[0 .. $ / 2], chain(rs[$ / 2 .. $] In the latter case there's no need for additional helpers but the constraint is a bit more bulky. Pros? Cons? Preferences? Andrei The former, definitely. The only helper function you're getting rid of that I see is allSatisfy, which describes the constraint very well. The recursive constraint obscures what the intended constraint is (that the passed types are input ranges with a common type) behind the recursion.
Re: Lazy evaluation of function pointers.
On Sunday, 10 April 2016 at 18:08:58 UTC, Ryan Frame wrote: Greetings. The following code works: void main() { passfunc(); } void passfunc(void function(string) f) { f("Hello"); } void func(string str) { import std.stdio : writeln; writeln(str); } Now if I change passfunc's signature to "void passfunc(lazy void function(string) f)" I would get the compiler error "Delegate f () is not callable using argument types (string)". I can lazily pass a void function() -- it seems that there is only a problem when the function contains parameters. The only difference should be when the pointer is evaluated, so why does lazy evaluation matter here? Thank you for your time --Ryan A parameter declared as `lazy T` has the type `T delegate()`, which, when called, evaluates the expression that was passed into the function. So effectively, this: void foo(lazy int x) { auto i = x(); } foo(a+b); Is the same as this: void foo(int delegate() x) { auto i = x(); } foo(() => a+b); T in your case is `void function(string)`. So you can do `auto func = f()` to get the function you passed in. It's not very useful in your example to lazily evaluate getting a function pointer, considering it's usually a constant expression after compiling.
Re: Fiber and Thread Communication
On Friday, 8 April 2016 at 14:08:39 UTC, Nordlöw wrote: So a TId can represent either a thread or a fiber? It represents a "logical thread", which currently consists of coroutines or OS threads but could theoretically be extended to, say, other processes or even other machines.
Re: __traits(compiles) and template instantiation
On Thursday, 7 April 2016 at 20:31:12 UTC, jmh530 wrote: I've been playing around with __traits and I find myself confused on one aspect. In the code below, I was testing whether some templates would compile given types. For the most part it works as I would expect. I think I get why the third one works with foo!(int). My guess is that it assumed that U is the same as T and both are int. However, that wouldn't make sense with the last one where I use bar!(int). In that one it's basically ignoring the second template constraint. So I don't understand what's going on for that last line to compile. To confirm I wasn't crazy, I get an error with alias bar_ = bar!(int); import std.traits : isNumeric; import std.range : isInputRange; void foo(T, U)(T x, U y) if (isNumeric!T && isNumeric!U) { } void bar(T, U)(T x, U y) if (isNumeric!T && isInputRange!U) { } void main() { assert(__traits(compiles, foo!(int, int))); //I get this assert(!__traits(compiles, foo!(bool, bool))); //I get this assert(__traits(compiles, foo!(int))); //I think I get this assert(__traits(compiles, bar!(int, int[]))); //I get this assert(!__traits(compiles, bar!(int, int)));//I get this assert(__traits(compiles, bar!(int))); //I don't get this } Neither the third nor sixth lines should be true. alias wrongfoo = foo!int; /* Error: template instance foo!int does not match template declaration foo(T, U)(T x, U y) if (isNumeric!T && isNumeric!U) */ alias rightfoo = foo!(int, int); /* ok */ File a DMD bug. (Also, you can use static assert here to check the assertions at build-time instead of run-time)
Re: Best properly way to destroy a 2 dimensional array?
On Wednesday, 6 April 2016 at 23:14:10 UTC, Jonathan Villa wrote: On Wednesday, 6 April 2016 at 21:33:14 UTC, Alex Parrill wrote: My general idea is first to get the predicted quantity of combinations Seems like you already know; your OP says you have 2^n combinations. so I can divide and parallelize them. std.parallelism.parallel can do this for you, and works on ranges. http://dlang.org/phobos/std_parallelism.html#.parallel What do you think can be the problem with the lack of deallocation? Don't know exactly. destroy just runs the destructors, it doesn't free any memory. Since the arrays are still in scope, it might not be able to free them.
Re: The Sparrow language
On Wednesday, 6 April 2016 at 21:35:51 UTC, mate wrote: On Wednesday, 6 April 2016 at 20:48:20 UTC, Lucian Radu Teodorescu wrote: On Wednesday, 6 April 2016 at 18:27:25 UTC, BLM768 wrote: On Wednesday, 6 April 2016 at 18:25:11 UTC, BLM768 wrote: Aside from the explicit annotations, I don't see how their solution is more flexible than D's CTFE, but I might be missing something. Never mind. Just saw their language embedding example. Neat! Compared to CTFE, in Sparrow you can run at compile-time *any* algorithm you like. No restrictions apply. Not only you can do whatever your run-time code can do, but can also call external programs at compile-time. Imagine that you are calling the D compiler from inside the Sparrow compiler to compile some D code that you encounter. Wow, could be dangerous to compile source code. Spawning processes during compilation is as dangerous as executing the program you just compiled (which you're going to do; the entire point of compiling a program is to execute it). I wouldn't be too concerned. If you're hosting an online compiler, then you're (hopefully) already sandboxing the compiler (to prevent source code that does a lot of CTFE/has large static arrays/etc from eating all your cpu+mem) and the compiled program (for obvious reasons) anyway. (Same argument for D's string import paths not allowing you into symlinks/subdirectores; there are more thorough sandboxing options for those concerned)
Re: Putting things in an enum's scope
On Wednesday, 6 April 2016 at 13:59:42 UTC, pineapple wrote: Is there any way in D to define static methods or members within an enum's scope, as one might do in Java? It can sometimes help with code organization. For example, this is something that coming from Java I'd have expected to be valid but isn't: enum SomeEnum{ NORTH, SOUTH, EAST, WEST; static int examplestaticmethod(in int x){ return x + 2; } } int z = SomeEnum.examplestaticmethod(2); You can use UFCS: enum SomeEnum { NORTH, ... } int examplestaticmethod(in SomeEnum e) { return e+2; } SomeEnum.NORTH.examplestaticmethod();
Re: Best properly way to destroy a 2 dimensional array?
On Wednesday, 6 April 2016 at 19:54:32 UTC, Jonathan Villa wrote: I wrote a little program that given some number it generates a list of different combinations (represented by a ubyte array), so in the end my function with name GenerateCombinations(int x) returns a ubyte[][] (list of arrays of ubytes). ... Why not make a range instead? No need to reserve memory for the entire array if you can compute the elements as-needed. If you really want an array, std.experimental.allocator will let you manually allocate/release objects.
Re: What's the rationale for considering "0x1.max" as invalid ?
On Tuesday, 5 April 2016 at 21:40:59 UTC, Basile B. wrote: On Tuesday, 5 April 2016 at 21:10:47 UTC, Basile B. wrote: On Tuesday, 5 April 2016 at 20:56:54 UTC, Alex Parrill wrote: On Tuesday, 5 April 2016 at 19:00:43 UTC, Basile B. wrote: 0x1.max // exponent expected in hex float 0x1 .max // OK 1.max // OK What's the ambiguity when it's an hex literal ? It's potentially ambiguous with hexadecimal floating point numbers 0xdeadbeef.p5 // hex float or hex int + method? dlang.org/spec/lex.html#HexFloat Yes but it's pointless to allow the decimal separator to be followed by the exponent: void main() { import std.stdio; writeln( typeof(0x1p5).stringof ); // double writeln( typeof(0x1.p5).stringof ); // double } I mean that the rule could be: the decimal separator must be followed by a second group of digits. The second group of digits must be followed by an exponent. The first group of digits can be followed by an exponent. 0x1.0p5 // valid 0xp5 // valid 0x1.p5 // invalid (p is not a hex digit) 0x1.ap5 // valid Looks like that's how it works for decimal floats; I.e. 1.e5 is an int and property lookup, while 1.0e5 is 10f. Curiously, 1. Is 1.0. I agree that floats should be parsed consistently. For now, you can do (0x1).max or typeof(0x1).max.
Re: What is the best way to store bitarray (blob) for pasting in database?
On Wednesday, 6 April 2016 at 12:56:39 UTC, Suliman wrote: I have next task. There is PostgreSQL DB. With field like: id, mydata. mydata - is binary blob. It can be 10MB or even more. I need load all data from PostgreSQL to SQLLite. I decided ti create struct that and fill it with data. And then do INSERT operation in sqllite. But I do not know is it's good way, and if it's ok what data type should I use for blob (binary data). struct MyData { string id; string mydata; // what datatype I should use here?? } MyData [] mydata; MyData md; while (rs.next()) { md.id = to!string(rs.getString(1)); md.mydata = to!string(rs.getString(2)); //?? mydata ~= md; } stmtLite.executeUpdate(`insert into MySyncData(id,mydata) values(md.id,md.data)`); //ddbc driver is it's normal way to insert data? Blobs are byte arrays, so they should be ubyte[]. They shouldn't be strings, which are explicitly text only.
Re: What's the rationale for considering "0x1.max" as invalid ?
On Tuesday, 5 April 2016 at 19:00:43 UTC, Basile B. wrote: 0x1.max // exponent expected in hex float 0x1 .max // OK 1.max // OK What's the ambiguity when it's an hex literal ? It's potentially ambiguous with hexadecimal floating point numbers 0xdeadbeef.p5 // hex float or hex int + method? dlang.org/spec/lex.html#HexFloat
Re: uniform initialization in D (as in C++11): i{...}
On Tuesday, 5 April 2016 at 05:39:25 UTC, Timothee Cour wrote: q{...} // comment (existing syntax) That is syntax for a string literal, not a comment (though unlike other string literals, the contents must be valid D tokens and editors usually do not highlight them as strings).
Re: debugger blues
Comparing a logging framework with a basic print function is not a fair comparison. I'd like to point out that Python's logging module[1] also takes format strings. So this really is just an argument of D's writeln vs Python's print. In which case, this seems like a small thing to get upset over. Yes, implicit spacing is convenient, but in some cases it isn't. It's a fairly arbitrary choice. I'd argue that D's writeln follows Python's philosophy of "Explicit is better than implicit" better than Python does. But it's not overly hard to implement your own print function: void print(Args...)(Args args) { foreach(i, arg; args) { if(i != 0) write(" "); write(arg); } writeln(); } [1] https://docs.python.org/3/library/logging.html
Re: Can we check the arguments to format() at compile time?
On Friday, 1 April 2016 at 21:25:46 UTC, Yuxuan Shui wrote: Clang has this nice feature that it will warn you when you passed wrong arguments to printf: #include int main(){ long long u = 10; printf("%c", u); } clang something.c: something.c:4:15: warning: format specifies type 'int' but the argument has type 'long long' [-Wformat] With the CTFE power of D, we should be able to do the same thing when the format string is available at compile time. Instead of throwing exceptions at run time. Not as-is, because the format string is a runtime argument and not a compile-time constant. Consider: writefln(rand() >= 0.5 ? "%s" : "%d", 123); It's certainly possible with a new, templated writef function. Hypothetically: writefln_ctfe!"%s"(1234); // would fail
Re: Tristate - wanna?
On Sunday, 27 March 2016 at 02:19:56 UTC, crimaniak wrote: On Saturday, 26 March 2016 at 22:39:58 UTC, Alex Parrill wrote: ... If we're going down that route, might as well use state tables. ... For Boolean, Ternary, and N-state logic: a && b == min(a, b) a || b == max(a, b) ~a == N-1-a why to optimize it more? That's incorrect for the `unknown` value. Lets say you represented true as 1f, false as 0f, and unknown as NaN... std.algorithm.max(0, 0f/0f) = 0, but should be NaN std.math.fmax(1, 0f/0f) = NaN, but should be 1 N-state logic isn't just about probabilities either. According to Wikipedia, Bochvar's three-valued logic has an "internal" state, where any operation with `internal` results in `internal` (similar to NaN). More broadly, the values and operations between them could be whatever the mathematician or developer wants, so a truth table is one of the ways to generally specify an operator.
Re: [Blog post] Why and when you should use SoA
On Sunday, 27 March 2016 at 00:42:07 UTC, maik klein wrote: I think SoA can be faster if you are commonly iterating over a section of a dataset, but I don't think that's a common occurrence. This happens in games very often when you use inheritance, your objects just will grow really big the more functionality you add. Like for example you just want to move all objects based on velocity, so you just care about Position, Velocity. You don't have to load anything else into memory. An entity component system really is just SoA at its core. You can't have a struct-of-arrays with polymorphic data like game objects; the individual objects would have different properties and methods. If you use a Unity-esque component system, you could potentially pool each object's component into an array... but then whatever component updates you're running likely touch most of the object state anyway (ex. the hypothetical PositionComponent would be updating both its position and velocity). Also I forgot to mention: Your "Isn’t SoA premature optimization?" section is a textbook YAGNI violation. I might have to refactor my web app to support running across multiple servers and internationalization when it becomes the Next Big Thing, but it more than likely will not become the Next Big Thing, so it's not productive for me to add additional complexity to "make sure my code scales" (and yes, SoA does add complexity, even if you hide it with templates and methods). Since AoS vs SoA is highly dependent on usage, I'd like to see some performance metrics with real-world access patterns instead of benchmarks that unrealistically only look at part of the data at a time, or use structs that are too small to matter. Of course, actually getting those metrics is the hard part...
Re: [Blog post] Why and when you should use SoA
On Friday, 25 March 2016 at 01:07:16 UTC, maik klein wrote: Link to the blog post: https://maikklein.github.io/post/soa-d/ Link to the reddit discussion: https://www.reddit.com/r/programming/comments/4buivf/why_and_when_you_should_use_soa/ I think structs-of-arrays are a lot more situational than you make them out to be. You say, at the end of your article, that "SoA scales much better because you can partially access your data without needlessly loading unrelevant data into your cache". But most of the time, programs access struct fields close together in time (i.e. accessing one field of a struct usually means that you will access another field shortly). In that case, you've now split your data across multiple cache lines; not good. Your ENetPeer example works against you here; the the packetThrottle* variables would be split up into different arrays, but they will likely be checked together when throttling packets. Though admittedly, it's easy to fix; put fields likely to be accessed together in their own struct. The SoA approach also makes random access more inefficient and makes it harder for objects to have identity. Again, your ENetPeer example works against you; it's common for servers to need to send packets to individual clients rather than broadcasting them. With the SoA approach, you end up accessing a tiny part of multiple arrays, and load several cache lines containing data for ENetPeers that you don't care about (i.e. loading irrelevant data). I think SoA can be faster if you are commonly iterating over a section of a dataset, but I don't think that's a common occurrence. I definitely think it's unwarranted to conclude that SoAs "scale much better" without noting when they scale better, especially without benchmarks. I will admit, though, that the template for making the struct-of-arrays is a nice demonstration of D's templates.
Re: Tristate - wanna?
On Saturday, 26 March 2016 at 22:11:53 UTC, Nordlöw wrote: On Saturday, 26 October 2013 at 15:41:32 UTC, Andrei Alexandrescu wrote: While messing with std.allocator I explored the type below. I ended up not using it, but was surprised that implementing it was quite nontrivial. Should we add it to stdlib? I can think of many variants of for this. What about { yes, // 1 chance no, // 0 chance likely, // > 1/2 chance unlikely, // < 1/2 chance unknown // any chance } ? Partial implementation at https://github.com/nordlow/justd/blob/master/fuzzy.d#L15 :) If we're going down that route, might as well use state tables. With CTFE + templates, you could possibly do something like this: immutable State[] StateOrTable = ParseStateTable!q{ | yes | no | likely | unlikely | unknown -- yes | yes | yes | yes| yes | yes no | yes | no | likely | unlikely | unknown likely | yes | likely | likely | likely | likely unlikely| yes | unlikely | likely | unlikely | unknown unknown | yes | unknown | likely | unknwon | unknown }; State opBinary(string op)(State other) if(op == "||") { return StateOrTable[this.value*NumStates+other.value]; } Though I see issues with having a generic n-state value template and also rewriting `a != b` to `!(a == b)`; I suspect that there may be some class of values where the two are not equivalent.
Re: Synchronization on immutable object
On Tuesday, 22 March 2016 at 10:49:01 UTC, Johan Engelen wrote: Quiz: does this compile or not? ``` class Klass {} void main() { immutable Klass klass = new Klass; synchronized (klass) { // do smth } } ``` A D object contains two (!) hidden pointers. Two? Yes: the vtable pointer __vptr, and a pointer to a Monitor struct which contains a synchronization mutex. The synchronized statement is lowered into druntime calls that *write* to __monitor. Quiz answer: yes it compiles. Oops? This is related to an earlier discussion on whether TypeInfo objects should be immutable or not [1]. Should one be able to synchronize on typeid(...) or not? ``` interface Foo {} void main() { synchronized(typeid(Foo)) { // do smth } } ``` Because LDC treats the result of typeid as immutable, the code is bugged depending on the optimization level. [1] http://forum.dlang.org/post/entjlarqzpfqohvnn...@forum.dlang.org As long as there's no race conditions in the initial creation of the mutex, it shouldn't matter, even though it does internally mutate the object, because it's transparent to developers (unless you're going out of your way to access the internal __monitor field). What exactly is bugged about the typeid example under LDC?
d-vulkan, automatically generated D bindings for Vulkan
https://github.com/ColonelThirtyTwo/dvulkan I know there are a few other bindings for Vulkan around, but I didn't see one that generated the bindings from the XML spec, so I made d-vulkan. The included vkdgen.py script leverages the spec parser included in the Vulkan-Docs repo to generate D bindings that can easily be updated with new versions and extensions. The bindings load all functions using the vkGetInstanceProcAddr function; however, it does not provide any way of loading that function by default, and you must provide it when loading Vulkan. The `with-derelict-loader` dub configuration provides uses derelict.util to load the vkGetInstanceProcAddr function, and I've added a wiki page demonstrating loading the function using GLFW. This includes bindings for all extensions, except for the platform-dependent VK_KHR_*_surface APIs, which require type declarations from other projects (like X11) that I didn't want to include. The platform-independent VK_KHR_surface extension is available, however. (Currently the Derelict loader only works in Windows because I don't know the library names for Vulkan on Linux or OSX; if anyone knows them, please tell me, and I'll add them)
Re: d-vulkan, automatically generated D bindings for Vulkan
On Sunday, 20 March 2016 at 00:03:16 UTC, Nicholas Wilson wrote: On Saturday, 19 March 2016 at 19:37:38 UTC, Alex Parrill wrote: On Saturday, 19 March 2016 at 12:57:18 UTC, Nicholas Wilson wrote: On Saturday, 19 March 2016 at 01:12:08 UTC, Alex Parrill wrote: Should be doable using appropriate version blocks. The problem is that I'd have to define my own structs (Xlib Display, Xlib Window, etc), which will be incompatible with the ones defined in any bindings to those libraries. You don't. Code in undefined versions need only be syntactically valid not semantically valid. i.e. the types in versions not compiled in need not be declared nor defined. version(none) { xcb_connection_t* con; } will compile fine. Yes, I know. The issue is, when compiling with the version, where does xcb_connection_t come from? If I declare it myself, as `struct xcb_connection_t;` in the version block, then that type will be different than the xcb_connection_t declared in the XCB bindings that the developer is likely using, and thus they will be incompatible. If I import a xcb_connection_t from some bindings, it ties d-vulkan to those bindings, which I'd rather not do.
Re: Need help with delegates and vibed
On Saturday, 19 March 2016 at 19:53:01 UTC, Suliman wrote: Thanks! I am understand a little bit better, but not all. ``` shared static this() { auto settings = new HTTPServerSettings; settings.port = 8080; listenHTTP(settings, ); } void handleRequest(HTTPServerRequest req, HTTPServerResponse res) { if (req.path == "/") res.writeBody("Hello, World!", "text/plain"); } ``` https://github.com/rejectedsoftware/vibe.d/blob/master/source/vibe/http/server.d#L104 I expected to see in listenHTTP() function some processing but it's simply get args and then do return: return listenHTTP(...) Could you explain why it's do so? -- Where is constructor of this class? http://vibed.org/api/vibe.http.client/HTTPClientRequest How I should use it if have only docs, and do not have examples? (I am trying understand how to use docs without cope-past examples) The function is overloaded; it's calling the main implementation at line 77 after transforming the arguments. The constructor for HTTPClientRequest is likely undocumented because you should not construct it yourself; vibe.d constructs it and passes it to the function you register with listenHTTP.
Re: d-vulkan, automatically generated D bindings for Vulkan
On Saturday, 19 March 2016 at 12:57:18 UTC, Nicholas Wilson wrote: On Saturday, 19 March 2016 at 01:12:08 UTC, Alex Parrill wrote: Should be doable using appropriate version blocks. The problem is that I'd have to define my own structs (Xlib Display, Xlib Window, etc), which will be incompatible with the ones defined in any bindings to those libraries.
Re: Error: constructor Foo.this default constructor for structs only allowed with @disable, no body, and no parameters
On Monday, 7 March 2016 at 13:23:58 UTC, Nicholas Wilson wrote: I'm not quite sure what this error is saying. Is it that the only struct constructor that can have no parameters is @disable this(){} ? Yes, this is exactly right. You cannot have a structure with a default constructor, except with @disable. You can, however, specify the initial values of fields, as in your second example. Note that you can use typeof on the variable you are currently declaring. VkFenceCreateInfo CI = typeof(CI)(cast(typeof(CI.sType))StructureType.eFenceCreateInfo, null, 0);
Re: std.range: Lockstep vs. Zip
On Wednesday, 2 March 2016 at 08:51:07 UTC, Manuel Maier wrote: Hi there, I was wondering why I should ever prefer std.range.lockstep over std.range.zip. In my (very limited) tests std.range.zip offered the same functionality as std.range.lockstep, i.e. I was able to iterate using `foreach(key, value; std.range.zip(...)) {}` which, according to the docs, is what std.range.lockstep was supposed to be designed for. On top of that, std.range.zip is capable of producing a RandomAccessRange, but std.range.lockstep only produces something with opApply. Cheers zip uses the InputRange protocol, and bundles up all the values in a Tuple. lockstep uses the opApply protocol, and doesn't bundle the values. Lockstep is useful for foreach loops since you don't need to unpack a tuple, but zip is compatible with all of the std.range and std.algorithm functions that take ranges.
Re: Combining template conditions and contracts?
On Monday, 29 February 2016 at 14:38:52 UTC, Ozan wrote: Is it possible to combine template conditions and contracts? Like in the following T square_root(T)(T x) if (isBasicType!T) { in { assert(x >= 0); } out (result) { assert((result * result) <= x && (result+1) * (result+1) > x); } body { return cast(long)std.math.sqrt(cast(real)x); } Compiler says no. Maybe it's a missunderstanding from my side.. Thanks & regards, Ozan You have a spare { after the template constraint in your sample
Re: Why file.exists of relative path on Linux always return false?
On Monday, 29 February 2016 at 14:50:51 UTC, Suliman wrote: I am trying to check relative path on Linux for exists. import std.stdio; import std.path; import std.file; import std.string; string mypath = "~/Documents/imgs"; void main() { if(!mypath.exists) { writeln(mypath, " do not exists"); } if(!mypath.exists) { writeln(mypath, " do not exists"); } if("/home/dima/Documents/imgs".exists) { writeln("/home/dima/Documents/imgs"); writeln("Dir exists"); } } ~/Documents/imgs always return "do not exists". But full path: "/home/dima/Documents/imgs" is "Dir exists". Why? It's same paths! ~ is expanded by your shell. It is not a relative path, and system calls do not recognize it (same with environmental variables). See also http://stackoverflow.com/questions/3616595/why-mkdir-fails-to-work-with-tilde
Re: Pseudo-random numbers in [0, n), covering all numbers in n steps?
On Friday, 26 February 2016 at 16:45:53 UTC, Andrei Alexandrescu wrote: On 02/26/2016 10:19 AM, Alex Parrill wrote: On Friday, 26 February 2016 at 14:59:43 UTC, Andrei Alexandrescu wrote: On 02/25/2016 06:46 PM, Nicholas Wilson wrote: The technical name for the property of distribution you describe is k-Dimensional Equidistribution (in this case k=1). I would suggest taking a look at http://www.pcg-random.org. They claim to have both arbitrary period and k-Dimensional Equidistribution Thanks, that's indeed closest! A hefty read. Anyone inclined to work on a PCG random implementation? -- Andrei Beat you to it: http://code.dlang.org/packages/d-pcg It only has the basic generators at the moment. I'll look into the more advanced stuff. (Also 64 bit outputs aren't implemented yet because they need a 128 bit uint for state. I noticed D reserves the names cent and ucent but hasn't implemented them) That's pretty darn cool! I don't see a way to create a generator given a range expressed as a power of two. Say e.g. a client wants to say "give me a generator with a cycle of 32768". Is this easily doable? Also: when the generator starts running, does it generate a full cycle, or it starts with a shorter cycle and then settle into a full cycle? Thanks, Andrei My port at the moment only provides the basic pgm32 generators; their behavior should match the pgm32_* classes from the C++ library. I'll look into which of the generators support the equidistributed results, though I suspect that they are distributed across the entire domain of the result type.
Re: Pseudo-random numbers in [0, n), covering all numbers in n steps?
On Friday, 26 February 2016 at 14:59:43 UTC, Andrei Alexandrescu wrote: On 02/25/2016 06:46 PM, Nicholas Wilson wrote: The technical name for the property of distribution you describe is k-Dimensional Equidistribution (in this case k=1). I would suggest taking a look at http://www.pcg-random.org. They claim to have both arbitrary period and k-Dimensional Equidistribution Thanks, that's indeed closest! A hefty read. Anyone inclined to work on a PCG random implementation? -- Andrei Beat you to it: http://code.dlang.org/packages/d-pcg It only has the basic generators at the moment. I'll look into the more advanced stuff. (Also 64 bit outputs aren't implemented yet because they need a 128 bit uint for state. I noticed D reserves the names cent and ucent but hasn't implemented them)
Re: Vulkan bindings
On Thursday, 18 February 2016 at 03:39:30 UTC, Kapps wrote: On Thursday, 18 February 2016 at 03:38:42 UTC, Kapps wrote: This is what I did with OpenGL for my own bindings. It had some nice benefits like having the documentation be (mostly) accessible. Unfortunately, turns out the spec contains a lot of typos, including wrong arguments / function names. And I should clarify, ahead of time to generate a .d file, not at compile-time. :P Yea, by "directly", I meant using D templates and CTFE, not a script that generates a D file. For my own project, since I just need the function names, I'm using a Python script to generate a CSV file from the OpenGL spec, then importing/parsing that with D. It's neat, but slows down the build a lot. I haven't had any issues with typos, though.
Re: Vulkan bindings
On Tuesday, 16 February 2016 at 19:01:58 UTC, Satoshi wrote: Hello Vulkan API 1.0 is here and I just wrapped it into D. https://github.com/Rikarin/VulkanizeD Have fun! Please consider making it a Dub package! (IMO It would be cool to generate OpenGL and Vulkan bindings directly from the XML spec; std.xml doesn't work in CTFE. Though it would probably take a long time to compile)
Re: C Macro deeper meaning?
On Sunday, 31 January 2016 at 02:58:28 UTC, Andrew Edwards wrote: If I understand correctly, this piece of code: enum NOTUSED(v) do { (void)(1 ? (void)0 : ( (void)(v) ) ); } while(0) can be converted to the following in D: void notUsed(T)(T v) { return cast(void)0; }; since it always returns cast(void)0 regardless of the input. But it cannot be that simple, so what am I missing? Thanks, Andrew Edwards Might want to change the function argument to `ref T v`, as struct postblits might run otherwise. Probably no reason to `return` either.
Re: Nothrow front() when not empty()
On Wednesday, 6 January 2016 at 14:17:51 UTC, anonymous wrote: try return !haystack.empty && pred(haystack.front); Might want to use std.exception.assumeWontThrow instead return assumeWontThrow(!haystack.empty && pred(haystack.front)); http://dlang.org/phobos/std_exception.html#.assumeWontThrow
Re: link to C++ function in a namespace whose name is a D keyword
On Wednesday, 6 January 2016 at 18:35:07 UTC, Carl Sturtivant wrote: Hello, From D I want to call e.g. /* C++ prototype */ namespace ns { int try(int x); } without writing a C or C++ wrapper. Presumably the following D doesn't work, because it doesn't mangle the name as if it's in the namespace ns. pragma(mangle, "try") extern(C++, ns) int try_(int x); So how to I get correct mangling here? Isn't try a C++ keyword though? Wouldn't that make it impossible to use in an identifier?
Re: reduce a BitArray[]
On Tuesday, 29 December 2015 at 09:26:31 UTC, Alex wrote: The problem is, that the last line with the reduce does not compile. Why? If you get an error, it is imperative that you tell us what it is. For the record, this code: import std.bitmanip; import std.stdio; import std.algorithm; void main() { BitArray[] arr7 = [BitArray([0, 1, 0, 1, 0, 1]), BitArray([0, 1, 0, 0, 0, 0]), BitArray([0, 1, 0, 1, 0, 0]), BitArray([0, 1, 0, 1, 0, 0])]; BitArray common = BitArray([1,1,1,1,1,1]); foreach(BitArray ba; arr7) { common &= ba; } writeln("common2: ", common); writeln("common1: ", reduce!((a,b) => a & b)(arr7)); } Gives me the error: /opt/compilers/dmd2/include/std/algorithm/iteration.d(2570): Error: variable f868.main.F!(__lambda1).e cannot be declared to be a function /opt/compilers/dmd2/include/std/meta.d(546): Error: template instance f868.main.F!(__lambda1) error instantiating /opt/compilers/dmd2/include/std/algorithm/iteration.d(2477): instantiated from here: staticMap!(ReduceSeedType, __lambda1) /d486/f868.d(16):instantiated from here: reduce!(BitArray[]) /d486/f868.d(16): Error: template std.algorithm.iteration.reduce cannot deduce function from argument types !((a, b) => a & b)(BitArray[]), candidates are: /opt/compilers/dmd2/include/std/algorithm/iteration.d(2451): std.algorithm.iteration.reduce(fun...) if (fun.length >= 1) On 2.069.1 (dpaste: http://dpaste.dzfl.pl/8d7652e7ebeb). I don't have time ATM to diagnose it further. It definitely shouldn't be that cryptic of an error message.
Re: argument type const char* can pass string, buf why const wchar* can not pass wstring
On Sunday, 27 December 2015 at 03:34:18 UTC, riki wrote: void ccf(const char* str){} void cwf(const wchar* str){} void main() { ccf("aaa");//ok cwf("xxx"w); // error and why ? } Unrelated to your error, but those functions should probably take a `string` and `wstring` respectively instead.
Re: Convert to string an enum item
On Wednesday, 23 December 2015 at 13:11:28 UTC, tcak wrote: [code] import std.stdio; import std.conv; enum Values: ubyte{ One = 1, Two = 2 } void main(){ writeln( std.conv.to!string( Values.One ) ); } [/code] Output is "One". casting works, but to be able to cast correctly, I need to tell compiler that it is "ubyte". Isn't there any NON-HACKISH solution to print out the value of enum item? And do not decrease the performance as well please. It runs on web server. So you want the enum's integer value? Try casting it to an integer. writeln(cast(ubyte) Values.One);
Re: Why should file names intended for executables be valid identifiers?
On Tuesday, 15 December 2015 at 03:31:18 UTC, Shriramana Sharma wrote: I expect it should not be difficult for the compiler to see that this D file is not a module being imported by anything else or even being compiled to a library which would need to be later imported. In which case, why does it insist that the file should be given a valid module name? All files in D are modules. The only thing special about the "main" module is that it exports a function called `main`, which druntime calls at startup. It's like asking why you need to have a class in Java that only contains `public static void main(...)`, instead of just having the main function itself; it's simply how D is designed, and it reduces the number of special cases. Though after compiling, module names are irrelevant; you can name the binary whatever you want: `dmd -o whatever-filename.exe my_module.d` Name mangling is irrelevant; you can't have a dash in the module name because it would make certain code ambiguous (ex. `foo.my-module.bar`: is one module field reference or a subtraction between two field references?)
Re: deep copying / .dup / template object.dup cannot deduce function from argument types
On Sunday, 13 December 2015 at 18:54:24 UTC, Robert M. Münch wrote: Hi, I just wanted to naively copy an object and used: a = myobj.dup; and get the following error messages: source/app.d(191): Error: template object.dup cannot deduce function from argument types !()(BlockV), candidates are: /Library/D/dmd/src/druntime/import/object.d(1872): object.dup(T : V[K], K, V)(T aa) /Library/D/dmd/src/druntime/import/object.d(1908): object.dup(T : V[K], K, V)(T* aa) /Library/D/dmd/src/druntime/import/object.d(3246): object.dup(T)(T[] a) if (!is(const(T) : T)) /Library/D/dmd/src/druntime/import/object.d(3262): object.dup(T)(const(T)[] a) if (is(const(T) : T)) /Library/D/dmd/src/druntime/import/object.d(3273): object.dup(T : void)(const(T)[] a) Hmm... so, is .dup not the way to go? And, am I correct, that a deep-copy needs to be hand coded? `dup` is an array method; it only works on arrays. Structs are value types, so `a = b` will "duplicate" a struct. For classes, you will need to define your own clone function.
Re: How do you create an opengl window with DerelictOrg?
On Monday, 7 December 2015 at 21:33:57 UTC, Enjoys Math wrote: I've seen these: https://github.com/DerelictOrg?page=1 BUt not sure how to use them, examples? Derelict is just bindings for other libraries, for using C libraries with D. Pick a library that does windows management (I use GLFW, but I also see SFML and SDL), find the docs for them.
Re: AA struct hashing bug?
On Monday, 7 December 2015 at 18:48:18 UTC, Random D user wrote: struct Foo { this( int k ) { a = k; } int a; } Foo foo; int[ Foo ] map; map[ foo ] = 1; // Crash! bug? // This also crashes. I believe crash above makes a call like this (or similar) in the rt. //auto h = typeid( foo ).getHash( ); // Crash! win64 & dmd 2.69.2 Also works on DMD v2.069.2 on XUbuntu Linux x64. I can try it on Windows later. Exact code I tested: struct Foo { this( int k ) { a = k; } int a; } void main() { Foo foo; int[ Foo ] map; map[ foo ] = 1; }
Re: mutex usage problem?
On Wednesday, 2 December 2015 at 13:55:02 UTC, Ish wrote: The following code does core dump (compiled with gdc). Pointers will be appreciated. import std.stdio; import std.conv; import std.math; import std.concurrency; import core.thread; import core.sync.mutex; enum count = 5; __gshared double rslt = 0.0; __gshared Mutex mutex; void term(immutable(int)* nterm) { double r; auto n = to!double(*nterm); r = 4.0*pow(-1.0, *nterm)/(2.0*n + 1); writefln("%s: %6.6f.", *nterm, r); mutex.lock(); rslt = rslt + r; mutex.unlock(); } void main() { foreach (i; 0 .. count) { int* jm = new int; *jm = i; immutable int *j = cast(immutable) jm; Tid tid = spawn(, j); } thread_joinAll(); writefln("Result: %6.9f.", rslt); } -ish You never initialize Mutex, so it is a null pointer when you call `mutex.lock`. Also, no point in passing a pointer here; just pass `i` instead of `j`.
Re: std.socket replacement
On Sunday, 29 November 2015 at 09:12:14 UTC, tired_eyes wrote: On Sunday, 29 November 2015 at 09:05:37 UTC, tcak wrote: On Sunday, 29 November 2015 at 08:56:30 UTC, tired_eyes wrote: I was a bit surprised to see that std.socket is deprecated as of 2.069. Just curious, what's wrong with it? And what should I use as a replacement? I know there is vibe.socket, but I don't want to include fullstack web framework as a dependency just to make some HTTP reqests. I also don't see any proposed replacements in a review queue. Will std.socket and std.socketstream be just thrown away? I would say "WTF" at first, then checked the documentation, but don't see anything about deprecation. My current whole business relies on that. Wow, sorry, I meant std.stream and std.socketstream, not std.socket and std.socketstream std.stream, and the stream interface in general, is deprecated in favor of ranges, which are more generic and flexible.
Re: Password Storage
On Friday, 27 November 2015 at 00:17:34 UTC, brian wrote: I'm starting to build a small web-based application where I would like to authenticate users, and hence need to store passwords. After reading this: http://blog.codinghorror.com/youre-probably-storing-passwords-incorrectly/ and many other posts that I zombie-surfed to from that page, I'm now fearful of doing this badly. :( My reading of that post was that I should be storing things as: hash = md5('salty-' + password) So when a user tries to authenticate, I need to: 1) validate the user id 2) find the unique "salt" I generated for that user when they registered 3) pre- or post-pend the salt to the password entered (apparently there is a difference??) 4) md5 the lot 5) check this md5(salt+password) against what I have stored. So for each user, I need to store in my database: UserName/UserID Salt Hashed_Password Can the developers in the room confirm if this is the correct approach? Are there examples of betters ways of doing this? Regards Brian Do not use MD5 or SHA for hashing passwords. Use PBKDF2, bcrypt, or maybe scrypt. There should be C libraries available for those algorithms; use them. More info: http://security.stackexchange.com/questions/211/how-to-securely-hash-passwords/31846#31846
Re: Password Storage
On Friday, 27 November 2015 at 00:50:25 UTC, brian wrote: Thanks for the blatant faux pas. I wasn't going to use MD5, I just meant "hash it somehow", which was not apparent from my question. My bad. Algorithm aside, the rest of that approach seems sensible then? The hash implementation was probably going to be a part 2 of this question. I'd use dcrypt (https://github.com/puzzlehawk/dcrypt) to keep all the d-goodness, but according to the author, that's not "production ready" yet. In lieu of that, I'll have a gander at those libraries you mentioned. Yea. I've used bcrypt a few times; it's usually just using the hash function to hash the passwords, then the check function to check them, and that's it (bcrypt stores the salt along with the password). I don't know if I'd trust dcrypt yet. No offence to the authors, but I doubt that it has gone through the review that more popular C libraries have.