modInverse & powMod

2024-06-07 Thread Salih Dincer via Digitalmars-d-learn
I know there is modular exponentiation 
[std.math.exponential.powmod](https://dlang.org/library/std/math/exponential/powmod.html) in the standard library.While it works great in Pyrhon (even with very large numbers), it doesn't work with signed numbers in D. That's why I turned to the alternative below. Don't let it be misunderstood, I don't want to wear out the D language, I use whatever I have, I love D and I don't ask why it works so strangely.


```d
//import std.math.exponential : fpowmod = powmod; /*
T fpowmod(T)(T base, T exponent, T modulus)
{
auto r = T(1);
for (T x = base, y = exponent; y;
x = x * x % modulus, y /= 2)
if (y % 2) r = r * x % modulus;

return r;
}//*/
```

Thanks...

SDB@79

I have only one question: Is there a modInverse() function in the 
standard library for use in RSA? I did research on this subject 
within the relevant modules.  I guess not these?


* 
[std.mathspecial.logmdigammaInverse](https://dlang.org/phobos/std_mathspecial.html)
* 
[std.numeric.inverseFft](https://dlang.org/library/std/numeric.html)


Re: FIFO

2024-05-14 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 13 May 2024 at 15:07:39 UTC, Andy Valencia wrote:

On Sunday, 12 May 2024 at 22:03:21 UTC, Ferhat Kurtulmuş wrote:

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

This is a stack, isn't it?  LIFO?

Ahh yes. Then use dlist


Thank you.  I read its source, and was curious so I wrote a 
small performance measurement: put 10,000 things in a FIFO, 
pull them back out, and loop around that 10,000 times.  My FIFO 
resulted in:


Also try the code I gave in this thread:
https://forum.dlang.org/post/fgzvdhkdyevtzznya...@forum.dlang.org

In fact, please use this facility in the standard library: 
https://dlang.org/phobos/std_datetime_stopwatch.html#benchmark


SDB@79


Re: FIFO

2024-05-13 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 13 May 2024 at 15:07:39 UTC, Andy Valencia wrote:


Representing the FIFO as a linked list clearly has its cost, 
but I found the increased system time interesting.  OS memory 
allocations maybe?


I know you want FIFO, I usually keep this on hand for fixed size 
LIFO; It can easily convert to FIFO and doesn't use LinkedList:


```d
class LIFO(T)
{
  T * element;
  size_t length, size;
  this(size_t s) {
element = cast(T*)new T[s];
length = s;
  }
  auto rewind() => size = length;

  bool empty() => !size;
  auto front() => element[size - 1];
  auto popFront() => --size;

  auto pop() => empty ? T(0) : element[--size];
  alias push = insertFront;
  auto insertFront(T value)
  in(size < length, "Stack is overflow!")
=> element[size++] = value;

  auto ref opDollar() => length;
  auto ref opIndex(size_t i) => element[i];
  auto ref opSlice(size_t first, size_t last)
=> element[first..last];

} unittest {

  enum test = 7;
  auto stack = new LIFO!size_t(test);

  assert(!stack.size);
  foreach (prime; 1..test + 1)
  {
stack.insertFront(prime);
  }
  assert(stack.size == test); // == 7

  stack.writeln(": ", stack.length); // [7, 6, 5, 4, 3, 2, 1]: 7
  stack[$/2].writeln("-", stack[0]); // 4-1


  stack.rewind();
  stack.size.write(": ["); // 10:
  while (auto next = stack.pop)
  {
if (next == 1) next.writeln("]");
else next.write(", ");
  }
  stack.size.writeln; // 0
  stack.rewind();
  assert(stack.size == test);
}

SDB@79



Re: Challenge Tuples

2024-05-02 Thread Salih Dincer via Digitalmars-d-learn

On Wednesday, 1 May 2024 at 14:15:19 UTC, Andrey Zherikov wrote:



Shorter and without allocations:
```d
import std.typecons : tuple;
import std.algorithm : sum, each;

auto sum(int i) => i;

void main()
{
  auto t = tuple(1, 2, 3, [1, 3], 5);

  int res=0;
  t.each!(e => res += sum(e));
  assert(res == 15);
}
```


Super!

In summary, D is clearly ahead of the tuple. Especially with its 
features similar to AliasSeq, I think it is unrivaled. Wouldn't 
it be great if there was a feature that worked at runtime...


SDB@79



Re: Challenge Tuples

2024-04-27 Thread Salih Dincer via Digitalmars-d-learn

On Saturday, 27 April 2024 at 15:36:40 UTC, Nick Treleaven wrote:
On Saturday, 27 April 2024 at 15:32:40 UTC, Nick Treleaven 
wrote:

On Saturday, 27 April 2024 at 11:55:58 UTC, Basile B. wrote:

foreach const e in u do
if echo(is, e, T) do
result += e;



static if (is(typeof(e) == int))
r += e;


Actually I would write that:
```d
R r;
foreach (e; v)
{
static if (is(typeof(e) : R))
```


I like the new sum() function, great Nick!  Moreover, it also 
works with an ordinary range:


```d
  enum limit = 100; // sum = 5050
  iota(limit + 1).sum.writeln;
```

Python seems too complicated to me, but C# looks delicious. 
Moreover, it was implemented without defining IEnumerator. Well 
done Matheus!


SDB@79


Challenge Tuples

2024-04-26 Thread Salih Dincer via Digitalmars-d-learn
You have a 5-item data tuples as Tuple(1, 2, 3, [1, 3], 5) and 
implement the sum (total = 15) with the least codes using the 
sum() function of the language you are coding...



Let's start with D:

```d
import std.typecons : tuple;
import std.algorithm : sum;

void main()
{
  auto t = tuple(1, 2, 3, [1, 3], 5);

  int[] arr;
  t.each!(e => arr ~= e);
  assert(arr.sum == 15);
}
```

and bonus:

```d
import std.typecons : tuple;
import std.stdio : writeln;
void main()
{
  auto t = tuple(1, 2, 3, [1, 3], 5);
  auto results = [0];

  foreach (data; t)
  {
static
if (is(typeof(data) == int[]))
{
  int sum;
  foreach (d; data)
  {
sum += d;
  }
  results ~= sum;
}
else
{
  results ~= data;
}
  }
  results.writeln; // [0, 1, 2, 3, 4, 5]
```

I bet you won't be able to do it this easily with other 
languages!  Note: I tried with C# and Python and it didn't work!


SDB@79


Re: Adapting foreign iterators to D ranges

2024-04-23 Thread Salih Dincer via Digitalmars-d-learn

On Tuesday, 23 April 2024 at 06:02:18 UTC, cc wrote:
Just to offer an alternative solution (since it sometimes gets 
overlooked), there is also the `opApply` approach.  You don't 
get full forward range status, and checking whether it's empty 
essentially requires doing something like std.algorithm 
`walkLength`, but if all you need is basic iteration, it can be 
a simpler solution:




Yes, `opApply()` works! You just need to use `do while()` instead 
of `while()` because it skips the first item.


```d
struct Node
{
  int item;
  Node* next;
}

class List
{
  Node* root, iter;

  this(int item = 0)
  {
iter = new Node(item, null);
root = iter;
  }

  List dup()
  {
auto backup = new List();
backup.root = root;
backup.iter = iter;

return backup;
  }

  void insertFront(T)(T item)
  {
(*iter).next = new Node(item, null);
this.Next;
  }

  bool empty() const => iter is null;
  auto front() inout => iter;
  auto popFront()=> iter = this.Next;
  auto getItem() => iter.item;
  auto rewind()  => iter = root;
}

auto Next(List list) => list.iter = list.iter.next;
auto gaussian(T)(T n)=> (n * n + n) / 2;

void main()
{
  import std.stdio;
  enum LIMIT = 10;

  auto list = new List(1);
  foreach(t; 2 .. LIMIT + 1)
  {
list.insertFront(t);
  }

  auto tmp = list.dup;
  list.rewind();

  size_t sum;
  do sum += list.getItem; while(list.Next);
  assert(gaussian(LIMIT) == sum);

  sum.writeln; // 55

  auto next = LIMIT + 1;
  tmp.insertFront(next);
  tmp.rewind();
  sum = 0;

  foreach(t; tmp) sum += t.item;
  assert(gaussian(LIMIT) + next == sum);

  sum.writeln; // 66
  tmp.rewind();

  auto range = Range(tmp);

  foreach(r; range) r.item.write(" ");
  writeln; //  2 3 4 5 6 7 8 9 10 11
  // ? (1) --^
}

struct Range
{
  private List iter;

  int opApply(scope int delegate(Node* t) dg)
  {
while(auto current = iter.Next)
{
  if (auto r = dg(current))
return r;
}
return 0;
  }
}
```

SDB@79




Re: Inconsistent chain (implicitly converts to int)

2024-04-06 Thread Salih Dincer via Digitalmars-d-learn

On Saturday, 6 April 2024 at 09:21:34 UTC, rkompass wrote:


I checked:

```d
import std.stdio,
   std.range,
   std.algorithm;

struct N(T)
{
  T last, step, first;
  bool empty() => first >= last;
  T front() => first;
  auto popFront() => first += step;
}

void main() {
  auto r1 = N!size_t(10, 1, 1);
  auto r2 = N!real(15, .5, 10);
```
and it seems to work as I said.


Thank you for checking again, but it is important to be solution 
oriented. How about Tuple?


Yes, it might be wise to use a tuple in this case:
```d
  //...
  auto tuple = a.zip(b);
  tuple.writeln;
  // [Tuple!(int, dchar)(97, 'd'), Tuple!(int, dchar)(98, 'e'), 
Tuple!(int, dchar)(99, 'f')]


  tuple.map!(num => num[0].to!dchar).write;
  tuple.map!"a[1]".writeln; // abcdef
}
```

SDB@79


Re: CTFE write message to console

2024-04-05 Thread Salih Dincer via Digitalmars-d-learn

On Friday, 5 April 2024 at 14:41:12 UTC, Carl Sturtivant wrote:

On Friday, 5 April 2024 at 07:37:20 UTC, Paolo Invernizzi wrote:

pragma(msg, x) ?


No.

`__ctfeWrite(x)` is executed inside an executing function like 
any other statement in it, and can have an argument `x` 
computed during that execution.


It is defined to output the computed text `x` to stderr when 
the function it is a part of is called as CTFE by the compiler 
and to be a no-op if that function is called at run time in the 
compiled executable.


So it is a replacement for `std.stdio.write` in a CTFE 
function, handy among other things for reporting what's going 
on during the execution of that function by the compiler.


`pragma(msg, x)` works during its *compilation*, so putting it 
as a line in a CTFE-called function would not execute it when 
the function is called by the compiler. That being the case, 
`x` may not be a value computed when that function executes. 
Such a value is "not available at compile time", only at CTFE 
run time. The CTFE function is not running when it is being 
compiled.


It is possible that `x` in `pragma(msg, x)` be computed with a 
call to a function as its return value, i.e. computed by CTFE, 
but that call will be made when `pragma(msg, x)` is compiled, 
and is a part of compiling it. Only when the function has 
returned producing `x` does the `pragma(msg, x)` do its work.


This works:
```d

alias E = double;
auto r = 0.iota!E(1,.05)

static this()
{
 alias ranges = imported!"std.meta".AliasSeq!(isRandomAccessRange,
 isForwardRange, isInputRange, isOutputRange, 
isBidirectionalRange);

 static foreach(R; ranges) pragma(msg, R!(typeof(r), E));
}

void main() {}
```
SDB@79


Re: Inconsistent chain (implicitly converts to int)

2024-04-05 Thread Salih Dincer via Digitalmars-d-learn

On Friday, 5 April 2024 at 21:16:42 UTC, rkompass wrote:


In the first example the int's are converted to doubles (also 
common type).
But they appear as int's because writeln does not write a 
trailing .0.


But it doesn't work as you say! I even tried it on an older 
version and got the same result.


SDB@79


Re: Inconsistent chain (implicitly converts to int)

2024-04-05 Thread Salih Dincer via Digitalmars-d-learn

On Friday, 5 April 2024 at 16:05:20 UTC, H. S. Teoh wrote:
On Fri, Apr 05, 2024 at 03:18:09PM +, Salih Dincer via 
Digitalmars-d-learn wrote:

Hi everyone,

Technically r1 and r2 are different types of range. Isn't it 
inconsistent to chain both? If not, why is the char type 
converted to int?

[...]

It's not inconsistent if there exists a common type that both 
range element types implicit convert to.


The real problem is the implicit conversion of char to int, 
which I have been against for a long time.  Walter, however, 
disagrees.



T

```d
  auto a = [97, 98, 99];
  auto b = ['d', 'e', 'f'];

  a.chain(b).map!(chr => chr.to!char).writeln;
  // abcdef
```

Nice, there is a solution that requires memory allocation, but it 
still makes you think!


However, they can fix this in Phobos3 because now we have this 
too: 
https://dlang.org/changelog/2.108.0.html#range_predicate_element


PS. I think I unintentionally made a chain by repeating the 
source code above, sorry :)


SDB@79


Inconsistent chain (implicitly converts to int)

2024-04-05 Thread Salih Dincer via Digitalmars-d-learn

Hi everyone,

Technically r1 and r2 are different types of range. Isn't it 
inconsistent to chain both? If not, why is the char type 
converted to int?


```d
import std.stdio,
   std.range;

void main() {
  auto r1 = N!size_t(10, 1, 1);
  auto r2 = N!real(15, .5, 10);

  r1.chain(r2).writeln;
  // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10.5, 11, 11.5, 12, 12.5, 
13, 13.5, 14, 14.5]


  auto a = [97, 98, 99];
  auto b = ['d', 'e', 'f'];

  a.chain(b).writeln;
  // [97, 98, 99, 100, 101, 102]
}

struct N(T)
{
  T last, step, first;
  bool empty() => first >= last;
  T front() => first;
  auto popFront() => first += step;
}
void main() {
  auto r1 = N!size_t(10, 1, 1);
  auto r2 = N!real(15, .5, 10);

  r1.chain(r2).writeln;
  // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10.5, 11, 11.5, 12, 12.5, 
13, 13.5, 14, 14.5]


  auto a = [97, 98, 99];
  auto b = ['d', 'e', 'f'];

  a.chain(b).writeln;
  // [97, 98, 99, 100, 101, 102]
}

struct N(T)
{
  T last, step, first;
  bool empty() => first >= last;
  T front() => first;
  auto popFront() => first += step;
}
```

SDB@79


Re: How to add a character literal to a string without ~ operator?

2024-04-04 Thread Salih Dincer via Digitalmars-d-learn

On Thursday, 4 April 2024 at 19:56:50 UTC, Ferhat Kurtulmuş wrote:

My favorite d feature is lazy ranges. No allocation here.

```d
auto s = chain("as ", "df ", "j"); // s is lazy
writeln(s);
```


```d
import std.range : chain;
void main()
{
  string word = "hello";
  auto noError = chain(word, "f", " ", "World");
  /** auto noCompile = chain('f', " ", "World");
* ^
 *|/
}
```

SDB@79


Re: How to add a character literal to a string without ~ operator?

2024-04-04 Thread Salih Dincer via Digitalmars-d-learn

On Thursday, 4 April 2024 at 18:14:54 UTC, BoQsc wrote:
I'm looking for more readable standard function to add a 
**character** literal to a **string**.


The `~` operator is clearly not great while reading a source 
code.
I'm not here to discuss that. I'm looking for a function inside 
standard library.


The function should be straightforward, up to two words.

Here is what I expect from a programming language:

Pseudo example:


```d
import std.array, std.stdio;
void main()
{
  auto word = appender("hello");
  word.put('f');
  word.put(" ");
  word.put("World");
  word.writeln;
}   
```
SDB@79




Re: CTFE write message to console

2024-04-04 Thread Salih Dincer via Digitalmars-d-learn
On Thursday, 4 April 2024 at 15:47:53 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

Oh hey!

https://github.com/dlang/dmd/pull/16250

It was implemented literally 2 weeks ago!

Nightly should have it 
https://github.com/dlang/dmd/releases/tag/nightly


Good news, thanks...

SDB@79



Re: Setting up a final switch from a list

2024-03-29 Thread Salih Dincer via Digitalmars-d-learn

On Friday, 29 March 2024 at 00:37:21 UTC, Jonathan M Davis wrote:
On Thursday, March 28, 2024 4:21:03 PM MDT Salih Dincer via 
Digitalmars-d- learn wrote:
How can we add all members of an enum type to a list without 
duplicating code?


As the documentation for EnumMembers explains, you can use 
std.meta.NoDuplicates to strip out duplicates if you want to do 
something like generate a switch statement from the list of 
enum members.


https://dlang.org/phobos/std_traits.html#EnumMembers

- Jonathan M Davis


I guess this falls into metaprogramming. Maybe we should expect 
this possibility from IDEs because I've seen something like this 
in VScode. All enum members were added automatically.


SDB@79


Re: Why is this code slow?

2024-03-28 Thread Salih Dincer via Digitalmars-d-learn

On Friday, 29 March 2024 at 00:04:14 UTC, Serg Gini wrote:

On Thursday, 28 March 2024 at 23:15:26 UTC, Salih Dincer wrote:
There is no such thing as parallel programming in D anyway. At 
least it has modules, but I didn't see it being works. 
Whenever I use toys built in foreach() it always ends in 
disappointment


I think it just works :)
Which issues did you have with it?


A year has passed and I have tried almost everything! Either it 
went into an infinite loop or nothing changed at the speed. At 
least things are not as simple as openMP on the D side! First I 
tried this code snippet: futile attempt!


```d
struct RowlandSequence {
  import std.numeric : gcd;
  import std.format : format;
  import std.conv : text;

  long b, r, a = 3;
  enum empty = false;

  string[] front() {
string result = format("%s, %s", b, r);
return [text(a), result];
  }

  void popFront() {
long result = 1;
while(result == 1) {
  result = gcd(r++, b);
  b += result;
}
a = result;
  }
}

enum BP {
  f = 1, b = 7, r = 2, a = 1, /*
  f = 109, b = 186837516, r = 62279173, //*/
  s = 5
}

void main()
{
  RowlandSequence rs;
  long start, skip;

  with(BP) {
rs = RowlandSequence(b, r);
start = f;
skip = s;
  }
  rs.popFront();

  import std.stdio, std.parallelism;
  import std.range : take;

  auto rsFirst128 = rs.take(128);
  foreach(r; rsFirst128.parallel)
  {
if(r[0].length > skip)
{
  start.writeln(": ", r);
}
start++;
  }
}
```
SDB@79


Re: Two chunks but No allocation

2024-03-28 Thread Salih Dincer via Digitalmars-d-learn

On Thursday, 28 March 2024 at 23:08:54 UTC, rkompass wrote:

You can drop and take from the folded values range.

I got `[1, 0.67, 0.625, 0.619048, 0.618182, 0.618056, 
0.618037, 0.618034, 0.618034, 0.618034]` from the above code.


Thank you so much...

I solved the problem: r.back doesn't work because recurrence() 
runs forever and you need to use it with take. In other words, 
the range functions up to the map must have members such as 
length() and opSlice().


SDB@79


Re: range.chunks(2) error

2024-03-28 Thread Salih Dincer via Digitalmars-d-learn

On Thursday, 28 March 2024 at 17:50:17 UTC, Salih Dincer wrote:

Hi,

When I use the chunks() template with iota(), for instance, 
with chunks(2), I can access both r.front and r.back. However, 
in a range of my own type (named iras in the code below), only 
r.front is working. I think the error given by r.back is not a 
bug related to chunks, is it?


It's really nice to solve a problem on your own. Turns out I 
needed to add save, opSlice, length and opDollar members to the 
range.


SDB@79




Re: Why is this code slow?

2024-03-28 Thread Salih Dincer via Digitalmars-d-learn

On Thursday, 28 March 2024 at 20:18:10 UTC, rkompass wrote:

I didn't know that OpenMP programming could be that easy.
Binary size is 16K, same order of magnitude, although somewhat 
less.

D advantage is gone here, I would say.


There is no such thing as parallel programming in D anyway. At 
least it has modules, but I didn't see it being works. Whenever I 
use toys built in foreach() it always ends in disappointment :)


SDB@79


Re: Setting up a final switch from a list

2024-03-28 Thread Salih Dincer via Digitalmars-d-learn
On Thursday, 10 August 2023 at 08:33:13 UTC, Christian Köstlin 
wrote:
I think one part of the original question (now fanished in the 
nntp backup) was how to get all enum members into a list 
without duplicating code.



```d
import std.traits : EnumMembers;
import std.stdio : writeln;
import std.algorithm : map;
import std.conv : to;
enum alphabet {
  a, b, c, d
}

void main()
{
  writeln(EnumMembers!alphabet);
  writeln([EnumMembers!alphabet]);
  writeln([EnumMembers!alphabet].map!(a => "test" 
~a.to!string));

}
```

results in

```d
abcd
[a, b, c, d]
["testa", "testb", "testc", "testd"]```
```


How can we add all members of an enum type to a list without 
duplicating code?


I wonder if this is something we'll see soon as the D language 
feature?


In the D programming language, this can be achieved using 
features provided by the language such as __traits and AliasSeq. 
For instance, the EnumMembers trait from the std.traits module 
returns all members of an enum type as a tuple. This tuple 
contains the enum members in sequence, allowing for iteration 
over them or conversion into a list.


Finally, utilizing these language features to avoid code 
duplication and write cleaner, more maintainable code is a good 
practice. Sorry to resurrect this old thread, but what do you 
think; people living in 2024 ?


SDB@79


range.chunks(2) error

2024-03-28 Thread Salih Dincer via Digitalmars-d-learn

Hi,

When I use the chunks() template with iota(), for instance, with 
chunks(2), I can access both r.front and r.back. However, in a 
range of my own type (named iras in the code below), only r.front 
is working. I think the error given by r.back is not a bug 
related to chunks, is it?


```d
import std.array, std.algorithm,
   std.range,
   std.stdio;

void main()
{
  auto rng1 = iota!real(24.0, 1321.0, 16.5).take(8);
  auto rng2 = iras!real(24.0, 1321.0, 16.5).take(8);

  auto noError = rng1.chunks(2)
 .map!(r =>
  r.back - r.front);

  assert(noError.equal([16.5, 16.5, 16.5, 16.5]));
  /*
  auto error = rng2.chunks(2)
 .map!(r =>
  r.back - r.front);/*

main.d(18): Error: none of the overloads of template
  `std.range.primitives.back` are callable using
   argument types `!()(Take!(InclusiveRange))`*/
}
/*
 * iras v3
 * (inclusiveRange) Source:
 * 
https://forum.dlang.org/post/bnnxentwstkjnxkyc...@forum.dlang.org

*/
```

The same problem occurs here:

```d
struct Range(T)
{
  T n = 3;
  bool empty;

  alias back = front;
  auto front() => n.cube - n * 0.5;

  auto popFront() => n += 2;
  auto backFront() => n -= 2;
}
```
SDB@79


Re: Why is this code slow?

2024-03-28 Thread Salih Dincer via Digitalmars-d-learn

On Thursday, 28 March 2024 at 11:50:38 UTC, rkompass wrote:


Turning back to this: Are there similarly simple libraries for 
C, that allow for

parallel computation?


You can achieve parallelism in C using libraries such as OpenMP, 
which provides a set of compiler directives and runtime library 
routines for parallel programming.


Here’s an example of how you might modify the code to use OpenMP 
for parallel processing:


```c
#include 
#include 
#include 

#define ITERS 10
#define STEPS 31

double leibniz(int i) {
  double r = (i == ITERS) ? 0.5 * ((i % 2) ? -1.0 : 1.0) / (i * 
2.0 + 1.0) : 0.0;

  for (--i; i >= 0; i -= STEPS)
r += ((i % 2) ? -1.0 : 1.0) / (i * 2.0 + 1.0);
  return r * 4.0;
}

int main() {
  double start_time = omp_get_wtime();

  double result = 0.0;

  #pragma omp parallel for reduction(+:result)
  for (int s = ITERS; s >= 0; s -= STEPS) {
result += leibniz(s);
  }

  // Calculate the time taken
  double time_taken = omp_get_wtime() - start_time;

  printf("%.16f\n", result);
  printf("%f (seconds)\n", time_taken);

  return 0;
}
```
To compile this code with OpenMP support, you would use a command 
like gcc -fopenmp your_program.c. This tells the GCC compiler to 
enable OpenMP directives. The #pragma omp parallel for directive 
tells the compiler to parallelize the loop, and the reduction 
clause is used to safely accumulate the result variable across 
multiple threads.


SDB@79


Re: Two chunks but No allocation

2024-03-27 Thread Salih Dincer via Digitalmars-d-learn

On Wednesday, 27 March 2024 at 20:50:05 UTC, rkompass wrote:

This works:


I decided to give the full code. Maybe then it will be better 
understood what I mean. I actually pointed out the indirect 
solution above but it's a bit ugly and I'm sure there must be a 
better way?


```d
import std.datetime.stopwatch;
import std.stdio, std.algorithm,
   std.range;

auto cube(T)(T n)
  => n * n * n;

auto S1(T, R)(R a, T n)
  => n.cube - n; //

auto s1(T)(T first, size_t skip = 3)
  => recurrence!S1(0, first).drop(skip);

enum ITERATIONS = 14_000;
enum BENCHMARKS = 100;

void main()
{
real result;
long total_time = 0;

for(int i = 0; i < BENCHMARKS; i++)
{
  auto sw = StopWatch(AutoStart.no);
  sw.start();

  result = s1(3.0).take(ITERATIONS)
  .chunks(2)
  .map!(r => 4/r.front)
  .array // <- can't it be done without this?
  .chunks(2)
  .map!"a[0] - a[1]"
  .fold!"a + b"(3.0);
  sw.stop();
  total_time += sw.peek.total!"nsecs";
}
writefln("%f (nsecs)", total_time / BENCHMARKS / 1e9);
writefln("%0.16f (result)", result);```
} /*
0.000456 (nsecs)
3.1415926535890670 (result)
//*/
```

SDB@79


Re: Why is this code slow?

2024-03-27 Thread Salih Dincer via Digitalmars-d-learn

On Wednesday, 27 March 2024 at 08:22:42 UTC, rkompass wrote:
I apologize for digressing a little bit further - just to share 
insights to other learners.


Good thing you're digressing; I am 45 years old and I still 
cannot say that I am finished as a student! For me this is 
version 4 and it looks like we don't need a 3rd variable other 
than the function parameter and return value:


```d
auto leibniz_v4(int i) @nogc pure {
  double n = 0.5*((i%2) ? -1.0 : 1.0) / (i * 2.0 + 1.0);

  while(--i >= 0)
n += ((i%2) ? -1.0 : 1.0) / (i * 2.0 + 1.0);

  return n * 4.0;
} /*
3.1415926535892931
3.141592653589 793238462643383279502884197169399375105
3.14159365359077420 (v1)
Avg execution time: 0.33
*/
```

SDB@79


Two chunks but No allocation

2024-03-27 Thread Salih Dincer via Digitalmars-d-learn
Is it possible to process both chunks without requiring memory 
allocation (not using an array)?


For example:

```d
import std;
void main()
{
  auto fib = (real a, real b)
   => recurrence!"a[n-1] + a[n-2]"(a, b);

  auto myFib = fib(1, 1).take(48).array;
  auto goldenRadio = myFib.chunks(2).map!
  //"a[1] / a[0]";/* line #9
  ((a) {
const m = a.front;
a.popFront();
const n = a.front;

return m/n; });//*/

  goldenRadio.back.writefln!"%.21f";
  writeln("0.61803398874989484820");
}
```

Of course, it also works if you remove the comment marks on line 
#9 but I'm still using .array because the .chunks error tells me 
that.


So, not works this:

```d
fib(1, 1).take(48)
 //.array
 .chunks(2)
 .map!"a[1] / a[0]"
 .back
 .writeln; // 1.61803
```

Thanks...

SDB@79


Re: Why is this code slow?

2024-03-26 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 25 March 2024 at 14:02:08 UTC, rkompass wrote:


Of course you may also combine the up(+) and down(-) step to 
one:


1/i - 1/(i+2) = 2/(i*(i+2))

```d
double leibniz(int iter) {
  double n = 0.0;
  for (int i = 1; i < iter; i+=4)
n += 2.0 / (i * (i+2.0));
  return n * 4.0;
}
```
or even combine both approaches. But of, course mathematically 
much more is possible. This was not about approximating pi as 
fast as possible...


The above first approach still works with the original speed, 
only makes the result a little bit nicer.


It's obvious that you are a good mathematician. You used sequence 
A005563.  First of all, I must apologize to the questioner for 
digressing from the topic. But I saw that there is a calculation 
difference between real and double. My goal was to see if there 
would be a change in speed.  For example, with 250 million cycles 
(iter/4) I got the following result:



3.14159265158976691 (250 5million (with real)
3.14159264457621568 (250 million with double)
3.14159265358979324 (std.math.constants.PI)


First of all, my question is: Why do we see this calculation 
error with double?  Could the changes I made to the algorithm 
have caused this?  Here's an executable code snippet:


```d
enum step = 4;
enum loop = 250_000_000;

auto leibniz(T)(int iter)
{
  T n = 2/3.0;
  for(int i = 5; i < iter; i += step)
  {
T a = (2.0 + i) * i; // https://oeis.org/A005563
n += 2/a;
  }
  return n * step;
}

import std.stdio : writefln;

void main()
{
  enum iter = loop * step-10;
  
  65358979323.writefln!"Compare.%s";

  iter.leibniz!double.writefln!"%.17f (double)";
  iter.leibniz!real.writefln!"%.17f (real)";

  imported!"std.math".PI.writefln!"%.17f (enum)";
} /* Prints:

Compare.65358979323
3.14159264457621568 (double)
3.14159265158976689 (real)
3.14159265358979324 (enum)
*/
```

In fact, there are algorithms that calculate accurately up to 12 
decimal places with fewer cycles. (e.g. )


SDB@79


Re: Why is this code slow?

2024-03-24 Thread Salih Dincer via Digitalmars-d-learn

On Sunday, 24 March 2024 at 22:16:06 UTC, Kdevel wrote:
The term containing the `pow` invocation computes the 
alternating sequence -1, 1, -1, ..., which can be replaced by 
e.g.


```d
   immutable int [2] sign = [-1, 1];
   n += sign [i & 1] / (i * 2.0 - 1.0);
```

This saves the expensive call to the pow function.


I also used this code:
```d
import std.stdio : writefln;
import std.datetime.stopwatch;

enum ITERATIONS = 1_000_000;
enum BENCHMARKS = 20;

auto leibniz(bool speed = true)(int iter) {
  double n = 1.0;

  static if(speed) const sign = [-1, 1];

  for(int i = 2; i < iter; i++) {
static if(speed) {
  const m = i << 1;
  n += sign [i & 1] / (m - 1.0);
} else {
  n += pow(-1, i - 1) / (i * 2.0 - 1.0);
}
  }
  return n * 4.0;
}

auto pow(F, G)(F x, G n) @nogc @trusted pure nothrow {
import std.traits : Unsigned, Unqual;

real p = 1.0, v = void;
Unsigned!(Unqual!G) m = n;

if(n < 0) {
if(n == -1) return 1 / x;
m = cast(typeof(m))(0 - n);
v = p / x;
} else {
switch(n) {
  case 0: return 1.0;
  case 1: return x;
  case 2: return x * x;
  default:
}
v = x;
}
while(true) {
if(m & 1) p *= v;
m >>= 1;
if(!m) break;
v *= v;
}
return p;
}

void main()
{
double result;
long total_time = 0;

for(int i = 0; i < BENCHMARKS; i++)
{
auto sw = StopWatch(AutoStart.no);
sw.start();

result = ITERATIONS.leibniz;//!false;

sw.stop();
total_time += sw.peek.total!"nsecs";
}

result.writefln!"%0.21f";
writefln("Avg execution time: %f\n", total_time / BENCHMARKS 
/ 1e9);

}
```

and results:


dmd -run "leibnizTest.d"
3.141594653593692054727
Avg execution time: 0.002005


If I compile with leibniz!false(ITERATIONS) the average execution 
time increases slightly:



Avg execution time: 0.044435


However, if you pay attention, it is not connected to an external 
library and a power function that works with integers is used. 
Normally the following function of the library should be called:


Unqual!(Largest!(F, G)) pow(F, G)(F x, G y) @nogc @trusted pure 
nothrow

if (isFloatingPoint!(F) && isFloatingPoint!(G))
...


Now, the person asking the question will ask why it is slow even 
though we use exactly the same codes in C; rightly. You may think 
that the more watermelon you carry in your arms, the slower you 
naturally become. I think the important thing is not to drop the 
watermelons :)


SDB@79


Re: Challenge: Make a data type for holding one of 8 directions allowing increment and overflow

2024-03-13 Thread Salih Dincer via Digitalmars-d-learn

On Wednesday, 13 March 2024 at 10:27:49 UTC, Basile B. wrote:
The semantics of the operators are actually not as clear as 
that. What if you define


```d
enum Direction
{
N = 1, NE, S = 45, SW
}
```

?


Certainly! EnumMembers; can be used. The EnumMembers template 
from the std.traits module is used to retrieve all the members of 
an enumeration. It generates a tuple containing all the 
enumeration values, which can be iterated over using a foreach 
loop. In the D programming language, you can use EnumMembers to 
iterate over enum values at compile time, which is useful for 
generating code based on enum members.

Here’s a simple code example:

```d
 enum Days
 {
   Monday= 1001,
   Tuesday   = 1010,
   Wednesday = 1011,
   Thursday  = 1100,
   Friday= 1101,
   Saturday  = 1110,
   Sunday= 
 }

 import std.traits : EnumMembers;
 foreach(day; EnumMembers!Days)
   day.writeln(":", cast(int)day);
```

SDB@79


Re: Challenge: Make a data type for holding one of 8 directions allowing increment and overflow

2024-03-12 Thread Salih Dincer via Digitalmars-d-learn

On Tuesday, 12 March 2024 at 05:38:03 UTC, Liam McGillivray wrote:
Perhaps this would be a good programming challenge for someone 
more experienced than me. Make a data type (probably a struct) 
for holding one of 8 directional values using 3 bits. It should 
accept the use of increment operators to change the angle.


D is such a perfect language that you can do the features you 
mentioned and more. I also implemented the following during my 
rookie years:


```d
alias Direction = enumSet;
union enumSet(T)
{
  T e;

  alias e this;
  struct
  {
int i;

auto opUnary(string op: "++")()
  => i = i < e.max ? ++i : e.min;

auto opUnary(string op: "--")()
  => i = i > e.min ? --i : e.max;

auto opOpAssign(string op: "+")(int val)
{
  i += val;
  if(i > e.max) i -= e.max + 1;
}

auto opOpAssign(string op: "-")(int val)
{
  i -= val;
  if(i < e.min) i += e.max + 1;
}
  }

  string toString() const
=> e.to!string;
}

unittest
{
 auto direction = Direction!Directions(Directions.N);
 direction++;
 assert(direction == Directions.NE);
 direction+=3;
 assert(direction == Directions.S);
 direction--;
 assert(direction == Directions.SE);
 direction-=4;
 assert(direction == Directions.NW);
}

import std.stdio, std.conv;

void main()
{
  enum Directions
  {
N , NE , E, SE, S, SW , W, NW
  }

  auto test = enumSet!Directions(Directions.W);
   test += 9; /*

   ++test; ++test; ++test;
   ++test; ++test; ++test;
   ++test; ++test; ++test;//*/

   test.writeln;

   test--; test--;
   test.writeln;
}
```

Here union was used with an extra template parameter. I also 
added 2 aliases to avoid confusion.


SDB@79


Re: struct initializer

2023-12-01 Thread Salih Dincer via Digitalmars-d-learn

Hi All,

I feel lonely, just as those who come from C++ find it strange, 
because I think it makes it difficult to read code.


On Friday, 1 December 2023 at 14:53:16 UTC, Paul Backus wrote:


Technically you don't *have* to repeat the type. You can write 
the return type as `auto`:


```d
auto fun() { return S(5, 2); }
```

Or you can use `typeof(return)`:

```d
SomeReallyLongReturnType fun()
{
return typeof(return)(5, 2);
}
```


Paul's example is very readable and short so it's nice. Moreover, 
when there are named parameters in D, what is the need for them. 
While there is so much convenience in D, getting stuck on a very 
simple option...


You decide:
```d
struct Point
{
  int x, y;

  auto opBinary(string  op : "-")(Point that)
  => Point(this.x - that.x, this.y - that.y);

  auto opBinary(string  op : "+")(Point that)
  => Point(this.x + that.x, this.y + that.y);

  auto opBinary(string  op : "*")(Point that)
  => Point(this.x * that.x, this.y * that.y);
  // Moreover, it was possible to do this trio
  // at once with mixin...
}

void main()
{
  auto upperRightCorner = Point(y:768);
  Point x =  { 10, 268  };

  import std.stdio : dout = writeln;

  dout(upperRightCorner - x);
  dots(a: upperRightCorner, b: x).dout;
}

alias dots = differenceOfTwoSquares;
auto differenceOfTwoSquares(Point a, Point b)
  => (a - b)*(a + b);

/*
 * dmd -run "namedParameters.d"
 * Point(-10, 500)
 * Point(-100, 518000)
 */
```
SDB@79


Re: Convert String to Date and Add ±N Hours

2023-11-07 Thread Salih Dincer via Digitalmars-d-learn
On Saturday, 4 November 2023 at 21:10:38 UTC, Steven 
Schveighoffer wrote:

On Saturday, 4 November 2023 at 18:11:53 UTC, Vahid wrote:

Hi,

I have a date string with the format of "2023-11-04 23:10:20". 
I want to convert this string to Date object and also, add ±N 
hours to it. For example:


`"2023-11-04 23:10:20" + "+2:00" = "2023-11-05 01:10:20"`
`"2023-11-04 23:10:20" + "-2:30" = "2023-11-05 20:40:20"`

How can I do this?


Parse the date. There is a nice package on code.dlang.org that 
is for date parsing: https://code.dlang.org/packages/dateparser


-Steve


I couldn't get it to work, can you help me with this? I think the 
error is related to line 803 in the package.d file:



import containers.dynamicarray : DynamicArray;


This means it is dependent on containers by Dlang Community.

This was installed it: 
https://github.com/dlang-community/containers


However I get these errors:

dmd -w -of"bench.a" "bench.d" containers/package.d 
dateparser/package.d


/usr/bin/ld: bench.o:(.data.rel.ro+0x60): undefined reference 
to `_D10containers12dynamicarray12__ModuleInfoZ'
/usr/bin/ld: bench.o:(.data.rel.ro+0x78): undefined reference 
to `_D10containers8internal4node12__ModuleInfoZ'
/usr/bin/ld: bench.o:(.data.rel.ro+0x120): undefined reference 
to `_D10containers12cyclicbuffer12__ModuleInfoZ'
/usr/bin/ld: bench.o:(.data.rel.ro+0x128): undefined reference 
to `_D10containers12dynamicarray12__ModuleInfoZ'
/usr/bin/ld: bench.o:(.data.rel.ro+0x130): undefined reference 
to `_D10containers7hashmap12__ModuleInfoZ'
/usr/bin/ld: bench.o:(.data.rel.ro+0x138): undefined reference 
to `_D10containers7hashset12__ModuleInfoZ'
/usr/bin/ld: bench.o:(.data.rel.ro+0x140): undefined reference 
to `_D10containers11openhashset12__ModuleInfoZ'
/usr/bin/ld: bench.o:(.data.rel.ro+0x148): undefined reference 
to `_D10containers5slist12__ModuleInfoZ'
/usr/bin/ld: bench.o:(.data.rel.ro+0x150): undefined reference 
to `_D10containers7treemap12__ModuleInfoZ'
/usr/bin/ld: bench.o:(.data.rel.ro+0x158): undefined reference 
to `_D10containers5ttree12__ModuleInfoZ'
/usr/bin/ld: bench.o:(.data.rel.ro+0x160): undefined reference 
to `_D10containers12unrolledlist12__ModuleInfoZ'
/usr/bin/ld: bench.o:(.data.rel.ro+0x1c8): undefined reference 
to `_D10dateparser9timelexer12__ModuleInfoZ'
/usr/bin/ld: bench.o:(.data.rel.ro+0x1d0): undefined reference 
to `_D10dateparser3ymd12__ModuleInfoZ'
/usr/bin/ld: bench.o:(.data.rel.ro+0x1d8): undefined reference 
to `_D10dateparser11parseresult12__ModuleInfoZ'
/usr/bin/ld: bench.o:(.data.rel.ro+0x1e0): undefined reference 
to `_D10dateparser10parserinfo12__ModuleInfoZ'

/usr/bin/ld: bench.o: in function `_Dmain':
dateparser/package.d:(.text._Dmain[_Dmain]+0x1e): undefined 
reference to `_D10dateparser10parserinfo10ParserInfo7__ClassZ'
/usr/bin/ld: dateparser/package.d:(.text._Dmain[_Dmain]+0x2f): 
undefined reference to 
`_D10dateparser10parserinfo10ParserInfo6__ctorMFNfbbZCQBzQBqQBh'
/usr/bin/ld: bench.o: in function 
`_D3std4conv__T6toImplTEQv8datetime4date5MonthTSQBt8typecons__T8NullableTiViN2147483648ZQzZQCyFQBwZQCy':

dateparser/package.d:

.
.
.
collect2: error: ld returned 1 exit status
Error: linker exited with status 1


SDB@79


Re: bigEndian in std.bitmanip

2023-11-02 Thread Salih Dincer via Digitalmars-d-learn

On Tuesday, 31 October 2023 at 14:43:43 UTC, Imperatorn wrote:
It might make sense to change since little endian is the most 
common when it comes to hardware. But big endian is most common 
when it comes to networking. So I guess it depends on your view 
of what is most common. Interacting with your local hardware or 
networking.


I realized that I had to make my prefer based on the most common. 
But I have to use Union. That's why I have to choose 
little.Endian. Because it is compatible with both Union and 
HexString. My test code works perfectly as seen below. I'm 
grateful to everyone who helped here and [on the other 
thread](https://forum.dlang.org/thread/ekpvajiablcfueyip...@forum.dlang.org).


```d
enum sampleText = "Hello D!"; // length <= 8 char

void main()
{
  //import sdb.string : UnionBytes;
  mixin UnionBytes!size_t;
  bytes.init = sampleText;

  import std.digest: toHexString;
  auto hexF = bytes.cell.toHexString;
  assert(hexF == "48656C6C6F204421");

  import std.string : format;
  auto helloD = sampleText.format!"%(%02X%)";
  assert(hexF == helloD);

  import std.stdio;
  bytes.code.writeln(": ",  helloD); /* Prints:

  2397076564600448328: 48656C6C6F204421  */

  import std.conv : hexString;
  static assert(sampleText == hexString!"48656C6C6F204421");

  //import sdb.string : readBytes;
  auto code = bytes.cell.readBytes!size_t;
  assert(code == bytes.code);

  bytes.init = code;
  code.writeln(": ", bytes); /* Prints:

  2397076564600448328: Hello D!  */

  assert(bytes[] == [72, 101, 108, 108, 111, 32, 68, 33]);

  //import sdb.string : HexString
  auto str = "0x";
  auto hex = HexString!size_t(bytes.code);
  hex.each!(chr => str ~= chr);
  str.writeln; // 0x48656C6C6F204421
}
```

My core template (UnionBytes) is initialized like this, and 
underneath I have the readBytes template, which also works with 
static arrays:


```d
// ...
  import std.range : front, popFront;
  size_t i;
  do // new version: range support
  {
char chr;  // default init: 0xFF
chr &= str.front;  // masking
code |= T(chr) << (i * 8); // shifting
str.popFront;  // next char
  } while(++i < size);
}

auto opCast(Cast : T)() const
  => code;

auto opCast(Cast : string)() const
  => this.format!"%s";

auto toString(void delegate(in char[]) sink) const
  => sink.formattedWrite("%s", cast(char[])cell);

  }
  UnionBytes bytes; // for mixin
}

template readBytes(T, bool big = false, R)
{// pair endian version 2.1
  import std.bitmanip;

  static if(big) enum E = Endian.bigEndian;
  else enum E = Endian.littleEndian;

  import std.range : ElementType;
  alias ET = ElementType!R;

  auto readBytes(ref R dat)
  {
auto data = cast(ET[])dat;
return read!(T, E)(data);
  }
}
```

SDB@79


Re: Function Overloading

2023-11-02 Thread Salih Dincer via Digitalmars-d-learn

On Wednesday, 1 November 2023 at 20:04:52 UTC, Basile B. wrote:


Yes. D constructors are not named but the current 
implementation adds a name that is `__ctor`, so add


```d
alias add = __ctor;
```

to you struct.



Yeah, it works! Thanks...:)

SDB@79


Function Overloading

2023-10-31 Thread Salih Dincer via Digitalmars-d-learn

```d
struct Calculate
{
    int memory;
string result;

    auto toString() => result;

    this(string str)
    {
        add(str);
    }

    this(int num)
{
        add(num);
}

import std.string : format;

    void add(string str)
    {
        result ~= str.format!"%s + ";
    }

void add(int num)
    {
        memory += num;
        add(num.format!"%s");
    }
}

import std.stdio;
void main()
{
    // without constructor:
    Calculate c;
    c.add("x");
    c.add(2);
    c.writeln; // x + 2 +
    
    // with constructor:
    c = Calculate("x");
c.add(2);
    c.writeln; // x + 2 +
}
```

There is a simple struct like the one above that is not related 
to reality. There can be more than 2 function overloading in it, 
but in our example there are only 2. Without implementing a 
similar function again for each constructor; is it possible to do 
something like `alias add = this;`?


```d
struct Calculate
{
    int memory;
string result;

    auto toString() => result;

    // alias add = this;
    
import std.string : format;

    this(string str)
    {
        result ~= str.format!"%s + ";
    }

this(int num)
    {
        memory += num;
        add(num.format!"%s");
    }
}
```

SDB@79


Re: bigEndian in std.bitmanip

2023-10-31 Thread Salih Dincer via Digitalmars-d-learn
On Tuesday, 31 October 2023 at 10:24:56 UTC, Jonathan M Davis 
wrote:
On Tuesday, October 31, 2023 4:09:53 AM MDT Salih Dincer via 
Digitalmars-d- learn wrote:

Hello,

Why isn't Endian.littleEndian the default setting for read() in
std.bitmanip?


Why would you expect little endian to be the default? The 
typical thing to do when encoding integral values in a 
platform-agnostic manner is to use big endian, not little 
endian...


Because when we create a structure with a Union, it does reverse 
insertion with according to the static array(bytes) index; I 
showed this above.  I also have a convenience template like this:


```d
template readBytes(T, bool big = false, R)
{// pair endian version 2.0
  import bop = std.bitmanip;

  static if(big)
enum E = bop.Endian.bigEndian;
  else
enum E = bop.Endian.littleEndian;

  auto readBytes(ref R dat)
   => bop.read!(T, E)(dat);
}
```
Sorry to give you extra engage because I already solved the 
problem with readBytes(). Thank you for your answer, but there is 
1 more problem, or even 2! The read() in the library, which is 
2nd function, conflicts with std.write. Yeah, there are many 
solutions to this, but what it does is just read bytes. However, 
you can insert 4 ushorts into one ulong.


Don't you think the name of the function should be readBytes, not 
read?  Because it doesn't work with any type other than ubyte[]!


SDB@79



bigEndian in std.bitmanip

2023-10-31 Thread Salih Dincer via Digitalmars-d-learn

Hello,

Why isn't Endian.littleEndian the default setting for read() in 
std.bitmanip?


Okay, we can easily change this if we want (I could use enum LE 
in the example) and I can also be reversed with 
data.retro.array().


```d
void main()
{
  import std.conv : hexString;
  string helloD = hexString!"48656C6C6F204421";
  // compile time converted literal string -ˆ

  import std.string : format;
  auto hexF = helloD.format!"%(%02X%)";

  import std.digest: toHexString;
  auto arr = cast(ubyte[])"Hello D!";

  auto hex = arr.toHexString;
  assert(hex == hexF);

  import std.stdio : writeln;
  hex.writeln(": ", helloD);
// 48656C6C6F204421: Hello D!
  assert(helloD == "Hello D!");

  auto data = arr.readBytes!size_t;
  data.code.writeln(": ", data.bytes);
// 2397076564600448328: Hello D!
}

template readBytes(T, R)
{
  union Bytes
  {
T code;
char[T.sizeof] bytes;
  }
  import std.bitmanip;
  enum LE = Endian.littleEndian;

  auto readBytes(ref R data)
  {
   import std.range : retro, array;
   auto reverse = data.retro.array;
   return Bytes(reverse.read!T);
  }
}
```

However, I think it is not compatible with Union. Thanks...

SDB@79


Re: SlicedString Length

2023-10-20 Thread Salih Dincer via Digitalmars-d-learn

Good news!

I collected them in a template with the condition of running 
split() once at compile time.  The result seems perfect?  What 
are your thoughts?


```d
void main()
{
  auto slc = sliceOff!"abc def ghi";

  auto len = slc.length;
  slc.index = len;

  import std.stdio, std.algorithm: equal;
  assert(slc.equal(["abc", "def", "ghi"]));

  foreach(s; slc) s.write;
  writeln; // abcdefghi

  // Push Test
  with(slc)
  {
string test = "jkl";
push(test);

auto p = elementsPos[$ - 1];
assert(data[p[0]..p[1]] == test);
  }

  foreach(s; slc) s.write;
  writeln; // abcdefghijkl

  auto tmp = slc.dup;
  assert(tmp.front == "abc");
  tmp.popFront;
  assert(slc.front == "abc");
  assert(tmp.front == "def");
}

template sliceOff(string STR, string SEP = " ")
{
  auto sliceOff()
  {
SlicedString s;
s.popFront();
return s;
  }

  import std.array : split;
  import std.range : walkLength;
  enum LEN = STR.split(SEP).walkLength;

  struct SlicedString
  {
long index, back, next = -1;
size_t len = LEN;
string data = STR;

auto push(string data)
{
  this.data ~= SEP ~ data;
  len++;
  index++;
}

auto elementsPos()
{
  long[][] result;
  auto r = this.dup;
  while(!r.empty)
  {
result ~= [r.back, r.next];
r.popFront();
  }
  return result;
}

alias dup = save;
auto save() { return this; }
auto length() { return len; }
bool empty() { return index == 0; }
auto front() { return data[back..next]; }
void popFront()
{
  import std.string : find = indexOf;
  --index;
  back = ++next;
  next = data.find(SEP, next);
  if(next == -1)
  {
next = data.length;
  }
}
  }
}
```

SDB@79



SlicedString Length

2023-10-20 Thread Salih Dincer via Digitalmars-d-learn

Hi,

I have a string wrapper called SlicedString. What it does is very 
simple: Returning each piece as a slice with a assured separator 
at compile time by used indexOf() ! Here it is:


```d
struct SlicedString(string E)
{
  long index, back, next = -1;
  string data;

  auto length() const
  {
import std.array : split;
import std.range : walkLength;
return data.split(E).walkLength;
  }

  auto popIndex(ref SlicedString!E range)
  {
scope(exit) range.popFront();
return [range.back, range.next];
  }

  auto elementsPos()
  {
long[][] result;
auto r = SlicedString!E(index, back, next, data);

while(!r.empty)
{
  result ~= popIndex(r);
}
return result;
  }

  bool empty() { return index == 0; }
  auto front() { return data[back..next]; }
  void popFront()
  {
import std.string : find = indexOf;
--index;
back = ++next;
next = data.find(E, next);
if(next == -1)
{
  next = data.length;
}
  }
}

auto sliceOff(string E = " ")(string data)
{
  SlicedString!E s;
  s.data = data;
  s.popFront();

  return s;
}

// UNIT TESTS:

void main()
{
  auto str = "abc def ghi";
  auto slc =  str.sliceOff;

  auto len = slc.length;
  slc.index = len;

  import std.stdio, std.algorithm: equal;
  assert(slc.equal(["abc", "def", "ghi"]));

  // Print range:
  foreach(s; slc) s.write;
  writeln;

  // Print Elements Position
  slc.elementsPos.writeln;
  slc.elementsPos.writeln;
}
```

The unit tests work as I want, but I find calculating the length 
with split() too expensive; despite walkLength()...



Is there a more accurate method? Last year, Ali Çehreli told me 
that splitter() was also possible, but then he did something with 
map(). I really don't understand these!


Thanks...

SDB@79



Re: How to use ".stringof" to get the value of a variable and not the name of the variable (identifier) itself?

2023-10-17 Thread Salih Dincer via Digitalmars-d-learn

On Sunday, 15 October 2023 at 07:22:53 UTC, Imperatorn wrote:


You already got a lot of good answers, I thought I'd just share 
this for anyone searching for nogc string formatting compatible 
with betterC:


https://code.dlang.org/packages/bc-string


Doesn't it make more sense to use [ParseResult!T parse(T)(cstring 
str)](https://github.com/tchaloupka/bc-string/blob/master/source/bc/string/conv.d) instead of nested if's here:

https://github.com/tchaloupka/bc-string/blob/master/source/bc/string/numeric.d

Thanks,

SDB@79


Re: How to use ".stringof" to get the value of a variable and not the name of the variable (identifier) itself?

2023-10-09 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 9 October 2023 at 16:33:32 UTC, rempas wrote:
I'm trying to create a series of function. There will be ten of 
them, and they will be called `function_0`, `function_1`, etc. 
However, in my example, "stringof" returns the character "i" 
itself and turns that into a string instead of getting its 
actual value (number).


Any ideas how I can achieve what I'm trying to achieve?


Great masters generally warn to stay away from stringof. Please 
do not use it as much as possible. The following code snippet 
will be useful to you:


```d
alias CN = __traits(allMembers, CardinalNumbers);

static foreach(i; CN)
{
  mixin(create_fn!(i[1]));
}

enum create_fn(char num) = `
  auto function_`~ num ~`()
    => "Hello from function `~ num ~`!";
`;

enum CardinalNumbers
{
  n0, n1, n2, n3, n4, n5, n6, n7, n8, n9
}

void main()
{
  assert(function_9() == "Hello from function 9!");
}
```

SDB@79


Re: Type constraint

2023-10-09 Thread Salih Dincer via Digitalmars-d-learn

On Tuesday, 3 October 2023 at 14:35:31 UTC, Joel wrote:

Oh, I found,
```d
static if (isIntegral!T)
```
seems to work.


If you are using a struct, another way to affect the whole is as 
follows:


```d
struct S(T)
{

  invariant() {
      static assert(isIntegral!T);
  }

  auto addUp() { /**/ }
}
```
For detailed information and examples, please continue here:

https://tour.dlang.org/tour/en/gems/contract-programming

SDB@79


Re: Type constraint

2023-10-09 Thread Salih Dincer via Digitalmars-d-learn

On Sunday, 8 October 2023 at 10:09:02 UTC, IchorDev wrote:

On Wednesday, 4 October 2023 at 01:46:42 UTC, Joel wrote:
I think the if without static is still static, since it's part 
of the function name part, or so (outside of the curly bracket 
scope).


You can't have regular if-statements inside templates. Regular 
if-statements are checked at runtime but templates only exist 
at compile-time.


The way to write a *template constraint*—which is what you 
want, and uses the `if` keyword—is thus:


```d
struct List(T)
if(__traits(isIntegral, T)){
  auto addUp()
//(Add numbers)
  }
}
```
Notice that the curly brace for the template comes after the 
template constraint, and that there are only 2 curly braces 
rather than the 3 from your example.


This snippet does not compile.  The curly brackets must be an 
even number, that is, they must terminate each other.


SDB@79


Re: how to assign multiple variables at once by unpacking array?

2023-10-08 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 9 October 2023 at 01:15:21 UTC, Salih Dincer wrote:
the staticMapN() template implemented by Ali Çehreli, which is 
not in the standard library, is needed:




It would be great if the unlimited version was added to std.meta. 
 This template seeded/sprouted in here:


https://forum.dlang.org/thread/vwxilrqgjqtvjrnjj...@forum.dlang.org

SDB@79




Re: how to assign multiple variables at once by unpacking array?

2023-10-08 Thread Salih Dincer via Digitalmars-d-learn

On Saturday, 7 October 2023 at 16:12:47 UTC, mw wrote:
Interesting: in terms of easy of coding, clarity and future 
maintenance, which one is superior?


The one liner in Python, or your "solution" with dozen lines of 
code? BTW, is that a solution at all? Did it achieved what the 
original goal asked in the OP question?


So, who should learn from whom?


If you don't expect to do a single line of coding, there are many 
methods in D that can do this kind of thing (but at compile time).


**Your snippet with struct and tupple:**

```d
import std;

struct MyVariables
{
  int age, phone, country;
}

void main()
{
  enum sep = ", ";
  enum str = "21, 3149474, 90";
  enum arr = str.split(sep)
                .map!(x => x.to!int)
.array//*/
;
  alias MrSmith = AliasSeq!(arr[0],
                            arr[1],
                            arr[2]);

  auto mv = MyVariables(MrSmith);
  assert(mv == MyVariables(21, 3149474, 90));
}
```

and **worksheet example:**


```d
import std;

struct DATA(string str, T, size_t s)
{
  enum title = str;
  T[s] data;
}

void main()
{
  alias Columns = AliasSeq!("Stock Name", "PN Codes", "P.Prices");
  alias T = AliasSeq!(string, int, double);
  alias Items = AliasSeq!(4, 8, 8);
  
  staticMapN!(3, DATA, Columns, T, Items) worksheet;
  
  // inputs first column:
  worksheet[0].data = ["capacitor", "transistor", "resistor", 
"varistor"];

  
  // prints column titles:
  foreach(s; worksheet)
    s.title.writef!"%14s";
  
  "=".repeat(42).writefln!"\n%-(%s%)";
  
  // prints first column:
  foreach(name; worksheet[0].data)
    name.writefln!"%14s";
    //...
  "=".repeat(42).writefln!"%-(%s%)";
}/* Prints:
Stock Name  PN Codes  P.Prices
==
 capacitor
transistor
  resistor
  varistor
==
*/
```

By the way, in order for the above code snippet to work, the 
staticMapN() template implemented by Ali Çehreli, which is not in 
the standard library, is needed:


```d
template staticMapN(size_t N, alias fun, args...)
if(args.length % N == 0)
{
  alias staticMapN = AliasSeq!();
  static foreach (i; 0..args.length / N)
  {
static if (N == 1)
{
  staticMapN = AliasSeq!(staticMapN, fun!(
args[i]
      ));}
  
    else static if (N == 2)
{
staticMapN = AliasSeq!(staticMapN, fun!(
args[0..$ / N][i],
args[$ / N..($ / N) * 2][i]
      ));}
  
else static if (N == 3)
{
  staticMapN = AliasSeq!(staticMapN, fun!(
args[0..$ / N][i],
args[$ / N..($ / N) * 2][i],
args[($ / N) * 2..($ / N) * 3][i]
  ));}
  }
}
```
SDB@79




Re: how to assign multiple variables at once by unpacking array?

2023-10-07 Thread Salih Dincer via Digitalmars-d-learn

On Saturday, 7 October 2023 at 07:31:45 UTC, mw wrote:

https://stackoverflow.com/questions/47046850/is-there-any-way-to-assign-multiple-variable-at-once-with-dlang

How to do this Python code in D:

```

s = "1 2 3"
A,B,C = map(int, s.split(" "))
A,B,C

(1, 2, 3)

```

Is there a better way (since 2017)?


My words to those who come from Python:

If you are making money from Python, please stay there, but if 
you want to learn new things and a modern language, "Welcome to D"


and please use Tuples :)

