Re: Struct immutable data and dict

2018-09-04 Thread nkm1 via Digitalmars-d-learn

On Tuesday, 4 September 2018 at 11:25:15 UTC, Alex wrote:

On Tuesday, 4 September 2018 at 10:30:24 UTC, Timoses wrote:


However, of course this also fails because randomly assigning 
the array elements will overwrite it. So the associative array 
seems like the better idea. However, not being able to 
INITIALIZE an assoc array element disallows its usage.


Is there any solution, trick or workaround??

I tried two workarounds:
1) let the immutable away.
2) preallocate a full array of immutables. Then, misuse the 
assoc array by using the keys only. If the key is there, then, 
yield the appropriate element from the preallocated array. If 
not, yield the "elephant in Cairo".


I also had this problem recently. I think aa.require() should 
allow to add immutables (feature request). Anyway, my workaround 
was along the lines of:


final class AA(Key, Value)
{
Value[] _storage;
size_t[Key] _aa;

void opIndexAssign(Value value, Key key)
{
if (key !in _aa)
{
_storage ~= value;
_aa[key] = _storage.length - 1;
}
}

Value opIndex(Key key)
{
if (auto index = key in _aa)
return _storage[*index];

throw new Exception("no key");
}
}

immutable struct S
{
int num;
}

void main()
{
import std.stdio : writeln;

auto aa = new AA!(string, S);

aa["one"] = S(1);
aa["two"] = S(2);

writeln(aa["one"]);
writeln(aa["two"]);
}



Re: extern __gshared const(char)* symbol fails

2018-08-31 Thread nkm1 via Digitalmars-d-learn

On Friday, 31 August 2018 at 06:20:09 UTC, James Blachly wrote:

Hi all,

I am linking to a C library which defines a symbol,

const char seq_nt16_str[] = "=ACMGRSVTWYHKDBN";

In the C sources, this is an array of 16 bytes (17 I guess, 
because it is written as a string).


In the C headers, it is listed as extern const char 
seq_nt16_str[];


When linking to this library from another C program, I am able 
to treat seq_nt16_str as any other array, and being defined as 
[] fundamentally it is a pointer.


No. This is a misconception. Fundamentally, it's an array.



When linking to this library from D, I have declared it as:

extern __gshared const(char)* seq_nt16_str;

***But this segfaults when I treat it like an array (e.g. by 
accessing members by index).***


Because I know the length, I can instead declare:

extern __gshared const(char)[16] seq_nt16_str;

My question is: Why can I not treat it opaquely and use it 
declared as char* ? Does this have anything to do with it being 
a global stored in the static data segment?


For the same reason you can't do it in C.

--- main.c ---
#include 

extern const char* array; /* then try array[] */

int main(void)
{
printf("%.5s\n", array);
return 0;
}

--- lib.c ---
const char array[] = "hello world";


# gcc -o main main.c lib.c
# ./main
Segmentation fault

You need to declare your extern array as array in D and also in 
C, so that the compiler would know what that is (an array, not a 
pointer). In many situations C compiler would silently convert an 
array into a pointer (when it already knows its dealing with 
array), but it won't convert a pointer into an array.


Re: GC and void[N] in struct

2018-08-06 Thread nkm1 via Digitalmars-d-learn

On Monday, 6 August 2018 at 18:22:24 UTC, vit wrote:

Hello,
I have this struct:

struct S{
uint kind;
void[N] data_;

}

Instances of struct S are allocated by standard GC new and 
S.data_ can contain pointers/ranges to GC allocated data.
If is GC disabled then  program run fine. But when is GC 
enabled then it fail randomly.


If the definition of S look like this:

struct S{
void[N] data_;
uint kind;
}

then program run fine with GC.enable.

Whats the problem? Something with alignment?


Probably. Try something like:

struct S
{
uint kind;
align((void *).alignof) void[N] data_;
}

And see if it solves the problem.


Re: Compile-time variables

2018-04-06 Thread nkm1 via Digitalmars-d-learn

On Friday, 6 April 2018 at 13:10:23 UTC, Kayomn wrote:
ID tags are unique and spsecific to the class type. There 
shouldn't be more than one type ID assigned to one class type.


