Re: How to build a specific library version with dub?

2021-04-15 Thread martinm via Digitalmars-d-learn

On Sunday, 11 April 2021 at 15:01:04 UTC, Mike Parker wrote:

On Sunday, 11 April 2021 at 13:43:47 UTC, martinm wrote:
I'm trying to use wayland-d which depends on 
derelict-util-2.0.6.

DUB can't download the zip and fails.
I download the zip to ~/.dub/packages/derelict-util folder, 
unzip and build.

DUB builds **DerelictUtil.a ~master**.


That's not how to go about this. You should never need to 
manually install a library for dub to use it.


I think so, too but when it's not working what can I do.
I wrote 2. sentence DUB fails can't download, timeout and fails.


Assuming you mean this library:

https://github.com/rtbo/wayland-d


Yes that one.

It's the DerelictUtil dependency is configured as ~>2.0.3. This 
syntax means >= 2.0.3 and < 2.1.0. So when you build the 
wayland package for the first time, dub should pick up the 
latest version in the 2.0.x series without any special help 
from you.


Like said before. DUB download does not work.



Trying to rebuild wayland-d, DUB can't find 
**derelict-util-2.0.6** dependency.

*dub list | grep -i derelict* shows:
*derelict-util ~master 
~/.dub/packages/derelict-util-2.0.6/derelict-util/*

is there.



Dub is picking up `~master` in this case because you 
**manually** copied DerelictUtil into the .dub directory from 
the zip file. Dub has absolutely no way to know what version of 
the library that is un less you tell  it (see below).


Yes, I download DerelictUtil v. 2.0.6 release from github, unzip 
in .dub/packages and build myself.




How can DUB build 2.0.6 version ?
*dub build library@2.0.6* fails
*(1) : Error: Got JSON of type null_, expected object.*


Have you modified DerelictUtil's dub.json in any way? I just 
ran `dub build` on the 2.0 branch of DerelictUtil and built 
2.0.6 without error.


Yes, I added "version": "2.0.6" to dub.json and 2.0.6 is now 
correctly in registry.




How can I change registry and manually change **~master** to 
**2.0.6** ?




IMO, the best thing to do is to delete the DerelictUtil folder 
you unzipped and let dub pull down DerelictUtil automatically, 
then it will know it has 2.0.6.


DUB still fails to download file itself. Maybe DUB should try 
GITHUB like I did.


However, whenever you want to manually install a package, you 
don't have to put the source files in the .dub directory. You 
can put them anywhere on your system, then use the dub command 
line to add that folder to your local registry and specify the 
version. Something like: `dub add-local . --version=2.0.6`.
You could also just run `dub fetch derelict-util 
--version=2.0.6`.


This is good advice. Thank you.

I know my way is bad but it works for me and I prefer Makefile 
than DUB. Makefile can be complex but if problem I search in 
internet and 5 or 10 minutes later problem is solved. DUB is good 
when works but when not I see ??? I search in internet and find 
nothing and need come to forum and after 1h, problem can be fixed 
or not.


But thank you for explanation.


Re: Range Error

2021-04-15 Thread martinm via Digitalmars-d-learn

On Sunday, 11 April 2021 at 19:48:42 UTC, Ruby The Roobster wrote:
On Sunday, 11 April 2021 at 19:45:30 UTC, Ruby The Roobster 
wrote:

What am I doing wrong here? Is it the 'for' loop?
Nevermind. I messed up what line it was. It was actually this 
line:



```d
square[i][j] = new Square(Color.none, sColor.white);
```


This is maybe interesting for you: 
https://wiki.dlang.org/Component_programming_with_ranges


Re: How do I create classes dynamically?

2021-04-15 Thread Ali Çehreli via Digitalmars-d-learn

On 4/14/21 1:38 PM, Mario wrote:

> Maybe I am just too short in D, but I wanted to find out if it is
> possible to create classes dynamically.

In D world, "dynamically" means "at run time".

> Maybe at mixin templates?

Both mixins and templates are compile time features.

> Normally I would think of a macro first

If we are talking about C (and C++) macros, they are compile time 
features as well.


So, I think you want help from D to generate types, which can happen 
only at compile time with statically-typed languages like D. And yes, D 
is a great language for "generative programming" like that.


> "I was not written, but still I exist!"

Not possible by this "programming language", which wants a source code 
written, by a human or a machine, to be compiled. Still, anything is 
possible: For example, you can generate source code, dispatch a 
compiler, and load dynamically at run time. :)


Ali



Re: How do I create classes dynamically?

2021-04-15 Thread Imperatorn via Digitalmars-d-learn

On Wednesday, 14 April 2021 at 20:38:16 UTC, Mario wrote:
Maybe I am just too short in D, but I wanted to find out if it 
is possible to create classes dynamically. My problem is, I 
just don't know where to start reading. Maybe at mixin 
templates?


CreateClassWithName!("MyDynamicClassName");

should create the following class to work with dynamically:

class MyDynamicClassName {
this() { writeln("I was not written, but still I exist!"); }
}

So that I in the end by means of

MyDynamicClassName cls = new MyDynamicClassName;

can work with it.

Normally I would think of a macro first, but as far as I 
understood D doesn't know macros (which I'm not really sad 
about), but maybe I'm just thinking too complicated yet. I 
would appreciate any hints, because as I said, I don't even 
know where to start reading.


ldc.JIT presumably has smth like that

https://gist.github.com/eldar/2294388

Also look up ldc.dynamic_compile


Re: How do I create classes dynamically?

2021-04-15 Thread Kagamin via Digitalmars-d-learn

On Wednesday, 14 April 2021 at 20:38:16 UTC, Mario wrote:
Maybe I am just too short in D, but I wanted to find out if it 
is possible to create classes dynamically. My problem is, I 
just don't know where to start reading. Maybe at mixin 
templates?


CreateClassWithName!("MyDynamicClassName");

should create the following class to work with dynamically:

class MyDynamicClassName {
this() { writeln("I was not written, but still I exist!"); }
}

So that I in the end by means of

MyDynamicClassName cls = new MyDynamicClassName;


String mixins is D replacement of macros for code generation.
Works like this:
```d
mixin("class MyDynamicClassName { }");
MyDynamicClassName cls = new MyDynamicClassName;
```


Re: How do I create classes dynamically?

2021-04-15 Thread Imperatorn via Digitalmars-d-learn

On Thursday, 15 April 2021 at 16:39:30 UTC, Kagamin wrote:

On Wednesday, 14 April 2021 at 20:38:16 UTC, Mario wrote:
Maybe I am just too short in D, but I wanted to find out if it 
is possible to create classes dynamically. My problem is, I 
just don't know where to start reading. Maybe at mixin 
templates?


CreateClassWithName!("MyDynamicClassName");

should create the following class to work with dynamically:

class MyDynamicClassName {
this() { writeln("I was not written, but still I exist!"); 
}

}

So that I in the end by means of

MyDynamicClassName cls = new MyDynamicClassName;


String mixins is D replacement of macros for code generation.
Works like this:
```d
mixin("class MyDynamicClassName { }");
MyDynamicClassName cls = new MyDynamicClassName;
```


Yes but not at runtime


Re: How do I create classes dynamically?

2021-04-15 Thread Martin via Digitalmars-d-learn

On Wednesday, 14 April 2021 at 20:38:16 UTC, Mario wrote:
I wanted to find out if it is possible to create classes 
dynamically.


out of curiosity: Why you would like to do this? I cannot think 
of a use case for this - this is why i ask.


AliasSeq different from just using the symbol name(s)?

2021-04-15 Thread z via Digitalmars-d-learn
I've tried to group together a bundle of alias template 
parameters with AliasSeq, but while without it works just fine, 
when the verbose parameters are grouped with multiple AliasSeqs, 
the lengths of the array parameters passed through AliasSeq are 
0(inside the templated function, before the call it's still OK) 
and a range violation/exception occurs.


This is weird because the templated function does not change the 
length of its array parameters, and printing the parameter's 
string name to stdout at runtime shows that they are supposedly 
the same(in symbol name at least), but somehow it isn't the same?


To see what i mean : https://run.dlang.io/is/VXDRL4 (i could not 
manage to trigger it here however.)


Big thanks


Re: AliasSeq different from just using the symbol name(s)?

2021-04-15 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 15 April 2021 at 18:43:29 UTC, z wrote:
To see what i mean : https://run.dlang.io/is/VXDRL4 (i could 
not manage to trigger it here however.)


Without an example that shows the actual problem you encountered, 
it will be almost impossible for anyone to help you figure out 
what is causing it.


Since you were not able to trigger it, it seems likely that the 
problem is related to something other than the AliasSeq which you 
have left out of the example.


Re: AliasSeq different from just using the symbol name(s)?

2021-04-15 Thread z via Digitalmars-d-learn

On Thursday, 15 April 2021 at 18:58:40 UTC, Paul Backus wrote:
Without an example that shows the actual problem you 
encountered, it will be almost impossible for anyone to help 
you figure out what is causing it.


Since you were not able to trigger it, it seems likely that the 
problem is related to something other than the AliasSeq which 
you have left out of the example.


I understand that it won't be possible to pinpoint the cause 
without a reduced test case, but :


```D
int[] a,b,c,d,e;
void templatef(args...){/*...*/}
//...
auto seq = AliasSeq!(b,c,d);
templatef!(a,seq,e);
templatef!(a,b,c,d,e); //am i being mistaken for thinking these 
two template calls should be equivalent in behavior?

