Re: Choosing the correct compiler version

2022-07-20 Thread Alexander Zhirov via Digitalmars-d-learn

On Tuesday, 19 July 2022 at 23:19:28 UTC, jfondren wrote:
Finding an old version that works on your machine will be very 
easy, but for example the random 2016 build that I grabbed was 
also too old to build dmd master, so you want to prefer a newer 
build that still works. It's not necessary to build dmd master 
though: in the worst case, you should be able check out interim 
releases (look at 'git tag --list', then 'git checkout 
v2.094.0' for example), build those, then used them to build a 
newer release.


Yes, you were right! I managed to launch the 2020 version. Now 
I'm trying to build `ldc2`. I will report on the successes a 
little later. Thanks!


Re: Working with arrays (flatten, transpose, verfify rectangular)

2022-07-20 Thread ag0aep6g via Digitalmars-d-learn

On 20.07.22 11:18, anonymouse wrote:

     d
     auto isRectangular(A)(A a) if (isArray!A)
     {
     bool result;
     size_t length = a[0].length;

     foreach (e; a) {
     result = e.length == length;
     }
     return result;
     }
     

This only works if a is a 2D array, how do I extend this to 
support arrays with larger dimensions (3D, 4D, 5D, etc.)?


(Aside: You don't need that many backticks to mark code fragments.)

You've got a bug there. This should pass, but fails with your version:

assert(!isRectangular([[1, 2], [], [3, 4]]));

Once `result` becomes false, you cannot let it switch to true again.

As for generalizing the function, instead of comparing the lengths of 
the elements, you want to compare their "shapes". The shape of a `Foo[] 
a1;` is `[a1.length]`. The shape of a rectangular `Foo[][] a2;` is 
`[a2.length, a2[0].length]`. And so on.


Start by extending `isRectangular` to also (optionally) return the shape 
of the array:


bool isRectangular(A)(A a) if (isArray!A)
{
size_t[] dummy;
return isRectangular(a, dummy);
}
bool isRectangular(A)(A a, out size_t[] shape) if (isArray!A)
{
size_t first_length = a[0].length;
foreach (e; a)
{
if (e.length != first_length) return false;
}
shape = [a.length, first_length];
return true;
}
unittest
{
size_t[] shape;
assert(isRectangular([[1, 2], [3, 4], [5, 6]], shape));
assert(shape == [3, 2]);
assert(!isRectangular([[1, 2], [], [3, 4]]));
}

Extend it to one-dimensional arrays:

bool isRectangular(A)(A a, out size_t[] shape) if (isArray!A)
{
shape = [a.length];
alias E = typeof(a[0]);
static if (isArray!E)
{
size_t first_length = a[0].length;
shape ~= first_length;
foreach (e; a)
{
if (e.length != first_length) return false;
}
}
return true;
}
unittest /* one dimension */
{
size_t[] shape;
assert(isRectangular([1, 2, 3], shape));
assert(shape == [3]);
}

Finally, use the magic of recursion to conquer higher dimensions:

bool isRectangular(A)(A a, out size_t[] shape) if (isArray!A)
{
shape = [a.length];
alias E = typeof(a[0]);
static if (isArray!E)
{
size_t[] first_shape;
if (!isRectangular(a[0], first_shape)) return false;
shape ~= first_shape;
foreach (e; a)
{
size_t[] e_shape;
if (!isRectangular(e, e_shape)) return false;
if (e_shape != first_shape) return false;
}
}
return true;
}
unittest /* higher dimensions */
{
size_t[] shape;
assert(isRectangular([
[[ 1,  2,  3,  4], [ 5,  6,  7,  8], [ 9, 10, 11, 12]],
[[13, 14, 15, 16], [17, 18, 19, 20], [21, 22, 23, 24]]
], shape));
assert(shape == [2, 3, 4]);
}

I'm sure the function can be improved further, but I'm not going to get 
into that.


For task 3, I can visit each element of the array, but I have no idea 
how to compose the flattened (1D) version:


     d
     import std.range.primitives: ElementType;
     auto flatten(A)(A a) if (isArray!A)
     {
     //ElementType!(A)[] result; //[1]
     foreach (i; a) {
     static if (isArray!(typeof(i)))
    flatten(i);
     else {
     writeln(i);
     // result ~= i; //[2]
     }
     }
     //return result; // [3]
     }
     


You've got the right idea there with `flatten` calling itself on each 
element. You only need to apply that idea when getting the element type, 
too (and actually append the result of the recursive call to `result`):


import std.range.primitives: ElementType;
template FlatElementType(A) if (isArray!A)
{
alias E = ElementType!A;
static if (isArray!E)
{
alias FlatElementType = FlatElementType!E;
}
else
{
alias FlatElementType = E;
}
}
unittest
{
static assert(is(FlatElementType!(int[]) == int));
static assert(is(FlatElementType!(int[][]) == int));
static assert(is(FlatElementType!(int[][][]) == int));
}
auto flatten(A)(A a) if (isArray!A)
{
FlatElementType!A[] result;
foreach (i; a)
{
static if (isArray!(typeof(i)))
result ~= flatten(i);
else
result ~= i;
}
return result;
   

Re: null == "" is true?

2022-07-20 Thread Antonio via Digitalmars-d-learn

On Wednesday, 20 July 2022 at 13:35:14 UTC, Kagamin wrote:

On Tuesday, 19 July 2022 at 18:05:34 UTC, Antonio wrote:
In a relational database, `NULL` is not the same that `""`... 
and `NULL` is not the same that `0`.  Are semantically 
different and there are database invariants (like foreign 
keys) based on it.   Trying to "mix" this concepts in a 
database is a mistake.


So, it's an implementation detail or a relational database that 
leaks into business logic because nobody thought about it? Just 
because a relational database has many features, it doesn't 
mean business logic must use them all, it must use only what 
makes sense for business logic.


It is not about "so many fetaures"... it is about entity model 
and how relational database stores it.   General purpose 
programming languages include their own representation to the 
NULL concept that is not "relational model" dependent:  Optional, 
Maybe, Nullable, Union types


What semantics your domain models implement? Is it semantics of 
all features of a relational database or is semantics of 
business logic?


Database is an **strict repository**:  it stores the entity model 
with relational semantics including strict invariant management 
(primary keys, foreign keys, field types, nullablility, ...) and 
following normalization rules (3th normal form, at least).  It 
is, basically, a "consistent" model.


Business logic **trust on database repository invariants** and 
implements whatever your Business Model require (i.e.:  complex 
model operations involving multiple repository operations).  
Business works using Objects/Entities of the domain and it is 
required a way to map this to relational model (ORM or manual 
SQL)... Usually in a specific "Data" or "DAO" layer.  
Transactions are your friend (The only way to ensure that high 
level invariants are enforced)


If you can't be confident with database invariants (because you 
are using NoSQL repository like MongoDB or DynamoDB or an Old 
ISAM MySQL or "trash" models over relational engine) then you 
need to "move" all these "consistency" control to the business 
layer developing workflows/processes that must be ready to work 
with "inconsistent" data...  (You can read this article I wrote 2 
years ago about SQL/NoSQL solutions and Brewer's conjecture: 
https://qr.ae/pvklQA)



Business "architecture" based on a single repository is the 
simplest one...  But the pleasure of trusting on a relational 
database is always welcome.


Re: "Memory allocation failed" on big array

2022-07-20 Thread urned utt via Digitalmars-d-learn

Big thank.


Switch to /bin64 and now works until full memory using.


Re: "Memory allocation failed" on big array

2022-07-20 Thread ryuukk_ via Digitalmars-d-learn
My guess is you are compiling to 32bit and the GC tries to 
reserve >4gb wich it can't, therefore out of memory


Compiling to 64bit with: `dmd -m64 -run test.d` works no problem






"Memory allocation failed" on big array

2022-07-20 Thread urned utt via Digitalmars-d-learn

Hello.

having about 6 Gb free RAM, trying to execute:

```d
string[] dic;

for (int i = 0; i < 100_000_000; i++)
{

dic ~= "just a word number "~to!string(i);

if (i%1_000_000 == 0)
{
		writef("processed line %s: %s\n", format("%,3d", i), 
format("%,3d", dic.length));

}
}

```

got an error:
"processed line 32,000,000: 32,000,001
core.exception.OutOfMemoryError@src\core\lifetime.d(126): Memory 
allocation failed"


app used is about 1.6 Gb, more than 4 stays free.

1. What is happened, why dynamic array have mem limit? For 
example, golang uses all free memory that it can.

2. How to fix this?
3. (optional) How to display memory usage? Cannot find function 
for this.


Thanks.


Re: Working with arrays (flatten, transpose, verfify rectangular)

2022-07-20 Thread Salih Dincer via Digitalmars-d-learn

On Wednesday, 20 July 2022 at 09:18:29 UTC, anonymouse wrote:
Given an array of arbitrary dimensions, I would like to 
accomplish three things:
1) verify that it is rectangular (e.g. all elements 
have the same length, all sub-elements have the same length, 
etc.)

2) flatten and return the flattened copy
3) transpose and return the transposed copy