The idea behind what it is I am doing is I am implementing a 
solution to getting a type index, similar to 
std.variant.Variant.type(). The way that I implemented this in 
C++ is like so:



inline unsigned int getNodeTypeID() {
static unsigned int lastID = 0;

return lastID++;
}

template inline unsigned int getNodeTypeID() {
static unsigned int typeID = getNodeTypeID();

return typeID;
}


In this C++ example I am exploiting the fact that templates are 
generated at compile-time to execute getNodeTypeID for each new 
type instance generated. After initial type generation, 
whenever they are called at runtime they were return the ID 
assigned to that function template instance that was generated 
at compile-time.


It's pretty simple, and to be honest I'm surprised this has 
been causing me such a headache implementing it in D.


That's because the C++ code doesn't do what you think it does. 
Apparently you think that getNodeID() is executed at compile 
time. This is not the case, which you can verify by adding 
"constexpr" to it:


$ g++ -std=c++14 -Wall -Wextra -c -o example example.cpp
main.cpp: In function ‘constexpr unsigned int getNodeTypeID()’:
main.cpp:2:25: error: ‘lastID’ declared ‘static’ in ‘constexpr’ 
function

 static unsigned int lastID = 0;

In fact, you're "exploiting" the fact that static variables in 
C++ can be initialized at runtime (which is probably not what you 
want).

The equivalent D code is:

uint newID()
{
static uint lastID;

return lastID++;
}

uint getNodeID(T)()
{
static bool inited;
static uint id;

if (!inited)
{
id = newID();
inited = true;
}

return id;
}

(yes, C++ does insert some hidden bool that tells it whether the 
variable was initialized or not).
Naturally, you can't use that for constructing switches or other 
compile time constructs.


Re: #import mapi.h

2018-03-21 Thread nkm1 via Digitalmars-d-learn
On Wednesday, 21 March 2018 at 16:22:45 UTC, Martin Tschierschke 
wrote:
Is there an step by step introduction how to convert a C header 
of an external lib into the right extern(C){} block?


A blog post or tutorial, or chapter in a D book? (I have those 
from Packt Publishing)