```
And if not, does it mean that the problem i encountered is a 
possible bug?


Re: AliasSeq different from just using the symbol name(s)?

2021-04-15 Thread z via Digitalmars-d-learn

On Thursday, 15 April 2021 at 19:38:04 UTC, z wrote:

```D
int[] a,b,c,d,e;
void templatef(args...){/*...*/}
//...
auto seq = AliasSeq!(b,c,d);
templatef!(a,seq,e);
templatef!(a,b,c,d,e); //am i being mistaken for thinking these 
two template calls should be equivalent in behavior?

```

woops, meant `void templatef(args...)(){}`


Re: AliasSeq different from just using the symbol name(s)?

2021-04-15 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 15 April 2021 at 19:38:04 UTC, z wrote:
I understand that it won't be possible to pinpoint the cause 
without a reduced test case, but :


```D
int[] a,b,c,d,e;
void templatef(args...){/*...*/}
//...
auto seq = AliasSeq!(b,c,d);
templatef!(a,seq,e);
templatef!(a,b,c,d,e); //am i being mistaken for thinking these 
two template calls should be equivalent in behavior?

```
And if not, does it mean that the problem i encountered is a 
possible bug?


They're not *exactly* the same. When you write

auto seq = AliasSeq!(a, b, c);

...you are declaring a sequence of three *new* array variables 
[1] and initializing them with copies of the original arrays. 
It's as though you'd written:


auto seq_a = a;
auto seq_b = b;
auto seq_c = c;
alias seq = AliasSeq!(a, b, c);

If you want to refer directly to the original variables, you need 
to create your sequence with `alias` instead of `auto`:


alias seq = AliasSeq!(a, b, c);

[1] 
https://dlang.org/articles/ctarguments.html#type-seq-instantiation


Re: How do I create classes dynamically?

2021-04-15 Thread mw via Digitalmars-d-learn

On Thursday, 15 April 2021 at 18:21:16 UTC, Martin wrote:

On Wednesday, 14 April 2021 at 20:38:16 UTC, Mario wrote:
I wanted to find out if it is possible to create classes 
dynamically.


out of curiosity: Why you would like to do this? I cannot think 
of a use case for this - this is why i ask.


In response to user input?

e.g. createObject(userInputString);

of course, one can manually dispatch:

if  (userInputString == "cat") createCat();
else if (userInputString == "dog") createDog();
...

but this this tedious.


I have a similar question: how to dynamically use user's input 
string as function name can call it? suppose the function has no 
argument.


callFunc(userInputString)();  // call that func.

again, one can manually dispatch, but is there a way to avoid 
this tediousness?






Re: How do I create classes dynamically?

2021-04-15 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Apr 15, 2021 at 08:56:18PM +, mw via Digitalmars-d-learn wrote:
[...]
> of course, one can manually dispatch:
> 
> if  (userInputString == "cat") createCat();
> else if (userInputString == "dog") createDog();
> ...
> 
> but this this tedious.

---
// Disclaimer: this is proof of concept, I didn't actually run this yet
class Animal {}
class Cat : Animal {}
class Dog : Animal {}

alias SupportedTypes = AliasSeq!(Cat, Dog, /* whatever else you want here */);

string userInputString = ...;
Animal result;
SW: switch (userInputString) {
static foreach (T; SupportedTypes) {
case T.stringof:
result = new T;
break SW;
}
default:
throw new Exception("Unknown object type");
}
---


> I have a similar question: how to dynamically use user's input string
> as function name can call it? suppose the function has no argument.

Same idea:

---
// Disclaimer: this is proof of concept, I didn't actually run this yet
struct Dispatcher {
void bark() { ... }
void meow() { ... }
void moo() { ... }
... // whatever else you want here
}

Dispatcher disp;
string userInputString = ...;
SW: switch (userInputString) {
static foreach (fieldName; __traits(allMembers, disp)) {
static if (is(typeof(__traits(getMember, disp, fieldName))
== function)
{
case fieldName:
__traits(getMember, disp, fieldName)();
break SW;
}
}
}
---

Basically, the idea is to obtain a list of types/methods/whatever
somehow (either by explicitly listing instances, or via compile-time
introspection), then statically generate switch cases from it.  You can
eliminate many kinds of boilerplate using this little trick.


T

-- 
Береги платье снову, а здоровье смолоду. 


Re: How do I create classes dynamically?

2021-04-15 Thread Jack via Digitalmars-d-learn

On Thursday, 15 April 2021 at 17:48:02 UTC, Imperatorn wrote:

On Thursday, 15 April 2021 at 16:39:30 UTC, Kagamin wrote:

On Wednesday, 14 April 2021 at 20:38:16 UTC, Mario wrote:

[...]


String mixins is D replacement of macros for code generation.
Works like this:
```d
mixin("class MyDynamicClassName { }");
MyDynamicClassName cls = new MyDynamicClassName;
```


Yes but not at runtime


Could you give an example of what you're trying to archive?


Re: How do I create classes dynamically?

2021-04-15 Thread Ali Çehreli via Digitalmars-d-learn

On 4/15/21 1:56 PM, mw wrote:

>>> I wanted to find out if it is possible to create classes dynamically.
>>
>> out of curiosity: Why you would like to do this? I cannot think of a
>> use case for this - this is why i ask.
>
> In response to user input?

That's a different question because creating a class is different from 
creating instances (objects) of existing classes.


> again, one can manually dispatch, but is there a way to avoid this
> tediousness?

H. S. Teoh showed methods where lookup keys are known at compile time 
and are used to generate e.g. a switch statement.


I have a system where the main logic of the program has no idea what 
types are out there. All it has is a lookup table. (Uncompiled pseude 
code follows.)


struct Functions {
  void * function deserialize(ubyte[] bytes);
  void function process(void* input, void* output);
  void function serialize(ubyte[] bytes);
}

shared Functions[string] registration;

So, the main logic uses user input to look up what the functions are:

  auto funcs = registration[userInput];

And applies those functions to some data at runtime.

This is "dynamic" because registration is populated by the 'shared 
static this()' blocks of unknown modules that are loaded dynamically 
(and in my case conditionally):


module foo;

// This struct is what this module is about:
struct Foo {
  // ...
}

// The module registers itself with the main lookup system when loaded:
shared static this() {
  register("my lookup string",
   Functions(&deserializer!Foo,
 &processor!Foo,
 &serializer!Foo));
}

Note that registered functions are template instances tailored for this 
specific type. However, the main logic has no klowledge of individual 
modules, not even the templates like 'deserializer': It only knows about 
a lookup table that contains some function pointers.


I haven't used object creation functions above but that can be added to 
Functions as well.


Ali



How to implement a range?

2021-04-15 Thread Jack via Digitalmars-d-learn
In order to my array class work with filter, I went to implement 
an ``InputRange``. But I don't quite get how do that and didn't 
find much help on the docs. From below code, is ``moveFront()`` 
implemented correctly? I'm using a simple int i as index of 
current item and in popFront() just increment it. I must reset 
the i value once the loop is done, right? where am I supposed to 
do that? opApply()? not properly reseting it result in obvious 
bugs like subsequent calls doesn't work because the index is in 
the end of the array:


```d
auto arr = new MyArray!int;
arr.Add(1);
arr.Add(2);
arr.Add(3);
arr.Add(4);
auto r = arr.filter!(n => (n % 2) == 0);
auto r2 = arr.filter!(n => n >= 2);
writeln(r); // ok
writeln(r2); // empty
```

yeah, i'm a bit confused... here's the code:

```d
class MyArray(T) : InputRange!T
{
private T[] arr;
private int i = 0;

void Add(T item)
{
arr ~= item;
}

void Add(T[] items)
{
foreach(item; items)
{
Add(item);
}
}

size_t length() nothrow
{
return arr.length;
}

bool empty()
{
return i == length;
}

T front()
{
return arr[i];
}

void popFront()
{
i++;
}

T moveFront()
{
auto r = front;
popFront();
return r;
}

int opApply(scope int delegate(ref T) dg)
{
int result = 0;

foreach (item; arr)
{
result = dg(item);
if (result) {
break;
}
}

return result;
}

int opApply(scope int delegate(T) dg)
{
int result = 0;

foreach (item; arr)
{
result = dg(item);
if (result) {
break;
}
}

return result;
}

int opApply(scope int delegate(uint, T) dg)
{
int result = 0;

foreach (j, item; arr)
{
result = dg(j, item);
if (result) {
break;
}
}

return result;
}
}
```


Re: How to implement a range?

2021-04-15 Thread Mike Parker via Digitalmars-d-learn

On Friday, 16 April 2021 at 06:21:35 UTC, Jack wrote:
In order to my array class work with filter, I went to 
implement an ``InputRange``. But I don't quite get how do that 
and didn't find much help on the docs. From below code, is 
``moveFront()`` implemented correctly? I'm using a simple int i 
as index of current item and in popFront() just increment it. I 
must reset the i value once the loop is done, right? where am I 
supposed to do that? opApply()? not properly reseting it result 
in obvious bugs like subsequent calls doesn't work because the 
index is in the end of the array:




Generally, you don't want your containers to be ranges 
themselves. You want them to produce ranges, i.e., separate the 
duties of iteration from the duties of the container. Also, it's 
best to make your range types as structs rather than classes for 
an easier time.


A basic input range doesn't need to worry about `moveFront`. So 
you can get away with `empty`, `front`, and `popFront` on a 
struct.


```d
import std.stdio;

class MyArray(T)
{
private T[] _a;

this(T[] a) { _a = a; };
auto opIndex() { return Range(_a[]); }

private static struct Range {
T[] a;
T front() { return a[0]; }
void popFront() { a = a[1 .. $]; }
bool empty() { return a.length == 0; }
}
}

void main()
{
auto ma = new MyArray!int([10, 20, 30, 44, 55]);
foreach(i; ma[])
{
writeln(i);
}
}
```

I've overloaded the slice operator via the no-arg `opIndex` to 
provide the range so that you can do `ma[]` to get to it. You'd 
want to expand on that to handle start & end points for a slice.


But anyway, the whole idea behind ranges is you want to keep your 
iteration separate from the data. Then ranges can be copied 
around and consumed without every changing the original data 
structure.