Re: Function which returns a sorted array without duplicates

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

On Sunday, 22 January 2023 at 23:26:45 UTC, dan wrote:


So what i was missing was std.array.


Of course you can use the uniq from Phobos.  But since we already 
use array, you should also try the 3rd classic version:


```d
import std.algorithm;
import std.array;

// qef. version:
private S[] sortArray ( S )( S[] x )
{
  auto y = x.dup;
  return y.sort.uniq.array;
}

// no dup. version:
private S[] sortArrayy ( S )( S[] x )
{
  S[] w;
  foreach ( v ; x ) w ~= v;
  return w.sort.uniq.array;
}

// classic version:
private S[] sortArrayyy ( S )( S[] x )
{
  S[] w = x.dup;
  w.sort;

  size_t diff;
  for (size_t j, i = 1; i < w.length; ++i) {
if (w[j] != w[i]) {
  w[++j] = w[i];
} else {
  ++diff;
}
  }
  return w[0 .. $ - diff];
}

void main()
{
  uint[] nums = [1, 3, 2, 5, 1, 4, 2, 8];

  auto sorted = nums.sortArray;
  assert(sorted.equal(nums.sortArrayy));
  assert(sorted.equal(nums.sortArrayyy));

  import std.stdio;
  writeln( "Input:  ", nums );
  writeln( "Output: ", sorted );
}
```

In fine, we have implemented 3 ways to sort an array and return 
it without repetition. I guess, there is no alternative to this 
basic algorithm...


SDB@79


Re: Non-ugly ways to implement a 'static' class or namespace?

2023-01-22 Thread Mike Parker via Digitalmars-d-learn
On Monday, 23 January 2023 at 00:36:36 UTC, thebluepandabear 
wrote:




I haven't been programming for a long time, but most of the 
other languages I used had such a namespace feature. Kotlin has 
something called an `object` which is essentially a namespace 
and it is great. The benefits of adding a namespace-like 
feature outweigh its costs, imo.


If you really want to, you can mostly force a namespace use like 
this:


```
// mylib/package.d
module mylib;
public static import mylib.impl.funcs;

// mylib/impl/funcs.d
module mylib.impl.funcs;

void foo() { }
```

Now when users import mylib, the public static import means hey 
call mylib.foo. Just don't bother documenting the impl subpackage 
and only those who look at the source will even know it exists.


I went through this same process when I first came to D years 
ago. D's modules *are* namespaces, and I wanted a way to force 
them. Eventually, I got over it. There's no reason to force a 
namespace. Namespaces are intended to disambiguate conflicting 
symbols. So let the users use them that way. There's no need to 
force them to type out the namespace all the time. It's certainly 
not an OOP vs. procedural issue, as namespaces have nothing to do 
with OOP.


Re: Non-ugly ways to implement a 'static' class or namespace?

2023-01-22 Thread Mike Parker via Digitalmars-d-learn
On Monday, 23 January 2023 at 00:11:17 UTC, thebluepandabear 
wrote:




Sorry don't like that solution specifically. That's because it 
is a procedural implementation, not an OOP-style one. I don't 
know how much of the D community writes procedurally but I'm 
personally an OOP-type of guy.


A class full of static methods is not OOP either.


Re: vibe.d community/forum/whatever ?

2023-01-22 Thread Rey Valeza via Digitalmars-d-learn

On Monday, 30 August 2021 at 02:39:06 UTC, someone wrote:

https://forum.rejectedsoftware.com/groups/rejectedsoftware.vibed/

I've been reading vibe.d tour and some documentation today to 
get some first impressions. https://vibed.org/community pointed 
to the link above ... but it seems it is full of crap.


Hi,

I just uploaded to Github a second edition of the tutorial I 
wrote last year:

https://github.com/reyvaleza/vibed/blob/main/Build%20Web%20Apps%20in%20Vibed%20second%20edition.pdf

Hope this helps.


Re: Non-ugly ways to implement a 'static' class or namespace?

2023-01-22 Thread Ali Çehreli via Digitalmars-d-learn

On 1/22/23 16:21, thebluepandabear wrote:

> Again, stuffing it into a module is not the same thing as a namespace.

That is correct but it is also one answer of D's to namespaces. There 
are others. For example, structs and classes provide namespacing as well.