(Especially I am trying to get this used with D:
Montetdb C-API 
https://www.monetdb.org/Documentation/Manuals/SQLreference/Programming/MAPI
With: 
https://github.com/snaga/monetdb/blob/master/clients/mapilib/mapi.h)


The page: https://dlang.org/spec/interfaceToC.html is known, 
but not detailed enough for me.


The easiest thing to do is to write a wrapper in C. The wrapper 
will include all necessary headers and provide some easy to use 
functions that you can call from D. Of course, you'll need to use 
a C compiler to compile it.
Anyway, this header looks very straightforwar, no particular 
tricks with the preprocessor. It should be something like this 
(untested, obviously):


import core.stdc.stdio : FILE;

enum
{
MAPI_AUTO  = 0,  /* automatic type detection */
MAPI_TINY  = 1,
MAPI_UTINY = 2,
MAPI_SHORT = 3,
MAPI_USHORT= 4,
MAPI_INT   = 5,
MAPI_UINT  = 6,
MAPI_LONG  = 7,
MAPI_ULONG = 8,
MAPI_LONGLONG  = 9,
MAPI_ULONGLONG = 10,
MAPI_CHAR  = 11,
MAPI_VARCHAR   = 12,
MAPI_FLOAT = 13,
MAPI_DOUBLE= 14,
MAPI_DATE  = 15,
MAPI_TIME  = 16,
MAPI_DATETIME  = 17,
MAPI_NUMERIC   = 18,
}

enum int PLACEHOLDER = '?';

enum
{
MAPI_SEEK_SET = 0,
MAPI_SEEK_CUR = 1,
MAPI_SEEK_END = 2,
}

enum
{
MAPI_TRACE  = 1,
MAPI_TRACE_LANG = 2,
}

alias MapiMsg = int;

enum
{
MOK =  0,
MERROR  = -1,
MTIMEOUT= -2,
MMORE   = -3,
MSERVER = -4,
}

enum
{
LANG_MAL= 0,
LANG_SQL= 2,
LANG_JAQL   = 3,
}

/* prompts for MAPI protocol */
enum int PROMPTBEG = '\001'; /* start prompt bracket */

 /* prompt: ready for new query */
const(char)* PROMPT1 = "\001\001\n".ptr;

/* prompt: more data needed */
const(char)* PROMTP2 = "\001\002\n".ptr;

/*
 * The table field information is extracted from the table headers
 * obtained from the server. This list may be extended in the 
future.

 * The type of both the 'param' and 'binding'
 * variables refer to their underlying C-type. They are used for
 * automatic type coercion between back-end and application.
 */
struct MapiStruct;
alias Mapi = MapiStruct*;

/* this definition is a straight copy from 
sql/include/sql_query.h */

enum
{
Q_PARSE = 0,
Q_TABLE = 1,
Q_UPDATE= 2,
Q_SCHEMA= 3,
Q_TRANS = 4,
Q_PREPARE   = 5,
Q_BLOCK = 6,
}

struct MapiStatement;
alias MapiHdl = MapiStatement*;

alias mapi_uint64 = ulong;
alias mapi_int64 = long;

/* three structures used for communicating date/time information 
*/
/* these structs are deliberately compatible with the ODBC 
versions

   SQL_DATE_STRUCT, SQL_TIME_STRUCT, and SQL_TIMESTAMP_STRUCT */

/* used by MAPI_DATE */
struct MapiDate
{
short year;
ushort month;
ushort day;
}

/* used by MAPI_TIME */
struct MapiTime
{
ushort hour;
ushort minute;
ushort second;
}

/* used by MAPI_DATETIME */
struct MapiDateTime
{
short year;
ushort month;
ushort day;
ushort hour;
ushort minute;
ushort second;
uint fraction;  /* in 1000 millionths of a second (10e-9) */
}

/* connection-oriented functions */
extern (C)
{
Mapi mapi_mapi(const char *host,
   int port,
   const char *username,
   const char *password,
   const char *lang,
   const char *dbname);


// and so on...
}


Re: Is it possible to specify the address returned by the address of operator?

2017-09-27 Thread nkm1 via Digitalmars-d-learn
On Wednesday, 27 September 2017 at 20:24:24 UTC, DreadKyller 
wrote:
The attitude of "some people use this feature incorrectly, so 
let's ban it's use entirely" is honestly ridiculous to me, but 
oh well, that's apparently the modern philosophy.


Not even modern, see Java :) ("I left out operator overloading as 
a fairly personal choice because I had seen too many people abuse 
it in C++." - James Gosling)


Re: Is it possible to specify the address returned by the address of operator?

2017-09-27 Thread nkm1 via Digitalmars-d-learn
On Wednesday, 27 September 2017 at 16:35:54 UTC, DreadKyller 
wrote:
Been using D for a couple years now, however one problem I've 
had, more so recently since I've been dealing a lot with OpenGL 
is related to pointers.


I have a matrix object to aid with the matrix math required for 
working with 3D transforms. However OpenGL (I'm using 
DerelictGL3 bindings) requires pointers to the data. I am 
currently doing the following:


Matrix!float ortho(float l, float r, float b, float t, float f, 
float n = -1)

{
Matrix!float oMat = identity(); // Get default Identity Matrix

oMat[0,0] =  2 / (r - l);
oMat[1,1] =  2 / (t - b);
oMat[2,2] = -2 / (f - n);

oMat[3] = [-(r+l)/(r-l), -(t+b)/(t-b), -(f+n)/(f-n), 1];

return oMat;
}

And then to use with OpenGL (passing as uniform into shader):

glUniformMatrix4fv(transform_uniform, 1, GL_FALSE, matrix.addr 
);


where addr is a property that returns the address of the first 
item in the Matrix's internal data. I know I can also use 
[0][0]


My question is about overloading, several operators can be 
overloaded in D, one of the ones that can't apparently is the 
address of operator (). My question is have I simply 
missed it or does it actually not exist, and if it's not 
overloadable, is there any reason why this was decided? Because 
there's been numerous times that it'd be useful to me, just 
recently with how much I use the operator because of OpenGL I 
decided to ask.


& is not overloadable, presumably because some people were 
annoyed by abuse of operator overloading in C++. The reason is to 
improve readability (of other people's code).
Just rename matrix.addr to matrix.ptr... like in arrays: 
https://dlang.org/spec/arrays.html#array-properties
That would be clearer (opinion), since the reader of your code 
can assume that matrix.ptr does the same thing with your matrix 
as array.ptr does with arrays. OTOH, overloading  to do 
something different from built in  seems like a pointless 
obfuscation to me.


Re: [OT] Converting booleans to numbers

2017-09-20 Thread nkm1 via Digitalmars-d-learn

On Wednesday, 20 September 2017 at 19:25:58 UTC, Timon Gehr wrote:

Actually, it is useful enough to have a Wikipedia page:
https://en.wikipedia.org/wiki/Iverson_bracket


Mmmm... "The notation was originally introduced by Kenneth E. 
Iverson in his programming language APL".
APL... yeah :) Programmers didn't like it, did they. Anyway, that 
seems to be explicit notation, analogous to (cond ? 1 : 0).



Example of a good use:

void floodFill(dchar[][] data,dchar c,int i,int j) {
void dfs(int a, int b) {
if (a<0 || a >= data.length) return;
if (b<0 || b >= data[a].length) return;
if (data[a][b] == c) return;
data[a][b] = c;
foreach(i; 0 .. 4){
dfs(a + (i==0) - (i==1),
b + (i==2) - (i==3));
}
}
dfs(i, j);
}


I don't agree it's a good use. Actually, that seems quite 
obfuscated to me. Consider:

foreach (point; [[1, 0], [-1, 0], [0, 1], [0, -1]]) {
dfs(a + point[0], b + point[1]);
}
Finds some random 10 programmers and ask them what's easier to 
understand...
Also, in my experience (in C and C++) it is extremely rare for 
programmers to use booleans in arithmetic. So even if in some 
situation you would have to replace this thing with more verbose 
(i == 0 ? 1 : 0), it's no big deal.
OTOH, booleans being numbers is a source of some bugs (just like 
other cases of weak typing). Not a ton of bugs, but the utility 
of implicit conversion to numbers is so unnoticeable that I'm 
sure it's just not worth it.


Re: What the hell is wrong with D?

2017-09-19 Thread nkm1 via Digitalmars-d-learn
On Wednesday, 20 September 2017 at 02:16:16 UTC, EntangledQuanta 
wrote:
Your an idiot, I know about how operator precedence works far 
more than you do. Wanna bet? how much? Your house? your wife? 
Your life? It's about doing things correctly, you seem to fail 
to understand, not your fault, can't expect a turd to 
understand logic.


Ok, you win. I see now that you're very smart :)



Re: What the hell is wrong with D?

2017-09-19 Thread nkm1 via Digitalmars-d-learn
On Tuesday, 19 September 2017 at 17:40:20 UTC, EntangledQuanta 
wrote:
Yeah, that is really logical! No wonder D sucks and has so many 
bugs! Always wants me to be explicit about the stuff it won't 
figure out but it implicitly does stuff that makes no sense. 
The whole point of the parenthesis is to inform the compiler 
about the expression to use. Not use everything to the left of 
?.


There are two issues there; operator precedence and booleans 
(_win[0] == '@') being a valid operands to +.
If someone is too stupid to learn how precedence works, they 
should consider a different career instead of blaming others.
OTOH, booleans converting to numbers is a very questionable 
feature. I certainly have never seen any good use for it. This is 
just an unfortunate legacy of C, which didn't even have booleans 
for a long time.




Re: extern(C) enum

2017-09-17 Thread nkm1 via Digitalmars-d-learn

On Sunday, 17 September 2017 at 17:06:10 UTC, bitwise wrote:
I don't really see a way to deal with this aside from branching 
the entire library and inserting something like 
'FT_SIZE_REQUEST_TYPE__FORCE_INT = 0x' into every enum 
incase the devs used it in a struct.


Just put the burden on the users then. It's implementation 
defined, so they are in position to figure it out...


for example, gcc: "Normally, the type is unsigned int if there 
are no negative values in the enumeration, otherwise int. If 
-fshort-enums is specified, then if there are negative values it 
is the first of signed char, short and int that can represent all 
the values, otherwise it is the first of unsigned char, unsigned 
short and unsigned int that can represent all the values. On some 
targets, -fshort-enums is the default; this is determined by the 
ABI."

https://gcc.gnu.org/onlinedocs/gcc-6.4.0/gcc/Structures-unions-enumerations-and-bit-fields-implementation.html#Structures-unions-enumerations-and-bit-fields-implementation

msvc++: "A variable declared as enum is an int."
https://docs.microsoft.com/en-us/cpp/c-language/enum-type

It's probably pretty safe to assume it's an int; people who play 
tricks with "-fshort-enums" deserve what's coming to them :)


Re: extern(C) enum

2017-09-16 Thread nkm1 via Digitalmars-d-learn
On Saturday, 16 September 2017 at 03:06:24 UTC, Timothy Foster 
wrote:
You are correct, however 6.7.2.2 "Enumeration specifiers" 
states: "Each enumerated type shall be compatible with char, a 
signed integer type, or an unsigned integer type. The choice of 
type is implementation-defined, but shall be capable of 
representing the values of all the members of the enumeration."


I believe that means that if you have the following:

enum ABC { A, B, C }

Then A, B, and C are by themselves ints, but the enum type ABC 
can be a char if the compiler decides that's what it wants it 
to be.


Oops, you're right. Then the situation must be the same as in 
C++? If enum ABC is by itself a parameter of a function, the 
argument will be int (and if it weren't, it would be promoted to 
int anyway), but if the enum is a part of a structure, then it 
can be anything...
At least, if enumerators themselves are ints, the enum type 
probably won't be larger than an int... small consolation :)


Re: extern(C) enum

2017-09-15 Thread nkm1 via Digitalmars-d-learn
On Friday, 15 September 2017 at 19:21:02 UTC, Timothy Foster 
wrote:
I believe C enum size is implementation defined. A C compiler 
can pick the underlying type (1, 2, or 4 bytes, signed or 
unsigned) that fits the values in the enum.


No, at least, not C99. See 6.4.4.3: "An identifier declared as an 
enumeration constant has type int". You must be thinking about 
C++.


Re: Inout table

2017-09-13 Thread nkm1 via Digitalmars-d-learn
On Wednesday, 13 September 2017 at 17:39:29 UTC, Steven 
Schveighoffer wrote:

Correct. So given a function:

inout(int*) foo(inout(int*)p1, inout(int*)p2)

The table shows what inout is resolved as when calling the 
function.


If you consider the column the mutability of p1, and the row 
the mutability of p2, then the value in the table represents 
the mutability of the return value.


So for instance:

int *m;
const int *c;
immutable int *i;
inout int *w;

auto v1 = foo(m, m); // typeof(v1) is int*
auto v2 = foo(m, c); // typeof(v2) is const(int*)
auto v3 = foo(i, m); // typeof(v3) is const(int*)
auto v4 = foo(w, w); // typeof(v4) is inout(int*)
auto v5 = foo(w, i); // typeof(v5) is inout(const(int *))

etc.


Thank you. Now it is clear to me. The source of my confusion was 
that, say, given a function:

inout(int*) foo(inout(int*) p)
as per table, combining (mutable) argument int* m with parameter 
inout(int*) p would produce parameter type const(int*). But now I 
see that the table deduces the common type of all parameters, not 
the common type of a parameter and its argument (the 
documentation is kind of hard to parse: "If such a match occurs, 
the inout is considered the common qualifier of the matched 
qualifiers...").


Re: Adding empty static this() causes exception

2017-09-12 Thread nkm1 via Digitalmars-d-learn

On Tuesday, 12 September 2017 at 19:59:52 UTC, Joseph wrote:
The compiler shouldn't arbitrarily force one to make arbitrary 
decisions that waste time and money.


You might want to educate yourself about arbitrary decisions that 
waste time and money: 
https://isocpp.org/wiki/faq/ctors#static-init-order




My solution was to turn those static this's in to functions and 
simply call them at at the start of main(). Same effect yet 
doesn't crash. The compiler should only run the static this's 
once per module load anyways, right? If it is such a problem 
then some way around it should be included: @force static 
this() { } ?


There is a way, turn static this's into functions and simply call 
them at the start of main().


The compiler shouldn't make assumptions about the code I write 
and always choose the worse case, it becomes an unfriendly 
relationship at that point.


If you want C++, you know where to find it, although I wouldn't 
exactly call it "friendly".





Re: Override with function overloads

2017-09-11 Thread nkm1 via Digitalmars-d-learn

On Monday, 11 September 2017 at 18:15:36 UTC, jmh530 wrote:
An interesting example. I'm not sure overriding is the issue so 
most as what is in the overload set. I think foo(int) is not 
part of the overload set yet. The compiler is able to cast the 
long to int and then call the one in class B without needing to 
look to the base class. The behavior is also the same if you 
use alias this (below).


It's just an issue (not really an issue :) of name lookup. First, 
compiler searches for names, that is, for something called "foo". 
Then, when it finds "foo" (or several in the same scope), it does 
overload resolution on them. If those are wrong names, it just 
reports an error, for example:


class A {
final void foo(int) {
writeln("A.foo(int)");
}
}

class B : A {
string foo = "bar";
}

void main() {
B b = new B;
int n = 1;
b.foo(n);
}

While looking for names, it doesn't even care if "foo" is a 
function or whatever.




Would there be any problems with final functions of inherited 
or alias this types being included in the overload set?




I don't know, maybe don't use alias this :) IMO, it's a really 
dubious feature...


Re: Override with function overloads

2017-09-11 Thread nkm1 via Digitalmars-d-learn

On Monday, 11 September 2017 at 15:13:25 UTC, jmh530 wrote:
I suppose my issue is that final should prevent function 
hijacking because I shouldn't be allowed to override string 
bar(double d) anyway. It shouldn't be a worry.


It has nothing to do with overriding. Consider:

import std.stdio;

class A {
final void foo(int) {
writeln("A.foo(int)");
}
}

class B : A {
final void foo(long) {
writeln("B.foo(long)");
}
}

void main() {
B b = new B;
int n = 1;
b.foo(n);
}

That prints "B.foo(long)", even though foo() was called with an 
int (tbh, I'd say it's hijacking and shouldn't even compile, like 
it doesn't with virtual functions - try to remove finals). The 
compiler starts looking from B, finds name "foo" and tries that 
without looking any futher into base classes.


If you want that, you can do it manually:

class Foo2 : Foo
{
alias bar = super.bar; // bring Foo.bars in scope
override void bar(int x) { }
}


Inout table

2017-09-08 Thread nkm1 via Digitalmars-d-learn
There is this little table in 
https://dlang.org/spec/function.html#inout-functions:


Common qualifier of the two type qualifiers
   mutable const  immutable inout inout const
mutable (= m)  m   c  c c c
const (= c)c   c  c c c
immutable (= i)c   c  i wcwc
inout (= w)c   c  wcw wc
inout const (= wc) c   c  wcwcwc

I don't understand what it is trying to say. What is it that is 
calculated here? The qualifier for the return value?

And what's an "inout const"?


Re: ushort calls byte overload

2017-05-30 Thread nkm1 via Digitalmars-d-learn

On Tuesday, 30 May 2017 at 21:16:26 UTC, Oleg B wrote:

Hello. I have this code

import std.stdio;

void foo(byte a) { writeln(typeof(a).stringof); }
void foo(short a) { writeln(typeof(a).stringof); }
void foo(int a) { writeln(typeof(a).stringof); }

void main()
{
foo(0); // int, and byte if not define foo(int)
foo(ushort(0)); // byte (unexpected for me)
foo(cast(ushort)0); // byte (unexpected too)

foo(cast(short)0); // short
foo(short(0)); // short

ushort x = 0;
foo(x); // short
}

Is this a bug or I don't understand something?


Hm, interesting. I think what you're seeing here is an unexpected 
application of value range propagation: 
http://www.drdobbs.com/tools/value-range-propagation/229300211


None of these functions can be called with ushort without 
conversions. As the manual says:


The function with the best match is selected. The levels of 
matching are:

no match
match with implicit conversions
match with conversion to const
exact match

All of your functions require some implicit conversions (the 
ushort here can be converted to byte because of value range 
propagation). So the next rule is in effect - the functions are 
ordered and the "most specialized" is chozen. The byte function 
is the most specialized, so it is called.

Or something like that :)

but if compiler find one-to-one correspondence it don't make 
assumptions, like here?
Apparently then it just chooses the function that is "exact 
match".





Re: Out of memory error (even when using destroy())

2017-05-27 Thread nkm1 via Digitalmars-d-learn

On Saturday, 27 May 2017 at 17:57:03 UTC, Mike B Johnson wrote:

And what if one isn't interfacing to C? All pointers should be 
known.


Apparently some people are (were?) working on semi-precise GC: 
https://github.com/dlang/druntime/pull/1603

That still scans the stack conservatively, though.

Therefor, in a true D program(no outsourcing) with no pointers 
used, the GC should never have to scan anything.
All realistic programs (in any language) use a lot of pointers - 
for example, all slices in D have embedded pointers (slice.ptr), 
references are pointers, classes are references, etc.


It seems the GC can be smarter than it is instead of just 
making blanket assumptions about the entire program(which 
rarely hold), which is generally always a poor choice when it 
comes to performance...
If you only have compile time information, making blanket 
assumptions is inevitable - after all, compiler can't understand 
how a nontrivial program actually works. The alternative is doing 
more work at runtime (marking pointers that changed since 
previous collection, etc), which is also not good for performance.


Who knows, some pointer externally might be peeping in on our 
hello world program.

Of course, there is a pointer :)

