Re: implicit conversions to/from shared

2016-07-10 Thread Alex Parrill via Digitalmars-d

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

2016-07-06 Thread Alex Parrill via Digitalmars-d-learn

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

2016-06-27 Thread Alex Parrill via Digitalmars-d-learn

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

2016-06-20 Thread Alex Parrill via Digitalmars-d-learn

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

2016-06-14 Thread Alex Parrill via Digitalmars-d-learn

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?

2016-06-12 Thread Alex Parrill via Digitalmars-d-learn

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?

2016-06-10 Thread Alex Parrill via Digitalmars-d-learn

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?

2016-06-10 Thread Alex Parrill via Digitalmars-d-learn

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

2016-06-10 Thread Alex Parrill via Digitalmars-d-learn

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

2016-06-09 Thread Alex Parrill via Digitalmars-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

2016-06-07 Thread Alex Parrill via Digitalmars-d-learn

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

2016-06-07 Thread Alex Parrill via Digitalmars-d-learn

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

2016-06-07 Thread Alex Parrill via Digitalmars-d-learn

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

2016-06-06 Thread Alex Parrill via Digitalmars-d-learn

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

2016-06-06 Thread Alex Parrill via Digitalmars-d-learn

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

2016-06-06 Thread Alex Parrill via Digitalmars-d-learn

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

2016-06-06 Thread Alex Parrill via Digitalmars-d-learn

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

2016-06-06 Thread Alex Parrill via Digitalmars-d-learn

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

2016-06-04 Thread Alex Parrill via Digitalmars-d

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

2016-06-01 Thread Alex Parrill via Digitalmars-d

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

2016-05-31 Thread Alex Parrill via Digitalmars-d

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?

2016-05-30 Thread Alex Parrill via Digitalmars-d-learn

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 ?

2016-05-30 Thread Alex Parrill via Digitalmars-d-learn

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

2016-05-30 Thread Alex Parrill via Digitalmars-d
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

2016-05-29 Thread Alex Parrill via Digitalmars-d
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

2016-05-29 Thread Alex Parrill via Digitalmars-d-announce

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

2016-05-28 Thread Alex Parrill via Digitalmars-d-announce

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...

2016-05-26 Thread Alex Parrill via Digitalmars-d-learn

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)

2016-05-25 Thread Alex Parrill via Digitalmars-d

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

2016-05-21 Thread Alex Parrill via Digitalmars-d-announce

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

2016-05-20 Thread Alex Parrill via Digitalmars-d-learn

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

2016-05-20 Thread Alex Parrill via Digitalmars-d-learn

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