> The user can just bypass this by writing `drawLine`, there's nothing in
> the language currently that would 'force' the user to write in a
> namespace-like/static-class-like fashion, and that's the biggest problem.

I agree with Adam here. The language should provide solutions and the 
programmer should pick appropriate ones.


Later you added that you were talking about library design. There is no 
problem in the library providing an awesome and very usable API but the 
programmers still picking some other method that works better for them.[1]


I would like to add to your C++ examples:

  Keyboard::Key.A// Fine
  Key.A  // Fine
  foo// Fine

That last line can exactly be the same as the previous two in C++.

OOP is always a solution where it makes sense. I've been very happy with 
writing free-standing functions and dumb data types that the functions 
operate on... until... some invariant matters. Then I make the function 
a member, etc.


Perhaps because I don't buy into the "everything is a class" anymore, I 
am very happy with D's approach. Mostly structs and functions for me. 
But I use classes as well when they make sense.


Having said all that, I realize that your asking specifically for static 
classes made me think of a solution around classes. However, doesn't D 
has the equivalent in structs? Isn't the following what you are looking for?


struct Algo {
static void drawLine(Canvas c, Pos from, Pos to) { .. };
}

Now the user is forced to use it like this:

  Algo.drawLine(new Canvas(), new Pos(5, 3), new Pos(7, 9));

or this:

  Algo().drawLine(/* ... */);

but that can be @disabled.

Ali

[1] It is interesting that limiting the programmer in some way seems to 
help with language marketing. And D is deficient in that marketing move 
because it does the opposite: Gives the programmer choices. I tried to 
show this point on this slide: https://youtu.be/0JL9uT_XGZE?t=701 The 
point "not taking anything away from the programmer" can be seen as a 
marketing issue.




Re: Non-ugly ways to implement a 'static' class or namespace?

2023-01-22 Thread thebluepandabear via Digitalmars-d-learn

On Monday, 23 January 2023 at 00:27:29 UTC, Adam D Ruppe wrote:
On Monday, 23 January 2023 at 00:21:12 UTC, thebluepandabear 
wrote:
there's nothing in the language currently that would 'force' 
the user


Why do you hate freedom?


It's not a freedom issue, it's a library-design issue. Some 
libraries want to incorporate a namespace-like design to force 
the user to be more 'explicit' with what they want.


SFML has a `Keyboard` namespace which has a `Key` enum.

