Re: template/mixin magic for to! auto inferring type from variable

2024-02-02 Thread Chris Katko via Digitalmars-d-learn

On Friday, 2 February 2024 at 21:01:53 UTC, Paul Backus wrote:


No, D only does bottom-up type inference, not top down.

If you want to avoid repeating the type, use `auto` on the left 
side:


```d
auto time = to!uint(data[1]);
auto priority = to!int(data[2]);
```


Okay thanks. It finally clicked what bottom-up/top-down type 
interference is.


The auto solution won't work for a struct however which I'm using:

```D
struct procTable{ //contains all the fields inside a file I'm 
parsing

   uint time;
   int priority;
   string name;
   // etc
   }
```



template/mixin magic for to! auto inferring type from variable

2024-02-01 Thread Chris Katko via Digitalmars-d-learn

Is there some way to do:
```D
string[3] data; //strings from some file input, some are ints, 
uints, etc.


auto into!(T)(T value){return to!???(value); } // ???

uint time = into!(data[1]); // We already know this is uint
int priority = into!(data[2]);
```

instead of:
```D
uint time = to!uint(data[1]); // specifying type twice
int priority = to!int(data[2])
```


Re: Would this be a useful construct to add to D? auto for constructor call.

2024-01-27 Thread Chris Katko via Digitalmars-d-announce
On Wednesday, 24 January 2024 at 08:22:49 UTC, Walter Bright 
wrote:

On 1/23/2024 8:01 AM, Steven Schveighoffer wrote:
zero proposals that infer type from how they are used have 
been accepted by Walter, this one probably will be no 
different.


Types are inferred in D from the bottom up. Mixing in special 
cases of it being top down leads to confusion over how the type 
is determined.


Thanks to everyone for the feedback. And sorry I selected the 
wrong forum. Apologies,

--Chris


Would this be a useful construct to add to D? auto for constructor call.

2024-01-22 Thread Chris Katko via Digitalmars-d-announce

```D
class dataGridLayerView{
   int t;
   this(int _t){
  t = _t;
  }
   }

class myClass{
   dataGridLayerView dataGrid;

   this()
  {
  dataGrid = new auto(15); // <--- new
  // instead of
  dataGrid = new dataGridLayerView(15);
  }
   }
```

Because it seems, conceptually, the compiler should know all the 
details required here to simply insert the right constructor 
name. Basically just the reverse of:


```D
auto t = sqrt(15);
```

So intuitively it makes sense to me.

It might even be possible to write a mixin to do this, I'm not 
sure.


I'm no D wizard, but I don't see any obvious name or lexing 
conflicts/ambiguity.


Cheers,
--Chris


How to write an interface but with different signatures

2023-11-19 Thread Chris Katko via Digitalmars-d-learn
I know that sounds stupid on the face of it. An interface 
shouldn't change. But consider this:


A frame timer and a clock timer(seconds) that re-use 
functionality from a parent class/interface.


```
class timerType
{
void start() = 0;
void stop() = 0;
void restart() = 0;
void set(?) = 0; // 
}

class frameTimer : timerType
{
void set(int numFrames){}
}

class clockTimer : timerType
{
void set(float numSeconds){}
}

```

If we put both signatures in the top we're kind of polluting the 
interface. If we don't put them in the interface, then you can 
create a timer with no set() function.


None of this is super important on a practical level. There's 
going to probably be a total of two or three timer types. But as 
a learning exercise, I'm curious if there is a right/proper/best 
way to solve this conceptual problem.


And to be clear, frames and seconds are NOT directly 
interchangeable or convertible. If the game runs at 2 FPS for a 
moment, a 5 second timer is still 5 seconds (e.g. a countdown), 
but a frame timer of 2 (for an animation) is still going to be 2 
frames.


Re: Print debug data

2023-07-16 Thread Chris Katko via Digitalmars-d-learn

On Monday, 17 July 2023 at 03:43:04 UTC, Alain De Vos wrote:

Is it possible to print runtime memory usage of:
-The stack
-The heap
-The garbage collector ?


there's gc.stats for part of it:

https://dlang.org/library/core/memory/gc.stats.html



Re: Advice on debugging possible exception or crash

2023-07-06 Thread Chris Katko via Digitalmars-d-learn

On Thursday, 6 July 2023 at 06:00:04 UTC, Cecil Ward wrote:
My program is instrumented with a load of writeflns. At one 
point it looks as though it suddenly quits prematurely because 
the expected writeflns are not seen in the output. It could be 
that I am just reading the flow of control wrong as it goes 
ret, ret etc. I’m wondering if it is throwing an exception, or 
has a fault initiating a crash, perhaps even due to the 
fetching of arguments of one of the writeflns. In my limited 
experience, exceptions produce an error message though, and I’m 
not seeing anything. Any advice on how to debug this, silent 
termination ?


I don’t have a debugger on this machine, but on an x86-64 box I 
could use gdb if I first take the time to work out how.


one thing I do is have gdb/lldb break on d assert, before it 
destroys the stack. That helped me catch a class of bugs.


```sh
# in the gdb interface before running
break _d_assertp
break _d_assert
break _d_assert_msg

# or to combine it into the commandline:
gdb -ex "break _d_assert" -ex "break _d_assert_msg" -ex "run $1" 
./main


# can also add it to your .gdbinit startup code.
```


Re: Options for Cross-Platform 3D Game Development

2023-07-06 Thread Chris Katko via Digitalmars-d-learn

On Wednesday, 5 July 2023 at 22:27:46 UTC, Andrew wrote:
So, I've gotten the itch to have a go at game development in D, 
after doing a bit of it in Java last year. I've previously used 
LWJGL, which is a java wrapper for OpenGL, OpenAL, GLFW, and 
some other useful libs.


The problem is, apparently OpenGL is deprecated for apple 
devices, so I don't really want to use that unless there are no 
decent alternatives.


So far, the most promising I've seen is 
[bindbc-bgfx](https://code.dlang.org/packages/bindbc-bgfx), but 
it's been a pain to set up due to having to build the bgfx 
codebase, which requires a specific version of glibc that my 
distro (Linux Mint) doesn't offer yet.


Are there any other recommendations for cross-platform 
rendering libraries? Of course I could use a pre-made game 
engine like Unity or Godot, but for me, most of the fun is in 
making the engine.


Are you trying to make a PC game, or a mobile game? Because in 
99% of cases I would pick a different toolchain for mobile than 
PC. OpenGL being depreciated on a single, walled-garden platform, 
does not rule it out for the entire rest of installed systems.


Only if I absolutely needed, cross-platform out-of-the-box with 
mobiles and PC, would I pick a package like, Xamarin. Which now 
forces me to use C#, and the size bloat of including a mono 
framework with all my apps. I would not pick Xamarin just because 
I wanted to keep my options open, I would d pick it because I 
have a planned application that needed to be 1:1 synced across 
iPhone, Android (and possibly PC).


There's also other options. Such as using a OpenGL -> Metal 
conversion layer, like MetalAngle:


https://github.com/kakashidinho/metalangle

https://chromium.googlesource.com/angle/angle

So be sure exactly what you want as the best tools for the job 
will depend greatly on the requirements of the project.




official activate script is super confusing

2023-07-01 Thread Chris Katko via Digitalmars-d-learn

https://dlang.org/install.html#activate

I ran the two curl liners for grabbing DMD and LDC newest.

So now I have ~/dlang/ldc-1.32.2 and ~/dlang/dmd-2.104.0

How am I supposed to have both "activated"? Why does LDC have to 
override DMD, and DMD have to override LDC in the PATH?


I have both installed on another system without using this script 
and they run fine side-by-side. I can call dmd, or ldc, without 
any special "activate" calls. But this script seems to be the 
easiest/fastest way to download DMD and LDC.


I normally have separate scripts for dmd and ldc. (godmd, and 
goldc) But it seems I'll have to hardcode calls to the right 
activate script before my normal script code.


```sh
#godmd
~/dlang/dmd-2.104.0/activate
dmd -I...
```

But the activate scripts may have different version numbers in 
path!


~/dlang/dmd-2.104.0/activate

will one day become

~/dlang/dmd-2.105.0/activate

and so on.


Re: Debugging by old fashioned trace log printfs / writefln

2023-06-29 Thread Chris Katko via Digitalmars-d-learn

On Thursday, 29 June 2023 at 18:27:22 UTC, Cecil Ward wrote:
I’m trying to debug my D program with old-fashioned printfs 
stuck in various strategic places, actually using writefln(). 
My problem is that the addition of printf fights with the 
existing declarations for pure nothrow @nogc @safe and I have 
to adjust them, then put them back correctly when the 
writefln() trace statements are later removed.


Is there something else I could be using, something that is 
allowed to violate the checking rules for purity, nothrow, 
@nogc? Would pragma( msg, "…" ) do the trick? Is that what I 
should be using?


pragma(msg, "") is only for compile time. It for debugging 
functions/templates if they're actually used (which static path 
is used), instantiated, and you can also get type values from 
template inputs to confirm they're what you expect. "Oh this is a 
char[][] not a char[]!"


pragmas are the D equivalent of C/C++ pragmas. In this case, 
C/C++:

```C
#pragma message( message-string )
```



Re: pragma msg field name?

2023-06-27 Thread Chris Katko via Digitalmars-d-learn

On Tuesday, 27 June 2023 at 22:34:17 UTC, Adam D Ruppe wrote:

On Tuesday, 27 June 2023 at 22:20:22 UTC, Chris Katko wrote:

pragma(msg, t.stringof); // does not see any new fields!


D's declarations are all order-independent, in theory those 
foreaches are done simultaneously, so it is kinda a race 
condition.


Thank you, that's what I thought, but then I started adding them 
and there was no warning and I was like "wait... is this 
top-down???"




In practice, the compiler does them in two passes but both 
based on the same initial state.


Adding stuff and then reflecting over the stuff you add must be 
done as explicit steps on the outside, like you can make a 
`struct step1 {}` then `alias step2 = transform!step1;` then 
`alias step3 = transform_again!step2;` or something.


Okay again makes more sense. The amount of stuff that was "kinda" 
working, plus learning through tiny 3 liner code snippets in 
docs, was making my brain explode a bit.


A constructor/factory pattern for this makes way more sense.

Sometimes it's hard to tell where things are symbolic / 
functional, verses procedural/linear.





Re: pragma msg field name?

2023-06-27 Thread Chris Katko via Digitalmars-d-learn
Does anyone know why the new variables don't show up after the 
static foreach?


I have a struct, it has some marked fields. I want to note those 
fields at compile time and make some similarly named fields like 
myField becomes myField__replicated.


The code doesn't _have_ to be inside the struct/class itself. It 
could be:

```
auto replicatedObject = makeReplicated!(myObject);
```
for example.

I'm not sure the high-level best way right now, as I'm currently 
having issues with the nitty-gritty implementation of templates.





snippetcode (drop right into run.dlang.io):
```D
import std;

struct multiplayerObject2
{
ushort type;
ushort type2;
float x, y;

static foreach(t; typeof(this).tupleof)
{
pragma(msg, t.stringof);
		mixin("bool " ~ t.stringof ~ "25;"); // copy the fieldname with 
a suffix

}

pragma(msg, "-separator-");

static foreach(t; typeof (this).tupleof) // again
{
pragma(msg, t.stringof); // does not see any new fields!
}
}

void main()
{

}
```



```D
// Output
type
type2
x
y
-separator-
type
type2
x
y
```


Re: pragma msg field name?

2023-06-26 Thread Chris Katko via Digitalmars-d-learn

On Tuesday, 27 June 2023 at 04:56:19 UTC, Ali Çehreli wrote:

On 6/26/23 21:25, Chris Katko wrote:

> How do I get just the field name?

I know .tupleof, which you can typeof() as well:

class myObject{
int field1, field2, field3;

static foreach(field; typeof(this).tupleof)
{
pragma(msg, field.stringof);
}

static foreach(MemberType; typeof(typeof(this).tupleof)) {
pragma(msg, MemberType);
}
}

The output:

field1
field2
field3
int
int
int

I had to consult what I wrote years ago:

  http://ddili.org/ders/d.en/tuples.html#ix_tuples..tupleof

Ali


That seems to do the trick, I was really not expecting so much 
text just to get something so simple!


At the moment I'm trying to take variables with an attribute 
(rep) and then make a duplicate of them inside the struct. It 
seems to work. If I had duplicate names, it fails. However, the 
new fields don't appear to be showing up on a second enumeration:



enum rep;
struct multiplayerObject2
{
@rep ushort type;
@("rep2") ushort type2;
float x, y;

static foreach(t; typeof(this).tupleof)
{
// no if rep/rep2 here, i'm just testing:
pragma(msg, t.stringof); // does not see any new fields!
		mixin("bool " ~ t.stringof ~ "25;"); // copy the fieldname 
with a suffix

}

pragma(msg, "-separator-");

static foreach(t; typeof (this).tupleof) // again
{
pragma(msg, t.stringof); // does not see any new fields!
}
}


output
```
type
type2
x
y
-separator-
type
type2
x
y
```

However, if I do try to force the names to duplicate (say 
"type2") I get an error involving some sort of __anonymous 
subobject.

```
source/app.d-mixin-123(123,6): Error: variable 
`app.multiplayerObject2.__anonymous.type2` conflicts with 
variable `app.multiplayerObject2.type2` at source/app.d(116,19)

```

I also never realized you could put a static/static foreach 
inside the body of a struct (and not a function) so I'm still 
having trouble wrapping my head around that. Is it processing 
top-down?


Jonathan M Davis: Yeah, it does what I listed if you add the UDA 
to it.


pragma msg field name?

2023-06-26 Thread Chris Katko via Digitalmars-d-learn

inside a static foreach I can do

```
enum rep;

class myObject{
int field1, field2, field3;

static foreach(field; getSymbolsByUDA!(typeof(this), rep))
{
pragma(msg, field);  // fails
pragma(msg, fullyQualifiedName!field); // works
}
}
```

error for pragma(msg, field)
```
source/app.d(33,16): Error: value of `this` is not known at 
compile time

source/app.d(33,4):while evaluating `pragma(msg, field)`

[repeating for every variable in the class]
```

How do I get just the field name? And why does it think this is a 
run-time value? I need to wrap it in some sort of template?


All I see in std.traits docs are: fullyQualifiedName mangledName 
moduleName packageName


Re: Beerconf June 2023

2023-06-24 Thread Chris Katko via Digitalmars-d-announce
On Saturday, 24 June 2023 at 22:43:50 UTC, Steven Schveighoffer 
wrote:

On 6/24/23 9:01 AM, Richard (Rikki) Andrew Cattermole wrote:

Linkity link link https://meet.jit.si/Dlang2023JuneBeerConf


Unfortunately, we were getting some spam joiners. So if you 
want to join, the password is now `DlangRox`


-Steve


Will there be a YouTube/whatever mirror of the conference 
afterward?


Returning a reference to be manipulated

2023-04-13 Thread Chris Katko via Digitalmars-d-learn
I'm trying to figure out how to return a reference to something 
that may not be a reference type.