2016-05-20 Thread Alex Parrill via Digitalmars-d-learn
(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 ?

2016-05-19 Thread Alex Parrill via Digitalmars-d-learn

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

2016-05-18 Thread Alex Parrill via Digitalmars-d

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

2016-05-18 Thread Alex Parrill via Digitalmars-d-learn

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

2016-05-09 Thread Alex Parrill via Digitalmars-d-learn

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

2016-05-06 Thread Alex Parrill via Digitalmars-d-learn

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?

2016-05-05 Thread Alex Parrill via Digitalmars-d-learn

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

2016-05-03 Thread Alex Parrill via Digitalmars-d-learn

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

2016-05-03 Thread Alex Parrill via Digitalmars-d-learn

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

2016-05-02 Thread Alex Parrill via Digitalmars-d

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

2016-04-26 Thread Alex Parrill via Digitalmars-d-learn

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

2016-04-21 Thread Alex Parrill via Digitalmars-d

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

2016-04-20 Thread Alex Parrill via Digitalmars-d-learn

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

2016-04-20 Thread Alex Parrill via Digitalmars-d-learn

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

2016-04-20 Thread Alex Parrill via Digitalmars-d

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

2016-04-20 Thread Alex Parrill via Digitalmars-d

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

2016-04-20 Thread Alex Parrill via Digitalmars-d-learn

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

2016-04-20 Thread Alex Parrill via Digitalmars-d-learn

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

2016-04-20 Thread Alex Parrill via Digitalmars-d-learn

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

2016-04-20 Thread Alex Parrill via Digitalmars-d

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

2016-04-20 Thread Alex Parrill via Digitalmars-d
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

2016-04-19 Thread Alex Parrill via Digitalmars-d
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

2016-04-16 Thread Alex Parrill via Digitalmars-d-learn

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

2016-04-15 Thread Alex Parrill via Digitalmars-d
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.

2016-04-10 Thread Alex Parrill via Digitalmars-d-learn

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

2016-04-08 Thread Alex Parrill via Digitalmars-d-learn

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

2016-04-07 Thread Alex Parrill via Digitalmars-d-learn

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?

2016-04-06 Thread Alex Parrill via Digitalmars-d-learn

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

2016-04-06 Thread Alex Parrill via Digitalmars-d

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

2016-04-06 Thread Alex Parrill via Digitalmars-d-learn

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?

2016-04-06 Thread Alex Parrill via Digitalmars-d-learn

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 ?

2016-04-06 Thread Alex Parrill via Digitalmars-d-learn

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?

2016-04-06 Thread Alex Parrill via Digitalmars-d-learn

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 ?

2016-04-05 Thread Alex Parrill via Digitalmars-d-learn

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{...}

2016-04-05 Thread Alex Parrill via Digitalmars-d

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

2016-04-01 Thread Alex Parrill via Digitalmars-d
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?

2016-04-01 Thread Alex Parrill via Digitalmars-d

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?

2016-03-26 Thread Alex Parrill via Digitalmars-d

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

2016-03-26 Thread Alex Parrill via Digitalmars-d-announce

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

2016-03-26 Thread Alex Parrill via Digitalmars-d-announce

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?

2016-03-26 Thread Alex Parrill via Digitalmars-d

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

2016-03-22 Thread Alex Parrill via Digitalmars-d

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

2016-03-19 Thread Alex Parrill via Digitalmars-d-announce

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

2016-03-19 Thread Alex Parrill via Digitalmars-d-announce

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

2016-03-19 Thread Alex Parrill via Digitalmars-d-learn

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

2016-03-19 Thread Alex Parrill via Digitalmars-d-announce

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

2016-03-07 Thread Alex Parrill via Digitalmars-d-learn

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

2016-03-03 Thread Alex Parrill via Digitalmars-d-learn

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?

2016-02-29 Thread Alex Parrill via Digitalmars-d-learn

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?

2016-02-29 Thread Alex Parrill via Digitalmars-d-learn

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?

2016-02-26 Thread Alex Parrill via Digitalmars-d
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?

2016-02-26 Thread Alex Parrill via Digitalmars-d
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

2016-02-18 Thread Alex Parrill via Digitalmars-d

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

2016-02-17 Thread Alex Parrill via Digitalmars-d

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?

2016-01-31 Thread Alex Parrill via Digitalmars-d-learn

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()

2016-01-06 Thread Alex Parrill via Digitalmars-d-learn

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

2016-01-06 Thread Alex Parrill via Digitalmars-d-learn
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[]

2015-12-29 Thread Alex Parrill via Digitalmars-d-learn

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

2015-12-26 Thread Alex Parrill via Digitalmars-d-learn

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

2015-12-23 Thread Alex Parrill via Digitalmars-d-learn

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?

2015-12-17 Thread Alex Parrill via Digitalmars-d-learn
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

2015-12-13 Thread Alex Parrill via Digitalmars-d-learn
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?

2015-12-07 Thread Alex Parrill via Digitalmars-d-learn

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?

2015-12-07 Thread Alex Parrill via Digitalmars-d-learn

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?

2015-12-02 Thread Alex Parrill via Digitalmars-d-learn

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

2015-11-29 Thread Alex Parrill via Digitalmars-d-learn

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

2015-11-26 Thread Alex Parrill via Digitalmars-d-learn

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

2015-11-26 Thread Alex Parrill via Digitalmars-d-learn

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.


  1   2   >