```d
import std.typecons, std.stdio;

struct DICT(C, F, S)
{
  S[C] dict;
  C[F] freq;

  void opAssign(Tuple!(C, F, S) chr) {
dict[chr[0]] = chr[2];
freq[chr[1]] = chr[0];
  }

  string toString() const
  {
import std.array : appender;
import std.algorithm : sort;
import std.format : formattedWrite;

auto r = appender!string;
foreach(f; freq.keys.sort!"a>b") {
  auto key = freq[f];
  r.formattedWrite("(%c) %s, %.1f\n",
key, dict[key], f);
}
return r.data;
  }
}

void main()
{
  alias index = char;
  alias rank = float;
  alias name = string;

  alias Dict = DICT!(index, rank, name);
  alias chr = Tuple!(index, rank, name);

  auto chrs = [ chr(44, 61.3, "Comma"),
chr(34, 26.7, "Doublequote"),
chr(39, 24.3, "Apostrophe"),
chr(45, 15.3, "Hyphen"),
chr(63,  5.6, "Question"),
chr(58,  3.4, "Colon"),
chr(33,  3.3, "Exclamation"),
chr(59,  3.2, "Semicolon")
  ];

  Dict enDict;
  foreach(tup; chrs) //multiple insertion
enDict = tup;

  writeln("Frequency distributions of punctuation marks used in 
English: ");

  enDict = chr(46, 65.3, "Dot"); // single insertion
  enDict.writeln;
}
```