```D
struct stats
{
float[string] data=0;

float ref opIndex(string key)
  {
  return data[key]; // want a ref to a specific element
  }
}

void test()
{
stats foo;
auto x = foo.bar(); // returns some sort of reference
   // data["tacos"] = 0
x++;   // data["tacos"] = 1
}
```

Right now, I'm using pointers which resolves to:

```D
// float* opIndex(string key){...} using pointer
(*s["tacos"])++; // works with pointer, but is strange looking

s["tacos"]++; // preferred syntax or something similar
```



Assocative array lookup for object

2023-04-11 Thread Chris Katko via Digitalmars-d-learn

```D
class bitmapHandler
{
bitmap*[string] bmps;

void get(string name){return bmps[name]; /* plus other code */}
}

void usage()
{
bitmapHandler bh;
bitmap foo = bh.get("bar");  // works
bitmap foo2 = bh["bar"]; // desired
}
```

Should I be using opEquals? Or something different? The problem 
with 'alias this' here is I want to wrap access to the insides 
with getter functions that do various things like logging and 
error checking.


I mean, if I ruined some encapsulation, I could make a function 
called "bh" and have the usage:

```D
bh("bar");
```
and have it access a singleton object.



Virtual method call from constructor

2023-04-04 Thread Chris Katko via Digitalmars-d-learn

dscanner reports this as a warning:

```D
struct foo{
this()
  {
  /* some initial setup */
  refresh();
  }
void refresh() { /* setup some more stuff */}
// [warn] a virtual call inside a constructor may lead to 
unexpected results in the derived classes


}
```

Firstly, are all calls virtual in a struct/class in D? Is this 
any different from C++? IIRC, in C++, a struct cannot have 
virtual calls, and virtual methods are explicit keywords in 
classes.


Second, could you give me some case examples where this problem 
occurs? Is the issue if I override refresh in a derived class, 
and the base class will accidentally use child.refresh()?


Third, is there the expectation that you should _never_ call any 
internal, private, methods inside a constructor? Or do I just 
call/structure it a different way?


For a concrete example: I have a particle struct. It makes sense 
to me, to have initial setup code (placed in the refresh() 
function) called by this(), that later I can then call again; to 
reset the struct to an initial state in-memory without 
re-allocations.


I imagine in D that there's probably something like:

```D
particles[235] = foo.init;
```

but that blows up in a scenario where I'm only _partially_ 
resetting the struct data. For example, if I had a bunch of 
pointers to system modules, those values don't need to be nulled 
and re-set every time in this(), whereas the physical data like 
position, velocity, angle, need reset in refresh(). You could 
architect around that, but I'm trying to learn the language 
mechanics.


Re: templates and traits

2023-03-18 Thread Chris Katko via Digitalmars-d-learn

On Saturday, 18 March 2023 at 20:42:50 UTC, Nick Treleaven wrote:

On Saturday, 18 March 2023 at 19:22:07 UTC, Chris Katko wrote:
...


So there's multiple sub-problems to solve. I asked this years 
ago, and got 90% of the way done and then lost the code and 
cannot find the original forum post.


Maybe it was this?:
https://forum.dlang.org/post/dqzxnctucwvyhstfz...@forum.dlang.org


YES! I tried google search, forum search, even going through all 
my accounts posts, even my e-mail.


I think I accidentally made that post without logging in so it's 
not attached to my account posts.


templates and traits

2023-03-18 Thread Chris Katko via Digitalmars-d-learn

Given:
```D
struct pos {float x, y;}

draw(myBitmap, pos(320, 240), centered);
draw(pos(320, 240), myBitmap);
draw("text", myFont, pos(320, 240));
```

I'm writing a general "draw" template function that through 
compile-time, calls an associated DAllegro/Allegro 5 function:


```
draw(myBitmap, pos(320, 240), centered);   // 
al_draw_bitmap(myBitmap, pos.x - myBitmap.w/2, pos.y - 
myBitmap.h, 0);

draw(pos(320, 240), myBitmap); // order doesn't matter
draw("text", myFont, pos(320, 240)); // different function 
al_draw_text(...)

```

So there's multiple sub-problems to solve. I asked this years 
ago, and got 90% of the way done and then lost the code and 
cannot find the original forum post.


The pos(320,240) part works fine already. I need:

 - At compile-time, for a variadic template that can take any 
number of arguments, if specific arguments are available, I 
branch and use them to call a specific applicable C function.


I remember I need to write some sort of enum function that checks 
"IsAny" if an argument is passed at all, as well as one to find 
where that argument is. Passing duplicates probably don't matter 
(at least not right now), first valid argument is fine. I can't 
seem to write code (or find example code online) that does this.


But it's something like

```D
enum isAny() = ...;

void draw(T...)(T)
{
if(isAny(bitmap))
  {
  // it's a sprite, now find out if we need it rotated, 
stretched, etc.

  }
is(isAny(string))
  {
  // its text [...]
  }
}
```

A separate problem I've run into is, the 'centered' construct. If 
I have rotate(25) (rotate 25 degrees), that works. But I cannot 
just pass a type named "centered" with no variable attached to 
it, nor can I--I think--pass an enum.  I could do centered(false) 
or centered(0), but that's clunkier than just saying "if 
'centered' is an argument, we center it. If not, we don't." I 
could have a variable named centered, I guess. or an enum with 
{isCentered=1, notCentered=0} and detect if the enum is passed. 
Lot's of ways to skin this cat.


The idea here, is I've got a lot of optional arguments (centered, 
tinted, rotated, scaled, sheared, etc) that I can pick from and I 
don't want to have to sort through a list of 80 different 
permutations of function signatures, or, one gigantic 
megafunction with a ton of zeros/nulls for all the unused 
arguments.


This is a bit of a confusing problem to explain, so I've probably 
left something necessary out.





Convert array of simple structs, to C array of values

2022-10-03 Thread Chris Katko via Digitalmars-d-learn

```D
struct pair
  {
  float x;
  float y;
  }

pair[10] values;
import std.conv;
auto valuesInCStyle = to!(const float*)(values);

```

Now that's not going to work because (I would imagine) to! 
doesn't understand x, and y, can be placed in order to give an 
array of:


valuesInCStyle = [values[0].x, values[0].y, values[1].x 
,values[1].y, ...]


I know there's gotta be some simple one liner function in D, but 
I can't think of it.


Re: dlang bug - accessing module variable from method segfaults only when using module reference directly

2022-07-01 Thread Chris Katko via Digitalmars-d-learn

On Friday, 1 July 2022 at 13:28:26 UTC, Chris Katko wrote:
...wait, does "world" not 'exist' until after the constructor 
finishes? Is that's what's going on? But then why does it 
'exist' when I send it directly? Is it only "registered" with 
the module once this() finishes or something like that?


Yep, that's it.

moving all code in world.this() to world.initialize() and 
immediately calling initialize, works fine.


D
g.world = new g.world_t; // code would crash here
g.world.initialize();  // doesn't crash if moved here

class world
{
this(){}
void initialize(){/*...*/}
}

class elf : unit
{
this(pair _pos, atlasHandler atlas/*not used*/)
{   
super(0, _pos, pair(0, 0), g.dude_bmp);
		anim = new animation(1, elf_coords, g.world.atlas); //not 
crashing now

}
}


It appears module access to a class is broken until the 
constructor finishes.


Re: dlang bug - accessing module variable from method segfaults only when using module reference directly

2022-07-01 Thread Chris Katko via Digitalmars-d-learn

On Friday, 1 July 2022 at 13:12:05 UTC, Adam D Ruppe wrote:

On Friday, 1 July 2022 at 12:57:01 UTC, Chris Katko wrote:

Cannot access memory at address 0x10


Looks like an ordinary null pointer. How did you create the 
variable?



D
bool initialize() //called from main
{
g.world = new world_t;
}

class atlasHandler{}
class animation
{
this(int _numFrames, ipair[] coordinates, atlasHandler atlas)
{
}
}

class world_t
{   
atlasHandler atlas;

this()
{
viewTest();
atlas = new atlasHandler();

units ~= new elf(pair(200, 200), atlas); //crashes
}
logic()
{
// doesn't crash
units ~= new elf(pair(200, 200), atlas);
}

}

class elf : unit
{
this(pair _pos, atlasHandler atlas)
{   
super(0, _pos, pair(0, 0), g.dude_bmp);
//  anim = new animation(1, elf_coords, atlas); //doesn't crash
anim = new animation(1, elf_coords, g.world.atlas); //CRASH here
isTreeWalker = true;
}
}




also important. it seems to only occur in the constructor. If I 
create an elf after the world constructor, it's fine.


...wait, does "world" not 'exist' until after the constructor 
finishes? Is that's what's going on? But then why does it 'exist' 
when I send it directly? Is it only "registered" with the module 
once this() finishes or something like that?


Re: dlang bug - accessing module variable from method segfaults only when using module reference directly

2022-07-01 Thread Chris Katko via Digitalmars-d-learn
Forgot the last line. That's important because world MUST exist 
by time elf is called... because world... created and called elf.


So it's not a memory issue, but some sort of linkage issue.


Re: dlang bug - accessing module variable from method segfaults only when using module reference directly

2022-07-01 Thread Chris Katko via Digitalmars-d-learn
To add, I cannot even access g.world from inside elf's 
constructor.


... which is the function that called it.

D
Thread 1 "main" received signal SIGSEGV, Segmentation fault.
objects.elf.this(g.pair, objects.atlasHandler) (this=, atlas=, 
_pos=...) at ./src/objects.d:320


(gdb) bt
#0  objects.elf.this(g.pair, objects.atlasHandler) (this=, 
atlas=, _pos=...) at ./src/objects.d:320

#1  worldmod.world_t.this() (this=) at ./src/worldmod.d:60
#2  main.initialize() () at ./src/main.d:110
#3  main.main(immutable(char)[][]).__lambda6() (__capture=) at 
./src/main.d:462
#4  allegro5.system.al_run_allegro(scope int() 
delegate).main_runner(int, char**) ()

#5  allegro5.system.al_run_allegro(scope int() delegate) ()
#6  D main (args=...) at ./src/main.d:461

(gdb) x g.world
0x0:Cannot access memory at address 0x0






dlang bug - accessing module variable from method segfaults only when using module reference directly

2022-07-01 Thread Chris Katko via Digitalmars-d-learn

dmd (but I think LDC also is affected)

this bug has bit me multiple times now, to the point I can 
recognize it. Accessing module variables, from inside a method, 
causes a segfault. Even if the variable should be available by 
then through the call order. Proving that its a bug, you can 
directly send the exact same variable through an argument, and it 
works fine.



(not sure if this code will do it, last time I tried to replicate 
it with solely this kind of code, the bug disappeared.)


D

/// module g.d
class world
{
atlasHandler atlas;

void do()
{
atlas = new AtlasHanlder();
elf e = new elf(atlas);
}
}

/// module 'objects.d'
class atlasHandler{}

class elf
{
this(atlasHandler atlas)
{
assert(atlas !is null); //works fine
assert(g.world.atlas !is null); //crashes

	writefln("atlas [%p] vs g.world.atlas [%s]", atlas, 
g.world.atlas);

// crashes trying to read g.world.atlas
}
}


gdb output (not the exact same module names but you get the 
point):


Thread 1 "main" received signal SIGSEGV, Segmentation fault.

(gdb) p atlas
$1 = (objects.atlasHandler *)
(gdb) p g.world
$2 = (worldmod.world_t *)
(gdb) p g.world.atlas
Cannot access memory at address 0x10
(gdb) p this
$3 = (objects.elf *)
(gdb) x atlas
0x7fffec1cf380: 0x55826580
(gdb) x g.world.atlas
Cannot access memory at address 0x10


It appears that whatever value its sending, is in a protected 
memory segment and automatically segfaulting even upon reading.


Worst case I can public my repo and you can see it for yourself.


Re: nested function overloading

2022-06-23 Thread Chris Katko via Digitalmars-d-learn
On Wednesday, 22 June 2022 at 12:42:48 UTC, Steven Schveighoffer 
wrote:

On 6/22/22 2:05 AM, monkyyy wrote:
On Monday, 20 June 2022 at 13:20:51 UTC, Steven Schveighoffer 
wrote:
And you can also use an inner struct to define overloaded 
functions.


I believe templates make a better bandaid
```d
void main(){
 template bar(){
     void bar_(int){}
     void bar_(float){}
     alias bar=bar_;
 }
 bar(1);
 bar(3.14);
}
```


Wow, I never thought of that, it's a great idea! You don't even 
need to use the alias.


```d
void main(){
template bar(){
void bar(int){}
void bar(float){}
}
bar(1);
bar(3.14);
}
```

-Steve


Wow! That's great! Another trick to add to my toolbox.


Re: can you initialize a array of POD structs?

2022-06-18 Thread Chris Katko via Digitalmars-d-learn

On Saturday, 18 June 2022 at 17:52:16 UTC, Adam D Ruppe wrote:

On Saturday, 18 June 2022 at 17:37:44 UTC, Chris Katko wrote:

D
struct pair { float x, y;}

pair p[] = [[0, 0], [255, 255], [25,-25]]; //nope



An array of pair is `pair[]`, keep the brackets with the type.

Then a struct literal is either:

pair(0, 0) // using constructor syntax

or in some select contexts (including this one):

{0, 0} // using named literal syntax


Therefore:

pair[] p = [{0, 0}, {255, 255}, {25,-25}];

compiles here.


Thanks!!

One extra caveat for anyone who googles this. You can't use {0, 
0} notation if the struct has constructors. Which make sense 
since you don't want people accidentally bypassing a constructor 
if it exists.


can you initialize a array of POD structs?

2022-06-18 Thread Chris Katko via Digitalmars-d-learn

D
struct pair { float x, y;}

pair p[] = [[0, 0], [255, 255], [25,-25]]; //nope



multidim array with enum

2022-06-18 Thread Chris Katko via Digitalmars-d-learn
I'm having difficulty figuring out exactly what signature D is 
expecting.


D
enum DIR
{
UP = 0,
DOWN,
LEFT,
RIGHT,  
UPLEFT,
UPRIGHT,
DOWNRIGHT,
DOWNLEFT,
}

BITMAP*[2][DIR] bmps;

// ...

bmps[DIR.UP][0] = nope.
bmps[DIR.UP][0] = new BITMAP *; // nope
bmps[DIR.UP][0] = new BITMAP; // nope
bmps[DIR.UP] = new BITMAP*[2]; // compiles. runtime range 
violation.




I swear this all worked fine when it was just:
D
bmps[DIR] bmps;




Re: nested function overloading

2022-06-17 Thread Chris Katko via Digitalmars-d-learn

On Friday, 17 June 2022 at 12:19:33 UTC, bauss wrote:

On Friday, 17 June 2022 at 12:09:33 UTC, Chris Katko wrote:

I don't need this functionality, but I wanted to be sure.