void main()
{
import std.stdio;

writeln("hello world".ptr);
}


Re: The syntax of sort and templates

2017-05-26 Thread nkm1 via Digitalmars-d-learn

On Friday, 26 May 2017 at 11:27:19 UTC, zakk wrote:
I have a followup question: my background is C and in Wolfram 
Mathematica, so my
knowledge of templates is limited to trivial examples in C++... 
It seems to me that

when programming in D templates are something more powerful


Even in C++ templates can work with more than just types (e.g., 
C++ templates accept other templates, numbers and pointers). And 
of course, D templates are even more powerful than in C++, so 
they can work with even more things:


TemplateTypeParameter
TemplateValueParameter
TemplateAliasParameter
TemplateSequenceParameter
TemplateThisParameter

(you can read about it here: 
https://dlang.org/spec/template.html#TemplateParameters)


Re: Why does this compile (method in class without return type)

2017-05-03 Thread nkm1 via Digitalmars-d-learn

On Wednesday, 3 May 2017 at 07:34:03 UTC, Daniel Kozák wrote:


print in A is template:



What :)
How does it interact with 'final'?


Re: Why does this compile (method in class without return type)

2017-05-03 Thread nkm1 via Digitalmars-d-learn

On Wednesday, 3 May 2017 at 06:54:15 UTC, nkm1 wrote:

final method type inference stuff


Jacob and Jonathan - thank you, this is clear to me now. 
Hopefully it will get fixed at some point.


Why does this compile (method in class without return type)

2017-05-03 Thread nkm1 via Digitalmars-d-learn

Consider:

import std.stdio;

class A
{
final print() { writeln(this); } // no return type
}

class B : A
{
final void print() { writeln(this); }
}

void main()
{
auto b = new B;
b.print();

A a1 = b;
a1.print();

A a2 = new A;
a2.print();
}

That compiles:

$ dmd -de -w -g ./main.d
$ main
main.B
main.B
main.A

with dmd 2.074 on linux:

$ dmd --version
DMD64 D Compiler v2.074.0
Copyright (c) 1999-2017 by Digital Mars written by Walter Bright

Is that a bug? (in the compiler). I'm learning D, and I'm half 
way through Andrei's book; I also read the documentation (on D's 
website) and I think that shouldn't compile?