SDB@79


Re: The difference between T[] opIndex() and T[] opSlice()

2023-10-05 Thread Salih Dincer via Digitalmars-d-learn

On Thursday, 5 October 2023 at 16:40:49 UTC, Gaurav Negi wrote:
Well, in the D programming language, both opIndex and opSlice 
are two different operators used to access elements of a custom 
type.


Yeah, D is on its way to becoming a near-perfect programming 
language...


```d
enum initialSituation = [1, 2, 3];
import std.stdio;

void main()
{
  auto s = S(initialSituation);

  s[] = 1;
  s[1] = 2;
  s[2] += 2;
  
  assert(s.arr == initialSituation);

  auto d = s *= 2;
  
  assert(d == S([2, 4, 6]));
}
/* Prints:
[1, 1, 1]: onlineapp.S.opSliceAssign
[1, 2, 1]: onlineapp.S.opIndexAssign
[1, 2, 1]: onlineapp.S.opIndex
[2, 4, 6]: onlineapp.S.opOpAssign!"*".opOpAssign
*/

struct S
{
  int[] arr;

  auto opSliceAssign (int value)
  {
    scope(exit)
    {
      writefln("%s: %s", arr, __FUNCTION__);
    }
    return arr[] = value;
  }

  auto opIndexAssign(int value, int index)
  {
scope(exit)
    {
      writefln("%s: %s", arr, __FUNCTION__);
    }
    arr[index] = value;
  }

  ref opIndex(size_t index)
  {
scope(exit)
    {
      writefln("%s: %s", arr, __FUNCTION__);
    }
    return arr[index];
  }

  ref opOpAssign(string op)(int value)
  {
    scope(exit)
    {
      writefln("%s: %s", arr, __FUNCTION__);
    }
    mixin("arr[] " ~ op ~ "=value;");
    return this;
  }
}
```