Does function overloading not work with nested functions? I 
got a compiler error (something like "function already 
defined") when I tried it.


According to the spec then nested functions cannot be 
overloaded:


"Nested functions cannot be overloaded."

See: 19.17.1.3

https://dlang.org/spec/function.html#nested


Thanks!

re: documentation. That is one-line tiny footnote in a page 
that's over 85 pages long on my browser. :) I could easily see 
many people missing it until they encounter it.


nested function overloading

2022-06-17 Thread Chris Katko via Digitalmars-d-learn

I don't need this functionality, but I wanted to be sure.

Does function overloading not work with nested functions? I got a 
compiler error (something like "function already defined") when I 
tried it.


Re: a struct as an multidimensional array index

2022-06-10 Thread Chris Katko via Digitalmars-d-learn

On Friday, 10 June 2022 at 17:26:48 UTC, Ali Çehreli wrote:

On 6/10/22 08:13, z wrote:

> arrays of arrays has different order for declaration and
addressing,
> and declaring array of arrays has different order depending
on how you
> declare it and wether it's static or dynamic array, *oof*)
>
> To give you an idea of the situation :
> ```D
>  int[3][1] a;//one array of 3 int
>  writeln(a[0][2]);//first "column", third "row"
> ```

I've written about this multiple times in the past but D's way 
is consistent for me. That must be because I always found C's 
syntax to be very illogical on this. To me, C's problem starts 
with putting the variable name in the middle:


  // C code:
  int a[1][3]; // Why?

So, first, D moves the variable to its consistent place: after 
the type:


  int i;
  int[N] arr;

Both of those are in the form of "type and then name". Good...

And then, here is the consistency with arrays: "type and then 
square brackets".


  int[] dynamicArray;
  int[N] staticArray;

So, here is where you and I differ:

  int[3][1] arr;  // Ali likes
  int[1][3] arr;  // z wants

I like it because it is consistently "type and then square 
brackets". (It so happens that the type of each element is 
int[N] in this case.) If it were the other way, than array 
syntax would be inconsistent with itself. :) Or, we would have 
to accept that it is inside-out like in C.


But of course I understand how it is seen as consistent from 
C's point of view. :)


And this is consistent with static vs dynamic as well because 
again it's "type and then square brackets":


  int[1][] a;  // A dynamic array of int[1]
  int[][3] b;  // A static array of 3 int[]s

Ali


This is an interesting discussion. I had noticed multi-dim arrays 
seemed backwards but I assumed I was doing something wrong and 
had other thing to worry about. I had no idea it was DIFFERENT 
for static vs dynamic arrays? That's horrifying!


Also you reminded me of a possible D bug that I ran into. I had 
classes that had circular dependencies. One had to know about the 
other, and vice-versa. And I had derived classes. But somehow, 
they would explode. I would send one reference to the others 
constructor to 'link' them together, but the reference would be 
NULL. But if I accessed the exact same variable through a global 
reference, it worked fine.


I tried ripping the affected code into a new file but the bug 
wasn't replicated. Even if I matched the compiler/linker options. 
It was super frustrating.


Re: Run a command-line process with data sent, and retrieve the data.

2022-06-10 Thread Chris Katko via Digitalmars-d-learn

On Friday, 10 June 2022 at 17:37:30 UTC, Chris Katko wrote:
I want to pipe in string data to a shell/commandline program, 
then retrieve the output. But the documentation I read appears 
to only show usage for 'Files' for stdin/stdout/stderr.


ala something like this:
D
string input = "hello\nworld";
string output;
runProcess("grep hello", input, output);
assert(output = "hello");



Okay that's probably incorrect grep, but you get the point.


Run a command-line process with data sent, and retrieve the data.

2022-06-10 Thread Chris Katko via Digitalmars-d-learn
I want to pipe in string data to a shell/commandline program, 
then retrieve the output. But the documentation I read appears to 
only show usage for 'Files' for stdin/stdout/stderr.


ala something like this:
D
string input = "hello\nworld";
string output;
runProcess("grep hello", input, output);
assert(output = "hello");



a struct as an multidimensional array index

2022-06-10 Thread Chris Katko via Digitalmars-d-learn
Is it somehow possible to use a struct as a [multidimensional] 
array index:


D

struct indexedPair
{
size_t x, y;
}

bool isMapPassable[100][100];
auto p = indexedPair(50, 50);

if(isMapPassable[p]) return true;



Probably not, but I'm curious.


Odd construct idea. Splitting arguments inside a parameter list.

2022-05-23 Thread Chris Katko via Digitalmars-d-learn

D
struct pair
{
float x,y;
}

myFunction(float taco, float x, float y, float burrito)
 {
 // stuff
 }

myfunction(_taco, _x, _y, _burrito);  // call function

// But can we do this?
pair p;
myfunction(_taco, p; _burrito);  // p becomes (x,y) and satisfies 
the two floats in the signature


I don't know if I need this but I'm curious if it's a template 
possibility. Though under-the-hood it could violate some 
necessary assumption about function signature matching.


I'm curious if you can pass a struct of values (a 'tuple'?) with 
the right subfields, as if those fields occupied a function 
signature. (As I write this and try to explain it, it probably 
sounds impossible.)


I have an existing API that uses X/Y coordinates, but I like 
using packed/named tuples (right term?) for related arguments. 
pos(x,y) vs velocity(x,y) for example make it super easy to tell 
which x belongs to which construct. Worst case I could just write 
wrapper functions for like 60+ functions. But it's still an 
interesting "can D do this" idea that popped into my head 
tonight. I'm always curious about what's possible.


 - Note that it doesn't necessarily have the struct fields match 
the called function argument names. I'm talking about calling 
with a struct with two floats (of any name), fulfilling two float 
requirement of a function signature. Is there a way for a 
tuple/array/some-sort-of-combined object to fulfill two separate 
function arguments?


Of course we could always just do:
D
pair p;
myFunction(taco, p.x, p.y, burrito);



Re: template? mixin? template mixins? for modifying a struct setup

2022-05-19 Thread Chris Katko via Digitalmars-d-learn

On Thursday, 19 May 2022 at 10:35:30 UTC, ag0aep6g wrote:

On 19.05.22 12:15, Chris Katko wrote:

given
```D
struct COLOR
{
float r, g, b, a; // a is alpha (opposite of transparency)
}

auto red   = COLOR(1,0,0,1);
auto green = COLOR(0,1,0,1);
auto blue  = COLOR(0,0,1,1);
auto white = COLOR(1,1,1,1);
//etc
```

is there a way to do:
```D
auto myColor = GREY!(0.5);
// where GREY!(0.5) becomes COLOR(0.5, 0.5, 0.5, 1.0);
```


What's wrong with a simple plain function?

COLOR grey(float rgb)
{
return COLOR(rgb, rgb, rgb, 1);
}
auto myColor = grey(0.5);


Yeah that occurred to me as I was falling asleep. Though, do I 
have to a specify


```D
static auto myColor = grey(0.5);
```
to ensure it's done at compile time? It's not the end of the 
world, but ideally, these are static / hardcoded values that can 
be used thousands of times a second.


template? mixin? template mixins? for modifying a struct setup

2022-05-19 Thread Chris Katko via Digitalmars-d-learn

given
```D
struct COLOR
{
float r, g, b, a; // a is alpha (opposite of transparency)
}

auto red   = COLOR(1,0,0,1);
auto green = COLOR(0,1,0,1);
auto blue  = COLOR(0,0,1,1);
auto white = COLOR(1,1,1,1);
//etc
```

is there a way to do:
```D
auto myColor = GREY!(0.5);
// where GREY!(0.5) becomes COLOR(0.5, 0.5, 0.5, 1.0);
```


Re: Template shenannigans with multiple datatypes

2022-05-13 Thread Chris Katko via Digitalmars-d-learn

On Friday, 13 May 2022 at 07:05:36 UTC, vit wrote:

On Friday, 13 May 2022 at 06:43:39 UTC, Chris Katko wrote:
I have an intrinsicGraph(T) class that is given a pointer to a 
T dataSource and automatically polls that variable every frame 
to add it to the graph, whether it's a float, double, integer, 
and maybe bool.


[...]


I dont understand first qestion but second question has a 
solution:


```d
intrinsic_graph!T make_graph(T, Args...)(auto ref T val, auto 
ref Args args){

return new intrinsic_graph!T(val, args);
}


instrinsicGraph!float testGraph;
instrinsicGraph!ulong testGraph2;
// later
testGraph = make_graph(units[0].x, 100, 300, COLOR(1,0,0,1));
testGraph2 = make_graph(g.stats.fps, 100, 500, COLOR(1,0,0,1));


```


Okay, to clarify just in case I'm very confusing because I'm up 
late.


If I wanted a "multipleGraph". A graph that takes multiple values 
and plots them on the same graph. I need to store a buffer for 
each dataSource. Luckily, because I'm painting them to the 
screen, the buffers only really need to be float even if they 
started as a boolean, int, or double. However, if I'm keeping a 
list of pointers to things I want to snoop when I call onTick(), 
I can't think of a way to support multiple types:


```D
class intrinsicGraph(T)
   {
   T* dataSource;
   float[] buffer;

   void onTick()
 {
 //grab datasource data and do something.
 buffer ~= to!float(*datasource);
 }
   }

auto g = intrinsicGraph!float();
```

But what if there's multiple types?

```D
class multiGraph(???)
   {
   ???[] dataSources;
   float[] buffers;

   void onTick()
 {
 //grab datasource data and do something.
 foreach(d, i; dataSources)
buffers[i] ~= to!float(*d); //or whatever
 }
   }

auto g = multiGraph!???(, , );

```

This is a kinda "dynamic language" feature but it feels like this 
information is theoretically, knowable at static, compile-time. I 
know what the variable types will be at compile-time, but I don't 
know how to put them all in one class and reference them 
automatically.




Template shenannigans with multiple datatypes

2022-05-13 Thread Chris Katko via Digitalmars-d-learn
I have an intrinsicGraph(T) class that is given a pointer to a T 
dataSource and automatically polls that variable every frame to 
add it to the graph, whether it's a float, double, integer, and 
maybe bool.


This all works fine if you have a single template type. But what 
if I want ... multiple graphs? I cannot do

D
class intrinsicGraph(T???)
{
(void*) dataSources[];
}

and have it become whatever datatype I want. Even if I'm always 
storing the values in a float buffer, the dataSources themselves 
cannot be multiple types.


Basically I'm wondering if there's a way to have
D
int FPS;
float frameTime;
//
graph myGraph;
myGraph.add();
myGraph.add();

and it enumerates through its dataSources array and adds to the 
relevant buffers.


There is a key that might help, they're all types that can 
resolve to integer or float. I'm not trying to add support for 
adding myRandomClass or networkPacket. Only things that can 
resolve down to float in some form.


Is there some kind of clue in having an array of Object (the 
fundamental superclass?)?


I don't think this is necessarily a "run time" reflection 
problem. Because I could make a graph at compile time, and know 
its of type, say, (T V U). Say, float, double, uint. Some sort of 
vardiac template.


But then how would you store that, unless you use some sort of 
mixins to write separate variables. (float\* dataSource0 and 
double\* dataSource1)


Or, wrap each pointer in some sort of fat pointer class that 
stores the type and a void*, and have an array of those fat 
pointers and and use some compile time voodoo to cast back  
cast(float)dataSource[0] (zero is always float), 
cast(uint)dataSource[2] (index 2 has cast(uint) put in).


Additional questions:

This may sound strange but is there a way to avoid having to 
specify the template type twice?

```D
instrinsicGraph!float testGraph;
instrinsicGraph!ulong testGraph2;
// later
testGraph = new intrinsic_graph!float(units[0].x, 100, 300, 
COLOR(1,0,0,1));
testGraph2 = new intrinsic_graph!ulong(g.stats.fps, 100, 500, 
COLOR(1,0,0,1));

```
It'd be nice if I only had to specify the type once.

It'd also be kinda nice if I could hide the fact I need to 
specify the type at all and have it automatically become whatever 
type the passed in value is:


D
instrinsicGraph testGraph(g.stats.fps) //automatically stores an 
integer buffer.







Re: What are (were) the most difficult parts of D?

2022-05-12 Thread Chris Katko via Digitalmars-d-learn

On Thursday, 12 May 2022 at 16:04:09 UTC, Ali Çehreli wrote:
My view on private has changed over the years. I need to be 
convinced that there is usage that needs to be protected. :) I 
don't see people using types freely especially the ones that 
are in the same module. The only argument for private is to 
allow changing the implementation of published libraries in the 
future.


I use private as part of my rapid dev process. You write code, 
you get things working with no real worry for correctness or 
careful interfaces. You cannot make an interface until you 
actually know what you're making.


So you make things, with "bad" connections. Then you remove those 
connections.


1. Get system working with lots of direct access to class 
variables.

2. Make those variables forbidden (through private in C++).
3. The compiler now shows you every instance of your new 
interface encapsulation violations. No human decision to opt-in. 
No remembering to search. You have an automatically generated 
list of violations to fix.


I do the same thing with a module called "g" (for globals). I 
write new code into g, get it working. I can see how "dirty" a 
file is by simply searching for how many references to the module 
g there are. Then if I move the code into a proper new module, 
all references to g magically fail. It is impossible for me to 
leave dangling old code touching naughty internals, and I get a 
nice error view of all areas that need attention. If the uses are 
all over the place and not in only a few areas (instead of just 
in logic() and draw(), but all over the place) then I know I need 
to rewrite and introduce a system so everything is mostly in one 
place.


In D, I can do the module based method, but nothing short of 
renaming variables gives me a list of violations and, that also 
makes all the correct internal accesses wrong. Because private 
doesn't work.


Call it whatever keyword you want, I really want a 'private' 
specifier for classes. It's incredibly useful.


A template construct like using()

2022-04-26 Thread Chris Katko via Digitalmars-d-learn
I swear I asked something like this before years ago but it 
doesn't show up in my previous forum posts.


I'm looking for a construct that mimics using(var)/with(var)

D
bitmap* b;

draw_with(b)
  {
  draw_pixel(red, 16, 16); //draw red pixel to bitmap b (b is 
implied above)

  }


But the code ends up being:
D
bitmap* b;

set_target_bitmap(b); //entry code
draw_pixel(red, 16, 16); // body
set_target_bitmap(original_target); // exit code


The essence is wrapping something the code up in a kind of 
RAII-like entry and exit code that references a given target 
variable.


Perhaps a mixin is what I'm looking for?


Re: std.typecons Typedef initializers?

2022-04-25 Thread Chris Katko via Digitalmars-d-learn

On Monday, 25 April 2022 at 12:53:14 UTC, Mike Parker wrote:

On Monday, 25 April 2022 at 08:54:52 UTC, Chris Katko wrote:

D
struct pair
{
float x,y;
}

alias sPair = Typedef!pair; // pair of xy in screen space 
coordinates
alias vPair = Typedef!pair; // pair of xy in viewport space 
coordinates

//etc



How do you initialize a typedef'd struct?