Yesterday, I published an example of a lesson we developed with 
Ali.  It's same `transpose()` when I add extra `swap()` for you.  
I hope it works for you.


```d
import std.stdio;

struct Arrayish(T) {
  T[] element;
  size_t row, column;

  this(size_t row, size_t column) {
this.element = new T[row * column];
this.row = row;
this.column = column;
  }

  ref T opIndex(size_t row, size_t column) {
size_t first = row * this.column;
size_t index = first + column;

return element[index];
  }

  auto opCast(R : T[][])() {
T[][] d;
foreach(i; 0..row)
  d ~= slice(i);
return d;
  }

  auto slice(size_t i) {
size_t n = i * column;
return element[n..n + column];
  }

  @property {
auto length() {
  return row * column;
}

auto dup() {
  T[][] d;
  foreach(i; 0..row)
d ~= slice(i).dup;
  return d;
}
void swap() {
  auto tmp = row;
  row = column;
  column = tmp;
}
  }
}

enum { row = 2, col = 4 }

void main() {
  auto arrayish = Arrayish!int(row, col);

  foreach(r; 0..row) {
    foreach(c; 0..col) {
      const value = r * 1000 + c;
      arrayish[r, c] = value;
}
  }
  //arrayish.swap();
  const array = cast(int[][])arrayish;
  arrayish[1, 0] = 100;
  typeid(array).writeln(": ", array.length);
  array.writefln!"%(%s\n%)";

  arrayish.length.writeln(" total items");
  
  auto arrayCopy = arrayish.dup;
  arrayish[1, 0] = 1000;
  typeid(arrayCopy).writeln(": ", array.length);
  arrayCopy.writefln!"%(%s\n%)";
}
```