SDB@79


Re: opIndexAssign

2023-10-05 Thread Salih Dincer via Digitalmars-d-learn

On Thursday, 5 October 2023 at 12:00:22 UTC, Timon Gehr wrote:



void opIndexAssign(int value, int index){ i[index] = value; }


In this case I need to define many operator overloads. For 
example (+=), this won't work without returns ref:


```d
  s[1] += 3;
  assert(s.i == [2, 45]);
// Error: no `[]` operator overload for type `S`
```
SDB@79



Re: The difference between T[] opIndex() and T[] opSlice()

2023-10-03 Thread Salih Dincer via Digitalmars-d-learn

On Tuesday, 3 October 2023 at 18:09:55 UTC, Imperatorn wrote:
At the very least, the spec should do a better job of 
documenting when the compiler will try a fallback and when it 
won't.


Who will be the hero and add the documentation? 



More importantly, is there a priority order?  Because in our last 
example, when we leave a single overload, all features are 
executed through the ref opIndex except the bit:


```d
struct S
{
  int[] i;

  ref opIndex(size_t index) => i[index];

  //void opIndexAssign(int value) { i[] = value; }
  //void opIndexAssign(int value, size_t idx) { i[idx] = value; }
}

void main()
{
  auto s = S([2, 2]);

  s[0] = 2;
  assert(s.i == [2, 2]);

  s[1] = 42;
  assert(s.i == [2, 42]);

  s[0]++;
  assert(s.i == [3, 42]);

  s[0] += 1;
  assert(s.i == [4, 42]);
}
```