``d
vPair v1 = vPair(pair(1f, 2f));
```


So to use a typedef'd struct... I have to basically add the 
original type on top of the typedef'd type every time? Surely 
it's not this clunky?


I mean, why even use a typedef then. Why not use just pair, 
sPair, vPair, etc as  separate types with identical members and 
cast as necessary? I'm not sure what the benefit typedef is 
adding here.


Thanks


std.typecons Typedef initializers?

2022-04-25 Thread Chris Katko via Digitalmars-d-learn

D
struct pair
{
float x,y;
}

alias sPair = Typedef!pair; // pair of xy in screen space 
coordinates
alias vPair = Typedef!pair; // pair of xy in viewport space 
coordinates

//etc

void test()
{
pair v0 = pair(1f, 2f); // works fine, but what about the 
typedefs?


vPair v1 = vPair(1f, 2f); //nope

vPair v2 = Typedef!vPair(1f, 2f); //nope
}



How do you initialize a typedef'd struct?


save and load a 2d array to a file

2022-04-18 Thread Chris Katko via Digitalmars-d-learn

D
struct map_t{
int data[50][50];
} map;

//save
std.file.write("save.map", map.data); // compiles

//load
map.data = std.file.read("save.map", map.data.sizeof); // error

main.d(536): Error: cannot implicitly convert expression 
`read("save.map", 2500LU)` of type `void[]` to `ubyte[50][]`



I'm guessing here, that internally we've got an array of arrays 
(which means array of pointers), and D doesn't know how to split 
by one of the axis. So how do I do that? If I know it's exactly 
packed as it was before, can I smash it somehow by direct writing 
a bunch of ubytes?


What is the 'smash' way to do it, and if better, what's the 
elegant way to do it? (In case I need either going forward).


Thanks,
--Chris


Nested function requires forward declaration?

2022-04-14 Thread Chris Katko via Digitalmars-d-learn

Using DMD. v2.098-beta-2

Not sure if right terminology. But I just wrote a nested function 
that uses a variable outside its body. The capture (right term?) 
is obvious where the invocation is. However, I have to move the 
declaration of the variable to above the nested function for it 
to compile.


Here is the code that wont compile:
D
void execute()
{
bool isKey(ALLEGRO_KEY key)
{
return (event.keyboard.keycode == key);
}
ALLEGRO_EVENT event;
// later
isKey(ALLEGRO_KEY_W);

// main.d(491): Error: undefined identifier `event`


This however, will compile:
D
void execute()
{
ALLEGRO_EVENT event; // <--Only change
bool isKey(ALLEGRO_KEY key)
{
return (event.keyboard.keycode == key);
}
// later
isKey(ALLEGRO_KEY_W);


It appears the nested function's variable capture depends on 
forward declaration (the right term?). Whereas, I was under the 
impression most/all of D worked on a multiple pass compilation so 
the order of declarations shouldn't matter.


Is this a D spec, or a compiler parsing error/oversight?

I guess if I had two different variables called event, this could 
become confusing code to read except that, mentally these should 
still link up, right?


Hypothetical:
D
void execute()
{
bool isKey(ALLEGRO_KEY key)
{
return (event.keyboard.keycode == key);
}

   {
   ALLEGRO_EVENT event;
   isKey(ALLEGRO_KEY_W);
   } //lets say this does some memory housekeeping/deleting so 
that's why we use scope

   {
   ALLEGRO_EVENT event; //new 'event', same name, new memory
   isKey(ALLEGRO_KEY_W);
   }
}


in this case, 'event' under-the-hood could be renamed, say, 
"event2" and have the same expected compile time symbol linking 
occur. The second isKey call is obviously connected to the second 
'event' variable.


I imagine this is a really odd edge case but it's piqued my 
interest.


unit test broken [DUB bug?]

2021-12-11 Thread Chris Katko via Digitalmars-d-learn

Running 64-bit Linux
```
dmd --version
DMD64 D Compiler v2.098.0-beta.2

dub --version
DUB version 1.27.0-beta.2, built on Sep  7 2021
```

the following code 'compiles' in one project.

```d
unittest
{
gasdindgaslkdgansklnasgdlknaglkgansklsdg;
}

void main(){} // compiles, links, and 'runs unit tests'
```

dub
[shows compiling, linking, then runs]

dub test

```
Running dfile-test-library
All unit tests have been run successfully.
```

Which made no sense whatsoever until I placed it into a second, 
different DUB project and catches it immediately using the same 
commands and test.


In a separate dub project I get the error message:

```
widescreen ~main: building configuration "application"...
source/app.d(4,1): Error: undefined identifier 
`gasdindgaslkdgansklnasgdlknaglkgansklsdg`

/usr/bin/dmd failed with exit code 1.
```


I'm not doing anything special with DUB and made both projects 
within a couple weeks of each other. I tried dub clean, dub, dub 
test. Still broken.




dub.json for broken project
```json
{
"authors": [
"chris"
],
"copyright": "Copyright © 2021, chris",
"dependencies": {
"crypto": "~>0.2.16"
},
"description": "A minimal D application.",
"license": "proprietary",
"name": "dfile"
}
```

dub.json for working project
```json
{
"authors": [
"chris"
],
"copyright": "Copyright © 2021, chris",
"description": "A minimal D application.",
"license": "proprietary",
"name": "widescreen"
}
```

dub.json.selections (for broken project only)
```json
{
"fileVersion": 1,
"versions": {
"crypto": "0.2.16",
"intel-intrinsics": "1.6.1"
}
}
```

Other than unit testing being broken, everything seems to work 
fine. I even deleted 99.9% of my code and left only the bad 
unittest code and a main, and it still compiles.



Could it be a bug where the previous unit test (at some point) 
was valid, and it's caching and still running that one? I have a 
/.dub/code/ d file I found:


```d
module dub_test_root;
import std.typetuple;
static import notes;
alias allModules = TypeTuple!(notes);