SDB@79


Re: Expanding CTFE code during compilation

2022-07-20 Thread Dennis via Digitalmars-d-learn

On Wednesday, 20 July 2022 at 00:33:06 UTC, Azi Hassan wrote:
Where did you find it though ? I checked dmd --help and man dmd 
before making this thread, but to no avail.


It was implemented as an internal debugging tool, not a 
documented feature: https://github.com/dlang/dmd/pull/6556


It turned out to be useful for users as well though, and got 
exposure through the "AST" button on https://run.dlang.io/


Maybe it's time to document it, currently there's only this: 
https://wiki.dlang.org/DMD_Source_Guide#View_emitted_templates_instances_and_string.2Fmixins


Re: null == "" is true?

2022-07-20 Thread Kagamin via Digitalmars-d-learn

On Tuesday, 19 July 2022 at 18:05:34 UTC, Antonio wrote:
In a relational database, `NULL` is not the same that `""`... 
and `NULL` is not the same that `0`.  Are semantically 
different and there are database invariants (like foreign keys) 
based on it.   Trying to "mix" this concepts in a database is a 
mistake.


So, it's an implementation detail or a relational database that 
leaks into business logic because nobody thought about it? Just 
because a relational database has many features, it doesn't mean 
business logic must use them all, it must use only what makes 
sense for business logic.


When you treat with Domain Models, you try to represent this 
semantics in all levels of your software... including APIs


What semantics your domain models implement? Is it semantics of 
all features of a relational database or is semantics of business 
logic?


Re: Choosing the correct compiler version

2022-07-20 Thread kdevel via Digitalmars-d-learn

On Tuesday, 19 July 2022 at 23:19:28 UTC, jfondren wrote:

Thanks for your thorough presentation.