The user is 'forced' (although I am not sure if this is the case 
since it's C++) to use the `Keyboard.` declaration before using 
the `Key` enum. Looking at code block 1 and 2, which makes more 
sense?


```C++
Keyboard::Key.A
```

```C++
Key.A
```

The first one does, because looking at the second one, the person 
who will read the code might be confused what 'Key' means, is it 
a car key, a set of keys for unlocking something, etc?


Now, the user doesn't have to use the library if they don't want 
to. There will be plenty of libraries out there that don't have 
namespaces.


I haven't been programming for a long time, but most of the other 
languages I used had such a namespace feature. Kotlin has 
something called an `object` which is essentially a namespace and 
it is great. The benefits of adding a namespace-like feature 
outweigh its costs, imo.


Re: Non-ugly ways to implement a 'static' class or namespace?

2023-01-22 Thread Adam D Ruppe via Digitalmars-d-learn
On Monday, 23 January 2023 at 00:21:12 UTC, thebluepandabear 
wrote:
there's nothing in the language currently that would 'force' 
the user


Why do you hate freedom?


Re: Non-ugly ways to implement a 'static' class or namespace?

2023-01-22 Thread thebluepandabear via Digitalmars-d-learn
That way of naming a global function is essentially a poor 
man's^W^Wexcuse me, I mean, C's way of working around the lack 
of a proper namespacing / module system. In D, we do have a 
proper module system, so you could just call the function 
`drawLine` and put it in a file named Algo.d, then you can just 
use D's symbol resolution rules to disambiguate between 
Algo.drawLine and PersonalSpace.drawLine, for example. :-P



T


Again, stuffing it into a module is not the same thing as a 
namespace. The user can just bypass this by writing `drawLine`, 
there's nothing in the language currently that would 'force' the 
user to write in a namespace-like/static-class-like fashion, and 
that's the biggest problem.


Re: Non-ugly ways to implement a 'static' class or namespace?

2023-01-22 Thread thebluepandabear via Digitalmars-d-learn

Something interesting.

I know that D has C++ SFML bindings, although they are 
unmaintained.


I was interested to see how they would 'implement' the C++ 
namespaces of SFML, and - boy was I surprised.


Reading through `DSFML`, I see `final abstract class` getting 
used to implement SFML's `Keyboard` namespace:


`final abstract class Keyboard` at 
https://github.com/Jebbs/DSFML/blob/master/src/dsfml/window/keyboard.d


It seems like using `final abstract` is the best solution.




Re: Non-ugly ways to implement a 'static' class or namespace?

2023-01-22 Thread thebluepandabear via Digitalmars-d-learn

// app.d

import API = api;


void main()
{
API.draw();
}

```


Another thing that I don't like about that solution, is that it 
doesn't 'force' the user to write in a namespace-like style.


C++ `namespaces` force you to (I believe), and so does `static 
class` from Java/C#.


D is both an object oriented and procedural language, I would 
honestly love to see some sort of `namespace` or `static class` 
feature come into the language. I know that it's controversial 
here, but I would honestly think it would help develop the 
language in a good way. But that's just my opinion.


Re: Non-ugly ways to implement a 'static' class or namespace?

2023-01-22 Thread thebluepandabear via Digitalmars-d-learn

On Sunday, 22 January 2023 at 18:30:59 UTC, ryuukk_ wrote:
On Friday, 20 January 2023 at 11:28:23 UTC, thebluepandabear 
wrote:



D is not java/C#, it's better than that!


```D

// api.d

void draw(){}


// app.d

import API = api;


void main()
{
API.draw();
}

```


Sorry don't like that solution specifically. That's because it is 
a procedural implementation, not an OOP-style one. I don't know 
how much of the D community writes procedurally but I'm 
personally an OOP-type of guy.


Re: Function which returns a sorted array without duplicates

2023-01-22 Thread dan via Digitalmars-d-learn

On Sunday, 22 January 2023 at 07:33:01 UTC, evilrat wrote:

On Sunday, 22 January 2023 at 04:42:09 UTC, dan wrote:
I would like to write a function which takes an array as 
input, and returns a sorted array without duplicates.



```d
private S[] _sort_array( S )( S[] x ) {
  import std.algorithm;
  auto y = x.dup;
  y.sort;
  auto z = y.uniq;
  // Cannot just return z; this gives:
  // Error: cannot implicitly convert expression `z` of 
type

  // `UniqResult!(binaryFun, uint[])` to `uint[]`


uniq and other algorithms often returns a lazy range, you can 
build an array by using `std.array.array()`


https://dlang.org/phobos/std_array.html#array

try something like this or just `return array(y.uniq);`

```d
private S[] _sort_array( S )( S[] x ) {
import std.algorithm;
import std.array;
return x.dup
   .sort
   .uniq
   .array();
}
```

And IIRC you probably don't need `dup` as sort produces a lazy 
range.


Thanks evilrat, this works perfectly, and is just the right style 
too (imvho).


So what i was missing was std.array.

Thanks also Ali for your subsequent clarifying remarks.

(Probably what i need to do is read a good book on the std 
library for d.)


dan

Thanks also Ali for your subsequent remarks


Re: Function which returns a sorted array without duplicates

2023-01-22 Thread Ali Çehreli via Digitalmars-d-learn

On 1/21/23 23:33, evilrat wrote:

> And IIRC you probably don't need `dup`

Unfortunately, no. Skipping .dup is only possible if we are allowed to 
sort the original array.


> as sort produces a lazy range.

sort() returns a SortedRange but it can't be lazy. Even if it were, the 
first call to .front would have to sort anyway. However...


There is an optimization possible for such requirements if not all 
elements but just a number of them are needed. For example, if only the 
first 10 elements are needed, then a binary heap may be faster:


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

The usage would be similar to the following for "the first 10 unique 
elements":


  heapify(arr).uniq.take(10)

(Not tested.)

Ali



Re: Non-ugly ways to implement a 'static' class or namespace?

2023-01-22 Thread ryuukk_ via Digitalmars-d-learn
On Friday, 20 January 2023 at 11:28:23 UTC, thebluepandabear 
wrote:



D is not java/C#, it's better than that!


```D

// api.d

void draw(){}


// app.d

import API = api;


void main()
{
API.draw();
}

```


Re: Hipreme's #8 Tip of the day - Using custom runtime with dub projects

2023-01-22 Thread evilrat via Digitalmars-d-learn

On Sunday, 22 January 2023 at 18:16:35 UTC, Hipreme wrote:


Nope. Those DFLAGS environment variable is used to affect 
projects such as my dependencies. For example, my dependency 
needs to be built using my own runtime. The dflags defined in 
the dub.json only affect the current project, not its 
dependencies


Ah ok, got it, the compiler will fetch them for a whole session 
no matter what is currently being built.


Though this approach will make it harder to anyone who might want 
to use your project/library if this requirement remains for a 
user's project.


Re: Hipreme's #8 Tip of the day - Using custom runtime with dub projects

2023-01-22 Thread Hipreme via Digitalmars-d-learn

On Sunday, 22 January 2023 at 17:06:13 UTC, evilrat wrote:

On Sunday, 22 January 2023 at 16:57:56 UTC, Hipreme wrote:


The way to use dub's packages is by using the DFLAGS. With 
DFLAGS, I can set the import path to my own DRuntime and own 
std. That way I can make the dependencies behave more or less 
the same, this is an example of what is being done now:


Keep in mind that you'll probably need to setup some env 
variables such as mine done for making your script a little 
more portable to other developer's PCs. I would really like if 
there was a way to define global dflags on dub though.


Can't you just use env variable[1] and put into dub dflags like 
this?


https://github.com/Superbelko/ohmygentool/blob/cc75d915a8df8bdc2bba628df305d421151994a1/dub.json#L11


_(note that some of the listed predefines doesn't work in some 
sections though, a bug maybe?)_
[1] 
https://dub.pm/package-format-json.html#environment-variables


Nope. Those DFLAGS environment variable is used to affect 
projects such as my dependencies. For example, my dependency 
needs to be built using my own runtime. The dflags defined in the 
dub.json only affect the current project, not its dependencies


Re: Hipreme's #8 Tip of the day - Using custom runtime with dub projects

2023-01-22 Thread evilrat via Digitalmars-d-learn

On Sunday, 22 January 2023 at 16:57:56 UTC, Hipreme wrote:


The way to use dub's packages is by using the DFLAGS. With 
DFLAGS, I can set the import path to my own DRuntime and own 
std. That way I can make the dependencies behave more or less 
the same, this is an example of what is being done now:


Keep in mind that you'll probably need to setup some env 
variables such as mine done for making your script a little 
more portable to other developer's PCs. I would really like if 
there was a way to define global dflags on dub though.


Can't you just use env variable[1] and put into dub dflags like 
this?


https://github.com/Superbelko/ohmygentool/blob/cc75d915a8df8bdc2bba628df305d421151994a1/dub.json#L11


_(note that some of the listed predefines doesn't work in some 
sections though, a bug maybe?)_

[1] https://dub.pm/package-format-json.html#environment-variables


Hipreme's #8 Tip of the day - Using custom runtime with dub projects

2023-01-22 Thread Hipreme via Digitalmars-d-learn
I have been working with WebAssembly for at least 1 entire month 
into getting my entire Game Engine and DRuntime ported to it. As 
I'm almost reaching the point of the new announcement, I come 
here to show how I've done DUB's dependency compatibility with a 
custom runtime.


The way to use dub's packages is by using the DFLAGS. With 
DFLAGS, I can set the import path to my own DRuntime and own std. 
That way I can make the dependencies behave more or less the 
same, this is an example of what is being done now:



```
set DFLAGS=-I=%HIPREME_ENGINE%/modules/d_std/source ^
-I=%HIPREME_ENGINE%/build/wasm/runtime/webassembly/arsd-webassembly ^
-preview=shortenedMethods ^
-L-allow-undefined ^
-fvisibility=hidden ^
-d-version=CarelessAlocation

dub build --build=debug -c wasm  
--arch=wasm32-unknown-unknown-wasm

```


So, when dub tried to build their dependencies, your custom 
runtime overrides D's default ones. In that case I'm overriding 
both D std and D core/** and object.d


Keep in mind that you'll probably need to setup some env 
variables such as mine done for making your script a little more 
portable to other developer's PCs. I would really like if there 
was a way to define global dflags on dub though.


Re: Is there a way to get a template’s parameters and constraints?

2023-01-22 Thread Adam Ross Walker via Digitalmars-d-learn

On Friday, 20 January 2023 at 17:15:31 UTC, Quirin Schroll wrote:
Is there a trait (or a combination of traits) that gives me the 
constraints of a template?


Apologies, I missed the key part of your question.  But I think 
the above can be adapted if you were so inclined.


Re: Is there a way to get a template’s parameters and constraints?

2023-01-22 Thread Adam Ross Walker via Digitalmars-d-learn
There is a way but it's horrible.  You can take the `.stringof` 
and parse the result.  I knocked this up for something but it's 
not well tested and there are probably templates that it handles 
incorrectly.  I'm not claiming this is any good, I just happened 
to have it.


```d
enum TemplateParameterType { valueType, aliasType, typeType, 
thisType, sequenceType }


public struct TemplateParameter
{
TemplateParameterType type;
string name;
string defaultValue;
}

public auto templateParameters(alias T)()
{
static assert(__traits(isTemplate, T));

import std.algorithm : startsWith;
import std.array : appender;
import std.string : strip;

auto results = appender!(TemplateParameter[]);
auto isMissing = false;
const templateSignature = T.stringof;
const allParametersStart = 
findExpectedSource(templateSignature,  
'(', isMissing) + 1;

const allParametersEnd   = allParametersStart +
  
findExpectedSource(templateSignature[allParametersStart .. $], 
')', isMissing);


if (isMissing)
throw new Exception("{Expected `(` and `)` in template 
signature: `" ~ templateSignature ~ "`.");


auto parametersText = templateSignature[allParametersStart .. 
allParametersEnd];

auto parameterIndex = -1;

mainParameterLoop:
while (parametersText.length > 0)
{
parameterIndex++;

auto parameterEnd = findExpectedSource(parametersText, 
',', isMissing);

if (isMissing)
parameterEnd = parametersText.length;

auto parameterRemainingText = parametersText[0 .. 
parameterEnd];


if (parameterEnd < parametersText.length)
parametersText = parametersText[parameterEnd + 1 .. 
$];

else
parametersText = "";

auto token = parameterRemainingText.consumeToken;

if (parameterRemainingText.startsWith("..."))
{

results.put(TemplateParameter(TemplateParameterType.sequenceType, 
token, ""));

continue mainParameterLoop;
}

auto nextToken = parameterRemainingText.consumeToken;
if (nextToken == "")
{

results.put(TemplateParameter(TemplateParameterType.typeType, 
token, ""));

continue mainParameterLoop;
}

TemplateParameterType type;

if (token == "this")
type = TemplateParameterType.thisType;
else if (token == "alias")
type = TemplateParameterType.aliasType;
else if (nextToken == ":" || nextToken == "=")
type = TemplateParameterType.typeType;
else
type = TemplateParameterType.valueType;

if (type != TemplateParameterType.typeType)
{
token = nextToken;
nextToken = parameterRemainingText.consumeToken;
}

while (true)
{
if (nextToken == "")
{
results.put(TemplateParameter(type, token, ""));
continue mainParameterLoop;
}

if (nextToken == ":")
{
const identifierName = token;
while (true)
{
token = parameterRemainingText.consumeToken;
if (token.length == 0)
{
results.put(TemplateParameter(type, 
identifierName, ""));

continue mainParameterLoop;
}
else if (token == "=")
{
results.put(TemplateParameter(type, 
identifierName, parameterRemainingText.strip));

continue mainParameterLoop;
}
}

results.put(TemplateParameter(type, 
identifierName, parameterRemainingText.strip));

continue mainParameterLoop;
}

if (nextToken == "=")
{
const identifierName = token;
results.put(TemplateParameter(type, 
identifierName, parameterRemainingText.strip));

continue mainParameterLoop;
}

token = nextToken;

import std.conv : to;
if (token.length == 0)
throw new Exception("Cannot parse parameter " ~ 
parameterIndex.to!string ~ " in template `" ~ templateSignature ~ 
"`.");


nextToken = parameterRemainingText.consumeToken;
}
}

return results[];
}

private auto findExpectedCharacter(string source, char character, 
out bool isMissing)

{
foreach (offset; 0 .. source.length)
if (source[offset] == character)
return offset;

isMissing = true;
return 0;
}

private auto findExpectedText(string source, string text, out 
bool isMissing)

{
import std.algorithm : startsWith;

foreach (offset; 0 .. source.length)
if (source[offset .. $].startsWith(text))
return