import std.stdio;
import core.runtime;

		void main() { writeln("All unit tests have been run 
successfully."); }

shared static this() {
version (Have_tested) {
import tested;
import 
core.runtime;
import 
std.exception;

Runtime.moduleUnitTester = () => true;
enforce(runUnitTests!allModules(new 
ConsoleTestResultWriter), "Unit tests failed.");

}
}
```

Which doesn't appear in the "correct, not compiling" project 
directory which appears just empty. Possibly because it never 
successfully compiled a unit test suite.


Re: d strings are the bane of my existance

2021-12-05 Thread Chris Katko via Digitalmars-d-learn
On Sunday, 5 December 2021 at 16:32:16 UTC, rikki cattermole 
wrote:

The string is not the problem.

```d
string ip_address = "192.168.1.1";
auto x = new InternetAddress(ip_address, 8008);
```

That works.

A string in D is an alias for immutable(char)[]. This is 
defined in druntime (object.d).


Immutable does cast to const implicitly, so a string argument 
to the constructor works fine as it has the same meaning.


The port however, that needs to be a ubyte/ushort to pass in 
and not be a string like you had it.


Yes! Thank you! I just realized the latter part was broken when I 
switched to using a uint for the addr. But I didn't know string 
is an alias for immutable(char)[]! Thank you!


d strings are the bane of my existance

2021-12-05 Thread Chris Katko via Digitalmars-d-learn

All I want:

```d
string ip_address = "192.168.1.1";
auto x = new InternetAddress( ip_string, "8008");
```

```d
source/app.d(161,16): Error: none of the overloads of `this` are 
callable using argument types `(string, int)`
/usr/include/dmd/phobos/std/socket.d(1472,5):Candidates 
are: `std.socket.InternetAddress.this()`
/usr/include/dmd/phobos/std/socket.d(1519,5): 
   `std.socket.InternetAddress.this(scope const(char)[] addr, 
ushort port)`
/usr/include/dmd/phobos/std/socket.d(1542,5): 
   `std.socket.InternetAddress.this(uint addr, ushort port)`
/usr/include/dmd/phobos/std/socket.d(1550,5): 
   `std.socket.InternetAddress.this(ushort port)`
/usr/include/dmd/phobos/std/socket.d(1562,5): 
   `std.socket.InternetAddress.this(sockaddr_in addr)`

```

So InternetAddress cannot be constructed with a string. Only a 
const(char)[]. But toStringz gives me a immutable(char)*, which 
sounds like the same thing but isn't. and .dup on that just 
explodes. cast doesn't seem to work.  to! doesn't seem to work.


I know there "is" a solution, it's just so odd to have this much 
difficulty using a string.


sleeping vs sched_yield

2021-12-02 Thread Chris Katko via Digitalmars-d-learn

there's:

```d
  import core.thread;
  Thread.sleep( dur!("msecs")(10) );
```

but what if you want to simply yield all remaining time back to 
the time scheduler?


Is there a D std.library accessible version of POSIX sched_yield:

  https://man7.org/linux/man-pages/man2/sched_yield.2.html


It seems I can (thanks to the amazing work of D community) simply 
do:


```d
extern(C) int sched_yield(void);  // #include 
```

however, how does the linker know I need  and not some 
local library, or SDL library, or SDL2.0 library, etc. Shouldn't 
I be specifying the library somewhere?






Side side question: The above line fails to compile as-is because 
it has (void) instead of ().


```
source/app.d(226,16): Error: cannot have parameter of type `void`
```

Should that be corrected in the compiler? Shouldn't () and (void) 
be interchangeable as long as you're not doing void*?






automatic NaN propogation detection?

2021-09-25 Thread Chris Katko via Digitalmars-d-learn
Is there any automatic compiler-based or library methods for 
detecting NaNs? I mean, if the compiler is outputting code that 
it knows is going to be set in memory to NaN, why isn't it giving 
me at least a compiler warning? Is that some sort of "NP 
complete" can't-fix issue or something?


I mean, I can pass NaN to std.math.round() and it doesn't fire 
off an exception or anything. It compiles fine even though it's 
impossible-as-compiled to be correct. (Unless my absurd intention 
was to find the rounded value of NaN.) Instead, I'm stuck finding 
out where the NaN started, from a trail of destruction of values 
destroyed by NaN propogation. Why not stop it at its source?


Even dscanner won't flag this code!

```d
import std.stdio;
import std.math;

int main()
{
float x;
writeln(x);
writeln(round(x));
return 0;
}
```



Re: Is this a compiler aliasing bug?

2021-09-22 Thread Chris Katko via Digitalmars-d-learn

On Friday, 17 September 2021 at 10:29:12 UTC, bauss wrote:

On Friday, 17 September 2021 at 09:44:53 UTC, Chris Katko wrote:

[...]


It's not a bug because "obj.x" referes to the same symbol that 
is "this.x"


Alias will create an alias for a symbol, not an expression or 
the like.


So

obj.x is the same as this.x and in that case the alias will 
refer to the same thing.


The problem here is that the function is local to the class, so 
the alias will always refer to the class members directly and 
not the passed instance.


You really shouldn't use alias like this anyway and should just 
use auto, if it's because you want to save typing.


It shouldn't have any impact at all tbh.


Thanks everyone!

Okay, so yeah, back in 2017 I definitely was still learning D. 
And, after a year or two, I was re-learning it... using this bad 
learner codebase! There's been plenty of other things I had to 
fix that are "no-nos" in my modern codebases.





Is this a compiler aliasing bug?

2021-09-17 Thread Chris Katko via Digitalmars-d-learn
I'm debugging some code I wrote back in 2017 and a bounding box 
collision detection kept giving spurious answers till I resorted 
to assuming nothing and dumped every variable and alias.


I kept getting results like it was checking against itself, and 
of course, that would result in finding a collision. So I threw 
an assert in to check if it was identical objects (as in an error 
outside this function), and it didn't fire off. It appears 
(unless my eyes are deceiving me?) that variable aliases 
themselves are broken.


$ dmd --version
DMD64 D Compiler v2.098.0-beta.2

code:

```d
class drawable_object_t obj;

bool is_colliding_with(drawable_object_t obj) //was a class member
{
assert(this != obj);  //does not fire off

alias x1 = x;
alias y1 = y;
alias w1 = w;
alias h1 = h;

alias x2 = obj.x;
alias y2 = obj.y;
alias w2 = obj.w;
alias h2 = obj.h;

writeln("x1: ", x1, " y1: ", y1, " w1: ", w1, " h1: ", h1);
writeln("x2: ", x2, " y2: ", y2, " w2: ", w2, " h2: ", h2);

writeln("x1: ", x, " y1: ", y, " w1: ", w, " h1: ", h);
	writeln("x2: ", obj.x, " y2: ", obj.y, " w2: ", obj.w, " h2: ", 
obj.h);

}
/*
output:

x1: 50 y1: 81 w1: 5 h1: 6
x2: 50 y2: 81 w2: 5 h2: 6   <
x1: 50 y1: 81 w1: 5 h1: 6
x2: 200 y2: 86.54 w2: 26 h2: 16 <
*/
```

The arrows point to the dependency. The top two sets of numbers 
should _not_ be identical.


Re: sort a string

2020-05-01 Thread Chris Katko via Digitalmars-d-learn

On Friday, 1 May 2020 at 08:17:33 UTC, norm wrote:

On Friday, 1 May 2020 at 07:38:53 UTC, Chris Katko wrote:

[...]


You need to convert the sort output to dchar[], e.g.
---
dchar[] line3 = sort(line2.to!(dchar[])).to!(dchar[]);
---

Cheers,
Norm


That works, thanks!



sort a string

2020-05-01 Thread Chris Katko via Digitalmars-d-learn
I'm making anagrams. According to the nextPermutation() docs, I 
need to 'sort by less' to get all permutations. ... Except the 
doc page doesn't mention how to do that, nor does 
std.algorithm.sort show how to sort a string. ... and the google 
results on the dlang forums from 2017 don't work.


I've tried .byCodeUnit. , .representation. I've tried sorting on 
the dchar. I've tried sorting the on string.


The closest I've gotten:

string word = "bar";
string line2 = toLower!(string)(word);
dchar[] line3 = sort(line2.to!(dchar[]));

"Error: cannot implicitly convert expression sort(to(line2)) of 
type SortedRange!(dchar[], "a < b") to dchar[]"




Re: Get memory used by current process at specific point in time

2020-01-15 Thread Chris Katko via Digitalmars-d-learn

On Sunday, 12 January 2020 at 13:58:18 UTC, Per Nordlöw wrote:
Is there a druntime/phobos function for getting the amount of 
memory (both, stack, malloc, and GC) being used by the current 
process?


Valgrind will tell you the exact usage (except no delineation for 
GC) per here:


https://stackoverflow.com/questions/131303/how-to-measure-actual-memory-usage-of-an-application-or-process

Valgrind is an overall extremely useful tool for Linux devs.

Still, some internal instrumentation would be nice. But I'm not 
aware of any.





Re: Practical parallelization of D compilation

2020-01-08 Thread Chris Katko via Digitalmars-d-learn

On Wednesday, 8 January 2020 at 06:51:57 UTC, H. S. Teoh wrote:
On Wed, Jan 08, 2020 at 04:40:02AM +, Guillaume Lathoud via 
Digitalmars-d-learn wrote:

[...]

[...]

Generally, the recommendation is to separately compile each 
package. E.g., if you have a source tree of the form:


src/
src/main.d
src/pkg1/mod1.d
src/pkg1/mod2.d
src/pkg2/mod3.d
src/pkg2/mod4.d

then you'd have 3 separate compilations:

dmd -ofpkg1.o src/pkg1/mod1.d src/pkg1/mod2.d
dmd -ofpkg2.o src/pkg2/mod3.d src/pkg2/mod4.d
dmd -ofmyprogram src/main.d pkg1.o pkg2.o

The first two can be done in parallel, since they are 
independent of each other.


The reason per-package granularity is suggested is because the 
accumulated overhead of separately compiling every file makes 
it generally not worth the effort.  D compiles fast enough that 
per-package compilation is still reasonably fast, but you no 
longer incur as much overhead from separately compiling every 
file, yet you still retain the advantage of not recompiling the 
entire program after every change.


(Of course, the above example is greatly simplified; generally 
you'd have about 10 or more files per package, and many more 
packages, so the savings can be quite significant.)



T


What's the downsides / difficulties / "hoops to jump through" 
penalty for putting code into modules instead of one massive 
project? Is it just a little extra handwriting/boilerplate, or is 
there a performance impact talking to other modules vs keeping it 
all in one?


Re: Using tasks without GC?

2020-01-05 Thread Chris Katko via Digitalmars-d-learn
Thanks everyone, looks like i'll have to benchmark myself (which 
is fine) but I'm always afraid because I know "proper 
benchmarking is hard. (TM)"


Feel free to throw any other side advice in. I'm looking to get a 
broad perspective on this.


Straight up shutting off the garbage collector in exchange for 
memory is an interesting concept. But I wonder how quickly it 
will get eaten up. ALSO, if I do shut it off, when i turn it on 
is it going to take much longer? Does the GC take linear / 
quadratically more time based on the N of "items need to be 
freed"?


The thing is, I'm looking to parallelize a dedicated server for 
running MASSIVE numbers of objects (1's or 10's) at high 
tick rate. Worse, for my particular "game mode", the "rounds" can 
last hours. So while a slow crawl of RAM is okay, it won't be 
okay if it hits 30 GB in an hour. So that's going to be another 
"it works IF it works [in our particular game/application]" as 
opposed to "this definitely will/won't work". That's more 
"benchmarking and see" scenarios, which I'm trying to avoid as 
much as possible. You normally don't want to willfully START a 
project with a design where the only way to know if it works... 
is to bench.


There's also an option of periodically firing off (without ending 
the game) say, once every hour and tell everyone to just "live 
with it" because it's (I HOPE!) not going to be a 15/30/60 second 
delay. In my particular application, that still wouldn't be that 
disruptive. (Unless turning GC off hits max ram every couple 
minutes. Then again nobody is going to be okay with that.)


On Saturday, 4 January 2020 at 11:30:53 UTC, dwdv wrote:

Creates a Task on the GC heap that calls an alias.


If possible, there's also scopedTask, which allocates on the 
stack: https://dlang.org/phobos/std_parallelism.html#.scopedTask


So my question is: Has anyone done any analysis over how 
"dangerous" it is to use GC'd tasks for _small_ tasks (in 
terms of milliseconds)?


Nothing major, but 
https://github.com/mratsim/weave/tree/master/benchmarks/fibonacci puts quite a bit of pressure on various implementations. You might want to profile ./pfib 40:


import std;

ulong fib(uint n) {
if (n < 2) return n;

auto x = scopedTask!fib(n-1); // vs. Task!fib(n-1);
taskPool.put(x);
auto y = fib(n-2);
return x.yieldForce + y; // {yield,spin,work}Force
}

void main(string[] args) {
enforce(args.length == 2, "Usage: fib number requested>");

auto n = args[1].to!uint;
// defaultPoolThreads(totalCPUs);
writefln!"fib(%d) = %d"(n, fib(n));
}

At least D isn't locking up beyond 12 tasks; looking at you, 
stdlib-nim. :)





Using tasks without GC?

2020-01-03 Thread Chris Katko via Digitalmars-d-learn
When I program, it's usually videogame ideas. That implies a 
soft, real-time requirement. In general, that requires the mantra 
"allocations are evil, use object pools whenever possible." 
[storing data in static arrays and 'deleting' is usually just 
marking an entry as is_deleted=true and re-using "dead" ones.]


I'm looking through D's parallelism module and the docs state, 
up-front:


 >Creates a Task on the GC heap that calls an alias.

The modern, scalable way to make a parallel game engine uses 
tasks. (as opposed to functional decomposition where 1 thread is 
networking 1 thread is physics, etc.) That requires making LOTS 
of tasks (_per frame_!) and dispatching them. And a 60 FPS 
frametime is... 16 ms or less.


So my question is: Has anyone done any analysis over how 
"dangerous" it is to use GC'd tasks for _small_ tasks (in terms 
of milliseconds)? Is the GC going to fire off all the time and 
send jitter off the charts? Because while freeze-the-world for 20 
milliseconds would probably be unnoticable for many business 
apps, it would completely break a videogame.


I wonder how difficult it would be to either modify the existing 
parallel task codebase (or, write my own?) to use static pools 
instead. Allocate once an array of "MAX_NUM_TASKS" tasks (eating 
the minor memory hit) to prevent touching any allocation. [Even 
if it wasn't GC, allocating every frame in say, C++, is 
dangerous. malloc/new is slow and subject to fragmentation and 
permissions checks.]


Any advice, thoughts? Thanks,
--Chris Katko



Why is this allowed? Inheritance variable shadowing

2019-08-12 Thread Chris Katko via Digitalmars-d-learn

You can drop this straight into run.dlang.io:

import std.stdio;

class base{ float x=1;}
class child : base {float x=2;} //shadows base variable!

void main()
{

base []array;
child c = new child;
array ~= c;

writeln(c.x); //=2
writeln(array[0].x); //=1  //uses BASE's interface, yes,
//but why does the CHILD instance one exist at all?
}

It appears to be legal C++ as well but I can't imagine a 
situation where you'd want to allow the HUGE risk of 
shadowing/aliasing variables in an child class. Why is 
inheritance shadowing allowed? Especially when in D you have to 
explicitly "override" existing _methods_ but not fields/variables?


To quote a Stack Overflow comment on C++ having this "It's not a 
compile error, but it's certainly a design one." Is this allowed 
just because "C++ does it" or because it has some sort of real 
world use that justifies the risk?


Personally, I'd love a compile-time warning that I could turn on 
that flags this situation.


Thanks for your help,
--Chris


Easiest way to use Linux system C files / tiny C libraries

2019-03-29 Thread Chris Katko via Digitalmars-d-learn
What's the easiest way to use POSIX and Linux-specific C include 
files?


I know you can write a wrapper but it seems like half the time 
these files include 20 files which include 20 files which use 
strange enums, arrays, etc that don't clearly have answers on how 
to wrap them.


Is there something I'm missing?

For example, right now, the most recent problem I've had related 
to this is wanting to use the libprocps-dev library. All it does 
is expose the /proc/ process data in an easy-to-use format.


I "could" write my own in D but then once again, I've not solved 
my re-occurring problem of "what if I DO need a C library."


Do I need to implement every piece of a C header / library, or 
can I get away with a tiny subset that I'm actually using?


I don't know. I know this is all vague. But I've run into this 
problem multiple times and every time, after hours of googling, 
never gotten anywhere.


Thanks.


Re: D is supposed to compile fast.

2018-11-25 Thread Chris Katko via Digitalmars-d-learn

On Saturday, 24 November 2018 at 20:44:57 UTC, welkam wrote:

On Friday, 23 November 2018 at 08:57:57 UTC, Chris Katko wrote:

D is supposed to compile fast.


You didnt read the fine print. It compiles simple code fast. 
Also compilation is separate step from linking and your program 
might spend half of "compilation" time in link phase.


Wait wait wait wait wait.

So 1) I have to compile manually, then link. Except that also 
runs the files every time even if they're up-to-date. Is that 
normal behavior for C/C++?


Two questions/topics/issues:

---

#1 How to I only build files that are dirty? Do I actually need a 
build program like DUB, MAKE, or CMAKE to do that? (Can make, 
cmake be used?) How do they recognize files are out-dated if DMD 
can't? Is that just an industry-standard 
specialization/separation-of-responsibilities to not have the 
compiler auto-detect up-to-date builds?




I have the simplest project ever. Less than 10 files and my 
non-VStudio build-scripts have always been simple. A few lines or 
one long line running GCC/Clang/etc. I don't want to learn a make 
program's huge syntax just to compile a program if I can avoid 
it! (I've still got so many D and networking topics to learn on 
the back-burner!)


I've heard "just use dub" but I've also heard that dub have 
flaws/gotchas that I can't remember when it comes to say, dynamic 
linking DLLs/SOs. So I've been hesitant to learn it.





#2 I ran individual file times. They're pretty shocking.
---

std.regex is still, the Devil (TM), clocking in at almost FOUR 
SECONDS for a very simple set of code that simply matches lines 
for a poor-man's INI file parser (with a custom feature that 
allows tab indents to be nested sections). I was considering 
ripping it out and replacing it with JSON and this has REALLY 
motivated me to rip out the regex.


Here's the file times:

novous@saturn:~/Desktop/bitbucket/ss14$ time dmd -c molto.d
Class 4 - Scaled Rotated
hello
hello -- it matches!

real0m0.377s
user0m0.344s
sys 0m0.028s
novous@saturn:~/Desktop/bitbucket/ss14$ time dmd -c helper.d

real0m0.118s
user0m0.096s
sys 0m0.020s
novous@saturn:~/Desktop/bitbucket/ss14$ time dmd -c editor.d

real0m0.626s
user0m0.536s
sys 0m0.072s
novous@saturn:~/Desktop/bitbucket/ss14$ time dmd -c common.d

real0m0.755s
user0m0.636s
sys 0m0.092s
novous@saturn:~/Desktop/bitbucket/ss14$ time dmd -c map.d

real0m1.045s
user0m0.904s
sys 0m0.112s
novous@saturn:~/Desktop/bitbucket/ss14$ time dmd -c object_t.d

real0m0.359s
user0m0.336s
sys 0m0.024s
novous@saturn:~/Desktop/bitbucket/ss14$ time dmd -c animation.d

real0m0.365s
user0m0.280s
sys 0m0.068s
novous@saturn:~/Desktop/bitbucket/ss14$ time dmd -c ini.d

real0m3.672s <--- WOWZA
user0m3.292s
sys 0m0.332s



I have to tell you that, as an outsider (who is VERY interested 
in D), this is very frustrating. "Compile times are fast" != 
"build times" is a huge misconception that borders on being a 
clever lie or twisting of words. When people hear "compile 
times", they think "time to compile the whole project" not "time 
to compile a simple test case that doesn't use any typical D 
features--also, it's not linking." Second, as shown here, it's 
not fast even for compiling! Because the second you touch 
std.regex (which has NO WARNINGS in the documentation), you're 
greeted with another clever lie-by-omission: a 10x explosion of 
build time over some modules.


Now let's stop for a moment. I'm not accusing anyone, and "lie" 
is a strong word with heavy guilt implications--like people are 
intentionally being very sneaky to deceive new-comers. I'm not 
saying any of that, so you can relax and put down the pitchfork. 
I'm not attacking you or your group personally. However, I can't 
think of any better word.


So my point is, I keep running into either misconceptions that 
conveniently make D look good, and other gotchas with NO 
DOCUMENTATION that make the language much slower to work with 
than expected.


And if I'm experiencing this, there are dozens (hundreds?) who 
hit the same roadblocks and gotchas and many people are much less 
forgiving/understanding than I am and simply just "give up" 
without ever telling you. So I'm trying to say this with the best 
of intentions. You can't have standard modules with no warning 
documentation that explode your RAM usage and compile times 
orders-of-a-magnitude more than other ones. You can have an 
"alpha" or "beta" or "Addon" or "external" module. But putting it 
in your standard framework implies that it works well with the 
other modules (::cough::std.variant and threads::cough::), and 
that it's not incredibly slower or more resource intensive. 
Having it in your standard library implies it meets a certain 
_STANDARD_.


I mean, can you think of any module in the 

Re: D is supposed to compile fast.

2018-11-24 Thread Chris Katko via Digitalmars-d-learn
On Friday, 23 November 2018 at 10:00:17 UTC, Nicholas Wilson 
wrote:


If you pass all the files on the command line then they all get 
(re)compiled.


How are you supposed include files if not passing them to the 
compiler?


I'm only using std.regex in one file, IIRC, so whatever the 
"proper" way to only compile changed files should improve it 
drastically.


Almost all of my templates are incredibly simple like using 
generic arguments for taking float and doubles, instead of 
hardcoded float.


I am using both Allegro and DAllegro (a D binding for Allegro5). 
But until recently, the compile times have been very fast. So 
it's definitely been D features cutting things down.


And as for "compile-time doesn't matter" arguments, that's plain 
silly. I'm not a junior programmer. I've had builds that took 
over 30 minutes to compile and as we all (should!) know, the 
longer the build time (especially over 10 seconds), the quicker 
the mind loses its train-of-thought and the more difficulty the 
brain has with establishing cause-and-effect relationships 
between code and bugs. When our builds hit 30 minutes, we ended 
up so disconnected from the project we'd end up playing a short 
game of Duke Nukem 3-D inbetween builds. (Ha! Builds. Build 
engine = the Duke Nukem 3D engine. A super-niche pun.) We were 
incredibly unproductive until I re-wrote the entire thing in a 
different language. It ran in less than 10 seconds and suddenly 
we were powering through new problem after new problem. (A huge 
data conversion project between a discontinued, no-documentation 
product and a new product by a different company.)


Anyhow, if you REALLY want to look at some very WIP code with 
poor documentation and possibly lots of random swearing (hobby 
project for trying out D in a game), I'll make the repo public 
for now:


https://bitbucket.org/katasticvoyage/ss14/src/master/

 extra.d is a main code unit for this application.

 ini.d has regex. (and no, it's not a proper lexer. I'm probably 
swapping it out with JSON.)


D is supposed to compile fast.

2018-11-23 Thread Chris Katko via Digitalmars-d-learn
Any time I see people mention the benefits of D, I see "compile 
times" "compile times" "compile times" over and over.


I'm using very modest amounts of templates, for a fairly small 
sized program (very early work toward a game), and I'm hitting 
~15 seconds compile time in LDC and ~7 seconds in DMD. And I'm 
not even compiling with optimizations!


ldc2 -w -ofextra  extra.d molto.d helper.d editor.d common.d 
map.d object_t.d animation.d ini.d  -L-L. $@-gc -d-debug=3  
-de -fdmd-trace-functions


dmd -w -ofextra extra.d molto.d helper.d editor.d common.d map.d 
object_t.d animation.d ini.d -profile=gc  -profile  -g -debug 
-color -L-L.


I keep putting stuff into new files, but it feels like it's 
compiling everything from scratch / not getting faster the way 
C++ does.


And I'm not even bringing up the 800MB of RAM required because I 
dared to import std.regex. (On a laptop with 2 GB of RAM. RIP. If 
I dare to have tabs open, the compile time goes into the minutes 
thanks to swapping.)




Re: Why does nobody seem to think that `null` is a serious problem in D?

2018-11-20 Thread Chris Katko via Digitalmars-d-learn

Try to learn D.
Put writeln in deconstructor to prove it works as expected
Make random changes, program never runs again.
Takes 30+ minutes to realize that writeln("my string") is fine, 
but writeln("my string " ~ value) is an allocation / garbage 
collection which crashes the program without a stack.


My favorite D'ism so far:


Re: Why is stdio ... stdio?

2018-11-10 Thread Chris Katko via Digitalmars-d-learn

On Saturday, 10 November 2018 at 13:53:14 UTC, Kagamin wrote:
On Friday, 9 November 2018 at 09:11:37 UTC, Jonathan M Davis 
wrote:
No, I didn't. I just used underscores, which has been used 
with plain text for emphasis for decades. Supporting markdown, 
would involve stuff like backticks for code highlighting


Backticks are from ddoc. What's the other way to indicate a 
code fragment?


markup for urls - stuff that doesn't actually provide 
information to someone who's reading plain text but just gets 
in the way


If the url is messy, it's already a mess. If it isn't, it's 
easier to leave url as is than bother to markup it.


whereas the underscores _do_ provide information to someone 
reading plain text.


I think what's really missing is code highlighting. Emphasis 
isn't very useful, in your example the verb "do" is already 
emphasis, so markup doesn't provide any additional information, 
just gets in the way.


There is another possibility. Have the website run (fallible) 
heuristics to detect a snippet of code and automatically generate 
it. That would leave the mailing list people completely unchanged.


However, HOW fallible becomes a huge issue. It may be so well 
implemented that nobody ever complains. Or, it could be so bad 
that it often breaks up the author's post in ways the author 
never planned--almost taking away the poster as the controller of 
what they present.


That's a bit of an extreme, and unlikely, but I feel that 
examining extremes can be helpful to define the potential domain 
of the problem.


We can also easily have a checkmark next to each post that 
disables highlighting for that post (as well as disable them in 
your account settings), and even a button people could press that 
says "this post is highlighted wrong." and the developer would 
get a log with the code.


How many implementation "fixes" are needed depends on how 
fallible the detection code really is.


--

But, really, I don't personally see it being "that" bad for 
people to put code tags / code markers around code. It's not like 
they're going to be peppered everywhere. If you can ignore a 
comment in code, you can ignore two tags (start and end) in a 
single post.


It's an interesting argument to extend bold and italics... 
because people ARE already using them!


But I never suggested we should support "full markdown". There's 
no need to support an entire standard if your forum only needs 
part of it. It seems like a reasonable compromise favoring 
maximum utility, to support code tags, as well as tags people 
already use like italics and bold.


Automatic URL linking is a feature of 99% of forums and that 
would also have zero impact on the mailing list people.


There may be others. Even if the goal is "minimum changes for 
mailing list people" it can still be done.


Re: Why is stdio ... stdio?

2018-11-09 Thread Chris Katko via Digitalmars-d-learn
On Friday, 9 November 2018 at 09:11:37 UTC, Jonathan M Davis 
wrote:
On Friday, November 9, 2018 1:27:44 AM MST Kagamin via 
Digitalmars-d-learn wrote:

On Friday, 9 November 2018 at 06:42:37 UTC, Jonathan M Davis

wrote:
> [...]

You used markdown three times in your message.


No, I didn't. I just used underscores, which has been used with 
plain text for emphasis for decades. Supporting markdown, would 
involve stuff like backticks for code highlighting, and special 
markup for urls - stuff that doesn't actually provide 
information to someone who's reading plain text but just gets 
in the way, whereas the underscores _do_ provide information to 
someone reading plain text.


- Jonathan M Davis


FYI, Allegro.CC just uses


int main()
 {
 return 0;
 }


as well as  for pre-formatted "monospace" text.

Neither of those would pollute a mailing list in plain-text mode 
because they'd exist only at the start and end of code. I'm sure 
you had no problem reading my above code.


Why is stdio ... stdio?

2018-11-08 Thread Chris Katko via Digitalmars-d-learn

Simple curious question.

Why isn't :

import std.stdio;

instead:

import std.io;

(Also, while we're at it. Why doesn't this form have code 
highlighting? It would much improve readibility. Doesn't that 
seem almost essential for a programming forum?)



I mean, I get it. stdio is the c header from a thousand years 
ago. But this isn't C. So it's kind of odd to ask for the 
"Standard standard" io library.




Re: lazy variables

2018-10-17 Thread Chris Katko via Digitalmars-d-learn

On Wednesday, 17 October 2018 at 07:32:37 UTC, aliak wrote:

Hi,

Is there any notion of lazy vars in D (i see that there're 
parameters)?


i.e:

struct S {
  //...
  int y;
  //...
}

lazy S x = () {
// do some heavy stuff
}();

if (condition) {
  func(x.y); // heavy stuff evaluated here
}

Cheers,
- Ali


This might be helpful:

https://dlang.org/articles/lazy-evaluation.html


Why doesn't foreach support iterating?

2018-10-16 Thread Chris Katko via Digitalmars-d-learn

int [50]data;
foreach(i, datum; data){} // works

File file("gasdgasd");
foreach(i, line; file.byLine){} //NOPE.
foreach(line; file.byLine){} //works.

I finally noticed in the docs it says "for arrays only." The 
question is, why?


Every language that I used previously (as far as I can remember) 
implemented foreach in a way that's consistent / orthogonal.


Is there a way around this? Because currently I have to liter my 
foreach's with ugly manual index variables that hold scope even 
after it's gone.


int i = 0;
foreach(line; file.byLine){
//do stuff
i++;
}
i = 2; // still exists!


Re: std.regex is fat

2018-10-14 Thread Chris Katko via Digitalmars-d-learn

On Sunday, 14 October 2018 at 03:26:33 UTC, Adam D. Ruppe wrote:

On Sunday, 14 October 2018 at 03:07:59 UTC, Chris Katko wrote:
For comparison, I just tested and grep uses about 4 MB of RAM 
to run.


Running and compiling are two entirely different things. 
Running the D regex code should be comparable, but compiling it 
is slow, in great part because of internal templates...


There was an effort to speed up the template code, but it is 
still not complete.


I know that. I figured people would miss my point on it though so 
I should have clarified. That's why I said it's likely the 
templates/DMD that's exploding--not the actual regex action.


From a simple program, it takes ~100-150MB of RAM to compile. 
Adding a single regex (not compiled regex) balloons to 550MB at 5 
seconds of compile time.


---

Anyhow, I wrote my own simple "dgrep" and compared the results 
with grep, it's very competitive: (NOT to be confused with the 
above RAM stats for COMPILING)



Command being timed: "sh -c cat dgrep.d | ./dgrep 'write' "
User time (seconds): 0.00
System time (seconds): 0.00
Percent of CPU this job got: 0%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 3192
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 301
Voluntary context switches: 5
Involuntary context switches: 124
Swaps: 0
File system inputs: 8
File system outputs: 8
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0
Command being timed: "sh -c cat dgrep.d | grep 'write'"
User time (seconds): 0.00
System time (seconds): 0.00
Percent of CPU this job got: 0%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 2224
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 2
Minor (reclaiming a frame) page faults: 282
Voluntary context switches: 10
Involuntary context switches: 0
Swaps: 0
File system inputs: 760
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0

So I have to say I'm impressed with the actual performance of the 
regular expressions engine--especially considering "grep" is, 
IIRC, considered a fine-tuned beast.


Re: std.regex is fat

2018-10-13 Thread Chris Katko via Digitalmars-d-learn

On Sunday, 14 October 2018 at 02:44:55 UTC, Chris Katko wrote:

On Friday, 12 October 2018 at 13:42:34 UTC, Alex wrote:

[...]


So wait, if their solution was to simply REMOVE std.regex from 
isEmail. That doesn't solve the regex problem at all. And from 
what I read in that thread, this penalty is paid per template 
INSTANTIATION which could explode.


[...]


For comparison, I just tested and grep uses about 4 MB of RAM to 
run.


So it's not the regex. It's the dmd / templates / CTFE, right?


Re: std.regex is fat

2018-10-13 Thread Chris Katko via Digitalmars-d-learn

On Friday, 12 October 2018 at 13:42:34 UTC, Alex wrote:

On Friday, 12 October 2018 at 13:25:33 UTC, Chris Katko wrote:

Like, insanely fat.

All I wanted was a simple regex. The second include a regex 
function, my program would no longer compile "out of memory 
for fork".


/usr/bin/time -v reports it went from 150MB of RAM for D, 
DAllegro, and Allegro5.


To over 650MB of RAM, and from 1.5 seconds to >5.5 seconds to 
compile. Now I have to close all my Chrome tabs just to 
compile.


Just for one line of regex. And I get it, it's the overhead of 
the library import, not the single line. But good gosh, more 
than 3X the RAM of the entire project for a single library 
import?


Something doesn't add up!


Hm... maybe, you run into this:
https://forum.dlang.org/post/mailman.3091.1517866806.9493.digitalmar...@puremagic.com


So wait, if their solution was to simply REMOVE std.regex from 
isEmail. That doesn't solve the regex problem at all. And from 
what I read in that thread, this penalty is paid per template 
INSTANTIATION which could explode.


 1 - Does anyone know WHY it's so incredibly fat?

 2 - If this isn't going to be fixed anytime soon, shouldn't 
there be a DISCLAIMER on the documentation? (+potential 
workarounds like keeping regex queries in their own file.)


I mean, this kind of thing shouldn't require looking through 
forums. It's a clear bug, and if it's a WONTFIX (even 
temporarily), it should be documented clearly as such.


If I'm running into this issue, how many other people already 
did, and possibly even gave up on using D?





std.regex is fat

2018-10-12 Thread Chris Katko via Digitalmars-d-learn

Like, insanely fat.

All I wanted was a simple regex. The second include a regex 
function, my program would no longer compile "out of memory for 
fork".


/usr/bin/time -v reports it went from 150MB of RAM for D, 
DAllegro, and Allegro5.


To over 650MB of RAM, and from 1.5 seconds to >5.5 seconds to 
compile. Now I have to close all my Chrome tabs just to compile.


Just for one line of regex. And I get it, it's the overhead of 
the library import, not the single line. But good gosh, more than 
3X the RAM of the entire project for a single library import?


Something doesn't add up!




Re: Why are 2-D arrays reversed?

2018-10-10 Thread Chris Katko via Digitalmars-d-learn
On Wednesday, 10 October 2018 at 16:00:42 UTC, Steven 
Schveighoffer wrote:

On 10/10/18 9:22 AM, Chris Katko wrote:

int[][] data =
 [
     [1, 0, 1, 0, 0],
     [1, 0, 1, 0, 0],
     [1, 0, 1, 1, 1],
     [1, 0, 0, 1, 0],
     [5, 1, 1, 1, 0]
 ];

when drawn with data[i][j], prints the transpose of "data":

[1, 1, 1, 1, 5]
[0, 0, 0, 0, 1]
[1, 1, 1, 0, 1]
[0, 0, 1, 1, 1]
[0, 0, 1, 0, 0]

So, if I flip [i][j] and print a row of "j's", it'll be 
correct. It's very confusing and counter-intuitive to have to 
remember to swap i and j every time I use an array.


I guess when I load data from files, the i/j are already 
swapped and stay consistent, but when using an array in source 
code, they have to be flipped.


I'm not sure what code you are using, but it prints out just 
fine for me:


https://run.dlang.io/is/hrA0tj

-Steve


Ah, here's a simple example:

int[][] data3 =
[
[1, 0, 1, 0, 0],
[1, 0, 1, 0, 0],
[1, 0, 1, 1, 1],
[1, 0, 0, 1, 0],
[5, 1, 1, 1, 0]
];

for(int i = 0; i < 5; i++)
{
for(int j = 0; j < 5; j++)
{
write(data4[i][j]," ");
}
writeln();
}

  1 0 1 0 0
  1 0 1 0 0
  1 0 1 1 1
  1 0 0 1 0
  5 1 1 1 0

I have to draw j's first. I have to iterate through the 
"y"/columns/j to get the the "x's" first.


I mean, I guess it makes sense if the outer-most array indexer 
refers to the inner-most "element".


Wait, this IS the same as C, isn't it? So maybe this is just a 
"new" problem for me since I rarely-if-ever use hardcoded 
arrays...


Maybe my brain is just melting.


Why are 2-D arrays reversed?

2018-10-10 Thread Chris Katko via Digitalmars-d-learn

int[][] data =
[
[1, 0, 1, 0, 0],
[1, 0, 1, 0, 0],
[1, 0, 1, 1, 1],
[1, 0, 0, 1, 0],
[5, 1, 1, 1, 0]
];

when drawn with data[i][j], prints the transpose of "data":

[1, 1, 1, 1, 5]
[0, 0, 0, 0, 1]
[1, 1, 1, 0, 1]
[0, 0, 1, 1, 1]
[0, 0, 1, 0, 0]

So, if I flip [i][j] and print a row of "j's", it'll be correct. 
It's very confusing and counter-intuitive to have to remember to 
swap i and j every time I use an array.


I guess when I load data from files, the i/j are already swapped 
and stay consistent, but when using an array in source code, they 
have to be flipped.


Re: How do you iterate "vertically" over a 2-D array?

2018-10-09 Thread Chris Katko via Digitalmars-d-learn

On Tuesday, 9 October 2018 at 10:52:47 UTC, Chris Katko wrote:

I have a 2-D array:

int[5][5] data =
[
[1, 0, 1, 0, 0],
[1, 0, 1, 0, 0],
[1, 0, 1, 1, 1],
[1, 0, 0, 1, 0],
[1, 1, 1, 1, 0]
];


1 - Is there a way to foreach vertically through that? (that 
is, rotated 90 degrees from the usual iteration.)


2 - Is there a way to send that "vertical slice" to a function?

int count_numbers(){/*...*/}

count_numbers(data[0]); //horizontal sum of array[0][0..$-1] 
WORKS.
count_numbers(data[][0]); //vertical sum of array[0..$-1][0] 
HYPOTHETICAL


I'm working on an RLE encoding function and I need both 
vertical and horizontal strips. It just occurred to me that the 
problem is essentially the same, if you can "transpose" the 
matrix.


Oh geez, did I just realize what I need? some sort of matrix 
transpose function? I found this post;


https://forum.dlang.org/post/na8ikk$2ojo$1...@digitalmars.com

The problem is though, even if I use [][], instead of [5][5] 
(or try using his conversion function), I can call 
transposed... but I can't call my function with it!


void run_rle3(int [] a){/*...*/}

run_rle3(data[0]); //works
run_rle3(data.transposed[0]); //nope [see error below]
run_rle3(data[0].transposed); //nope (didn't expect this to)
run_rle3((data.transposed)[0]); //nope [see error below]

Error: function dmap.run_rle3 (int[] a) is not callable using 
argument types (Transversal!(int[][], cast(TransverseOptions)0))


So according to this:

https://dlang.org/library/std/range/transposed.html

It's trying to take my [0] as an argument for the 
TransverseOptions variable? But even if I wrap it in parenthesis, 
it still takes it! (See the last line of code.)


auto taco = (data.transposed);
run_rle3(taco); //same error, but < HERE?



How do you iterate "vertically" over a 2-D array?

2018-10-09 Thread Chris Katko via Digitalmars-d-learn

I have a 2-D array:

int[5][5] data =
[
[1, 0, 1, 0, 0],
[1, 0, 1, 0, 0],
[1, 0, 1, 1, 1],
[1, 0, 0, 1, 0],
[1, 1, 1, 1, 0]
];


1 - Is there a way to foreach vertically through that? (that is, 
rotated 90 degrees from the usual iteration.)


2 - Is there a way to send that "vertical slice" to a function?

int count_numbers(){/*...*/}

count_numbers(data[0]); //horizontal sum of array[0][0..$-1] 
WORKS.
count_numbers(data[][0]); //vertical sum of array[0..$-1][0] 
HYPOTHETICAL


I'm working on an RLE encoding function and I need both vertical 
and horizontal strips. It just occurred to me that the problem is 
essentially the same, if you can "transpose" the matrix.


Oh geez, did I just realize what I need? some sort of matrix 
transpose function? I found this post;


https://forum.dlang.org/post/na8ikk$2ojo$1...@digitalmars.com

The problem is though, even if I use [][], instead of [5][5] (or 
try using his conversion function), I can call transposed... but 
I can't call my function with it!


void run_rle3(int [] a){/*...*/}

run_rle3(data[0]); //works
run_rle3(data.transposed[0]); //nope [see error below]
run_rle3(data[0].transposed); //nope (didn't expect this to)
run_rle3((data.transposed)[0]); //nope [see error below]

Error: function dmap.run_rle3 (int[] a) is not callable using 
argument types (Transversal!(int[][], cast(TransverseOptions)0))




Re: std.socket tutorials? examples?

2018-10-04 Thread Chris Katko via Digitalmars-d-learn

On Thursday, 4 October 2018 at 08:52:28 UTC, Andrea Fontana wrote:

On Thursday, 4 October 2018 at 08:32:13 UTC, Chris Katko wrote:

I've been Google'ing and there's like... nothing out there.

One of the top results for "std.socket dlang examples"... is 
for TANGO. That's how old it is.


Socket paradigm is quite standard across languages.

Anyway you can find a couple of example here:
https://github.com/dlang/dmd/blob/master/samples/listener.d
https://github.com/dlang/dmd/blob/master/samples/htmlget.d

Andrea


I was hoping someone would have a walk-through or something. 
Those examples are 110 lines each!


Usually, with D, there's plenty of useful 
paradigms/templates/Phobos magic. So if I just port a C/C++/C# 
socket example over, how am I supposed to know if I'm doing it 
"the right/proper/best way" in D? That kind of thing.


std.socket tutorials? examples?

2018-10-04 Thread Chris Katko via Digitalmars-d-learn

I've been Google'ing and there's like... nothing out there.

One of the top results for "std.socket dlang examples"... is for 
TANGO. That's how old it is.


Re: Template/mixin ideas?

2018-10-03 Thread Chris Katko via Digitalmars-d-learn
On Wednesday, 3 October 2018 at 11:51:01 UTC, Sebastiaan Koppe 
wrote:

On Wednesday, 3 October 2018 at 11:01:53 UTC, Chris Katko wrote:

[...]


A combination of static introspection with string mixins does 
the trick:


---
enum colors {
reset = "\033[0m",
red = "\033[31m"
}

auto GenerateColorFuncs() {
string result;
static foreach(c; __traits(allMembers, colors))
result ~= "auto "~c~"(string str) { return colors."~c~" 
~ str ~ colors.reset; }";

return result;
}

mixin(GenerateColorFuncs());

void main()
{
import std.stdio;
writeln("bla".red);
}
---

Although you might want to replace the string concatenation 
with something more performant if used a lot.


The mixin part wouldn't be slowed by strings, right? So the 
"slowness" is the invokation part which changes strings and 
forces GC allocations, I guess?


What's the alternative to using strings... for strings?


Template/mixin ideas?

2018-10-03 Thread Chris Katko via Digitalmars-d-learn
I've got this simple task but I'm trying to perfect it as best I 
can to learn something in the process.


I have Linux terminal ASCII codes for coloring terminal output.

string red(string) { /* ... */ }

"Hello world".red => "\033[31mHello World\033[0m"

which translates to "[red]Hello World[reset to normal text]".

I have to do some slight trickery so I can chain them. But it all 
works fine. __The function is the same__ no matter what kind of 
color, bold, etc attribute I want. The only difference is the 
tag/prefix string.


So I have a table (or enum):
enum colors{
 reset = "\033[0m",
 red = "\033[31m",
 bold = "\033[1m" //...
 }

Absolute perfection would be some way to add a single line to 
that enum (or table) and magically get a new function. I add 
"blue" with its prefix code to the enum and immediately I can do:


"hello world".blue

Add yellow = "\033..." and I can do:

"hello world".bold.yellow

It's an interesting problem. Right now, I made a generic version 
that accepts the prefix code string directly called "color()" and 
red() translates to a call to color with the red string. blue() 
does the same. And so on. But it's still plenty of boiler plate. 
I do that so I don't have 80+ functions all a half-page 
long--which would be a nightmare to verify.


It's surely nothing mission critical. But I wonder if I can 
distill this simple problem down further, I may be able to learn 
some tricks for later problems.


Thanks.


Re: Dynamic Minimum width with Format / writefln

2018-10-02 Thread Chris Katko via Digitalmars-d-learn

On Wednesday, 3 October 2018 at 00:34:33 UTC, Adam D. Ruppe wrote:

On Wednesday, 3 October 2018 at 00:14:03 UTC, Chris Katko wrote:
Except it doesn't work and tries to decode col.width-1 into a 
hexadecimal number and only prints that. ("4D6EF6")


That number certainly isn't col.width (unless you have a width 
of like millions)...


It looks more like a pointer. What is the type of col.name? If 
it is string, this code should work fine.


I'm guessing it is a char*...


I'm not sure how I made this mistake. But it seems to only show 
up now if I leave .toStringz() with the writefln.


writefln("%-*s<", col.width-1, col.name.toStringz() /* here */);

So maybe I've been staring at code too long tonight and simply 
missed it?




Dynamic Minimum width with Format / writefln

2018-10-02 Thread Chris Katko via Digitalmars-d-learn
 - First, I'm confused. The docs say 's' is "whatever it needs to 
be". ("he corresponding argument is formatted in a manner 
consistent with its type:") But what if I specifically want a 
STRING. Because I only see floats, ints, etc. No forced string 
types.


 - Second,

This works fine in D:

printf("%-*s|", col.width-1, col.name.toStringz());

It's a left-aligned, string with a minimum width from the first 
argument, col.width. (-1 because I'm throwing a pipe symbol on 
the end.)


Now with writefln:

writefln("%-*s|", col.width-1, col.name);

Same format specifier, except I don't need a toStringz which is 
nice. Except it doesn't work and tries to decode col.width-1 into 
a hexadecimal number and only prints that. ("4D6EF6")


I looked through the docs:

https://dlang.org/phobos/std_format.html

 '%' Position Flags Width Separator Precision FormatChar

Width:
empty
Integer
'*'

But there are then zero examples or explanations of how to use 
that option. What's going on here?


Re: Sending Tid in a struct

2018-09-28 Thread Chris Katko via Digitalmars-d-learn
On Wednesday, 23 November 2016 at 08:47:56 UTC, Christian Köstlin 
wrote:

On 03/03/2012 18:35, Timon Gehr wrote:

On 03/03/2012 12:09 PM, Nicolas Silva wrote:

[...]


Yes, this seems to be a bug.

Workaround:

struct Foo{
string s;
Tid id;
}

void foo(){
Foo foo;
receive((Tuple!(string,"s",Tid,"id") 
bar){foo=Foo(bar.s,bar.id);});

}

void main(){
auto id = spawn();
id.send("string",id);
...
}
I had a similar problem with this an it seems this is still a 
bug with dmd 2.072.


best regards,
christian


So this appears to still be a bug in 2.078.0-beta.1. Sigh...

So the only way to actually use concurrency in D... is to use 
this hack? Or has it been fixed since January? Is there an 
official bug report?


Re: Simple parallel foreach and summation/reduction

2018-09-24 Thread Chris Katko via Digitalmars-d-learn

On Monday, 24 September 2018 at 07:13:24 UTC, Chris Katko wrote:

On Monday, 24 September 2018 at 05:59:20 UTC, Chris Katko wrote:

[...]



Actually, I just realized/remembered that the error occurs 
inside parallelism itself, and MANY times at that:


[...]


This JUST occurred to me. When I use an outer taskPool.[a]map, am 
I NOT supposed to use the taskPool version of reduce?! But 
instead, the std.algorithm one?


Because this is running with both/all cores, and only using 2.7MB 
of RAM:


sum = taskPool.reduce!(test)(
map!(monte)(range)   //map, not taskPool.map
);  

If that's the correct case, the docs did NOT make that obvious!

FYI, I went from ~5200 samples / mSec, to 7490 samples / mSec. 
36% difference for second "real" core. Better than nothing, I 
guess. I'll have to try it on my main machine with a proper CPU.


Re: Simple parallel foreach and summation/reduction

2018-09-24 Thread Chris Katko via Digitalmars-d-learn

On Monday, 24 September 2018 at 05:59:20 UTC, Chris Katko wrote:
On Saturday, 22 September 2018 at 02:26:41 UTC, Chris Katko 
wrote:
On Saturday, 22 September 2018 at 02:13:58 UTC, Chris Katko 
wrote:
On Friday, 21 September 2018 at 12:15:59 UTC, Ali Çehreli 
wrote:

On 09/21/2018 12:25 AM, Chris Katko wrote:

[...]


You can use a free-standing function as a workaround, which 
is included in the following chapter that explains most of 
std.parallelism:


  http://ddili.org/ders/d.en/parallelism.html

That chapter is missing e.g. the newly-added fold():

  
https://dlang.org/phobos/std_parallelism.html#.TaskPool.fold


Ali


Okay... so I've got it running. The problem is, it uses tons 
of RAM. In fact, proportional to the working set.


T test(T)(T x, T y)
{
return x + y;
}

double monte(T)(T x)
{
double v = uniform(-1F, 1F);
double u = uniform(-1F, 1F);
if(sqrt(v*v + u*u) < 1.0)
{
return 1;
}else{
return 0;
}
}

auto taskpool = new TaskPool();
sum = taskpool.reduce!(test)(
taskpool.amap!monte(
iota(num)
)   );  
taskpool.finish(true);

100 becomes ~8MB
1000 becomes 80MB
1, I can't even run because it says "Exception: 
Memory Allocation failed"


Also, when I don't call .finish(true) at the end, it just sits 
there forever (after running) like one of the threads won't 
terminate. Requiring a control-C. But the docs and examples 
don't seem to indicate I should need that...


So I looked into it. It's amap that explodes in RAM.

Per the docs, amap has "less overhead but more memory usage." 
While map has more overhead but less memory usage and "avoids 
the need to keep all results in memory."


But, if I make a call to map... it doesn't compile! I get:

Error: no [] operator overload for type 
std.parallelism.TaskPool.map!(monte).map!(Result).map.Map


Simply changing amap to map here:

sum = taskPool.reduce!(test)
(
taskPool.map!(monte)(range)
);



Actually, I just realized/remembered that the error occurs inside 
parallelism itself, and MANY times at that:


/usr/include/dmd/phobos/std/parallelism.d(2590): Error: no [] 
operator overload for type 
std.parallelism.TaskPool.map!(monte).map!(Result).map.Map
/usr/include/dmd/phobos/std/parallelism.d(2596): Error: no [] 
operator overload for type 
std.parallelism.TaskPool.map!(monte).map!(Result).map.Map
/usr/include/dmd/phobos/std/parallelism.d(2616): Error: no [] 
operator overload for type 
std.parallelism.TaskPool.map!(monte).map!(Result).map.Map
/usr/include/dmd/phobos/std/parallelism.d(2616): Error: no [] 
operator overload for type 
std.parallelism.TaskPool.map!(monte).map!(Result).map.Map
/usr/include/dmd/phobos/std/parallelism.d(2616): Error: no [] 
operator overload for type 
std.parallelism.TaskPool.map!(monte).map!(Result).map.Map
/usr/include/dmd/phobos/std/parallelism.d(2616): Error: no [] 
operator overload for type 
std.parallelism.TaskPool.map!(monte).map!(Result).map.Map
/usr/include/dmd/phobos/std/parallelism.d(2616): Error: no [] 
operator overload for type 
std.parallelism.TaskPool.map!(monte).map!(Result).map.Map
/usr/include/dmd/phobos/std/parallelism.d(2616): Error: no [] 
operator overload for type 
std.parallelism.TaskPool.map!(monte).map!(Result).map.Map
/usr/include/dmd/phobos/std/parallelism.d(2626): Error: no [] 
operator overload for type 
std.parallelism.TaskPool.map!(monte).map!(Result).map.Map
/usr/include/dmd/phobos/std/parallelism.d(2626): Error: no [] 
operator overload for type 
std.parallelism.TaskPool.map!(monte).map!(Result).map.Map
/usr/include/dmd/phobos/std/parallelism.d(2626): Error: no [] 
operator overload for type 
std.parallelism.TaskPool.map!(monte).map!(Result).map.Map
/usr/include/dmd/phobos/std/parallelism.d(2626): Error: no [] 
operator overload for type 
std.parallelism.TaskPool.map!(monte).map!(Result).map.Map
/usr/include/dmd/phobos/std/parallelism.d(2626): Error: no [] 
operator overload for type 
std.parallelism.TaskPool.map!(monte).map!(Result).map.Map
/usr/include/dmd/phobos/std/parallelism.d(2626): Error: no [] 
operator overload for type 
std.parallelism.TaskPool.map!(monte).map!(Result).map.Map
/usr/include/dmd/phobos/std/parallelism.d(2634): Error: no [] 
operator overload for type 
std.parallelism.TaskPool.map!(monte).map!(Result).map.Map
monte.d(64): Error: template instance 
std.parallelism.TaskPool.reduce!(test).reduce!(Map) error 
instantiating


Though I tried looking up the git version of prallelism.d and the 
lines don't quite line up:


https://github.com/dlang/phobos/blob/master/std/parallelism.d


Re: Simple parallel foreach and summation/reduction

2018-09-24 Thread Chris Katko via Digitalmars-d-learn

On Saturday, 22 September 2018 at 02:26:41 UTC, Chris Katko wrote:
On Saturday, 22 September 2018 at 02:13:58 UTC, Chris Katko 
wrote:
On Friday, 21 September 2018 at 12:15:59 UTC, Ali Çehreli 
wrote:

On 09/21/2018 12:25 AM, Chris Katko wrote:

[...]


You can use a free-standing function as a workaround, which 
is included in the following chapter that explains most of 
std.parallelism:


  http://ddili.org/ders/d.en/parallelism.html

That chapter is missing e.g. the newly-added fold():

  https://dlang.org/phobos/std_parallelism.html#.TaskPool.fold

Ali


Okay... so I've got it running. The problem is, it uses tons 
of RAM. In fact, proportional to the working set.


T test(T)(T x, T y)
{
return x + y;
}

double monte(T)(T x)
{
double v = uniform(-1F, 1F);
double u = uniform(-1F, 1F);
if(sqrt(v*v + u*u) < 1.0)
{
return 1;
}else{
return 0;
}
}

auto taskpool = new TaskPool();
sum = taskpool.reduce!(test)(
taskpool.amap!monte(
iota(num)
)   );  
taskpool.finish(true);

100 becomes ~8MB
1000 becomes 80MB
1, I can't even run because it says "Exception: Memory 
Allocation failed"


Also, when I don't call .finish(true) at the end, it just sits 
there forever (after running) like one of the threads won't 
terminate. Requiring a control-C. But the docs and examples 
don't seem to indicate I should need that...


So I looked into it. It's amap that explodes in RAM.

Per the docs, amap has "less overhead but more memory usage." 
While map has more overhead but less memory usage and "avoids the 
need to keep all results in memory."


But, if I make a call to map... it doesn't compile! I get:

Error: no [] operator overload for type 
std.parallelism.TaskPool.map!(monte).map!(Result).map.Map


Simply changing amap to map here:

sum = taskPool.reduce!(test)
(
taskPool.map!(monte)(range)
);


Re: Simple parallel foreach and summation/reduction

2018-09-21 Thread Chris Katko via Digitalmars-d-learn

On Saturday, 22 September 2018 at 02:13:58 UTC, Chris Katko wrote:

On Friday, 21 September 2018 at 12:15:59 UTC, Ali Çehreli wrote:

On 09/21/2018 12:25 AM, Chris Katko wrote:

[...]


You can use a free-standing function as a workaround, which is 
included in the following chapter that explains most of 
std.parallelism:


  http://ddili.org/ders/d.en/parallelism.html

That chapter is missing e.g. the newly-added fold():

  https://dlang.org/phobos/std_parallelism.html#.TaskPool.fold

Ali


Okay... so I've got it running. The problem is, it uses tons of 
RAM. In fact, proportional to the working set.


T test(T)(T x, T y)
{
return x + y;
}

double monte(T)(T x)
{
double v = uniform(-1F, 1F);
double u = uniform(-1F, 1F);
if(sqrt(v*v + u*u) < 1.0)
{
return 1;
}else{
return 0;
}
}

auto taskpool = new TaskPool();
sum = taskpool.reduce!(test)(
taskpool.amap!monte(
iota(num)
)   );  
taskpool.finish(true);

100 becomes ~8MB
1000 becomes 80MB
1, I can't even run because it says "Exception: Memory 
Allocation failed"


Also, when I don't call .finish(true) at the end, it just sits 
there forever (after running) like one of the threads won't 
terminate. Requiring a control-C. But the docs and examples don't 
seem to indicate I should need that...


Re: Simple parallel foreach and summation/reduction

2018-09-21 Thread Chris Katko via Digitalmars-d-learn

On Friday, 21 September 2018 at 12:15:59 UTC, Ali Çehreli wrote:

On 09/21/2018 12:25 AM, Chris Katko wrote:
On Thursday, 20 September 2018 at 05:51:17 UTC, Neia Neutuladh 
wrote:
On Thursday, 20 September 2018 at 05:34:42 UTC, Chris Katko 
wrote:
All I want to do is loop from 0 to [constant] with a for or 
foreach, and have it split up across however many cores I 
have.


You're looking at std.parallelism.TaskPool, especially the 
amap and reduce functions. Should do pretty much exactly what 
you're asking.


auto taskpool = new TaskPool();
taskpool.reduce!((a, b) => a + b)(iota(1_000_000_000_000L));


I get "Error: template instance `reduce!((a, b) => a + b)` 
cannot use local __lambda1 as parameter to non-global template 
reduce(functions...)" when trying to compile that using the 
online D editor with DMD and LDC.


Any ideas?


You can use a free-standing function as a workaround, which is 
included in the following chapter that explains most of 
std.parallelism:


  http://ddili.org/ders/d.en/parallelism.html

That chapter is missing e.g. the newly-added fold():

  https://dlang.org/phobos/std_parallelism.html#.TaskPool.fold

Ali


Okay... so I've got it running. The problem is, it uses tons of 
RAM. In fact, proportional to the working set.


T test(T)(T x, T y)
{
return x + y;
}

double monte(T)(T x)
{
double v = uniform(-1F, 1F);
double u = uniform(-1F, 1F);
if(sqrt(v*v + u*u) < 1.0)
{
return 1;
}else{
return 0;
}
}

auto taskpool = new TaskPool();
sum = taskpool.reduce!(test)(
taskpool.amap!monte(
iota(num)
)   );  
taskpool.finish(true);

100 becomes ~8MB
1000 becomes 80MB
1, I can't even run because it says "Exception: Memory 
Allocation failed"


Re: Simple parallel foreach and summation/reduction

2018-09-21 Thread Chris Katko via Digitalmars-d-learn
On Thursday, 20 September 2018 at 05:51:17 UTC, Neia Neutuladh 
wrote:
On Thursday, 20 September 2018 at 05:34:42 UTC, Chris Katko 
wrote:
All I want to do is loop from 0 to [constant] with a for or 
foreach, and have it split up across however many cores I have.


You're looking at std.parallelism.TaskPool, especially the amap 
and reduce functions. Should do pretty much exactly what you're 
asking.


auto taskpool = new TaskPool();
taskpool.reduce!((a, b) => a + b)(iota(1_000_000_000_000L));


I get "Error: template instance `reduce!((a, b) => a + b)` cannot 
use local __lambda1 as parameter to non-global template 
reduce(functions...)" when trying to compile that using the 
online D editor with DMD and LDC.


Any ideas?


Simple parallel foreach and summation/reduction

2018-09-19 Thread Chris Katko via Digitalmars-d-learn
All I want to do is loop from 0 to [constant] with a for or 
foreach, and have it split up across however many cores I have.


ulong sum;
foreach(i; [0 to 1 trillion])
  {
  //flip some dice using
  float die_value = uniform(0F,12F);
  if(die_value > [constant]) sum++;
  }
writeln("The sum is %d", sum);

However, there are two caveats.:

 - One: I can't throw a range of values into an array and foreach 
on that like many examples use. Because 1 trillion (counting from 
zero) might be a little big for an array. (I'm using 1 trillion 
to illustrate a specific bottleneck / problem form.)


 - I want to merge the results at the end.

Which means I either need to use mutexes (BAD. NO. BOO. HISS.)  
or each "thread" would need to know if it's separate, and then 
store their sums in, say, a thread[#].sum variable and then once 
all were completed, add those sums together.


I know this is an incredibly simple conceptual problem to solve. 
So I feel like I'm missing some huge, obvious, answer for doing 
it elegantly in D.


And this just occurred to me, if I had a trillion foreach, will 
that make 1 trillion threads? What I want is, IIRC, what OpenMP 
does. It divides up your range (blocks of sequential numbers) by 
the number of threads. So domain of [1 to 1000] with ten threads 
would become workloads on the indexes of [1-100], [101-200], 
[201-300], and so on. for each CPU. They each get a 100 element 
chunk.


So I guess foreach won't work here for that, will it? Hmmm...

 > But again, conceptually this is simple: I have, say, 1 
trillion sequential numbers. I want to assign a "block" (or 
"range") to each CPU core. And since their math does not actually 
interfer with each other, I can simply sum each core's results at 
the end.


Thanks,
--Chris


Re: Load entire file, as a char array.

2018-09-03 Thread Chris Katko via Digitalmars-d-learn

On Monday, 3 September 2018 at 07:38:51 UTC, Chris Katko wrote:

On Monday, 3 September 2018 at 06:28:38 UTC, bauss wrote:

On Monday, 3 September 2018 at 06:25:23 UTC, bauss wrote:
On Monday, 3 September 2018 at 03:19:39 UTC, Neia Neutuladh 
wrote:
On Monday, 3 September 2018 at 03:04:57 UTC, Chris Katko 
wrote:
This should be simple? All I want to do is load an entire 
file, and access individual bytes. The entire thing. I 
don't want to have know the file size before hand, or 
"guess" and have a "maximum size" buffer.


So far, all google searches for "dlang binary file read" 
end up not working for me.


Thank you.


http://dpldocs.info/experimental-docs/std.file.read.1.html

import std.file : read;
auto bytes = read("filename");

This gives you a void[], which you can cast to ubyte[] or 
char[] or whatever you need.


Or he could do readText() which returns a string, which in 
turn will give a proper char array when casted.


Actually ignore the casting thing, looking at readText it 
takes a template parameter.


So:

char[] a = readText!(char[])("filename");


Thanks, that works!

But... I'm so confused by D's fifty different string types.

I can run .strip() on a char[]. But I can't run 
.replace('\n','?') ?


So then I convert char[] to a temporary string and run replace 
on that.


but then writefln("%s") doesn't accept strings! Only char[].

  char []t = cast(char[])(c[i-15 .. i+1]).strip();
  string s = text(t); //s.replace('\n','?')
  writefln(" - [%s]", s); // fail

main.d(89): Error: template std.array.replace cannot deduce 
function from argument types !()(char[], char, char), 
candidates are:
/usr/include/dmd/phobos/std/array.d(2122):
std.array.replace(E, R1, R2)(E[] subject, R1 from, R2 to) if 
(isDynamicArray!(E[]) && isForwardRange!R1 && isForwardRange!R2 
&& (hasLength!R2 || isSomeString!R2))
/usr/include/dmd/phobos/std/array.d(2255):
std.array.replace(T, Range)(T[] subject, size_t from, size_t 
to, Range stuff) if (isInputRange!Range && 
(is(ElementType!Range : T) || isSomeString!(T[]) && 
is(ElementType!Range : dchar)))



What's going on here?


WAIT! This is my fault (not that I was saying it was "D's" fault, 
just that I was  confused).


it's not replace '' ''. It's replace "" "".  For some reason, I 
must have been thinking it was per-character (which is what I'm 
doing) so I should be using single quotes.


So I CAN run .replace("","") on a char[], just as I can a string. 
And THANK GOODNESS because I thought one of the major advantages 
of D was being relatively orthogonal/type agnostic and if I was 
going to have to remember "X() runs only on Y" for 3+ different 
string types that would be a nightmare!


Re: Load entire file, as a char array.

2018-09-03 Thread Chris Katko via Digitalmars-d-learn

On Monday, 3 September 2018 at 06:28:38 UTC, bauss wrote:

On Monday, 3 September 2018 at 06:25:23 UTC, bauss wrote:
On Monday, 3 September 2018 at 03:19:39 UTC, Neia Neutuladh 
wrote:
On Monday, 3 September 2018 at 03:04:57 UTC, Chris Katko 
wrote:
This should be simple? All I want to do is load an entire 
file, and access individual bytes. The entire thing. I don't 
want to have know the file size before hand, or "guess" and 
have a "maximum size" buffer.


So far, all google searches for "dlang binary file read" end 
up not working for me.


Thank you.


http://dpldocs.info/experimental-docs/std.file.read.1.html

import std.file : read;
auto bytes = read("filename");

This gives you a void[], which you can cast to ubyte[] or 
char[] or whatever you need.


Or he could do readText() which returns a string, which in 
turn will give a proper char array when casted.


Actually ignore the casting thing, looking at readText it takes 
a template parameter.


So:

char[] a = readText!(char[])("filename");


Thanks, that works!

But... I'm so confused by D's fifty different string types.

I can run .strip() on a char[]. But I can't run 
.replace('\n','?') ?


So then I convert char[] to a temporary string and run replace on 
that.


but then writefln("%s") doesn't accept strings! Only char[].

  char []t = cast(char[])(c[i-15 .. i+1]).strip();
  string s = text(t); //s.replace('\n','?')
  writefln(" - [%s]", s); // fail

main.d(89): Error: template std.array.replace cannot deduce 
function from argument types !()(char[], char, char), candidates 
are:
/usr/include/dmd/phobos/std/array.d(2122):
std.array.replace(E, R1, R2)(E[] subject, R1 from, R2 to) if 
(isDynamicArray!(E[]) && isForwardRange!R1 && isForwardRange!R2 
&& (hasLength!R2 || isSomeString!R2))
/usr/include/dmd/phobos/std/array.d(2255):
std.array.replace(T, Range)(T[] subject, size_t from, size_t to, 
Range stuff) if (isInputRange!Range && (is(ElementType!Range : T) 
|| isSomeString!(T[]) && is(ElementType!Range : dchar)))



What's going on here?


Re: Load entire file, as a char array.

2018-09-02 Thread Chris Katko via Digitalmars-d-learn

On Monday, 3 September 2018 at 03:19:39 UTC, Neia Neutuladh wrote:

On Monday, 3 September 2018 at 03:04:57 UTC, Chris Katko wrote:
This should be simple? All I want to do is load an entire 
file, and access individual bytes. The entire thing. I don't 
want to have know the file size before hand, or "guess" and 
have a "maximum size" buffer.


So far, all google searches for "dlang binary file read" end 
up not working for me.


Thank you.


http://dpldocs.info/experimental-docs/std.file.read.1.html

import std.file : read;
auto bytes = read("filename");

This gives you a void[], which you can cast to ubyte[] or 
char[] or whatever you need.


That works great! I thought all file i/o had to through the File 
class.


Load entire file, as a char array.

2018-09-02 Thread Chris Katko via Digitalmars-d-learn
This should be simple? All I want to do is load an entire file, 
and access individual bytes. The entire thing. I don't want to 
have know the file size before hand, or "guess" and have a 
"maximum size" buffer.


So far, all google searches for "dlang binary file read" end up 
not working for me.


Thank you.


Re: Doxygen newbie

2018-04-23 Thread Chris Katko via Digitalmars-d-learn

Oh goodness. I thought D was using Doxygen!

Thanks.


Doxygen newbie

2018-04-23 Thread Chris Katko via Digitalmars-d-learn
I'm a complete doxygen newbie. But my first thought when writing 
comments is... why not use Markdown? (Which has become almost 
universal online these days.)


So I google it and Moxygen comes up. Which seems pretty good.

https://sourcey.com/generating-beautiful-markdown-documentation-with-moxygen/

So my question is, can you use Markdown with normal Doxygen? Is 
Moxygen needed? And if so, would I run into any complications 
using D instead of C/C++ with Doxygen and Moxygen?


Would there be any strange demangling issues or anything like 
that?


Thanks


Re: Rotate array in writefln?

2018-04-19 Thread Chris Katko via Digitalmars-d-learn

On Wednesday, 18 April 2018 at 07:15:47 UTC, Simen Kjærås wrote:

On Wednesday, 18 April 2018 at 06:54:29 UTC, Chris Katko wrote:
I need to rotate an array by 90 degrees, or have writefln 
figure that out.


I need, say:

0 4 5 6
0 0 0 0
0 0 0 0
0 0 0 0

But it's outputting:

0 0 0 0
4 0 0 0
5 0 0 0
6 0 0 0

int [4][4] data;
file.writeln(format("%(%-(%d %)\n%)", data));


Generally, the solution would be std.range.transposed. However, 
since you're using a int[4][4], that's not a range-of-ranges, 
and transposed don't work out of the box. This helper function 
should help:


T[][] ror(T, size_t N1, size_t N2)(ref T[N1][N2] arr)
{
T[][] result = new T[][N2];
foreach (i, e; arr) {
result[i] = e.dup;
}
return result;
}

unittest
{
import std.stdio;
import std.range;

int [4][4] data;
data[2][3] = 4;
writefln("%(%-(%d %)\n%)", data);
writefln("%(%-(%d %)\n%)", data.ror.transposed);
}

--
  Simen


That makes sense why transpose wouldn't work for my arrays!

So you're saying if I used [][] (dynamic array) that's a range of 
ranges, and it would work?


Why is it you have to rework your templates for static vs dynamic 
ranges? Thanks!


  1   2   >