[...]
Another option is to get newer glibc onto this system (not 
installing it, just making it available for dmd. use 
LD_LIBRARY_PATH).


On older systems the dynamic loader (ld.so) may not execute the 
binary under the new glibc with the error message "ELF file OS 
ABI invalid". This is due to the addition of two features to the 
toolchain (`STB_GNU_UNIQUE`, `STT_GNU_IFUNC`) eleven years ago 
[0] an application programmer usually does not have to deal with.


In this case one needs to start dmd using the loader which 
accompanies the new glibc. In order to avoid that I use patchelf 
to set `INTERP` and `RUNPATH` on all binaries in linux/bin64 
accordingly.



[...]
Speaking of toolchains, it might be possible to use a modern 
server with a modern dmd with an ancient glibc: 
https://www.lordaro.co.uk/posts/2018-08-26-compiling-glibc.html


Since glibc is not forward compatible [1] I wonder why the dmd 
tools are not routinely linked against a long established glibc 
version.


[0] 

[1] 





Working with arrays (flatten, transpose, verfify rectangular)

2022-07-20 Thread anonymouse via Digitalmars-d-learn
Given an array of arbitrary dimensions, I would like to 
accomplish three things:
1) verify that it is rectangular (e.g. all elements have 
the same length, all sub-elements have the same length, etc.)

2) flatten and return the flattened copy
3) transpose and return the transposed copy

Here is my naive attempt to accomplish the first task:

d
auto isRectangular(A)(A a) if (isArray!A)
{
bool result;
size_t length = a[0].length;

foreach (e; a) {
result = e.length == length;
}
return result;
}


This only works if a is a 2D array, how do I extend this 
to support arrays with larger dimensions (3D, 4D, 5D, etc.)?


For task 3, I can visit each element of the array, but I have no 
idea how to compose the flattened (1D) version:


d
import std.range.primitives: ElementType;
auto flatten(A)(A a) if (isArray!A)
{
//ElementType!(A)[] result; //[1]
foreach (i; a) {
static if (isArray!(typeof(i)))
   flatten(i);
else {
writeln(i);
// result ~= i; //[2]
}
}
//return result; // [3]
}


The thought I had was to get the BaseType of the array (int, 
double, etc.) and use it to create a dynamic array [1]. I could 
then concatenate each element [2], and return the result once 
completed [3]. This approach has two major problems and probably 
many other's I'm not yet experienced enough to see. The first is 
that there's no way to get the BaseType of an array. ElementType 
in the example assumes that array is 2D, therefore anything else 
passed in will result in a multi-dimensional array being created 
to which individual elements cannot be concatenated. The second 
issue is that each call to flatten will have it's own result 
which will be discarded when the function exits, so the final 
result will be an empty array.


As for task 3, while I understand the concept of transposing a 
matrix, I'm not sure how to even begin.


These tasks are all self assigned and not associated with any 
high school or college course. Just trying get a better 
understanding of how arrays and matrices/tensors work while 
reading up on linear algebra. This is purely self study and I 
would really appreciate some assistance.


Thanks,
---anonymouse


Re: null == "" is true?

2022-07-20 Thread Antonio via Digitalmars-d-learn

On Tuesday, 19 July 2022 at 16:55:39 UTC, Kagamin wrote:


As I understand, in your scenario there's no difference between 
null string and empty string, they both work like empty string, 
and D treats them as empty string. That's what I mean when I 
said that distinction between null and empty is meaningless.



Sorry Kagamin... I dindn't read this comment and I added a very 
large answer to the next one that has no sense :-p. I miss being 
able to delete answers from the forum :-)


**Yes... I decided to treat the same way internally** for strings.

Previously

*  `DtoVal!(Null, string)( null)` was equivalent to 
`DtoVal!(Null,string)( Null() )`
*  `DtoVal!(Null, Person)( null)` was equivalent to 
`DtoVal!(Null,string)( Null() )`


Currently

* `DtoVal!(Null, string)( null )` is equivalent to 
`DtoVal!(Null,string)( "" )`;
* For other types this will raise a runtime exception:  
`DtoVal!(Null, Person)( null )`.

  * The correct way of is `DtoVal!(Null, Person)( Null() )`

Basically, **`null` is completely useless and out of my code** 
with the exception of strings.



Best regards
Antonio