So the important thing is: Who is dominant when another overload 
comes into play?


SDB@79


Re: Key and value with ranges

2023-10-02 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 2 October 2023 at 20:20:44 UTC, Joel wrote:


I want the output sorted by value.


Look: 
https://forum.dlang.org/post/qjlmiohaoeolmoavw...@forum.dlang.org


```d
struct SIRALA(T) { }
```

You can use SIRALA(T).  Okay, his language is Turkish but our 
common language is D. His feature is that he uses double AA.  You 
will like it.  Here is the source:


https://gist.github.com/run-dlang/808633909615dbda431baa01f795484f

SDB@79





opIndexAssign

2023-10-02 Thread Salih Dincer via Digitalmars-d-learn

Hi,

opIndexAssign, which is void, cannot compromise with opIndex, 
which is a ref!  Solution: Using opSliceAssign.  Could this be a 
bug?  Because there is no problem in older versions (e.g. 
v2.0.83).


```d
struct S
{
  int[] i;

  ref opIndex(size_t index) => i[index];

  auto opSliceAssign/*
  auto opIndexAssign//*/
  (int value) => i[] = value;
}

void main()
{
  auto s = S([1, 2]);

  s[] = 2;
  assert(s.i == [2, 2]);

  s[1] = 42;
  assert(s.i == [2, 42]);
}
```
**Source:** https://run.dlang.io/is/G3iBEw
If you converted comment line 7 with // and you will see this 
error:


onlineapp.d(19): Error: function `onlineapp.S.opIndexAssign(int 
value)` is not callable using argument types `(int, int)`

onlineapp.d(19):expected 1 argument(s), not 2


SDB@79


Re: The difference between T[] opIndex() and T[] opSlice()

2023-10-02 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 2 October 2023 at 20:42:14 UTC, Paul Backus wrote:


I don't know what's wrong in your example but this works for me:



I found the reason for the error:

https://forum.dlang.org/thread/vckvftkdzcrnikudu...@forum.dlang.org

SDB@79


Re: The difference between T[] opIndex() and T[] opSlice()

2023-10-02 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 2 October 2023 at 16:05:39 UTC, Paul Backus wrote:


`T[] opSlice()` is the D1 version and exists only for backwards 
compatibility. You should use `T[] opIndex()` in new code.



Forgive me for asking again, I think opSliceAssign(T value) has 
also been improved, right?

```d
   // ...

   auto opSlice()
   {
 return elements[];
   }

   auto opSliceAssign(T value)
   {
 foreach(i; 0 .. length)
 {
   ptr[i] = value;
 }
   }
 }
```
In an old version (for example, v2.0.83), the code you 
implemented in the places where Slice is written above works as 
desired.  In the most current versions, the parameterized 
opIndexAssign(T value) gives the error:


onlineapp.d(51): Error: function 
`onlineapp.Matrix!double.Matrix.opIndexAssign(double value)` is 
not callable using argument types `(double, ulong)`

onlineapp.d(51):expected 1 argument(s), not 2


**Source:** https://run.dlang.io/is/TPAg5m

Thanks...

SDB@79


Re: The difference between T[] opIndex() and T[] opSlice()

2023-10-02 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 2 October 2023 at 02:01:34 UTC, Jonathan M Davis wrote:


For most code, you'd just write an opIndex with a single 
parameter for indexing an element, opSlice with two parameters 
for slicing the range or container, and then either opIndex or 
opSlice with no parameters to return a slice of the entire 
container (in which case, personally, I'd use opSlice, because 
semantically, that's what you're doing, but either should work 
IIRC).


Overloading has nothing to do with indexing, so I'll use opSlice.

```d
import std.stdio;
import std.range;

struct Matrix(T)
{
  private T[][] elements;
  size_t length;
  T* ptr;

  this(size_t length)
  {
this.length = length * length;
size_t m = T.sizeof * this.length;
ubyte[] arr = new ubyte[](m);

ptr = cast(T*)arr.ptr;
m /= length;

foreach(i; 0 .. length)
{
  size_t n = i * m;
  elements ~= cast(T[])arr[n .. n + m];
}
  }

  ref T opIndex(size_t i)
  in(i < length)
    => ptr[i];

  auto opDollar() => length;
  auto opSliceAssign(T value, size_t a, size_t b)
  in(a <= length && b <= length)
    => ptr[a..b] = value;

  auto opSlice() => elements;
  auto opSliceAssign(T value)
  {
    foreach(i; 0 .. length)
{
  ptr[i] = value;
}
  }
}

void main()
{
  auto arr = Matrix!double(3);
  size_t n;

  foreach(value; iota(0.1, 1, 0.1))
    arr[n++] = value;
  
  arr[].writefln!"%-(%-(%s %)\n%)\n";
  
  arr[0..$/2] = 0;   // reset a slice

  arr[].writefln!"%-(%-(%s %)\n%)\n";

  arr[] = 0;             // reset all
  
  arr[].writefln!"%-(%-(%s %)\n%)\n";
  
  arr[6..9] = 1;       // set a slice
  arr[].writefln!"%-(%-(%s %)\n%)\n";
}
```

SDB@79


Re: The difference between T[] opIndex() and T[] opSlice()

2023-10-01 Thread Salih Dincer via Digitalmars-d-learn

On Sunday, 1 October 2023 at 17:41:08 UTC, Salih Dincer wrote:

Also, is it correct to use [] when returning?

Thanks...




[Here](https://dlang.org/spec/operatoroverloading.html#slice), 
the opIndex() is proposed and an example of parameterized the 
opSlice() is given for multidimensional arrays.  Like there's no 
difference, huh?


Puff :)


The difference between T[] opIndex() and T[] opSlice()

2023-10-01 Thread Salih Dincer via Digitalmars-d-learn

Hi,

What is the difference between T[] opIndex() and T[] opSlice(), 
which haven't parameters?


```d
struct S(T)
{
    T[] arr;
    
    T[] opIndex() => arr[];/*
    T[] opSlice() => arr;//*/
}

alias Type = int;
void main()
{
    auto s = S!Type([1,2,3]);
    auto arr = s[]; // calls s.opIndex()
    
assert(arr == [1,2,3]);
    assert(is(typeof(arr): Type[]));
}
```

Also, is it correct to use [] when returning?

Thanks...


Re: Dinamyc arrays

2023-09-17 Thread Salih Dincer via Digitalmars-d-learn

On Sunday, 17 September 2023 at 17:15:34 UTC, Timofey wrote:

I`ve just started learning d and have a question.
What should I write to set dinamyc rectangular array length in 
both dimentions?

For example, I have declareted an array:
```   int[][] matrix;```
and want set it as n*n matrix.
Thanks



There are many ways to do this, but I can quickly show you two:

```d
import std.stdio;
void main()
{
int[][] matrix;
    enum n = 6;

// method 1:
    //matrix = new int[][](n, n); /*

// method 2:
    matrix.length = n;
    foreach(ref e; matrix)
        e.length = n;//*/
    
matrix.writeln;
}
```

SDB@79


Re: Setting struct as default parameter of a function using struct literal?

2023-09-12 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 11 September 2023 at 23:47:33 UTC, H. S. Teoh wrote:
Since the type of the parameter is already known, the compiler 
does not need me to repeat the type name. It already knows 
enough to figure it out on its own.  "Don't Repeat Yourself" 
(DRY).


I think there are 3 possibilities, leaving aside what Steven 
suggested.  Well, since these options will generally be static, 
why not use a template parameter?  Besides, everything can be 
expressed with a single letter. For example:


```d
// Steven suggested...
void multiParams(bool silenceErrors = false, bool otherOption = 
true)

{
  writeln;
}

// (1) It cannot be customized.
auto someFunction(Options option = Options.init) => option;//*/

/*/ (2a) It doesn't run older versions:
auto someFunction(Options option = Options(silenceErrors: false)) 
=> option;//*/


/*/ (2b) There's a possibility of confusion:
auto someFunction(Options option = Options (false, false) => 
option;//*/


struct Options
{
  bool silenceErrors = true;
  bool printDebugs = true;

  string toString() => format("silenceErrors: %s\nprintDebugs: 
%s", silenceErrors, printDebugs);

}

import std.format, std.stdio;
void main()
{
  auto foo(T, T option = T.init)() => option;

  writeln(foo!Options);
  writeln(someFunction);
}
```

SDB@79


Re: Setting struct as default parameter of a function using struct literal?

2023-09-11 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 11 September 2023 at 22:13:25 UTC, H. S. Teoh wrote:


Because sometimes I want a specific type.



it's possible...

```d
alias ST = Options;
void specificType(ST option = ST())
{
  if(option)
  {
assert(false);
  } else
assert(true);
}

void main()
{
  specificType(); // No error
  specificType(ST.silenceErrorsOn); // assert failure
}
```

SDB@79


Re: Setting struct as default parameter of a function using struct literal?

2023-09-11 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 11 September 2023 at 20:17:09 UTC, H. S. Teoh wrote:


Someone should seriously come up with a way of eliminating the 
repeated type name in default parameters.


Why not allow it to be flexible enough by using a template 
parameter?


```d
enum Options : bool
{
  silenceErrorsOff, silenceErrorsOn
}

struct Opts
{
  bool silenceErrors;
}

void someFunction(T)(T option = T())
{
  import std.stdio;
  writeln(cast(bool)option); // true
}

void main()
{
  Opts o;
  someFunction(o.silenceErrors = true);

  with(Options)
  someFunction(silenceErrorsOn);
}
```
SDB@79


Re: Setting struct as default parameter of a function using struct literal?

2023-09-11 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 11 September 2023 at 17:51:04 UTC, BoQsc wrote:


Here is an example of what I would hope for to work but it 
surely does not work:


If I were you I would use enum, look at my code:

```d
enum Options
{
  silenceErrors = false
}

void someFunction (Options option = Options.silenceErrors)
{
  writeln(cast(bool)option); // false
}

import std.stdio;
void main()
{
  someFunction();
}
```

SDB@79



Re: class Object with Dependency Injection

2023-06-18 Thread Salih Dincer via Digitalmars-d-learn

On Sunday, 18 June 2023 at 16:58:15 UTC, Ali Çehreli wrote:
The problem is with the deduced type of 'services'. I don't 
know the mechanism behind it but the common type of 'truck' and 
'ship' are deduced to be Object. Apparently, their interfaces 
don't take part in that decision. I don't know why.


This is very interesting because it looks like a bug.  Why is 
there no problem in an abstracted object, but things get confused 
in the interface (ITransport)?


On Sunday, 18 June 2023 at 16:58:15 UTC, Ali Çehreli wrote:
One solution is to help the compiler by casting them to your 
desired interface:


In fact, there is no need to cast:

```d
interface ITransport
{
  string deliver();
}

//...

void main()
{
  auto truck = new Truck;
  ITransport ship = new Ship;

/* or
  ITransport truck = new Truck;
  auto ship = new Ship;

// or

  ITransport truck = new Truck;
  ITransport ship = new Ship;//*/
}
```

SDB@78


class Object with Dependency Injection

2023-06-18 Thread Salih Dincer via Digitalmars-d-learn
Hi, below is an example of DI-dependency injection with 3 
versions nested in the code. If you remove the leading // 
characters, you will not get the "no property `deliver` for 
`service` of type `object.Object`" error.  Because version-2I 
with interface wants its methods to depend on Object..


```d
//abstract class /* toggle-code
interface //* ^---version 2A */
ITransport
{
  string deliver();
}

class Ship : ITransport
{
  override string deliver()
  {
return "Ship Deliver";
  }
}

class Truck : ITransport
{
  override string deliver()
  {
return "Truck Deliver";
  }
}

abstract class Logistics
{
  ITransport createTransport();

