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!


Rotate array in writefln?

2018-04-18 Thread Chris Katko via Digitalmars-d-learn
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));




Re: Delegates and classes for custom code.

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

That was all pseudo-code typed by hand.

I got my code to work today. I don't know if it's the prettiest 
it can be, but it works:


// TESTING ACCESS TO the OWNING function
//---
class test_window
{
float x;
float y;

void draw_text(string text)
{
writeln(text);  
}

this( void function(test_window) onDraw  )
{   
this.onDraw = onDraw;
}

void run() //called every frame
{
onDraw(this);
}

void function (test_window) onDraw;
}


void test_dialog()
{
auto t = new test_window(function void(test_window ptr)
{
with(ptr)
{
draw_text( format("Hello, world. [x,y]=[%f,%f]", x, y));
}
});

t.run();
}





And a second attempt/version:





// TESTING ACCESS to anything
// --

struct data_to_access_t
{
int tacos;
}

struct data_to_access2_t
{
struct beans
{
int x;
};

beans b;
}

class abc(T)
{
int x;
void delegate(T) run_delegate;

T data;

this(T t, void delegate(T) d)
{
data = t;
run_delegate = d;
}

void execute()
{
run_delegate(data);
}
}

void test_dialog_anything()
{   
data_to_access_t  d;
data_to_access2_t d2;
d.tacos = 4;
d2.b.x  = 5;

	auto x = new abc!data_to_access_t ( d, (d) => writefln("test  
%d", d.tacos)  );
	auto y = new abc!data_to_access_t ( d, (d){writefln("test  %d", 
d.tacos);}  );
	auto z = new abc!data_to_access2_t(d2, delegate void 
(d2){writefln("test2 %d", d2.b.x);}  );


x.execute();
y.execute();
z.execute();
}





My only questions are:

 -  is there any way to make it "smart" enough to take the type 
of the argument, instead of me manually giving it a type.


	auto x = new abc!data_to_access_t ( d, (d) => writefln("test  
%d", d.tacos)  );

becomes
auto x = new abc( d, (d) => writefln("test  %d", d.tacos)  );

 - Is there any way to eliminate the first d? Which is 
essentially a "this" pointer.


	auto x = new abc!data_to_access_t ( d, (d) => writefln("test  
%d", d.tacos)  );

becomes
	auto x = new abc!data_to_access_t ( (d) => writefln("test  %d", 
d.tacos)  );


 - And preferably, if possible, both. But I'll take what I can 
get.


Re: Delegates and classes for custom code.

2018-04-16 Thread Chris Katko via Digitalmars-d-learn
I'm having trouble conceptualizing this issue at the moment. But 
it seems if I pass to the delegate my object, then I can ONLY use 
one class type.


Say, the delegate takes a "this" from... some class that wants to 
have a dialog. A window. Now the delegate NEEDS a this from a 
window, and only a window. So if I have a delegate in... 
something else, I'll either need to figure out some way for 
templates to work with that... or some kind of wrapping class / 
interface.


But all I want is a kind of Javascript'y:

Every time this object gets .onDraw() called. It does whatever I 
told it to do.


auto t = new object1( onDraw(){ do stuff} );
auto t2 = new object2( onDraw() { do other stuff} );

I'm trying to do the same kind of API for button handling where 
it automatically links into event queues (which works) and the 
button does whatever I want it to. But, it can only access PUBLIC 
INTERFACES (globals) because it can't access the underlying 
object and globals are the only ones it can statically figure out 
at compile-time.




Re: Delegates and classes for custom code.

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

Some typos in there.

execute == on_draw.

Basically, I'm just sending a delegate/lambda "custom function" 
at initialization time. But I'd like that delegate to somehow 
access the holding classes functions. Or figure out how to do 
that.


Maybe the class somehow sends the delegate a this parameter when 
the class goes to execute it?


Delegates and classes for custom code.

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

What I want:

class viewport_t
  {
  int x,y,w,h;
  }

class dialog_t
  {
  int x,y;

  this( int x, int y, delegate void (viewport_t) on_draw )
{
this.x = x;
this.y = y;
this.execute = execute;
}

  void draw_text(string text)
{
}

  delegate void (viewport_t) on_draw;
  }

void function()
  {
  viewport_t v;
  dialog_t (15, 15,
delegate void (viewport_t)
  {
  draw_text("hello world"); //calls dialog_t function
  }
)
  }

Is this possible? Pass to a class, the code to run. But the code 
has to somehow know about the class methods.


I don't think you can pass "dialog_t.this" as it's being 
constructed!


Re: Using iteration / method chaining / etc on multi-dimensional arrays

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

On Thursday, 12 April 2018 at 21:17:30 UTC, Paul Backus wrote:

On Thursday, 12 April 2018 at 20:34:40 UTC, Chris Katko wrote:


But each doesn't return anything, it mutates, right? I think 
that's the problem I ran into with my attempt. With your code, 
I get an error about void:


  string []x = split(file.readln.idup, " ");
  x.each((ref s) => s.each((ref n) => n.stripRight()));


You need to put an exclamation point after 'each' to pass the 
function as a template parameter:


x.each!((ref s) => s.each!((ref n) => n.stripRight()));


DOH.

But now I'm here:

extra.d(2493): Error: template extra.map_t.load_map2.each!((ref 
s) => s.each!((ref n) => n.stripRight())).each cannot deduce 
function from argument types !()(string[]), candidates are:


/usr/include/dmd/phobos/std/algorithm/iteration.d(899):
extra.map_t.load_map2.each!((ref s) => s.each!((ref n) => 
n.stripRight())).each(Range)(Range r) if 
(!isForeachIterable!Range && (isRangeIterable!Range || 
__traits(compiles, typeof(r.front).length)))


/usr/include/dmd/phobos/std/algorithm/iteration.d(934):
extra.map_t.load_map2.each!((ref s) => s.each!((ref n) => 
n.stripRight())).each(Iterable)(auto ref Iterable r) if 
(isForeachIterable!Iterable || __traits(compiles, 
Parameters!(Parameters!(r.opApply



From:

string []x = split(file.readln.idup, " ");
import std.algorithm;
x.each!((ref s) => s.each!((ref n) => n.stripRight()));

Looks like it can't tell if it's a Range or... an auto ref 
Iterable?


Re: Using iteration / method chaining / etc on multi-dimensional arrays

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

Wait, that might not be the error.


Re: Using iteration / method chaining / etc on multi-dimensional arrays

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

On Thursday, 12 April 2018 at 20:37:49 UTC, Chris Katko wrote:

Wait, that might not be the error.


Just the top one. This one:

extra.d(2493): Error: template std.algorithm.iteration.each 
cannot deduce function from argument types !()(string[], void), 
candidates are:
/usr/include/dmd/phobos/std/algorithm/iteration.d(864):
std.algorithm.iteration.each(alias pred = "a")




Re: Using iteration / method chaining / etc on multi-dimensional arrays

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

On Thursday, 12 April 2018 at 15:47:14 UTC, Uknown wrote:

On Thursday, 12 April 2018 at 15:38:34 UTC, Chris Katko wrote:

I googled but couldn't find any clear solution.

I've got a 2-D array of strings read from a text file I 
parsed. So it's like


0 1 15 0 0
2 12 1 0 0
...
0 1 0 10 0

They come in with spaces, so I join into an array between 
them. But then the last ones have a newline \n on the end, 
which explodes the to! type conversion.


If it was a single array, I could simply do:

string [25] test;

  test.each((ref n) => n.stripRight());

But how do you do that when it's a 2-D array?

I'm looking not just for this case, but the generate case of 
iterating / applying filters to 2-D arrays.


Thanks.


I think something like this would work:

test.each((ref s) => s.each((ref n) => n.stripRight()));

Essentially, get each 1D array from the 2D array, and then 
apply the algorithms on that. There's probably a better way 
though


But each doesn't return anything, it mutates, right? I think 
that's the problem I ran into with my attempt. With your code, I 
get an error about void:


  string []x = split(file.readln.idup, " ");
  x.each((ref s) => s.each((ref n) => n.stripRight()));

extra.d(2493): Error: template std.algorithm.iteration.each 
cannot deduce function from argument types !()(string[], void), 
candidates are:
/usr/include/dmd/phobos/std/algorithm/iteration.d(864):
std.algorithm.iteration.each(alias pred = "a")


extra.d(2499): Error: template std.algorithm.mutation.stripRight 
cannot deduce function from argument types !()(string), 
candidates are:
/usr/include/dmd/phobos/std/algorithm/mutation.d(2363):
std.algorithm.mutation.stripRight(Range, E)(Range range, E 
element) if (isBidirectionalRange!Range && is(typeof(range.back 
== element) : bool))
/usr/include/dmd/phobos/std/algorithm/mutation.d(2375):
std.algorithm.mutation.stripRight(alias pred, Range)(Range range) 
if (isBidirectionalRange!Range && is(typeof(pred(range.back)) : 
bool))


extra.d(2500): Error: template std.algorithm.mutation.stripRight 
cannot deduce function from argument types !()(string), 
candidates are:
/usr/include/dmd/phobos/std/algorithm/mutation.d(2363):
std.algorithm.mutation.stripRight(Range, E)(Range range, E 
element) if (isBidirectionalRange!Range && is(typeof(range.back 
== element) : bool))
/usr/include/dmd/phobos/std/algorithm/mutation.d(2375):
std.algorithm.mutation.stripRight(alias pred, Range)(Range range) 
if (isBidirectionalRange!Range && is(typeof(pred(range.back)) : 
bool))


Using iteration / method chaining / etc on multi-dimensional arrays

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

I googled but couldn't find any clear solution.

I've got a 2-D array of strings read from a text file I parsed. 
So it's like


0 1 15 0 0
2 12 1 0 0
...
0 1 0 10 0

They come in with spaces, so I join into an array between them. 
But then the last ones have a newline \n on the end, which 
explodes the to! type conversion.


If it was a single array, I could simply do:

string [25] test;

  test.each((ref n) => n.stripRight());

But how do you do that when it's a 2-D array?

I'm looking not just for this case, but the generate case of 
iterating / applying filters to 2-D arrays.


Thanks.


Re: Game and GC

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

On Monday, 9 April 2018 at 00:25:21 UTC, solidstate1991 wrote:
On Saturday, 24 February 2018 at 07:12:21 UTC, Guillaume Piolat 
wrote:

From my experience a combination of the following is necessary:
- not having the audio thread registered
- using pools aggressively for game entities


Also you can save a lot of clockcycles if you put @nogc 
everywhere you don't allocate on the heap, the stack will be 
automatically cleaned up.


I'm currently thinking on restructuring the way my engine 
handles display lists on sprites (dynamic array contains the 
priority, multiple associative arrays for Coordinates, sprites, 
attributes), however if enabling exception handling in @nogc 
parts will enable associative array indexing, I'll just skip 
the whole procedure, otherwise probably moving the whole thing 
to rbtree.


Why... associative arrays? Wouldn't that become expensive when 
you hit 1,000s, or 10,000's of objects, for something as tiny as 
a coordinate (two or three floats) lookup?


Re: How would you create this construct?

2018-03-30 Thread Chris Katko via Digitalmars-d-learn

On Friday, 30 March 2018 at 03:14:42 UTC, Mike Parker wrote:

On Friday, 30 March 2018 at 02:30:01 UTC, Chris Katko wrote:

[...]


Something like this?

=
import std.stdio;

[...]


This is beautiful. I mean, the struct stuff looks 
complicated/non-intuitive at first, but it's all boilerplate.


How would you create this construct?

2018-03-29 Thread Chris Katko via Digitalmars-d-learn


void start_draw_calls(BITMAP target_bitmap); //locks onto a 
resource

void end_draw_calls(); //frees previous resource lock

void my_function()
{
//...

start_draw_calls(target_bitmap) //whether this is a function, 
or class, lambda, or a "using"?

{
draw_call1();
draw_call2();
draw_call3();
} // end_draw_calls() is automatically called because 
we're hitting the closing curly.


//...
}


The key here is, I've got a resource (setting a target bitmap) 
whose handling functions have to occur before, and after a series 
of user calls. (at which point target bitmap is restored to what 
it was before). So it's kind of like RAII (or maybe exactly like).


What I'm trying to do is through this experimental API, is both 
eliminate the user needing to call a clean-up function 
explicitly, and, make the "right way" to use the API basically... 
the only way... to use it.


The way I have written above, there is no way for you to leave 
my_function() without it automatically calling the cleaning up 
call. Even if you did a nested version, it would still work!


At first glance, I could do:

start_draw_calls( {lambda containing all my code} )

But that's not quite as pretty and you're forcing all code to be 
inside a lambda which... I'm not sure if that has hidden 
implications / gotchas for code.


Thanks!


Re: Static Foreach + Marking "compile time" variables

2018-03-28 Thread Chris Katko via Digitalmars-d-learn

On Wednesday, 28 March 2018 at 23:42:26 UTC, Simen Kjærås wrote:

On Wednesday, 28 March 2018 at 23:02:53 UTC, Chris Katko wrote:

There's many things that can be done to make the code easier to 
follow. These lines:

[...]


[...]


WOW. Thank you. That's the kind of tricks for (or more properly: 
knowledge of) templates that I can use. That's much more clean 
looking and maintainable. Feel free to recommend more 
ideas/tricks!


I'm still definitely working on improving (and developing) that 
template/function so yeah, I left those duplicate static if's in 
at the time (I called it "quits" after getting it to actually 
compile, so there's still scribble in there.)


Re: Static Foreach + Marking "compile time" variables

2018-03-28 Thread Chris Katko via Digitalmars-d-learn
On Wednesday, 28 March 2018 at 17:42:45 UTC, Steven Schveighoffer 
wrote:

On 3/28/18 11:46 AM, Chris Katko wrote:

 enum hasRotate = anySatisfy!( isa(pos), a);  //if of type 
"pos"


anySatisfy!(isa!pos, a)

anySatisfy takes a template alias (in this case, an 
instantiation of isa with a specific type), and then applies 
the template to all the elements of the alias sequence, 
returning true if any statisfy.


-Steve


Yeah, that was one of my errors during my 4 AM binge. But I 
forgot/missed to update that when I posted.


So far, everything is working with some dummy calls, and now I 
just have to start doing the annoying work of writing the code.


It's just... I wish it was a little more elegant. Right now, I'm 
stuck with like tons of static if cases. [see code at end of 
post] If I add "centered position" vs "position" now, I have to 
figure out how to add that into a single compound statement to 
fit into a unique static if. As opposed to simply, "if centered 
pos, take position, and just change it by subtracting width and 
height."  In that case, I can get away with leaving them run-time 
statements, but more complex features not-so-much. The point is 
to use compile-time/static/templates to build the correct 
statement. Because at the core of what I'm doing... it IS all 
statically / compile-time knowable information.


And having TONS of static ifs means there's TONS of room for 
human error as its maintained.


If I wrote a Python/whatever script that pre-processed my D code 
from the AST, I'd have no theoretical reason to prevent me from 
doing this (though, clearly with much added frustration of 
implementation and debugging!).


I'm starting to wonder if a mixin will somehow help... hmm. I'm 
going to keep thinking about the problem.


Some code will probably help explain what I'm talking about:

funct2(g.tile_bmp, pos(100,100), scale(2), rotate(0.0f), 
center());


template isa(T){enum isa(U) = is(U == T); }

void funct2(A...)(ALLEGRO_BITMAP *bit, A a)
{
enum hasPosition = anySatisfy!(isa!(pos), typeof(a));
enum hasCenteredPosition = anySatisfy!(isa!(center), typeof(a));

enum hasRotate  = anySatisfy!(isa!(rotate), typeof(a));
enum hasScale   = anySatisfy!(isa!(scale), typeof(a));

static if (hasPosition && hasCenteredPosition)
{
float temp_x=a[staticIndexOf!(pos, typeof(a))].x - bit.w/2;
float temp_y=a[staticIndexOf!(pos, typeof(a))].y - bit.h/2;
}else{
float temp_x=a[staticIndexOf!(pos, typeof(a))].x;
float temp_y=a[staticIndexOf!(pos, typeof(a))].y;
}

static if (!hasPosition)
{
assert(0, "Need to pass a position!");
}

static if (hasPosition && !hasRotate && !hasScale)
{
// Stuff
pragma(msg, "Class 1");
writeln("x ", a[staticIndexOf!(pos, typeof(a))].x);
writeln("y ", a[staticIndexOf!(pos, typeof(a))].y);

al_draw_bitmap(bit,
temp_x,
temp_y,
0);
}

static if (hasPosition && hasRotate && !hasScale)
{
// Stuff
pragma(msg, "Class 2");
writeln("x ", a[staticIndexOf!(pos, typeof(a))].x);
writeln("y ", a[staticIndexOf!(pos, typeof(a))].y);

al_draw_rotated_bitmap(bit,
bit.w/2,
bit.h/2,
temp_x,
temp_y,
a[staticIndexOf!(rotate, typeof(a))].a,
0);

}


static if (hasPosition && !hasRotate && hasScale)
{
pragma(msg, "Class 3");
}

static if (hasPosition && hasRotate && hasScale)
{
pragma(msg, "Class 4");
}




}


Re: Static Foreach + Marking "compile time" variables

2018-03-28 Thread Chris Katko via Digitalmars-d-learn

On Wednesday, 28 March 2018 at 17:08:39 UTC, Chris Katko wrote:

On Wednesday, 28 March 2018 at 15:49:39 UTC, Chris Katko wrote:

On Wednesday, 28 March 2018 at 15:46:42 UTC, Chris Katko wrote:

[...]


Whoops! Wrong error message. That's if I replace isa(pos) with 
IsIntegral.


[...]


Okay, the key appears to be here:

funct2(123); //a function call

void funct2(A...)(A a)
{
enum hasRotate = isIntegral!(a[0]); // NOPE!
}

//E: template instance isIntegral!(_param_0) does not match 
template declaration isIntegral(T)


But if I do:

funct2!(123); //note !

I get

//E: tuple A is used as a type



GOT IT!!

I needed typeof on the right side.

template isa(T){enum isa(U) = is(U == T); }

funct2(g.tile_bmp, pos(100,100), scale(2), rotate(0.0f));

void funct2(A...)(ALLEGRO_BITMAP *bit, A a)
{
enum hasPosition= anySatisfy!(isa!(pos), typeof(a));
}

Works!


Re: Static Foreach + Marking "compile time" variables

2018-03-28 Thread Chris Katko via Digitalmars-d-learn

On Wednesday, 28 March 2018 at 15:49:39 UTC, Chris Katko wrote:

On Wednesday, 28 March 2018 at 15:46:42 UTC, Chris Katko wrote:

[...]


Whoops! Wrong error message. That's if I replace isa(pos) with 
IsIntegral.


[...]


Okay, the key appears to be here:

funct2(123); //a function call

void funct2(A...)(A a)
{
enum hasRotate = isIntegral!(a[0]); // NOPE!
}

//E: template instance isIntegral!(_param_0) does not match 
template declaration isIntegral(T)


But if I do:

funct2!(123); //note !

I get

//E: tuple A is used as a type


Re: Static Foreach + Marking "compile time" variables

2018-03-28 Thread Chris Katko via Digitalmars-d-learn

On Wednesday, 28 March 2018 at 15:46:42 UTC, Chris Katko wrote:

On Wednesday, 28 March 2018 at 08:05:55 UTC, Simen Kjærås wrote:

On Wednesday, 28 March 2018 at 07:45:59 UTC, Chris Katko wrote:
I have a static foreach that goes through the parameter list 
and if it sees a class like "rotate", ideally, I want it to 
mark a boolean "has_rotate=true"


Then simply later on, once I've parsed the list, I pick an 
output path:


static if(has_rotate && has_position && has_scale)
{
//call C function al_draw_rotated_scaled_bitmap(...);
}

So I pass a bunch of "options" and then based on those 
options, it picks the right function to call instead of me 
manually writing 
draw_fixed_centered_rotated_scaled_colored_compressed_bitmap() manually.


The problem is, I can foreach through those parameters all 
just fine... but I can't "set" a marker.


The error message makes perfect sense in retrospect:

 variable has_position cannot be read at compile time

has_position isn't a static/compile-time variable. The 
question is... do they exist in D? Because otherwise, I'll be 
going from a really clean, elegant solution that simply 
passes through each parameter, and then reacts to the 
combined result, and end up with something that has to "step 
toward" the result, or perhaps, test every possible 
permutation individually--so as to not need variables.


D does not have compile-time variables. The way you'd 
generally do what you describe is with the templates in 
std.meta. Instead of something like this:


bool hasRotate= false;
static foreach (e; MyTuple) {
hasRotate |= is(e == Rotate);
}
static if (hasRotate) { // Fails, since b is a runtime 
variable.

// Stuff
}

You'd be using a more functional style:

template isa(T) {
enum isa(U) = is(U == T);
}

enum hasRotate = anySatisfy!(isa!Rotate, MyTuple);
static if (hasRotate) {
// Stuff
}

--
  Simen


Thank you for the reply! But I'm unable to get that code to 
compile. For example:


/usr/local/bin/../import/std/meta.d(883): Error: template 
instance F!(_param_1) does not match template declaration 
isIntegral(T)
/usr/local/bin/../import/std/meta.d(888): Error: template 
instance extra.funct2!(int, int, 
int).funct2.anySatisfy!(isIntegral, _param_1) error 
instantiating
extra.d(264):instantiated from here: 
anySatisfy!(isIntegral, _param_1, _param_2, _param_3)
extra.d(385):instantiated from here: funct2!(int, int, 
int)
/usr/local/bin/../import/std/meta.d(883): Error: template 
instance F!(_param_2) does not match template declaration 
isIntegral(T)
/usr/local/bin/../import/std/meta.d(888): Error: template 
instance extra.funct2!(int, int, 
int).funct2.anySatisfy!(isIntegral, _param_2) error 
instantiating
/usr/local/bin/../import/std/meta.d(889):instantiated 
from here: anySatisfy!(isIntegral, _param_2, _param_3)
extra.d(264):instantiated from here: 
anySatisfy!(isIntegral, _param_1, _param_2, _param_3)
extra.d(385):instantiated from here: funct2!(int, int, 
int)
/usr/local/bin/../import/std/meta.d(883): Error: template 
instance F!(_param_3) does not match template declaration 
isIntegral(T)
/usr/local/bin/../import/std/meta.d(889): Error: template 
instance extra.funct2!(int, int, 
int).funct2.anySatisfy!(isIntegral, _param_3) error 
instantiating
/usr/local/bin/../import/std/meta.d(889):instantiated 
from here: anySatisfy!(isIntegral, _param_2, _param_3)
extra.d(264):instantiated from here: 
anySatisfy!(isIntegral, _param_1, _param_2, _param_3)
extra.d(385):instantiated from here: funct2!(int, int, 
int)



Perhaps I should post more of my code because there may be 
subtle differences that are important:


struct pos{float x, y;}
struct scale{float f;}
struct rotate{ float a; }

void test_inst()
{
funct2(tile_bmp, pos(100,100), scale(2), rotate(0.0f));
//this worked with the foreach version
// in the case that it compiled and read the arguments
}

Then I use your version:

template isa(T) {
enum isa(U) = is(U == T); //is(typeof(U) == T)  doesn't 
work either.

 }

void funct2(A...)(ALLEGRO_BITMAP *bitmap_bmp, A a)
{
enum hasRotate = anySatisfy!( isa(pos), a);  //if of type "pos"
static if (hasRotate)
{
// Stuff
}
}


Whoops! Wrong error message. That's if I replace isa(pos) with 
IsIntegral.


If I have isa(pos). It's almost identical:

/usr/local/bin/../import/std/meta.d(883): Error: template 
instance F!(_param_1) does not match template declaration isa(U)
/usr/local/bin/../import/std/meta.d(888): Error: template 
instance extra.funct2!(int, int, int).funct2.anySatisfy!(isa, 
_param_1) error instantiating
extra.d(263):instantiated from here: anySatisfy!(isa, 
_param_1, _param_2, _param_3)
extra.d(385):instantiated from here: funct2!(int, int, 
int)

Re: Static Foreach + Marking "compile time" variables

2018-03-28 Thread Chris Katko via Digitalmars-d-learn

On Wednesday, 28 March 2018 at 08:05:55 UTC, Simen Kjærås wrote:

On Wednesday, 28 March 2018 at 07:45:59 UTC, Chris Katko wrote:
I have a static foreach that goes through the parameter list 
and if it sees a class like "rotate", ideally, I want it to 
mark a boolean "has_rotate=true"


Then simply later on, once I've parsed the list, I pick an 
output path:


static if(has_rotate && has_position && has_scale)
{
//call C function al_draw_rotated_scaled_bitmap(...);
}

So I pass a bunch of "options" and then based on those 
options, it picks the right function to call instead of me 
manually writing 
draw_fixed_centered_rotated_scaled_colored_compressed_bitmap() 
manually.


The problem is, I can foreach through those parameters all 
just fine... but I can't "set" a marker.


The error message makes perfect sense in retrospect:

 variable has_position cannot be read at compile time

has_position isn't a static/compile-time variable. The 
question is... do they exist in D? Because otherwise, I'll be 
going from a really clean, elegant solution that simply passes 
through each parameter, and then reacts to the combined 
result, and end up with something that has to "step toward" 
the result, or perhaps, test every possible permutation 
individually--so as to not need variables.


D does not have compile-time variables. The way you'd generally 
do what you describe is with the templates in std.meta. Instead 
of something like this:


bool hasRotate= false;
static foreach (e; MyTuple) {
hasRotate |= is(e == Rotate);
}
static if (hasRotate) { // Fails, since b is a runtime 
variable.

// Stuff
}

You'd be using a more functional style:

template isa(T) {
enum isa(U) = is(U == T);
}

enum hasRotate = anySatisfy!(isa!Rotate, MyTuple);
static if (hasRotate) {
// Stuff
}

--
  Simen


Thank you for the reply! But I'm unable to get that code to 
compile. For example:


/usr/local/bin/../import/std/meta.d(883): Error: template 
instance F!(_param_1) does not match template declaration 
isIntegral(T)
/usr/local/bin/../import/std/meta.d(888): Error: template 
instance extra.funct2!(int, int, 
int).funct2.anySatisfy!(isIntegral, _param_1) error instantiating
extra.d(264):instantiated from here: 
anySatisfy!(isIntegral, _param_1, _param_2, _param_3)
extra.d(385):instantiated from here: funct2!(int, int, 
int)
/usr/local/bin/../import/std/meta.d(883): Error: template 
instance F!(_param_2) does not match template declaration 
isIntegral(T)
/usr/local/bin/../import/std/meta.d(888): Error: template 
instance extra.funct2!(int, int, 
int).funct2.anySatisfy!(isIntegral, _param_2) error instantiating
/usr/local/bin/../import/std/meta.d(889):instantiated 
from here: anySatisfy!(isIntegral, _param_2, _param_3)
extra.d(264):instantiated from here: 
anySatisfy!(isIntegral, _param_1, _param_2, _param_3)
extra.d(385):instantiated from here: funct2!(int, int, 
int)
/usr/local/bin/../import/std/meta.d(883): Error: template 
instance F!(_param_3) does not match template declaration 
isIntegral(T)
/usr/local/bin/../import/std/meta.d(889): Error: template 
instance extra.funct2!(int, int, 
int).funct2.anySatisfy!(isIntegral, _param_3) error instantiating
/usr/local/bin/../import/std/meta.d(889):instantiated 
from here: anySatisfy!(isIntegral, _param_2, _param_3)
extra.d(264):instantiated from here: 
anySatisfy!(isIntegral, _param_1, _param_2, _param_3)
extra.d(385):instantiated from here: funct2!(int, int, 
int)



Perhaps I should post more of my code because there may be subtle 
differences that are important:


struct pos{float x, y;}
struct scale{float f;}
struct rotate{ float a; }

void test_inst()
{
funct2(tile_bmp, pos(100,100), scale(2), rotate(0.0f));
//this worked with the foreach version
// in the case that it compiled and read the arguments
}

Then I use your version:

template isa(T) {
enum isa(U) = is(U == T); //is(typeof(U) == T)  doesn't 
work either.

 }

void funct2(A...)(ALLEGRO_BITMAP *bitmap_bmp, A a)
{
enum hasRotate = anySatisfy!( isa(pos), a);  //if of type "pos"
static if (hasRotate)
{
// Stuff
}
}



Static Foreach + Marking "compile time" variables

2018-03-28 Thread Chris Katko via Digitalmars-d-learn
I have a static foreach that goes through the parameter list and 
if it sees a class like "rotate", ideally, I want it to mark a 
boolean "has_rotate=true"


Then simply later on, once I've parsed the list, I pick an output 
path:


static if(has_rotate && has_position && has_scale)
{
//call C function al_draw_rotated_scaled_bitmap(...);
}

So I pass a bunch of "options" and then based on those options, 
it picks the right function to call instead of me manually 
writing 
draw_fixed_centered_rotated_scaled_colored_compressed_bitmap() 
manually.


The problem is, I can foreach through those parameters all just 
fine... but I can't "set" a marker.


The error message makes perfect sense in retrospect:

 variable has_position cannot be read at compile time

has_position isn't a static/compile-time variable. The question 
is... do they exist in D? Because otherwise, I'll be going from a 
really clean, elegant solution that simply passes through each 
parameter, and then reacts to the combined result, and end up 
with something that has to "step toward" the result, or perhaps, 
test every possible permutation individually--so as to not need 
variables.


Re: Compare AliasSeq isn't working

2018-03-28 Thread Chris Katko via Digitalmars-d-learn

On Wednesday, 28 March 2018 at 06:20:56 UTC, Ali Çehreli wrote:

On 03/27/2018 11:11 PM, Chris Katko wrote:

>  writeln(a[0]); //first is "pos(100,100)"
>  static if(
>  is(a[0] == pos) //<---never matches

It's because not a[0] but its *type* is pos:

is(typeof(a[0]) == pos) //<---MATCHES! :)

Ali


That's perfect!!! THANKS


Compare AliasSeq isn't working

2018-03-28 Thread Chris Katko via Digitalmars-d-learn
I'm trying this idea for an API style it's... not quite working. 
The part I'm failing at currently is actually classifying types 
passed in.


I want this to occur at compile time.

void funct(A...)(A a)
{
static if (a.length)
{
writeln(a[0]); //first is "pos(100,100)"
static if(
is(a[0] == pos) //<---never matches
)
{
writeln(a[0].x); //works, as "pos.x"
writeln(a[0].y);
}

static if (a.length > 1)
 funct(a[1 .. $]);
}
}

struct pos { float x, y; }
struct scale { float f; }
struct rotate { float a; }

void test_inst()
{
funct(pos(100,100), scale(2), rotate(0.0f));
}


I've tried all kinds of variations of test conditions. I've tried 
wrapping the right side in an AliasSeq. I've tried quotation 
marks. I've tried other stuff. I can't find any applicable posts 
or examples online.


All I want to do is (at this point anyway):

  - Pass a variable number of arguments (works), match them 
(FAIL), and read their interal values. (works)


At compile time.

Thanks.


Re: Does LDC support profiling at all?

2017-12-23 Thread Chris Katko via Digitalmars-d-learn
On Saturday, 23 December 2017 at 12:23:33 UTC, Johan Engelen 
wrote:

On Friday, 22 December 2017 at 09:52:26 UTC, Chris Katko wrote:
DMD can use -profile and -profile=gc. But I tried for HOURS to 
find the equivalent for LDC and came up with only 
profile-guided optimization--which I don't believe I want. 
Yet, if we can get PGO... where's the PROFILE itself it's 
using to make those decisions! :)


Fine grained PGO profiling:
-fprofile-instr-generate
http://johanengelen.github.io/ldc/2016/07/15/Profile-Guided-Optimization-with-LDC.html

Function entry/exit profiling:
-finstrument-functions
https://github.com/ldc-developers/ldc/issues/1839
https://www.youtube.com/watch?v=LNav5qvyK7I

I suspect it is not too much effort to add DMD's -profile and 
-profile=gc to LDC, but noone has done it yet.


Another thing that is relatively easy to add to LDC: 
https://llvm.org/docs/XRay.html


-Johan


Wow, thanks guys! I didn't realize I'd get so much information so 
quickly here on the forums. The documentation online for LDC is 
very sparse and confusing. After spending plenty of attempts, I 
went out of my way to install DMD just to get profiling because I 
couldn't figure it out with LDC.


It would probably be really helpful to get a clear Wiki guide for 
this information LDC. I'll write it myself if necessary once I 
try your recommendations and test them out.


Re: GC in D and synadard library.

2017-12-23 Thread Chris Katko via Digitalmars-d-learn

On Thursday, 21 December 2017 at 10:49:46 UTC, Dan Partelly wrote:


I started to look into D very recently. I would like to know 
the following, if you guys are so nice to help me:


1. What is the performance of D's GC, what trade-offs where 
done in design , and if a in-deep primer on efficient usage and 
gotchas of the current implementation exists.


2. GC is never good enough. What are the current plans in this 
area for D. In general, please point me to the place where 
current work on D is done.


3. I need to be able to run with GC totally disabled sometimes. 
In the light of this:
   - are there any features of core language which depend on 
garbage collection ? (i.e unbound arrays, strings ..)
   - are there any features from standard library which depend 
on active garbage collection?
   - Please point me to a list where there is an exhaustive 
enumeration of which language features *and* library features 
requires GC active. Looking at standard library docs I did not 
seen markings which identify clearly and unequivocally what 
requires GC active and what not.


4. Is Andrei Alexandrescu's book from 2009 on D still actual, 
or the language evolution made it obsolete ?


With thanks.


I make hobby/proto-type games and I've been doing it for 
well-over a decade at this point. Starting learning D and trying 
games with Allegro 5 and D the same way I used C++.


There's lots to learn. But so far it's a freaking DELIGHT to 
program in D compared to C++. It's so easy to reduce boilerplate, 
and extend code without huge swafts of boilerplate 
std::vector> template 
code.


I'm intentionally ABUSING the GC so far by having every smoke 
particle (hundreds) with new ones allocate and and old ones 
deallocating every frame. I'm also developing on a tiny 
Chromebook with a Intel Celeron ~N2950 and only 2 GB of RAM 
(which Ubuntu eats most of).


I'm still getting 115+ FPS drawing 600 alpha-blended "cloud" 
bitmaps each frame, plus the smoke trails, and allocations.


There is a microstutter issue I'm diagnosing that may be related 
to GC. (After all, I AM intentionally abusing it so I can get a 
"feel" for it.) But it's not terrible. I plan to move to static 
pools for everything eventually but this is a viability study for 
D and the GC without going out of my way to disable/avoid the GC.


Merely turning on Open Broadcast Studio to capture video of my 
game for explanations takes more CPU time than my game.


So depending on what you want to design, I really second 
everyone's recommendation "don't worry about it until it's a 
problem." D is so adaptable that it's really easy to move away 
from the GC (assuming you write good code anyway).


Now, to that previous point of "don't worry about it." I 
absolutely get the apprehension when someone tells you that. But 
yeah, it's not that bad. If you do "heavy lifting" stuff with 
static allocations, and leave the GC for making lambdas and stuff 
like that super-easy to write code, it's a good combination.


As others have mentioned, you can even allocate memory that the 
GC has literally no idea about and will never collect.


I definitely recommend trying D. The best way for you to know if 
it suits YOUR requirements is really... make a test app like I'm 
doing. Code the way you normally do and see if the GC affects 
you. Absolute worst case you can port your program to C++ pretty 
quickly.


Re: WARN on implicit super?

2017-12-23 Thread Chris Katko via Digitalmars-d-learn

On Thursday, 21 December 2017 at 10:13:47 UTC, bauss wrote:
On Thursday, 21 December 2017 at 06:47:25 UTC, Ali Çehreli 
wrote:

[...]


This is what I would believe __IS__ and __SHOULD__ be the 
default behavior too, because that's how it generally is in 
other languages.


It doesn't make much sense to call a super constructer after 
and it's very rare cases that you need too.


The only time you really call super constructors after is if 
the parameters are different.


Ex.

class Foo
{
int baz;
int boo;

this() { ... }

this(int baz, int boo) { ... }
}

class Bar : Foo
{
this()
{
int baz =getBazFromSomewhere();
int boo = getBooFromSomewhere();
super(baz, boo);
}
}

In that case it makes sense to call super() after, but you 
rarely end up in cases like that and thus you should generally 
be able to omit the call.


If super() is ever called explicit after (if no call to a super 
constructor has been done.) then I can only imagine A LOT of 
code will break, because it's a general concept and known 
behavior from most languages that base/super constructors are 
called before.


I think during many late night debugging, I had TWO bugs and 
confused super call-order and wrote that comment.


What I think happened was, super() was called correctly, but, the 
chain of classes was calling this()/super() constructors and 
DIDN'T call this(var, var)/super(var,var) constructors that I 
needed.


So AFAIK, I'd call this a closed problem / mistaken 
understanding. Thanks for your prompt replies and help. Sorry if 
I wasted your time.


[DMD or LDC] Is it possible to get the GC to print to stdout when it collects?

2017-12-23 Thread Chris Katko via Digitalmars-d-learn
I'm having a strange stuttering issue in my game prototype. I use 
GC allocations wildly for the heck of it at the moment--with 
eventual plans to remove them.


However, I'm not positive it's the GC that's the problem, and if 
so, I want to know exact lengths of time and frequency.


Currently, the game will freeze for up to even half a second or 
more (but pretty rarely of 15+ seconds apart or more) but 
strangely... I'm using stopwatch's to track the logic and drawing 
code's elapsed times and ... those stopwatches don't appear to 
show the frozen time. Maybe my time code is incorrect somewhere 
but I need to be sure.


The hallmarks of GC are there because it "seems" to occur more 
often / worse when I'm low on RAM.


In LDC2, I saw import/core/memory.d -> gc.collect() which calls 
gc_collect (a C function)


However, adding a printf in there doesn't appear to print, so I'm 
guessing that gc.collect is only for users and not actually 
called by any internal lib functions? So my next thought is, to 
get a full source distribution, and recompile DMD or LDC2 from 
source after finding that C source file and adding a printf in 
there.


I doubt a single printf (or some static string equivalent without 
formatting overhead) would take that much time compared to a 
complete garbage collection so I don't think it would skew the 
results enough to useless. The big thing to check here is if 
these "freezes" are directly related to garbage collections, or 
some other oddity.


Does LDC support profiling at all?

2017-12-22 Thread Chris Katko via Digitalmars-d-learn
DMD can use -profile and -profile=gc. But I tried for HOURS to 
find the equivalent for LDC and came up with only profile-guided 
optimization--which I don't believe I want. Yet, if we can get 
PGO... where's the PROFILE itself it's using to make those 
decisions! :)


Thanks.




Re: WARN on implicit super?

2017-12-20 Thread Chris Katko via Digitalmars-d-learn

On Thursday, 21 December 2017 at 06:47:25 UTC, Ali Çehreli wrote:

On 12/20/2017 10:36 PM, Chris Katko wrote:

[...]


There can be a number of solutions but can you please 
demonstrate the issue with compilable code? My attempt does not 
agree with your description: super() is called *before* the 
subclass constructor. (Compiled with DMD64 D Compiler 
v2.077.1-384-gc6829a8)


[...]


Well, crap, I'm writing this post a few days after I encountered 
the problem and my notes say "super gets called after". I'll have 
to test what I was thinking and get right back to you tomorrow.


Thank you for the prompt reply.


WARN on implicit super?

2017-12-20 Thread Chris Katko via Digitalmars-d-learn
Is there any way to get a warning anytime an implicit super 
constructor is called in a sub-class/child-class?


I have game objects with defaults. I specialize them with 
specifics. The problem is, if I forget to add an explicit super 
call and have it _before_ my code, my code runs, then the super 
constructor code unsets my values.


Now that I know why it's doing it, I can look for it, but Good 
Code (TM) would definitely benefit from an automatic warning / 
check for such cases. Opt-out, not opt-in, for error checking.


Example code:

class object_t
 {
 bitmap_t bmp;
 float x,y;
 this(float _x, float _y)
{
bmp = BMP_PLACEHOLDER;
x = _x;
y = _y;
}
 }

class building_t : object_t
{
this(float _x, float _y)
{
super(_x, _y);
 // ^^ If I forget this, it implicitly gets called AFTER
 // this function is done. Which resets bmp to BMP_PLACEHOLDER!
 // AND, it'll call the DEFAULT constructor this() with no 
arguments.


bmp = BMP_BUILDING;
}
}

Thanks.

At first glance, I could make the default constructor this() with 
an assert(0) if I never need the default constructor and that's 
the one automatically called. But I'd rather have a warning 
instead of opt-in coding.


The auto-calling really seems to be a dangerous mis-feature.


Pass type directly to a template function?

2017-02-07 Thread Chris Katko via Digitalmars-d-learn
Can I pass a type, instead of a variable of a type, to a template 
function in order to decide the datatype of T in a function?


void function(T)(T x) //works
 {
T data;
//do stuff with T, ignoring x.
}


void function2(T)() //hypothetical, specify the type... somehow?
{
T data;
}

void function3(T)(T) //hypothetical, specify the datatype in the 
argument list

{
T data;
}


void main()
{
float f=0;
float d=0;
function1(f); //works
function1(d); //works

function2!float(); //?
function3!float(); //?

function3(float);  //?
function3(double); //?
}



It seems like this would be a useful construct for Factory 
pattern that assembles any class that you specify as long as the 
called methods work out. (ala Duck Typing, "if it walks() and 
quacks() like a duck, it's a duck")





Re: Mixin template confusion / compiler error.

2017-01-19 Thread Chris Katko via Digitalmars-d-learn

Thank you!

So:

1 - Is there any way TO get the output 64,64? It seems like being 
able to get a comma out of a mixin is a useful feature.


2 - Is this very non-standard / unrecommended practice and 
there's a much better way to do this?


For example, in my actual code, I have an enumerator:

enum MAP_SIZE
{
PLANET = 2048,
SHIP = 256,
SHUTTLE = 64,
(etc)
} //this could also be translated to an array lookup. ala 
SHIP = 0, SHUTTLE = 1, etc. with an array holding the sizes.


and then I pass MAP_SIZE, into a map class, which then builds 
layers into that map based on the MAP_SIZE. The layers are 
statically sized at compile-time by translating a given MAP_SIZE 
down to the actual required dimensions.


So in plain English: Based on a MAP_SIZE, the inner structures 
are all sized appropriately at compile-time.


So, for example:

map_t!(MAP_SIZE.SHIP) x;

goes into

map_t(MAP_SIZE s)
{
layer_t!(mixin(sizer2D!(s))) layer;
}

which becomes

map_t(MAP_SIZE s)
{
layer_t!(64,64) layer;
}

and in layer_t:

layer_t(int width, int height)
{
int [width][height] data;
}


Is there a different way to go about this? Should I be building 
some sort of function inside a template that "decides" / 
"translates" a passed template parameter MAP_SIZE to width and 
height values?


I guess I could try putting the mixin inside layer_t and put the 
values into the square brackets, instead of commas. But again, 
"no commas" seem so arbitrary from an abstract, novice 
perspective. What if I was pre-processing English statements 
which include commas?


Thank you for your assistance. I appreciate it.




Re: Mixin template confusion / compiler error.

2017-01-19 Thread Chris Katko via Digitalmars-d-learn

Addendum:

Writing the following:

writeln(mixin(sizer2D!()));

simply dumps 64 to stdout.



What's going on here? Have I run into a compiler bug?


Mixin template confusion / compiler error.

2017-01-19 Thread Chris Katko via Digitalmars-d-learn
I've tried to narrow this down to the minimum code that exhibits 
the problem.


When I use a mixin, to supply the parameters for a template, it 
works with ONE argument, but NOT TWO.


template sizer2D() // no params here for simplicity
{
const char [] sizer2D = "64,64";  
}   
template sizer1D()
{
const char [] sizer1D = "64"; 
}   

class why_t ()
{
array_t!(64,64) case1;  // works
array_t!(mixin(sizer2D!())) case2; // FAILS (error below)

array2_t!(64) case3; // works
array2_t!(mixin(sizer1D!())) case4; // works

array3_t!(64) case5; // works
	array3_t!(mixin(sizer2D!())) case6; // WORKS using ONE ARGUMENT 
method using default parameter for height (see class)

}

class array_t (int width, int height)
{
int [width][height] data;
}
class array2_t (int width)
{
int [width][width] data;
}
class array3_t (int width, int height=width) //note default param
{
int [width][height] data;
}



The error I get is:

Error: template instance array_t!64 does not match template 
declaration array_t(int width, int height)


Error: template instance a5test.why_t!() error instantiating

And the strange thing is, it's like it's only outputting ONE of 
the two numbers. If it were outputting any other gibberish, it 
shouldn't compile at all. And I'm not misplacing the 1D vs 2D 
function names because originally there was NO 1D version at all. 
It was just the 2D and it wouldn't compile.


Is there any way to get a PRINTOUT of the mixin code upon failure 
to see what it's actually trying to compile?


-


I'm using LDC2:

LDC - the LLVM D compiler (e9b2b4):
  based on DMD v2.068.2 and LLVM 3.5.0




Generation of AST for semantic rule checking

2016-05-21 Thread Chris Katko via Digitalmars-d-learn
I have an idea for something. I know I can't be the only one to 
think this way but I can't find very much information on it.


Basically, I want compile-time enforcement of semantic rules.

For one example--I asked previously here--if it was possible to 
generate a compile-time warning or error if someone used a 
function without checking the return value. But that is one 
specific implementation of a more abstract idea: Setting up 
rulesets to prevent common developer errors in my codebase that 
trigger at compile-time.


I'm wondering how to go about a more general-purpose setup.

Now, if I was using C/C++, I could generate the AST (Abstract 
Syntax Tree) with Clang. (And if you've never done it, I strongly 
recommend it, it's quite beautiful.) Clang also has libclang for 
modifying and generating AST on-the-fly which opens up huge 
potential--but back to the point: if I can find how to get LDC2 
to generate AST, I could write a parser and scan the AST for 
patterns.


I've seen DIP50 and AST Macros which are very interesting... but 
as far as I know, it's not implemented in any compiler.


So the question is: Is there a way to get LDC2 to generate AST or 
similar, and if not, any other way to go about this?


And lastly, is there a proper term for this process, and/or a 
field of research? I have found GCC MELT. But documentation is 
sparse and it seems restricted to GCC and C/C++. I guess you 
could call this "static analysis" with custom rules?


Re: D equivalent of run-time DLLs / Plugins

2016-02-29 Thread Chris Katko via Digitalmars-d-learn

On Monday, 29 February 2016 at 22:12:37 UTC, jmh530 wrote:

On Monday, 29 February 2016 at 19:02:27 UTC, Chris Katko wrote:

Hello. Dlang newbie here.

Does D support run-time loading of D modules?

Basically, I'm looking to create an application with a plugin 
interface.


I've seen a few posts, but they're dated and it's hard to keep 
up with "What is the proper way to do X" when things change 
rapidly. Last thing I want to do is retread ground when 
someone else already has a more elegant solution.


Also, are there any features to avoid that will cause 
problems? I don't plan on needing anything too fancy.


Thanks.


Mike Parker's book covers the subject
https://www.packtpub.com/application-development/learning-d

That part of the book closely follows a series he wrote on 
gamedev (there's more than just that post)

http://www.gamedev.net/page/resources/_/technical/game-programming/binding-d-to-c-r3122


I'm confused. Both posts appear to be for linking D to C++ DLLs. 
I want to link to piece of D code at run-time. I want my D 
program to load, scan for files which are whatever D-equivalent 
of a DLL/SO is, and load those as well. Calling library 
functions, and having them call my core functions.


D equivalent of run-time DLLs / Plugins

2016-02-29 Thread Chris Katko via Digitalmars-d-learn

Hello. Dlang newbie here.

Does D support run-time loading of D modules?

Basically, I'm looking to create an application with a plugin 
interface.


I've seen a few posts, but they're dated and it's hard to keep up 
with "What is the proper way to do X" when things change rapidly. 
Last thing I want to do is retread ground when someone else 
already has a more elegant solution.


Also, are there any features to avoid that will cause problems? I 
don't plan on needing anything too fancy.


Thanks.


Re: Enforcing checks for return code

2016-02-21 Thread Chris Katko via Digitalmars-d-learn

On Thursday, 18 February 2016 at 10:46:03 UTC, Marc Schütz wrote:
On Thursday, 18 February 2016 at 07:21:05 UTC, Chris Katko 
wrote:

[...]


As Jonathan said, there's no such built-in feature, and 
exception are preferred over return codes. However, you can 
implement such a check at run time:


[...]


Thank you all for your insight. I think I have all the 
information I need.


Enforcing checks for return code

2016-02-17 Thread Chris Katko via Digitalmars-d-learn
Hello. I'm almost brand-new to the D language and still absorbing 
things.


I'm wondering if it's possible to fire off a compile-time (or 
worst case, a run-time) warning or error if a function is called, 
but the return value is not checked.


I'm not trying to enforce whether someone actually deciphers the 
value's meaning correctly. I just want to enforce that somewhere, 
a variable or expression is receiving the return value of a 
particular function.


Any ideas?

I imagine I could use a compiler flag to warn, but that's a 
global setting. I'm looking more for a specified subset of 
functions.