  auto operations()
  {
return createTransport.deliver();
  }
}

class RoadLogistics : Logistics
{
  override ITransport createTransport()
  {
return new Truck();
  }
}

class SeaLogistics : Logistics
{
  override ITransport createTransport()
  {
return new Ship();
  }
}

import std.stdio;
void main()
{
  // DI version 1:
  auto sl = new SeaLogistics;
  auto rl = new RoadLogistics;

  auto logistics = [ sl, rl ];
  foreach(deliver; logistics)
  {
auto str = deliver.operations();
str.length.writeln(": ", str);
  }

  import std.range : repeat;
  "÷ ".repeat(9).writefln!"%-(%s%)";

  // A->I version 2:
  auto truck = new Truck;
  auto ship = new Ship;

  auto services = [ truck, ship ];
  foreach(service; services)
  {
auto str = service.deliver();
str.length.writeln(": ", str);
  }
}
```
Maybe using an abstract class instead of interface or not using 
auto will solve the problem, but I can't accept the situation!  I 
wonder what makes the interface special?


SDB@79



Re: byte and short data types use cases

2023-06-10 Thread Salih Dincer via Digitalmars-d-learn

On Friday, 9 June 2023 at 23:51:07 UTC, Basile B. wrote:
Yes, a classsic resource is 
http://www.catb.org/esr/structure-packing/


So you can optimize memory usage by using arrays of things 
smaller than `int` if these are enough for your purposes,


So, is the sorting correct in a structure like the one below with 
partial overlap?


```d
struct DATA
{
union
{
ulong bits;
ubyte[size] cell;
}
enum size = 5;
bool last;
alias last this;

size_t length, limit, index = ulong.sizeof;

bool empty()
{
return index / ulong.sizeof >= limit; }

ubyte[] data;
ubyte front()
{
//..
```
This code snippet is from an actual working my project.  What is 
done is to process 40 bits of data.


SDB@79



Re: Proper way to handle "alias this" deprecation for classes

2023-05-17 Thread Salih Dincer via Digitalmars-d-learn

On Wednesday, 17 May 2023 at 08:00:17 UTC, Dom DiSc wrote:

If you want auto-conversion, you should be more explicit:
```d
float opCast() { }
```
because if you return "auto" it is not the highest-prio fit and 
therefore not chosen.
If you have multiple choices, you still don't need to use 
"auto". Instead you can return T:

```d
T opCast(T)() if(isFloatingPoint!T)
{
   return cast(T)num / cast(T)den; // float, double or real
}
```
Kind of ironic, but especially "auto" does NOT fit 
automatically :-)


Sorry for not expressing myself better.  Let me try to explain 
with another example:


```d
struct RightShift
{
  int num, shr;

  T opCast(T : char)()
   => cast(T)(num >> shr);
}
import std.stdio;
void main()
{
  auto f = RightShift(128, 2);
  char chr = cast(char)f | '\1';
  assert(chr == '!');
  
  //char test = f; // Error: cannot implicitly convert expression
  //assert(test == ' '); // `f` of type `RightShift` to `char`
}
```

This snippet works fine.  But hidden the code gives an error.  
The reason is that the compiler ignores the explicitly specified 
lines without using auto.


SDB@79


Re: Proper way to handle "alias this" deprecation for classes

2023-05-12 Thread Salih Dincer via Digitalmars-d-learn

On Sunday, 7 May 2023 at 21:04:05 UTC, Inkrementator wrote:
Open question to everybody: What you're opinion on using opCast 
for this? Since it's a type conversion, it seems fitting to me.


Can't converting without explicitly specifying in D is a big 
shortcoming in my opinion. There is such a thing as implicitly 
convertion though, but it's very confusing. I don't see that 
simplicity in C++ in the D codes!


```CPP
#include 
using namespace std;
struct Fraction {
int num, den;

Fraction(int n, int d) {
num = n;
den = d;
}

// Conversion operator: return float value of fraction
operator float() const
{
return float(num) / float(den);
}
};

int main()
{
Fraction f(2, 5);
float val = f;
cout << val << '\n'; // 0.4
return 0;
}
```

You should do the same in D like this:

```d
struct Fraction {
int num, den;

this(int n, int d)
{
num = n;
den = d;
}

// Cast Expression : convert float value of fraction
auto opCast(T : float)() const
{
return cast(float)(num) / cast(float)(den);
}
}

import std.stdio;

int main()
{
auto f = Fraction(2, 5);
float val = cast(float)f;
val.writeln; //0.4
return 0;
}
```

SDB@79



Re: Getting a total from a user defined variable

2023-04-21 Thread Salih Dincer via Digitalmars-d-learn

On Friday, 21 April 2023 at 05:23:14 UTC, Joel wrote:


Or: p.map!"a.age".sum; works too.


If it was me I would use each().  But D is such a powerful 
language that you have many alternatives:


```d
import std.algorithm, std.range, std.stdio;

struct Person { string name; int age; }
auto totalPersonAge = (int result, Person person)
=> result + person.age;
void main()
{
auto p = [
 Person("Kocaeli", 41),
 Person("Konya", 42)
];

p.map!(a => a.age).reduce!"a + b".writeln;
p.map!"a.age".reduce!"a + b".writeln;

auto result = reduce!((a, b) => a + b.age)(0, p);
result.writeln;

assert(result == reduce!totalPersonAge(0, p));
assert(result == p.fold!totalPersonAge(0));
assert(p.map!(a => a.age).sum == p.map!"a.age".sum);


size_t total;
p.each!( (ref person) => total += person.age);
total.writeln;
}
```
SDB@79


Re: Variable length arrays under -betterC?

2023-04-17 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 17 April 2023 at 19:12:20 UTC, user456 wrote:

... but you'll have to implement

- ctors
- concat assign
- slice assign
- copy construction
- value type elem alignment
- default elem construction
- default elem destruction
- etc.

to make that usable in on trivial cases.


I understand from the thread this: D gives us -betterC but 
nothing from the Phobos.  So he says, see what you have, do what 
the hell you want!


Am I wrong about this?

SDB@79


Re: vibe.db.postgresql: Example not working in Windows

2023-04-14 Thread Salih Dincer via Digitalmars-d-learn

On Friday, 14 April 2023 at 17:06:36 UTC, Vino wrote:
 I was just trying the new package vibe.db.postgresql and the 
example provided is not working, can some one provide me an 
working example.


Step performed
```
dub init
dub add vibe-d-postgresql
copy the example program to source/app.d
dub run
```


I would like to draw your attention to this point:

```d
#!/usr/bin/env dub
/+ dub.sdl:
dependency "vibe-d" version="~>0.9.0"
+/
void main()
{
import vibe.d;
listenHTTP(":8080", (req, res) {
res.writeBody("Hello, World: " ~ req.path);
});
runApplication();
}
```

Do you have a working vibe app?

SDB@79


Re: Unresolvable dependencies to package

2023-04-14 Thread Salih Dincer via Digitalmars-d-learn

On Friday, 14 April 2023 at 20:30:56 UTC, el machine code wrote:
so my question why am i'm getting this error and how do i fix 
this?


As far as I know imGUI works with SFML.  First, please appear a 
Japanese flag on your screen:


https://forum.dlang.org/post/apledbmyzlxsdaaow...@forum.dlang.org

SDB@79


Re: How to setup D with SFML? (using bindbc-sfml)

2023-04-14 Thread Salih Dincer via Digitalmars-d-learn

On Friday, 14 April 2023 at 12:26:25 UTC, Ki Rill wrote:
Yay! That worked! Now I have a working example. Though it's 
strange that it does not work with shared libs.


Good luck, I'm really happy for you...

Ki Rill, wait a minute!  Actually, i've been  very happy for the 
D community.  Because I really appreciate what you've done.  You 
are an idealistic person and please stay that way.  We can do 
more things.


SDB@79


Re: How to setup D with SFML? (using bindbc-sfml)

2023-04-13 Thread Salih Dincer via Digitalmars-d-learn

On Friday, 14 April 2023 at 00:28:53 UTC, Ki Rill wrote:

```
LINK : fatal error LNK1104: cannot open file 'libucrt.lib'
Error: linker exited with status 1104
```

Why does it require this library and where can I find it?


Since this library is a component of the Microsoft C Runtime 
(CRT) library, you may need to install this library.


To install the CRT library, follow these steps:

* Download and install the latest version of Microsoft Visual 
Studio.
* In the Visual Studio installer, install the "C++ Universal CRT" 
component under "Workloads > Desktop development with C++".

* Restart the build and check if the error is resolved.

**Source:** 
https://stackoverflow.com/questions/44763817/link-fatal-error-lnk1104-cannot-open-file-ucrt-lib


SDB@79


Re: Assocative array lookup for object

2023-04-12 Thread Salih Dincer via Digitalmars-d-learn

On Wednesday, 12 April 2023 at 13:09:07 UTC, Ali Çehreli wrote:
Not every type is null'able but nullable. ;) So, a design may 
use the following:

https://dlang.org/library/std/typecons/nullable.html


I implemented Handler into the Voldermort build, which Walter 
loved so much.  For convenience, I put an alias between the 
template and the function.  But Nullable didn't work, instead 
it's returning T.init...


```d
template Handler(alias A)
{
  alias T = typeof(A);

  auto Handler()
  {
struct Impl
{
  T*[string] data;

  void set(string key, ref T value)
  {
data[key] = 
  }

  auto opIndex(string key)
  {
if (auto ret = key in data)
{
  return **ret;
}
return T.init;/*
import std.typecons : Nullable;
return Nullable!T.init;//*/
  }

  auto opSlice()
  {
T[] result;
foreach (ref value; data.values)
  result ~= *value;
return result;
  }
}
return Impl();
  }
}

import std.stdio;

void main()
{
  struct List { string product; float price; }

  auto fruits = [ List("Manderin", 3.79),
  List("Orange", 2.99),
  List("Kiwi", 0.59),
  ];

  auto handlers = Handler!fruits;
  handlers.set("fruits", fruits);
  // please try it:  ^--v
  foreach(h; handlers["fruit"])
  {
h.product.write(": ");
h.price.writeln(" €");
  }

  auto handler = Handler!(List());

  import std.conv : text;
  foreach(i, ref fruit; fruits)
  {
handler.set(i.text, fruit);
  }
  handler[].writeln;
} /* Prints:

  Manderin: 3.79 €
  Orange: 2.99 €
  Kiwi: 0.59 €
  [List("Kiwi", 0.59), List("Manderin", 3.79), List("Orange", 
2.99)]


*/
```

SDB@79



Re: Assocative array lookup for object

2023-04-12 Thread Salih Dincer via Digitalmars-d-learn

On Wednesday, 12 April 2023 at 04:57:58 UTC, Salih Dincer wrote:

I think you want to do an encapsulation like below.

```d
  auto opIndex(string key)
    => *(key in data);
```


I made a little mistake and I'll fix it before someone rub nose 
in it :)


```d
  auto opIndex(string key) {
if(auto ret = key in data)
{
  return *ret;
}
return null;
  }

  assert(handler["D Lang"] == );
  assert(handler["null"] is null);
```

SDB@79




Re: How to setup D with SFML? (using bindbc-sfml)

2023-04-12 Thread Salih Dincer via Digitalmars-d-learn

On Tuesday, 11 April 2023 at 10:24:09 UTC, Ki Rill wrote:

My `dub.json`:
```Json
{
"authors": [
"rillki"
],
"copyright": "Copyright © 2023, rillki",
"dependencies": {
"bindbc-sfml": "~>1.0.2"
},
"description": "D/SFML project template",
"license": "BSL",
"name": "d-sfml-project-template",
"targetPath": "bin",
"versions": [
"SFML_Audio",
"SFML_Graphics",
"SFML_Network",
"SFML_System",
"SFML_Window",
"SFML_250"
]
}
```

I will try to make it work... Meanwhile, if someones spots what 
I am doing wrong, please reply to this post.


If I use your dub.json, my terminal screen says:


user@debian:~/Downloads$ cd dsfml
user@debian:~/Downloads/dsfml$ dub
Fetching bindbc-sfml 1.0.2 (getting selected version)
 Fetching bindbc-loader 1.0.3 (getting selected version)
 Starting Performing "debug" build using /usr/bin/dmd for 
x86_64.

 Building bindbc-loader 1.0.3: building configuration [noBC]
 Building bindbc-sfml 1.0.2: building configuration 
[dynamic]
 Building d-sfml-project-template ~master: building 
configuration [application]

  Linking d-sfml-project-template
  Running bin/d-sfml-project-template
Error Program exited with code -11


If I add "BindSFML_Static" to the DUB's version directive, I 
switch to static, which I guess you don't want. But then I also 
get a bunch of undefined errors:


/usr/bin/ld: 
/home/user/.dub/cache/d-sfml-project-template/~master/build/application-debug-TGcRCxHHanKq_MbfWLee8g/d-sfml-project-template.o: in function `_Dmain':
/home/user/Downloads/dsfml/source/app.d:11: undefined reference 
to `sfRenderWindow_create'

...
collect2: error: ld returned 1 exit status
Error: linker exited with status 1
Error /usr/bin/dmd failed with exit code 1.


If you wanted static I would add and run libraries easy, like 
this:

```Json
"libs": [
"csfml-audio",
"csfml-graphics"
],
"versions": [
"SFML_Audio",
"SFML_Graphics",
"BindSFML_Static",
]
}
```
In summary, DUB takes care of everything for us. It should be 
same in W$...


SDB@79



Re: Assocative array lookup for object

2023-04-11 Thread Salih Dincer via Digitalmars-d-learn

On Wednesday, 12 April 2023 at 01:16:17 UTC, Chris Katko wrote:
Should I be using opEquals? Or something different? The problem 
with 'alias this' here is I want to wrap access to the insides 
with getter functions that do various things like logging and 
error checking.


I think you want to do an encapsulation like below.

```d
class Handler(T)
{
  T*[string] data;

  auto set(string key, ref T value)
    => data[key] = 

  auto opIndex(string key)
    => *(key in data);
}

void main()
{
  class Bitmap {}
  Bitmap foo;

  auto handler = new Handler!Bitmap;
  handler.set("D Lang", foo);

  assert(handler["D Lang"] == );
}
```
SDB@79


Re: How to setup D with SFML? (using bindbc-sfml)

2023-04-08 Thread Salih Dincer via Digitalmars-d-learn

On Saturday, 8 April 2023 at 23:40:32 UTC, Mike Parker wrote:
Not without error messages. The first thing you should do is 
use the error API in bindbc.loader to print them out. That 
should tell you what the problem is.


I installed it on my Linux system without using a loader and with 
static SFML. I just used apt-get and dub. I did the following in 
order:


1. sudo apt-get install libsfml-dev libcsfml-dev
2. dub init dsfml bindbc-sfml
3. cd dsfml
4. edit dub.json and add:
```java
  "libs": [
"csfml-audio",
"csfml-graphics"
],
  "subConfigurations": {
"bindbc-sfml": "staticBC"
},
  "versions": [
"SFML_Audio",
"SFML_Graphics"
],
```
5. dub

**app.d**
```d
import bindbc.sfml;

void main()
{
  sfContextSettings* settings;
  sfEvent event;

  auto window = sfRenderWindow_create(
sfVideoMode(750, 500),
"Japanese Flag",
sfWindowStyle.sfDefaultStyle,
settings
  );

  auto flag = sfCircleShape_create();
   flag.sfCircleShape_setRadius(150);
   flag.sfCircleShape_setPosition(sfVector2f(225, 100));
   flag.sfCircleShape_setFillColor(sfRed);

  while(window.sfRenderWindow_isOpen())
  {
while(window.sfRenderWindow_pollEvent())
{
  if(event.type == sfEventType.sfEvtClosed)
  {
window.sfRenderWindow_close();
  }
}

window.sfRenderWindow_clear(sfWhite);
window.sfRenderWindow_drawCircleShape(flag, null);
window.sfRenderWindow_display();
  }
}
```

SDB@79


Re: member func is best choice for pointers?

2023-04-06 Thread Salih Dincer via Digitalmars-d-learn

On Thursday, 6 April 2023 at 14:26:01 UTC, a11e99z wrote:
member func has invariant that **this** is not null (programmer 
thinks so).
global func hasn't the one and programmer should check for it 
before doing something ...


I understand what you mean.  When you try to access the last node 
of a linked list, you will get the segmentation fault if you are 
using a built-in viewer (toString).  For example:


```d
struct Node
{
  int item;
  Node * back;

  string toString()
  {
import std.format : format;

return format("Node::%s (back)-> %s", item,
 back.item);
  }
}

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

  auto node1 = Node(41);
  auto node1Ptr = 

  //printNode(node1Ptr);/* NOT COMPILE!
  node1.writeln;//* Main::41 (back)-> null */

  auto node2 = Node(42);
  node2.back = node1Ptr;

  printNode(); // Main::42 (back)-> 41
  node2.writeln; // Node::42 (back)-> 41
}

void printNode(Node * p)
{
  import std.stdio : writefln;

  if(p.back is null)
  {
writefln("Main::%s (back)-> null", p.item);
  } else {
writefln("Main::%s (back)-> %s", p.item,
p.back.item);
  }
}
```

If you don't remove the comment line (just remove the // sign: 
toggle-comment) the above code will not compile.  Because it is 
not connect to any node.


@SDB


Re: constant pointer failing to compile

2023-04-06 Thread Salih Dincer via Digitalmars-d-learn

On Thursday, 6 April 2023 at 00:46:26 UTC, Josh Holtrop wrote:

```
constarrptr.d(5): Error: cannot use non-constant CTFE pointer 
in an initializer `cast(immutable(ubyte)*)data`

```

Why? And how can I do the equivalent to what I have been doing 
in C? I want these pointers to be generated at compile time, 
not initialized at runtime.


(the full project is generating this file containing the data 
array (which is much longer) and multiple pointer constants to 
locations within it)


You have 2 options: First, to use .ptr, or second, to do the 
initialization in static this:


```d
import std.stdio;

static const char[] d;
static const char * p;

static this() {
  d = [97, 98, 99];
  p = [0]; // == d.ptr;
}

void main()
{
  printf("%.*s\n", cast(int)d.length, d.ptr);
  writeln("*p = ", *p);
}/* Prints:

  abc
  *p = a

*/
```

SDB@79




Re: foreach (i; taskPool.parallel(0..2_000_000)

2023-04-06 Thread Salih Dincer via Digitalmars-d-learn
On Tuesday, 4 April 2023 at 16:22:29 UTC, Steven Schveighoffer 
wrote:

On 4/4/23 11:34 AM, Salih Dincer wrote:
On Tuesday, 4 April 2023 at 14:20:20 UTC, Steven Schveighoffer 
wrote:
parallel is a shortcut to `TaskPool.parallel`, which is 
indeed a foreach-only construct, it does not return a range.


I think what you want is `TaskPool.map`:

```d
// untested, just looking at the
taskPool.map!(/* your map function here */)
   (s.iota(len)).writeln;
```



I tried, thanks but it goes into infinite loop. For example, 
the first 50 of the sequence should have been printed to the 
screen immediately without waiting.


```d
long[50] arr;
RowlandSequence_v2 range;

auto next(long a)
{
   range.popFront();
   return arr[a] = range.front();
}

void main()
{
     range = RowlandSequence_v2(7, 2);
     taskPool.map!next(iota(50))/*
     s.iota(50)
  .map!next
  .parallel//*/
  .writeln;
}
```


Keep in mind that `arr` and `range` are thread-local, and so 
will be different states for different tasks.


I guess the reason it goes into an infinite loop is because gcd() 
a recursive function (gcd). This is the only solution I can think 
of about this:


```d
import std.range, std.algorithm : map;
import std.stdio, std.parallelism;
//import std.numeric : gcd;
/*
struct Vector {
  long x, y, result;
  alias result this;
}

Vector gcd(long a, long b) {
  if(b == 0) return Vector(1, 0, a);

  auto pre = gcd(b, a % b);
  auto tmp = (a / b) * pre.y;

  return Vector(pre.y, pre.x - tmp, pre.result);
}//*/

struct RowlandSequence_v3 {
  long b, r, n, a = 3, limit;

  bool empty() { return n == limit; }

  auto front() { return a; }

  void popFront() {
long result = 1;
while(result == 1) {
  result = gcd(r++, b);
  b += result;
}
a = result;
  }

  long gcd(long a, long b) {
long c;
while(b != 0) {
  c = a % b;
  a = b;
  b = c;
}
return a;
  }
}

auto next(ref RowlandSequence_v3 range) {
  with(range) {
if(empty) return [n, front];
popFront();
return [n++, front];
  }
}

long[179] arr;

void main()
{
  // initialization:
  RowlandSequence_v3[4] r = [
  RowlandSequence_v3(7 , 2, 0, 3, 112),
  RowlandSequence_v3(186837678, 62279227, 112, 3, 145),
  RowlandSequence_v3(747404910, 249134971, 145, 6257, 160),
  RowlandSequence_v3(1494812421, 498270808, 160, 11, 177)
  ];

  auto tasks = [ task(, r[0]),
 task(, r[1]),
 task(, r[2]),
 task(, r[3])
   ];

  // quad parallel operation:
  foreach(_; 0..r[0].limit)
  {
foreach(p, ref task; tasks)
{
task.executeInNewThread;
auto t = task.workForce;
arr[t[0]] = t[1];
}
  }

  // prints...
  foreach(x, n; arr) {
switch(x + 1) {
  case 112, 145, 160:
n.writeln; break;
  default:
n.write(", ");
}
  }
} /* PRINTS:
user@debian:~/Documents$ dmd -O rowlandSequence.d -release
user@debian:~/Documents$ time ./rowlandSequence
5, 3, 11, 3, 23, 3, 47, 3, 5, 3, 101, 3, 7, 11, 3, 13, 233, 3, 
467, 3, 5, 3, 941, 3, 7, 1889, 3, 3779, 3, 7559, 3, 13, 15131, 3, 
53, 3, 7, 30323, 3, 60647, 3, 5, 3, 101, 3, 121403, 3, 242807, 3, 
5, 3, 19, 7, 5, 3, 47, 3, 37, 5, 3, 17, 3, 199, 53, 3, 29, 3, 
486041, 3, 7, 421, 23, 3, 972533, 3, 577, 7, 1945649, 3, 163, 7, 
3891467, 3, 5, 3, 127, 443, 3, 31, 7783541, 3, 7, 15567089, 3, 
19, 29, 3, 5323, 7, 5, 3, 31139561, 3, 41, 3, 5, 3, 62279171, 3, 
7, 83, 3
29, 3, 1103, 3, 5, 3, 13, 7, 124559609, 3, 107, 3, 911, 3, 
249120239, 3, 11, 3, 7, 61, 37, 179, 3, 31, 19051, 7, 3793, 23, 
3, 5, 3, 6257, 3

3, 11, 3, 13, 5, 3, 739, 37, 5, 3, 498270791, 3, 19, 11, 3
3, 3, 5, 3, 996541661, 3, 7, 37, 5, 3, 67, 1993083437, 3, 5, 3, 
83, 3, 3, 0,

real7m54.093s
user7m54.062s
sys 0m0.024s
*/
```

However, parallel processing for 4-digit sequence elements is not 
promising at least for the Rowland Sequence.


SDB@79


Re: foreach (i; taskPool.parallel(0..2_000_000)

2023-04-04 Thread Salih Dincer via Digitalmars-d-learn
On Tuesday, 4 April 2023 at 14:20:20 UTC, Steven Schveighoffer 
wrote:
parallel is a shortcut to `TaskPool.parallel`, which is indeed 
a foreach-only construct, it does not return a range.


I think what you want is `TaskPool.map`:

```d
// untested, just looking at the
taskPool.map!(/* your map function here */)
   (s.iota(len)).writeln;
```



I tried, thanks but it goes into infinite loop. For example, the 
first 50 of the sequence should have been printed to the screen 
immediately without waiting.


```d
long[50] arr;
RowlandSequence_v2 range;

auto next(long a)
{
  range.popFront();
  return arr[a] = range.front();
}

void main()
{
range = RowlandSequence_v2(7, 2);
taskPool.map!next(iota(50))/*
s.iota(50)
 .map!next
 .parallel//*/
 .writeln;
}
```

On Tuesday, 4 April 2023 at 13:18:01 UTC, Ali Çehreli wrote:
I don't have time to experiment more at this time but I have 
the following chapters, which includes some of those other 
algorithms as well:


  http://ddili.org/ders/d/kosut_islemler.html


I read it, thanks...

SDB@79


Re: foreach (i; taskPool.parallel(0..2_000_000)

2023-04-04 Thread Salih Dincer via Digitalmars-d-learn
On Monday, 3 April 2023 at 22:24:18 UTC, Steven Schveighoffer 
wrote:

So for example, if you have:

```d
foreach(i; iota(0, 2_000_000).parallel)
{
   runExpensiveTask(i);
}
```

The foreach is run on the main thread, gets a `0`, then hands 
off to a task thread `runExpensiveTask(0)`. Then it gets a `1`, 
and hands off to a task thread `runExpensiveTask(1)`, etc. The 
iteration is not expensive, and is not done in parallel.


On the other hand, what you *shouldn't* do is:

```d
foreach(i; iota(0, 2_000_000).map!(x => 
runExpensiveTask(x)).parallel)

{
}
```

as this will run the expensive task *before* running any tasks.


I don't understand what `foreach()` does :)
```d
import std.range, std.algorithm : map;
import std.stdio, std.parallelism;
//import sdb.sequences : RowlandSequence_v2;/*
struct RowlandSequence_v2 {
  import std.numeric : gcd;

  long b, r, a = 3;
  enum empty = false;
  auto front() => a;
  void popFront() {
long result = 1;
while(result == 1) {
  result = gcd(r++, b);
  b += result;
}
a = result;
  }
}//*/

enum BP : long {
   // s, f, r, b = 7, /* <- beginning
   s = 178, r = 1993083484, b =  5979250449,//*/
   len = 190
}

void main()
{
  with(BP) {
long[len] arr;
auto range = RowlandSequence_v2(b, r);

s.iota(len)
 .map!((a){
range.popFront();
return arr[a] = range.front();
  }
  )
 .parallel
 .writeln;
  }
} /* PRINTS:

ParallelForeach!(MapResult!(__lambda3, 
Result))(std.parallelism.TaskPool, [5, 3, 73, 157, 7, 5, 3, 13, 
3986167223, 3, 7, 73], 1)


*/
```

Is it necessary to enclose the code in `foreach()`? I invite Ali 
to tell me! Please explain why parallel isn't running.


"Ben anlamıyor, foreach ne yapıyor  Kodu `foreach()` içine almak 
şart mı? Ali'yi davet ediyorum, bana anlatması için! Paralel() 
niye çalışmıyor, lütfen açıklayın hocam. Mümkünse Türkçe!" in 
Turkish.


SDB@79


Re: short guide on getting started with D

2023-04-03 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 3 April 2023 at 07:29:01 UTC, cgenie wrote:

Thanks, you got my attention...

It has come to my attention that you talked about this:

https://mesonbuild.com/Dlang-module.html

SDB@79


Re: foreach (i; taskPool.parallel(0..2_000_000)

2023-04-02 Thread Salih Dincer via Digitalmars-d-learn

On Sunday, 2 April 2023 at 04:34:40 UTC, Salih Dincer wrote:

I haven't seen rsFirst256 until now...


**Edit:** I saw, I saw :)

I am struck with consternation! I've never seen these results 
before. Interesting, there is such a thing as parallel threading 
:)


Here are my skipPoints:

```d
enum BP : long {
  //f, a, r, b = 7, /* <- beginning
   f = 113, r =   62279227, b =   186837678,
  // f = 146, r =  249134971, b =   747404910,
  // f = 161, r =  498270808, b =  1494812421,
  // f = 178, r = 1993083484, b =  5979250449,
  // f = 210, r = 3986167363, b = 11958502086,
  //*/
  s = 5
} /* PRINTS:
eLab@pico:~/Projeler$ ./RownlandSequence_v2
122: ["124559610, 373678827"]
128: ["249120240, 747360717"]
*/
```

It looks like there are 5 total skipPoints until 256 where it 
loops for a long time. (while passing 1's).


SDB@79


Re: foreach (i; taskPool.parallel(0..2_000_000)

2023-04-01 Thread Salih Dincer via Digitalmars-d-learn

On Saturday, 1 April 2023 at 22:48:46 UTC, Ali Çehreli wrote:

On 4/1/23 15:30, Paul wrote:

> Is there a way to verify that it split up the work in to
tasks/threads
> ...?

It is hard to see the difference unless there is actual work in 
the loop that takes time.


I always use the Rowland Sequence for such experiments.  At least 
it's better than the Fibonacci Range:


```d
struct RowlandSequence {
  import std.numeric : gcd;
  import std.format : format;
  import std.conv : text;

  long b, r, a = 3;
  enum empty = false;

  string[] front() {
string result = format("%s, %s", b, r);
return [text(a), result];
  }

  void popFront() {
long result = 1;
while(result == 1) {
  result = gcd(r++, b);
  b += result;
}
a = result;
  }
}

enum BP {
  f = 1, b = 7, r = 2, a = 1, /*
  f = 109, b = 186837516, r = 62279173, //*/
  s = 5
}

void main()
{
  RowlandSequence rs;
  long start, skip;

  with(BP) {
rs = RowlandSequence(b, r);
start = f;
skip = s;
  }
  rs.popFront();

  import std.stdio, std.parallelism;
  import std.range : take;

  auto rsFirst128 = rs.take(128);
  foreach(r; rsFirst128.parallel)
  {
if(r[0].length > skip)
{
  start.writeln(": ", r);
}
start++;
  }
} /* PRINTS:

46: ["121403", "364209, 121404"]
48: ["242807", "728421, 242808"]
68: ["486041", "1458123, 486042"]
74: ["972533", "2917599, 972534"]
78: ["1945649", "5836947, 1945650"]
82: ["3891467", "11674401, 3891468"]
90: ["7783541", "23350623, 7783542"]
93: ["15567089", "46701267, 15567090"]
102: ["31139561", "93418683, 31139562"]
108: ["62279171", "186837513, 62279172"]

*/
```

The operation is simple, again multiplication, addition, 
subtraction and module, i.e. So four operations but enough to 
overrun the CPU! I haven't seen rsFirst256 until now because I 
don't have a fast enough processor. Maybe you'll see it, but the 
first 108 is fast anyway.


**PS:** Decrease value of the `skip` to see the entire sequence. 
In cases where your processor power is not enough, you can create 
skip points.  Check out BP...


SDB@79


Re: InputRange in arrays

2023-03-30 Thread Salih Dincer via Digitalmars-d-learn

On Friday, 31 March 2023 at 04:15:24 UTC, Salih Dincer wrote:


...has it always been possible for arrays to be used as if they 
were ranges?


Playground is a very useful tool, it responds right away :)


Up to  2.078.3: Failure with output:
-
onlineapp.d(4): Error: no property 'popFront' for type 'int[]'
onlineapp.d(6): Error: no property 'front' for type 'int[]'
-



2.079.1 to 2.087.1: Failure with output:
-
onlineapp.d(4): Error: no property `popFront` for type `int[]`
onlineapp.d(6): Error: no property `front` for type `int[]`
-



Since  2.088.1: Failure with output:
-
onlineapp.d(4): Error: no property `popFront` for type `int[]`, 
perhaps `import std.range;` is needed?
onlineapp.d(6): Error: no property `front` for type `int[]`, 
perhaps `import std.range;` is needed?

-


SDB@79



Re: InputRange in arrays

2023-03-30 Thread Salih Dincer via Digitalmars-d-learn

On Friday, 31 March 2023 at 03:39:51 UTC, Salih Dincer wrote:
May be somewhere D compiler between v2.087 and v2.096 (works) 
but definitely not before v2.087 (including)...


Edit: The Phobos library I'm using is corrupted. That's why the 
last line was giving an error. But has it always been possible 
for arrays to be used as if they were ranges?


Thanks...

SDB@79


InputRange in arrays

2023-03-30 Thread Salih Dincer via Digitalmars-d-learn
Hi, there is a feature when working with the InputRange. I don't 
know when it released available. May be somewhere D compiler 
between v2.087 and v2.096 (works) but definitely not before 
v2.087 (including)...


Anyone know this?

```d
import std.range.primitives;
void main()
{
  auto arr = [0, 1];
  arr.popFront;

  assert(arr.front == 1);
  assert(isInputRange!(typeof(arr)));
}
```

SDB@79


Re: The Phobos Put

2023-03-30 Thread Salih Dincer via Digitalmars-d-learn
On Thursday, 30 March 2023 at 13:27:33 UTC, Steven Schveighoffer 
wrote:

But you can do `dig.copy(buf[])` since a dynamic array is.



Apparently, we will not be able to get rid of the necessity of 
using slices.  Neither with "copy" nor with "put"...


```d
import std.algorithm.mutation : copy;
import std.range.primitives : put;

void main()
{
  int[8] buf;// = new int[8];
  auto dig = [1, 2, 3, 4];

  //dig.copy(buf[2..$-2]);/*
  auto slice = buf[2..$-2];
  dig.copy(slice);
  
  assert(buf == [0, 0, 1, 2, 3, 4, 0, 0]);
  buf = 0;
  slice.put(dig);//*/
  assert(buf == [0, 0, 1, 2, 3, 4, 0, 0]);
}
```
SDB@79



Re: The Phobos Put

2023-03-29 Thread Salih Dincer via Digitalmars-d-learn
On Wednesday, 29 March 2023 at 20:50:04 UTC, Steven Schveighoffer 
wrote:

On 3/29/23 4:29 PM, ag0aep6g wrote:

But regardless of Salih's exact intent, the broader point is: 
a non-ref overload could be added to Phobos. And that would 
enable `a[1..$-1].phobos_put([2, 3])`. Which is what he asked 
about originally.


I think the idea of requiring ref output ranges is that you can 
then let the range keep track of its output state.


So why not copying the range to a static array?  The error during 
compilation of the code is as follows:


onlineapp.d(6): Error: none of the overloads of template 
`std.algorithm.mutation.copy` are callable using argument types 
`!()(int[], int[8])`

/dlang/dmd/linux/bin64/../../src/phobos/std/algorithm/mutation.d(367):
Candidate is: `copy(SourceRange, TargetRange)(SourceRange source, TargetRange 
target)`
  with `SourceRange = int[],
   TargetRange = int[8]`
  must satisfy the following constraint:
`   isOutputRange!(TargetRange, ElementType!SourceRange)`

```d
import std.algorithm.mutation : copy;
void main()
{
  int[8] buf;
  auto dig = [1, 2, 3, 4];
  auto rem = dig.copy(buf);
  assert(rem.length == 4);
}

```

Looks like 'copy' has the same overload issue.

SDB@79



Re: How to debug and watch globals in windows debugger?

2023-03-29 Thread Salih Dincer via Digitalmars-d-learn

On Wednesday, 29 March 2023 at 21:09:57 UTC, ryuukk_ wrote:
Also it's more of an accumulation of problems that makes me 
very annoyed


https://issues.dlang.org/show_bug.cgi?id=20737

This for example shouldn't be a thing in 2023, period


I agree with you because it's such a simple problem and it's 
surprising if it exists.  I've never used -betterC though, but 
it's a pity.


SDB@79


Re: The Phobos Put

2023-03-29 Thread Salih Dincer via Digitalmars-d-learn

On Wednesday, 29 March 2023 at 20:29:24 UTC, ag0aep6g wrote:
But regardless of Salih's exact intent, the broader point is: a 
non-ref overload could be added to Phobos. And that would 
enable `a[1..$-1].phobos_put([2, 3])`. Which is what he asked 
about originally.


Yes, that was it, but even more. Both functions serve the same 
thing. Why don't we combine them?


SDB@79



Re: The Phobos Put

2023-03-29 Thread Salih Dincer via Digitalmars-d-learn

On Wednesday, 29 March 2023 at 19:49:47 UTC, Ali Çehreli wrote:

On 3/29/23 12:21, ag0aep6g wrote:

> As far as I understand, you're saying that we cannot overload
on `ref`.
> But we can. Salih's code demonstrates just that.
>
> void f(ref int x) {}
> void f(int x) {}
> void main() { int x; f(x); f(42); } /* no errors */

I thought Salih was proposing two more overloads to the 
existing put(). When I copy the existing put(), which takes 
'ref R', not R[], then the code does not compile:


Wait a minute, isn't `copy` actually a `put` as well? Forget 
about `ref` for a moment, please. Actually, logically, the 
parameters have been swapped between the two functions. Well, if 
we only had `copy` and we used `put` like `copy`, what is the 
need for `put`? Examples are below: :)


```d
//version = simple;/*
version = standart;//*/

version(simple) {
  auto put(R)(R[] range, R[] source)
=> copyImpl(source, range);

  auto copy(R)(R[] source, R[] range)
=> copyImpl(source, range);

  auto copyImpl(R)(R[] source, R[] range)
  {
assert(source.length <= range.length);
foreach(element; source)
{
  range[0] = element;  // range.front()
  range = range[1..$]; // range.popFront()
}
return range;
  }

  void swap (ref int x, ref int y)
  {
x = x ^ y;
y = y ^ x;
x = x ^ y;
  }
}

version(standart)
  import std.algorithm.mutation,
 std.range : put;

void main()
{
  // copy() example:
  enum len = 10;
  auto buf = new int[len]; // buffer
  auto dig = [7, 1, 2, 3]; // digits

  auto diff = len - dig.length;
  auto rem = copy(dig, buf);

  assert(buf[0..$ - diff] == [7, 1, 2, 3]);

  swap(buf[0], rem[0]);
  assert(rem == [7, 0, 0, 0, 0, 0]);

  // put() example 1:
  put(rem, [4, 5, 6, 7, 8, 9]);
  assert(buf == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);

  // put() example 2:
  enum data = [1, 0, 0, 4];
  auto arr = data;
  auto slice = arr[1..$-1];

  version(standart)
put(slice, [2]);
  version(simple)
slice = put(slice, [2]);
  assert(arr == [1, 2, 0, 4]);

  version(standart)
put(slice, [3]);
  version(simple)
slice = put(slice, [3]);
  assert(arr == [1, 2, 3, 4]);

  version(standart) {
auto slc = arr[1..$-1];
put(slc, [0, 0]);
  }
  version(simple)
arr[1..$-1].put([0, 0]);
  assert(arr == data);
}
```
All you have to do is remove the // mark in the first line. The 
code compiles for me, what about you?


SDB@79


Re: The Phobos Put

2023-03-29 Thread Salih Dincer via Digitalmars-d-learn

On Wednesday, 29 March 2023 at 15:01:27 UTC, Ali Çehreli wrote:

On 3/29/23 04:48, Dennis wrote:
On the other hand, Phobos's put() works with any OutputRange so 
it has to take a 'ref' to advance to know where it is left off. 
This behavior makes its use with slices weird but sometimes 
such is life. :)


Would not adding a prototype without a ref cause ambiguity? In 
this way, it could also be used directly with slices. For example:


```d
auto put(R)(R[] range, R[] source)
  => putImpl(range, source);

auto put(R)(ref R[] range, R[] source)
  => putImpl(range, source);

void putImpl(R)(ref R[] range, R[] source)
{
  assert(source.length <= range.length);
  foreach(element; source)
  {
range[0] = element;  // range.front()
range = range[1..$]; // range.popFront()
  }
}

void main() {
  enum data = [1, 0, 0, 4];
  auto arr = data;
  auto slice = arr[1..$-1];

  slice.put([2]);
  assert(arr == [1, 2, 0, 4]);

  slice.put([3]);
  assert(arr == [1, 2, 3, 4]);

  arr[1..$-1].put([0, 0]);
  assert(arr == data);
}
```

SDB@79


The Phobos Put

2023-03-29 Thread Salih Dincer via Digitalmars-d-learn
Why does my `put` work but the Phobos `put` doesn't work with a 
slice?


onlineapp.d(11): Error: none of the overloads of template 
`std.range.primitives.put` are callable using argument types 
`!()(int[], int[])`

/dlang/dmd/linux/bin64/../../src/phobos/std/range/primitives.d(386):
Candidate is: `put(R, E)(ref R r, E e)`

```d
void main()
{
    import std.range : phobos_put = put;
  
    enum testLen = 4;
auto a = new int[testLen];
auto b = new int[testLen];

auto slice = a[1..$-1];
    slice.phobos_put([2, 3]);
    //a[1..$-1].phobos_put([2, 3]);
    b[1..$-1].put([2, 3]);

    import std.conv : text;
    assert(a == b, text(a));
}

void put(R)(R[] range, R[] source)
{
  assert(source.length <= range.length);
  foreach(element; source)
  {
range[0] = element;  // range.front()
range = range[1..$]; // range popFront()
  }
}
```

SDB@79


The Phobos put()

2023-03-29 Thread Salih Dincer via Digitalmars-d-learn
Why does my `put` work but the Phobos `put` doesn't work with a 
slice?


onlineapp.d(11): Error: none of the overloads of template 
`std.range.primitives.put` are callable using argument types 
`!()(int[], int[])`

/dlang/dmd/linux/bin64/../../src/phobos/std/range/primitives.d(386):
Candidate is: `put(R, E)(ref R r, E e)`

```d
void main()
{
    import std.range : phobos_put = put;
  
    enum testLen = 4;
auto a = new int[testLen];
auto b = new int[testLen];

auto slice = a[1..$-1];
    slice.phobos_put([2, 3]);
    //a[1..$-1].phobos_put([2, 3]);
    b[1..$-1].put([2, 3]);

    import std.conv : text;
    assert(a == b, text(a));
}

void put(R)(R[] range, R[] source)
{
  assert(source.length <= range.length);
  foreach(element; source)
  {
range[0] = element;  // range.front()
range = range[1..$]; // range popFront()
  }
}
```

SDB@79


Re: Step by step tutorials for using bindings in D

2023-03-26 Thread Salih Dincer via Digitalmars-d-learn

On Monday, 27 March 2023 at 00:06:36 UTC, Inkrementator wrote:


PS: To really understand what is happening, you might want to 
try manually compiling a hello world program that depends on a 
library instead of using dub. Some pointers:

`dub build -v` will print out the compiler and linkflags used.

`pkg-config --libs --cflags lua` would generate compiler 
options for you. Use it like

`dmd $(pkg-config --libs --cflags lua) program.d`

If you decide to try this, I can walk you through it. But 
remember that it's not that important this is probably all a 
bit much.


Even if I wrote similar articles ([for 
example](https://forum.dlang.org/post/qnzmxceqesmcsmfmz...@forum.dlang.org), in my own language), it would not be enough!


Even writing is not enough...
What era are we living in? There is something called YouTube:

[How to set up D and GLFW/OpenGL project on MacOS, Linux and 
Windows](https://www.youtube.com/watch?v=wG6OG6uWyDw=youtu.be) by Ki Rill


Likes **17**
Views **265**
Released on March **8, 2023**

I have to ask... How many of you have made such how-to videos?

This is a question I have to answer too! Use DUB, recommend, bird 
in the hand is worth two in the bush 


SDB@79






Re: Segfault with std.variant

2023-03-25 Thread Salih Dincer via Digitalmars-d-learn

On Saturday, 25 March 2023 at 07:42:28 UTC, Ali Çehreli wrote:


This looks like a bug to me.


Such a problem does not occur when you set all objects with the 
new operator.


```d
void main()
{
  import std.variant;

  auto var = Variant([
    "one": new Variant(1), "two": new Variant(2),
    "three": new Variant(3), "four": new Variant(4),
    "five": new Variant(5)
  ]);
  auto six = new Variant(6);
  var["six"] = new Variant(6);
  assert(var.length == 6);
}
```

SDB@79


Re: Implicit type conversion depending on assignment

2023-03-24 Thread Salih Dincer via Digitalmars-d-learn
On Thursday, 23 March 2023 at 13:38:51 UTC, Alexander Zhirov 
wrote:

```d
struct MyVal
{
string value;
// Here it would be possible to use an alias to this, but 
it can only be used 1 time

}

auto a = MyVal("100");
auto b = MyVal("11.2");

int MyInt = a;// Implicitly convert to target type
float myFloat = b;// Implicitly convert to target type
```


Have you tried using an associative array?

I feel that you will come up with a solution for your purpose 
from the examples below:


```d
template MyContainer(string data = "")
{   // Container name ---^
  struct Var
  {
import std.variant;

private Variant[string] values;
alias values this;

@property
{
  Variant opDispatch(string key)() const
  {
return values[key];
  }

  void opDispatch(string key, T)(T val)
  {
values[key] = val;
  }
}
  }

  static if(data.length > 0)
  {
import std.format;

mixin(data.format!"Var %s;");

  } else {

Var data; // no conflicts

  }
}

import std.stdio;

void main()
{
  enum Tarih
  {
AY  = 1,
YIL = 2023
  }
  mixin MyContainer!"date";

  date.month = cast(ubyte)Tarih.AY;
  date.month.write("/");

  assert(date["month"] != Tarih.AY);
  assert(date["month"].type == typeid(ubyte));

  date.year = cast(short)Tarih.YIL;
  date.year.writeln(" in Turkish format");

  assert(date["year"] != Tarih.YIL);
  assert(date["year"].type == typeid(short));

  writefln("Date: %s/%s", date.year, date.month);
}
```

SDB@79


Re: alias Error: need 'this'

2023-03-19 Thread Salih Dincer via Digitalmars-d-learn

On Sunday, 19 March 2023 at 11:52:50 UTC, bomat wrote:
It works fine with the `int` variable, but with the struct 
member I get a compilation error:

```
Error: need `this` for `memberWithALongName` of type `int`
```

What is that supposed to mean?


It is possible to achieve the convenience you want to achieve in 
2 ways. One of them is to use a static member but if not, to use 
an alias inside the container. For example:


```d
struct MyStruct
{
  int memberWithALongName;
  alias ln = memberWithALongName;

  static string str;
}

void main()
{
  auto myStruct = MyStruct(1);
   myStruct.ln = 2;
  alias alias2 =  MyStruct.str;
  alias2 = "2";

  import std.conv : text;
  assert(myStruct.ln.text == alias2);
}
```
SDB@79


  1   2   3   4   >