Re: Filter for opDispatch?

2021-05-15 Thread frame via Digitalmars-d-learn

On Sunday, 16 May 2021 at 04:38:52 UTC, Mike Parker wrote:

On Sunday, 16 May 2021 at 04:07:15 UTC, frame wrote:



But the same with fields work? They are also protected.


I'm not sure what you mean by "fields" here.


```d
protected:

// inaccessible
/*
void s(int v) {
  _s = v;
}

int s() {
  return _s;
}*/

// no problem here?
int s;
```


Re: Filter for opDispatch?

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

On Sunday, 16 May 2021 at 04:07:15 UTC, frame wrote:



But the same with fields work? They are also protected.


I'm not sure what you mean by "fields" here.


Re: Filter for opDispatch?

2021-05-15 Thread frame via Digitalmars-d-learn

On Sunday, 16 May 2021 at 03:19:04 UTC, Mike Parker wrote:

On Sunday, 16 May 2021 at 00:04:39 UTC, frame wrote:



Yes, but why should the derived class not have access to it?


I don't think that's your problem. From the template docs:

_TemplateInstances_ are always instantiated in the scope of 
where the _TemplateDeclaration_ is declared...


Your `opDispatch` templates are instantiated in the scope of 
`Base`, from which `_s` is not accessible when it's protected.


Indeed, the error goes away if each derived class has its own 
implementation.


But the same with fields work? They are also protected.


Re: Filter for opDispatch?

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

On Sunday, 16 May 2021 at 00:04:39 UTC, frame wrote:



Yes, but why should the derived class not have access to it?


I don't think that's your problem. From the template docs:

_TemplateInstances_ are always instantiated in the scope of 
where the _TemplateDeclaration_ is declared...


Your `opDispatch` templates are instantiated in the scope of 
`Base`, from which `_s` is not accessible when it's protected.


Re: Filter for opDispatch?

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

On Sunday, 16 May 2021 at 00:04:39 UTC, frame wrote:

On Saturday, 15 May 2021 at 23:59:49 UTC, Paul Backus wrote:


Does it work if you remove `protected` from the derived class?


Yes, but why should the derived class not have access to it?


Possibly because you're accessing it from an `opDispatch` method 
defined in the base class. I'm not 100% sure how `protected` 
works in that case, but just from reading the spec it seems like 
it could be an issue.


Re: ugly and/or useless features in the language.

2021-05-15 Thread zjh via Digitalmars-d-learn

I want to be able to support CP936, not just UTF8.

I can't use CP936. It's my pet peeve.

Hopefully we can solve the coding problem just like Python with 
#encoding= GBK.


Re: Filter for opDispatch?

2021-05-15 Thread frame via Digitalmars-d-learn

On Saturday, 15 May 2021 at 23:59:49 UTC, Paul Backus wrote:

On Saturday, 15 May 2021 at 23:41:19 UTC, frame wrote:

On Friday, 14 May 2021 at 23:02:22 UTC, frame wrote:

Thanks! I stumbled around with static asserts and mixins... 
totally forgot about the constraints but they will to the 
trick.


Now I run into the error

"class Foo member s is not accessible"
"template instance Base.opDispatch!("s", int, Foo) error 
instantiating"


and I have no clue why.


Does it work if you remove `protected` from the derived class?


Yes, but why should the derived class not have access to it?


Re: Filter for opDispatch?

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

On Saturday, 15 May 2021 at 23:41:19 UTC, frame wrote:

On Friday, 14 May 2021 at 23:02:22 UTC, frame wrote:

Thanks! I stumbled around with static asserts and mixins... 
totally forgot about the constraints but they will to the 
trick.


Now I run into the error

"class Foo member s is not accessible"
"template instance Base.opDispatch!("s", int, Foo) error 
instantiating"


and I have no clue why.


Does it work if you remove `protected` from the derived class?


Re: Filter for opDispatch?

2021-05-15 Thread frame via Digitalmars-d-learn

On Friday, 14 May 2021 at 23:02:22 UTC, frame wrote:

Thanks! I stumbled around with static asserts and mixins... 
totally forgot about the constraints but they will to the trick.


Now I run into the error

"class Foo member s is not accessible"
"template instance Base.opDispatch!("s", int, Foo) error 
instantiating"


and I have no clue why.

I swear the original code is just simple as that and 
satisfyDispatch works fine (there is no problem if I change s to 
a simple field).


```d
abstract class Base {
  void opDispatch(string property, S, this T)(auto ref S v) // if 
(satisfyDispatch!(T, property))

  {
 __traits(getMember, cast(T) this, property) = v; // error 
reported here

  }

  auto opDispatch(string property, this T)() // if 
(satisfyDispatch!(T, property))

  {
return __traits(getMember, cast(T) this, property);
  }
}

// other module
class Foo : Base {
  protected:
int _s;

// int s; // would work

void s(int v) {
_s = v;
}

int s() {
return _s;
}
}

// called from a method like this:
void updateValue(T, V)(V value, Object object) {
   (cast(T) object).opDispatch!(property)(value);
}

```

I first thought the compiler does a recursive call on 
__traits(getMember) but it has no problems with this simple code 
above.


Re: ugly and/or useless features in the language.

2021-05-15 Thread Ola Fosheim Grostad via Digitalmars-d-learn

On Saturday, 15 May 2021 at 14:31:08 UTC, Alain De Vos wrote:

Feature creep can make your own code unreadable.


Having many ways to express the same concept makes code harder to 
read. This is an issue in C++, but you can combat it by creating 
coding norms.


In general it is better to have fewer features and instead 
improve metaprogramming so that missing features can be done in a 
library.


Also some features could be merged, like alias and enum constants.



Re: struct destructor

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

On Saturday, 15 May 2021 at 18:26:08 UTC, Adam D. Ruppe wrote:

On Saturday, 15 May 2021 at 17:55:17 UTC, Alain De Vos wrote:
Feature request, a function old which does the opposite of 
new, allowing deterministic,real-time behavior and memory 
conservation.


You're best off doing malloc+free if you want complete control 
though.


You can use the heapAlloc / heapFree pair:


https://wiki.dlang.org/Memory_Management#Explicit_Class_Instance_Allocation


Which I added to my package here :-)

https://code.dlang.org/packages/jdiutil

https://github.com/mingwugmail/jdiutil/blob/master/source/jdiutil/memory.d


Re: struct destructor

2021-05-15 Thread Alain De Vos via Digitalmars-d-learn

I'll try first the first tip of Adam, here the code,

```
import std.stdio:writeln;
import core.memory: GC;
void myfun(){
class C{
int[1] x;
}//class C

struct S {
C c=null;
@disable this();

this(int dummy) {
c=new C();
writeln("Constructor");
};//Constructor

~this(){
writeln("Destructor");
.destroy(c);
void * address=GC.addrOf(cast(void *)c);
GC.free(address);
};//destructor
}//struct S
S mys=S(0);
};//myfun()

void main(){
myfun();
};//main
```


Re: struct destructor

2021-05-15 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 15 May 2021 at 17:55:17 UTC, Alain De Vos wrote:
Feature request, a function old which does the opposite of new, 
allowing deterministic,real-time behavior and memory 
conservation.


You're best off doing malloc+free if you want complete control 
though.


Re: struct destructor

2021-05-15 Thread Alain De Vos via Digitalmars-d-learn

Sorry free does , indeed.



Re: struct destructor

2021-05-15 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 15 May 2021 at 18:15:24 UTC, Dennis wrote:

On Saturday, 15 May 2021 at 17:55:17 UTC, Alain De Vos wrote:
Feature request, a function old which does the opposite of 
new, allowing deterministic,real-time behavior and memory 
conservation.


You can use 
[object.destroy](https://dlang.org/phobos/object.html#.destroy) 
to destruct, and 
[GC.free](https://dlang.org/phobos/core_memory.html#.GC.free) 
to free memory allocated with `new`.


Specifically you wanna do:

```
.destroy(*ptr);
GC.free(GC.addrOf(ptr));
```


Re: struct destructor

2021-05-15 Thread Alain De Vos via Digitalmars-d-learn

Thanks, good idea but,
It does not initiate a GC cycle or free any GC memory.


Re: struct destructor

2021-05-15 Thread Dennis via Digitalmars-d-learn

On Saturday, 15 May 2021 at 17:55:17 UTC, Alain De Vos wrote:
Feature request, a function old which does the opposite of new, 
allowing deterministic,real-time behavior and memory 
conservation.


You can use 
[object.destroy](https://dlang.org/phobos/object.html#.destroy) 
to destruct, and 
[GC.free](https://dlang.org/phobos/core_memory.html#.GC.free) to 
free memory allocated with `new`.


Re: struct destructor

2021-05-15 Thread Alain De Vos via Digitalmars-d-learn
Feature request, a function old which does the opposite of new, 
allowing deterministic,real-time behavior and memory conservation.


Re: Recommendations on avoiding range pipeline type hell

2021-05-15 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 15 May 2021 at 13:46:57 UTC, Chris Piker wrote:
I'm trying to do that, but range3 and range2 are written by me 
not a Phobos wizard, and there's a whole library of template 
functions a person needs to learn to make their own pipelines.  
For example:


Phobos has plenty of design flaws, you don't want to copy that.

Generally you should just accept the range with a simple foreach 
in your handler.


```
void processRange(R)(R r) {
   foreach(item; r) {
  // use item
   }
}
```

If you want it forwarded in a pipeline, make a predicate that 
works on an individual item and pass it to `map` instead of 
trying to forward everything.


If you're creating a range, only worry about the basic three 
functions: empty, front, and popFront. That's the minimum then it 
works with most phobos things too. That's where I balance ease of 
use with compatibility - those three basics let the phobos ones 
iterate through your generated data. Can't jump around but you 
can do a lot with just that.



(personally btw I don't even use most of this stuff at all)




// ... what's with the . before the ElementType statement?


Now that is good to know: that is a D language thing meaning 
"look this up at top level".


So like let's say you are writing a module with

```
void func();

class Foo {
void func();

void stuff() {
 func();
}
}
```

The func inside stuff would normally refer to the local method; 
it is shorthand for `this.func();`.


But what if you want that `func` from outside the class? That's 
where the . comes in:


```
void func();

class Foo {
void func();

void stuff() {
 .func(); // now refers to top-level, no more `this`
}
}
```

In fact, it might help to think of it as specifically NOT wanting 
`this.func`, so you leave the this out.




What the heck is that?


idk i can't read that either, the awful error message are one 
reason why i don't even use this style myself (and the other is 
im just not on the functional bandwagon...)


Most the time std.algorithm vomits though it is because some 
future function required a capability that got dropped in the 
middle.


For example:

some_array.filter.sort


would vomit because sort needs random access, but filter drops 
that. So like sort says "give me the second element" but filter 
doesn't know what the second element is until it actually 
processes the sequence - it might filter out ALL the elements and 
it has no way of knowing if anything is left until it actually 
performs the filter.


And since all these algorithms are lazy, it puts off actually 
performing anything until it has some idea what the end result is 
supposed to be.



The frequent advice here is to stick ".array" in the middle, 
which performs the operation up to that point and puts the result 
in a freshly-created array. This works, but it also kinda 
obscures why it is there and sacrifices the high performance the 
lazy pipeline is supposed to offer, making it process 
intermediate data it might just discard at the next step anyway.


Rearranging the pipeline so the relatively destructive items are 
last can sometimes give better results. (But on the other hand, 
sorting 100,000 items when you know 99,000 are going to be 
filtered out is itself wasted time... so there's no one right 
answer.)



anyway idk what's going on in your case. it could even just be a 
compile error in a predicate, like a typo'd name. it won't tell 
you, it just vomits up so much spam it could fill a monty python 
sketch.


messages. (Using interfaces or *gasp* casts, would break the 
TMI situation.)


i <3 interfaces

it is a pity to me cuz D's java-style OOP is actually pretty 
excellent. a few little things I'd fix if I could, a few nice 
additions I could dream up, but I'm overall pretty happy with it 
and its error messages are much better.


but too many people in the core team are allergic to classes. and 
i get it, classes do cost you some theoretical performance, and a 
lot of people's class hierarchies are hideous af, but hey they 
work and give pretty helpful errors. Most the time.


better know all of std.traits and std.meta cause you're going 
to need them too implement a range-of-ranges consumer.


Write your function like it is Python or javascript - use the 
properties you want on an unconstrained template function.


void foo(T)(T thing) {
// use thing.whatever
// or thing[whatever]
// or whatever you need
}

Even if that's a range of ranges:

void foo(T)(T thing) {
  foreach(range; thing)
  foreach(item; range)
   // use item.
}

It will work if you actually get a range of ranges and if not, 
you get an error anyway. It isn't like the constraint ones are 
readable, so just let this fail where it may. (In fact, I find 
the non-contraint messages to be a little better! I'd rather see 
like "cannot foreach over range" than "no match for ")


I don't even think phobos benefits from its traits signatures. If 
you do 

Re: struct destructor

2021-05-15 Thread Alain De Vos via Digitalmars-d-learn

On Saturday, 15 May 2021 at 16:53:04 UTC, Adam D. Ruppe wrote:

On Saturday, 15 May 2021 at 16:52:10 UTC, Alain De Vos wrote:


When I do a "new" in a struct constructor to assign to a 
member variable of this struct, what do i write in the same 
struct destructor to free the memory ?


If you used `new` the garbage collector is responsible for it.


Can I send a kind message to the garbage collector to please free 
that speficic memory at that time specified ?


struct destructor

2021-05-15 Thread Alain De Vos via Digitalmars-d-learn



When I do a "new" in a struct constructor to assign to a member 
variable of this struct, what do i write in the same struct 
destructor to free the memory ?


Re: struct destructor

2021-05-15 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 15 May 2021 at 16:52:10 UTC, Alain De Vos wrote:


When I do a "new" in a struct constructor to assign to a member 
variable of this struct, what do i write in the same struct 
destructor to free the memory ?


If you used `new` the garbage collector is responsible for it.


Re: Recommendations on avoiding range pipeline type hell

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

On 5/15/21 4:25 AM, Chris Piker wrote:

> But, loops are bad.

I agree with Adam here. Although most of my recent code gravitates 
towards long range expressions, I use 'foreach' (even 'for') when I 
think it makes code more readable.


> Is there some obvious trick or way of looking at the problem that I'm
> missing?

The following are idioms that I use:


* The range is part of the type:

struct MyType(R) {
  R myRange;
}


* If the type is too complicated as in your examples:

struct MyType(R) {
  R myRange;
}

auto makeMyType(X, Y)(/* ... */) {
  auto myArg = foo!X.bar!Y.etc;
  return MyType!(typeof(myArg))(myArg);
}


* If my type can't be templated:

struct MyType {
  alias MyRange = typeof(makeMyArg());
  MyRange myRange;
}

// For the alias to work above, all parameters of this
// function must have default values so that the typeof
// expression is as convenient as above.
auto makeMyArg(X, Y)(X x = X.init, Y y = Y.init) {
  // Then, you can put some condition checks here if
  // X.init and Y.init are invalid values for your
  // program.
  return foo!X.bar!Y.etc;
}

I think that's all really.

And yes, sometimes there are confusing error messages but the compiler 
is always right. :)


Ali



ugly and/or useless features in the language.

2021-05-15 Thread Alain De Vos via Digitalmars-d-learn

Which parts in dlang don't you use and why ?

Personally i have no need for enum types, immutable is doing fine.
Auto return types i find dangerous to use.
Voldermont types.
Named initialiser.
Tuple features.
Maybe some other ?
Feature creep can make your own code unreadable.

Offcourse taste can very from person to person.


Re: Scope of import

2021-05-15 Thread DLearner via Digitalmars-d-learn
On Saturday, 15 May 2021 at 11:38:22 UTC, Adam D. Ruppe wrote> 
Just use

```

dmd -i main.d

instead. It will be about 2x faster and more reliable.

```

Your suggestion worked.
Thank you.




Re: Recommendations on avoiding range pipeline type hell

2021-05-15 Thread Chris Piker via Digitalmars-d-learn

On Saturday, 15 May 2021 at 14:05:34 UTC, Paul Backus wrote:
If you post your code (or at least a self-contained subset of 
it) someone can probably help you figure out where you're 
running into trouble.


Smart idea.  It's all on github.  I'll fix a few items and send a 
link soon as I get a little shut eye.



all I can say from them is, "you must be doing something wrong."


I bet you're right :)

Take Care,



Re: Recommendations on avoiding range pipeline type hell

2021-05-15 Thread Chris Piker via Digitalmars-d-learn

On Saturday, 15 May 2021 at 13:43:29 UTC, Mike Parker wrote:

On Saturday, 15 May 2021 at 11:25:10 UTC, Chris Piker wrote:


In addition to what Adam said, if you do need to store the 
result for use in a friendlier form, just import `std.array` 
and append `.array` to the end of the pipeline. This will 
eagerly allocate space for and copy the range elements to an 
array, i.e., convert the range to a container:


Thanks for the suggestion.  Unfortunately the range is going to 
be 40+ years of Voyager magnetometer data processed in a pipeline.


I am trying to do everything in functional form, but the deep 
type dependencies (and my lack of knowledge) are crushing my 
productivity.  I might have to stop trying to write idiomatic D 
and start writing Java-in-D just to move this project along. 
Fortunately, D supports that too.


Re: Recommendations on avoiding range pipeline type hell

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

On Saturday, 15 May 2021 at 13:46:57 UTC, Chris Piker wrote:


Every time I slightly change the inputs to range2, then a 
function that operates on *range3* output types blows up with a 
helpful message similar to:

[snip]


If you post your code (or at least a self-contained subset of it) 
someone can probably help you figure out where you're running 
into trouble. The error messages by themselves do not provide 
enough information--all I can say from them is, "you must be 
doing something wrong."


Re: Recommendations on avoiding range pipeline type hell

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

On Saturday, 15 May 2021 at 11:25:10 UTC, Chris Piker wrote:

Thanks for your patience with a potentially dumb question.  
I've been working on the code for well over 12 hours so I'm 
probably not thinking straight it this point.




BTW, I can send you a couple of documents regarding ranges that 
you may or may not find useful. Please email me at 
aldac...@gmail.com if you're interested.





Re: Recommendations on avoiding range pipeline type hell

2021-05-15 Thread Chris Piker via Digitalmars-d-learn

On Saturday, 15 May 2021 at 11:51:11 UTC, Adam D. Ruppe wrote:

On Saturday, 15 May 2021 at 11:25:10 UTC, Chris Piker wrote:
The idea is you aren't supposed to care what the type is, just 
what attributes it has, e.g., can be indexed, or can be 
assigned, etc.


(Warning, new user rant ahead.  Eye rolling warranted and 
encouraged)


I'm trying to do that, but range3 and range2 are written by me 
not a Phobos wizard, and there's a whole library of template 
functions a person needs to learn to make their own pipelines.  
For example:

```d
// From std/range/package.d
CommonType!(staticMap!(ElementType, staticMap!(Unqual, Ranges))

alias RvalueElementType = CommonType!(staticMap!(.ElementType, 
R));
// ... what's with the . before the ElementType statement?  Line 
921 says
// .ElementType depends on RvalueElementType.  How can they 
depend on

// each other?  Is this a recursive template thing?
```

and all the other automagic stuff that phobos pulls off to make 
ranges work.  If that's what's needed to make a custom range 
type, then D ranges should come with the warning **don't try this 
at home**.  (Ali's book made it look so easy that I got sucker in)


Every time I slightly change the inputs to range2, then a 
function that operates on *range3* output types blows up with a 
helpful message similar to:

```
template 
das2.range.PrioritySelect!(PriorityRange!(DasRange!(Tuple!(int, 
int)[], int function(Tuple!(int, int)) pure nothrow @nogc @safe, 
int function(Tuple!(int, int)) pure nothrow @nogc @safe, 
Tuple!(int, int), int), int function() pure nothrow @nogc @safe), 
PriorityRange!(DasRange!(Tuple!(int, int)[], int 
function(Tuple!(int, int)) pure nothrow @nogc @safe, int 
function(Tuple!(int, int)) pure nothrow @nogc @safe, Tuple!(int, 
int), int), int function() pure nothrow @nogc 
@safe)).PrioritySelect.getReady.filter!((rng) => 
!rng.empty).filter cannot deduce function from argument types 
!()(PriorityRange!(DasRange!(Tuple!(int, int)[], int 
function(Tuple!(int, int)) pure nothrow @nogc @safe, int 
function(Tuple!(int, int)) pure nothrow @nogc @safe, Tuple!(int, 
int), int), int function() pure nothrow @nogc @safe), 
PriorityRange!(DasRange!(Tuple!(int, int)[], int 
function(Tuple!(int, int)) pure nothrow @nogc @safe, int 
function(Tuple!(int, int)) pure nothrow @nogc @safe, Tuple!(int, 
int), int), int function() pure nothrow @nogc @safe))

```
What the heck is that?

Anyway, you put it all in one bit thing and this is kinda 
important: avoid assigning it to anything. You'd ideally do all 
the work, from creation to conclusion, all in the big pipeline.


I fell back to using assignments just to make sure range2 values 
were saved in a concrete variable so that range3 didn't break 
when I changed the lambda that was run by range2 to mutate it's 
output elements.


What went in to getting the element to range3's doorstep is a 
detail that I shouldn't have to care about inside range3 code, 
but am forced to care about it, because changing range2's type, 
changes range3's type and triggers really obscure error messages. 
(Using interfaces or *gasp* casts, would break the TMI situation.)



So say you want to write it

auto mega_range = range1.range2!(lambda2).range3!(lambda3);
writeln(mega_range);

that'd prolly work, writeln is itself flexible enough, but 
you'd prolly be better off doing like


Sure it will work, because writeln isn't some function written by 
a new user, it's got all the meta magic.


This way the concrete type never enters into things, it is all 
just a detail the compiler tracks to ensure the next consumer 
doesn't try to do things the previous step does not support.


It's all just a detail the compiler tracks, until you're not 
sending to writeln, but to your own data consumer.  Then, you'd 
better know all of std.traits and std.meta cause you're going to 
need them too implement a range-of-ranges consumer.  And by the 
way you have to use a range of ranges instead of an array of 
ranges because two ranges that look to be identical types, 
actually are not identical types and so can't go into the same 
array.


Here's an actual (though formatted by me) error message I got 
stating that two things were different and thus couldn't share an 
array.  Can you see the difference?  I can't.  Please point it 
out if you do.


```d
das2/range.d(570,39): Error: incompatible types for (dr_fine) : 
(dr_coarse):


das2.range.PriorityRange!(
  DasRange!(
Take!(
  ZipShortest!(
cast(Flag)false, Result, Generator!(function () @safe => 
uniform(0, 128))

  )
),
int function(Tuple!(int, int)) pure nothrow @nogc @safe,
int function(Tuple!(int, int)) pure nothrow @nogc @safe,
Tuple!(int, int),
int
  ),
  int function() pure nothrow @nogc @safe
)

and

das2.range.PriorityRange!(
  DasRange!(
Take!(
  ZipShortest!(
cast(Flag)false, Result, Generator!(function () @safe => 
uniform(0, 128))

  )
),
int function(Tuple!(int, int)) 

Re: Recommendations on avoiding range pipeline type hell

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

On Saturday, 15 May 2021 at 11:25:10 UTC, Chris Piker wrote:

Is there some obvious trick or way of looking at the problem 
that I'm missing?




In addition to what Adam said, if you do need to store the result 
for use in a friendlier form, just import `std.array` and append 
`.array` to the end of the pipeline. This will eagerly allocate 
space for and copy the range elements to an array, i.e., convert 
the range to a container:


```d
auto mega_range = range1.range2!(lambda2).range3!(lambda3).array;
```

Sometimes you may want to set up a range and save it for later 
consumption, but not necessarily as a container. In that case, 
just store the range itself as you already do, and pass it to a 
consumer when you're ready. That might be `.array` or it could be 
`foreach` or something else.



```d
auto mega_range = range1.range2!(lambda2).range3!(lambda3);

// later
foreach(elem; mega_range) {
   doStuff(elem);
}
```


Re: Scope of import

2021-05-15 Thread Alain De Vos via Digitalmars-d-learn

In unix i give the compiler:
```
ldc2 `find . -name \*.d -print`
```
So he always takes all sourcefiles


Re: Scope of import

2021-05-15 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 15 May 2021 at 11:46:49 UTC, Dennis wrote:

You can do `dmd -i -run main.d`


Yeah but that's weird with how it handles arguments and without 
the compilation cache it gets really annoying to use.


Re: Recommendations on avoiding range pipeline type hell

2021-05-15 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 15 May 2021 at 11:25:10 UTC, Chris Piker wrote:
Then the type definition of mega_range is something in the 
order of:


The idea is you aren't supposed to care what the type is, just 
what attributes it has, e.g., can be indexed, or can be assigned, 
etc.


You'd want to do it all in one big statement, with a consumer at 
the end (and pray there's no errors cuz while you're supposed to 
hide from the type, it won't hide from you if there's a problem, 
and as you know the errors might be usable if they were formatted 
better and got to the point but they're not and sometimes the 
compiler withholds vital information from you! Error message 
quality is D's #1 practical problem. but ill stop ranting)


Anyway, you put it all in one bit thing and this is kinda 
important: avoid assigning it to anything. You'd ideally do all 
the work, from creation to conclusion, all in the big pipeline.


So say you want to write it

auto mega_range = range1.range2!(lambda2).range3!(lambda3);
writeln(mega_range);

that'd prolly work, writeln is itself flexible enough, but you'd 
prolly be better off doing like



```
range1
   .range2!lambda2
   .range3!lambda3
   .each!writeln; // tell it to write out each element
```

Or since writeln is itself a range consumer you could avoid that 
.each call. But it is really useful for getting the result out of 
a bit mess for a normal function that isn't a full range 
consumer. (It is basically foreach written as a function call 
instead of as a loop)



This way the concrete type never enters into things, it is all 
just a detail the compiler tracks to ensure the next consumer 
doesn't try to do things the previous step does not support.


But, loops are bad.  On the D blog I've seen knowledgeable 
people say all loops are bugs.


Meh, don't listen to that nonsense, just write what works for 
you. D's strength is that it adapts to different styles and meets 
you where you are. Listening to dogmatic sermons about idiomatic 
one true ways is throwing that strength away and likely to kill 
your personal productivity as you're fighting your instincts 
instead of making it work.


Re: Scope of import

2021-05-15 Thread Dennis via Digitalmars-d-learn

On Saturday, 15 May 2021 at 11:38:22 UTC, Adam D. Ruppe wrote:
* rdmd runs the program too, dmd -i just compiles. You run the 
program separately.


You can do `dmd -i -run main.d`


Re: Scope of import

2021-05-15 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 15 May 2021 at 07:15:51 UTC, DLearner wrote:

rdmd main.d


rdmd sucks, it runs the compiler twice and get the list of 
imports and even then it might not see them all.


Just use

dmd -i main.d

instead. It will be about 2x faster and more reliable.

The downside differences though:

* rdmd runs the program too, dmd -i just compiles. You run the 
program separately.
* rdmd will cache the executable, dmd -i will always recompile. 
But since running the program is a separate step, you just run it 
yourself if you don't want to recompile, and run dmd if you do.




Recommendations on avoiding range pipeline type hell

2021-05-15 Thread Chris Piker via Digitalmars-d-learn

Hi D

Since the example of piping the output of one range to another 
looked pretty cool, I've tried my own hand at it for my current 
program, and the results have been... sub optimal.


Basically the issue is that if one attempts to make a range based 
pipeline aka:


```d
auto mega_range = range1.range2!(lambda2).range3!(lambda3);
```
Then the type definition of mega_range is something in the order 
of:


```d
  TYPE_range3!( TYPE_range2!( TYPE_range1, TYPE_lamba2 ), 
TYPE_lambda3));

```
So the type tree builds to infinity and the type of `range3` is 
very much determined by the lambda I gave to `range2`.  To me 
this seems kinda crazy.


To cut through all the clutter, I need something more like a unix 
command line:

```bash
prog1 | prog2 some_args | prog3 some_args
```
Here prog2 doesn't care what prog1 *is* just what it produces.

So pipelines that are more like:

```d
ET2 front2(ET1, FT)(ET1 element, FT lambda){ /* stuff */ }
ET3 front3(ET2, FT)(ET2 element, FT lambda){ /* stuff */ }

void main(){

  for(; !range1.empty; range1.popFront() )
  {
ET3 el3 = front3( front2(range1.front, lambda2), lamda3) );
writeln(el3);
  }
}
```

But, loops are bad.  On the D blog I've seen knowledgeable people 
say all loops are bugs.  But how do you get rid of them without 
descending into Type Hell(tm).  Is there anyway to get some type 
erasure on the stack?


The only thing I can think of is to use Interfaces and Classes 
like Java, but we don't have the automagical JVM reordering the 
heap at runtime, so that means living life on a scattered heap, 
just like python.


Is there some obvious trick or way of looking at the problem that 
I'm missing?


Thanks for your patience with a potentially dumb question.  I've 
been working on the code for well over 12 hours so I'm probably 
not thinking straight it this point.


Cheers all,



Re: Any suggestions on dmd error message formatting?

2021-05-15 Thread SealabJaster via Digitalmars-d-learn

On Saturday, 15 May 2021 at 09:09:36 UTC, Berni44 wrote:

...


Honestly, even having a dumb formatter that puts things like this 
would be 100x more useable than what we currently get:


```d
das2.range.PriorityRange!(
  DasRange!(
Take!(
  ZipShortest!(
cast(Flag)false, Result, Generator!(
function (
) @safe => uniform(
0,
128
)
)
  )
),
int function(
Tuple!(
int,
int
)
) pure nothrow @nogc @safe,
int function(
Tuple!(
int,
int
)
) pure nothrow @nogc @safe,
Tuple!(
int,
int
),
int
  ),
  int function(
  ) pure nothrow @nogc @safe
)
```


Re: What is the difference between these template declaration forms?

2021-05-15 Thread evilrat via Digitalmars-d-learn

On Saturday, 15 May 2021 at 08:37:21 UTC, cc wrote:
Are these identical?  Or is there a different usage for the (T 
: something) form?

```d
auto opCast(T)() if (is(T == bool)) {
return _obj !is null;
}
```


They are the same in this case.


```d
auto opCast(T : bool)() {
return _obj !is null;
}
```


While the docs says it matches the most specialized type, which 
is bool in this case, IIRC it is actually takes anything 
convertible to bool despite what the docs says.

You should double check it yourself.

Anyway I would usually pick this form where possible as it yields 
cleaner error messages unlike arbitrary template constraint 
"stuff X doesnt takes Y, did you mean (basically X but not)" 
message that who knows what it wants you to do.


Re: Any suggestions on dmd error message formatting?

2021-05-15 Thread SealabJaster via Digitalmars-d-learn

On Saturday, 15 May 2021 at 08:15:19 UTC, Chris Piker wrote:
I did much the same as you and reformatted the error message to 
find the bug.  As to the larger question of how to 
automatically process compiler output... got any ideas?


Hope someone who knows how to modify DMD bothers to:

1. Implement some kind of ability for that to work.
2. Convinces Walter to let it through.

I can't do either, so just have to hope this issue is finally 
tackled at some point in the future.


My guess is that the `Result` item is a hint.  `Result` 
probably never equals another `Result` no matter what.


Yea, I can't see what's wrong just from that either.

My best guess is `Result` might be embedded within another 
templated thing, which might be different than the `Result` that 
the function is expecting. Place a couple of `pragma(msg, 
Result.stringof); // Might need to use typeof(Result).stringof, 
or even __traits(identifier, Result)` wherever it might be 
relevant, and see if that shows anything fun.


I also really can't see where else there'd be a type mismatch, 
especially if a `.array` is what fixes things.


e.g. `RangeThatReturns!OtherRange.Result != 
RangeThatReturns!(int[]).Result`


But other than that, I can't tell just from that error snippet.


Re: Any suggestions on dmd error message formatting?

2021-05-15 Thread Berni44 via Digitalmars-d-learn

On Saturday, 15 May 2021 at 04:54:15 UTC, Chris Piker wrote:

As always, your advice is much appreciated


I'm usually piping the results through hexdump. ;-)

No, in earnest, I often would have liked to have better formatted 
messages. The only thing I can say: Sometimes it helps to 
increase the size of the window (>300 columns or so). Without 
line breaking, sometimes you can spot patterns you didn't 
before...


What is the difference between these template declaration forms?

2021-05-15 Thread cc via Digitalmars-d-learn
Are these identical?  Or is there a different usage for the (T : 
something) form?

```d
auto opCast(T)() if (is(T == bool)) {
return _obj !is null;
}
```
```d
auto opCast(T : bool)() {
return _obj !is null;
}
```



Re: Any suggestions on dmd error message formatting?

2021-05-15 Thread Chris Piker via Digitalmars-d-learn

On Saturday, 15 May 2021 at 06:12:25 UTC, SealabJaster wrote:

On Saturday, 15 May 2021 at 04:54:15 UTC, Chris Piker wrote:

T_T My eyes burn.


Good, it's not just me.  If figured the Deities out there 
visually parse these messages even hung over.


Seems the final `int function` parameter needs to accept a 
`Tuple!(int, int)`


I did much the same as you and reformatted the error message to 
find the bug.  As to the larger question of how to automatically 
process compiler output... got any ideas?


Hey since you're pretty good at this, can you tell me why how a 
person fixes this error? I've already formatted it, but I haven't 
changed any of the non-whitespace text.


```
das2/range.d(570,39): Error: incompatible types for (dr_fine) : 
(dr_coarse):

```
```d
das2.range.PriorityRange!(
  DasRange!(
Take!(
  ZipShortest!(
cast(Flag)false, Result, Generator!(function () @safe => 
uniform(0, 128))

  )
),
int function(Tuple!(int, int)) pure nothrow @nogc @safe,
int function(Tuple!(int, int)) pure nothrow @nogc @safe,
Tuple!(int, int),
int
  ),
  int function() pure nothrow @nogc @safe
)

and

das2.range.PriorityRange!(
  DasRange!(
Take!(
  ZipShortest!(
cast(Flag)false, Result, Generator!(function () @safe => 
uniform(0, 128))

  )
),
int function(Tuple!(int, int)) pure nothrow @nogc @safe,
int function(Tuple!(int, int)) pure nothrow @nogc @safe,
Tuple!(int, int),
int
  ),
  int function() pure nothrow @nogc @safe
)

```
To get around the problem I used `.array` for a bit of type 
erasure, so for now this error isn't messing with my unittests, 
but danged if I can spot the problem, even formatted.


My guess is that the `Result` item is a hint.  `Result` probably 
never equals another `Result` no matter what.




Re: Scope of import

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

On Saturday, 15 May 2021 at 07:15:51 UTC, DLearner wrote:

On Saturday, 15 May 2021 at 07:05:00 UTC, Mike Parker wrote:


That's odd. What's your command line?


rdmd main.d


Okay, so it's definitely a bug in rdmd. Change module A to look 
like this and it works properly:


```d
module A;

import B;

void fnA1() {

   import std.stdio;

   writeln("Entered fnA1");
   fnB1();
   writeln("Leaving fnA1");
}
```


Re: Scope of import

2021-05-15 Thread DLearner via Digitalmars-d-learn

On Saturday, 15 May 2021 at 07:19:08 UTC, Mike Parker wrote:

Then it must be an issue with rdmd...



rdmd build 20210311
Running under Win-10.







Re: Scope of import

2021-05-15 Thread DLearner via Digitalmars-d-learn

On Saturday, 15 May 2021 at 07:05:00 UTC, Mike Parker wrote:


That's odd. What's your command line?


rdmd main.d


Re: Scope of import

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

On Saturday, 15 May 2021 at 07:15:51 UTC, DLearner wrote:

On Saturday, 15 May 2021 at 07:05:00 UTC, Mike Parker wrote:


That's odd. What's your command line?


rdmd main.d


Then it must be an issue with rdmd. The following both work as 
expected, whether your the `import B;` in `main` is commented out 
or not:


dmd -i main.d
dmd main.d A.d B.d


Re: Scope of import

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

On Saturday, 15 May 2021 at 06:55:47 UTC, DLearner wrote:

1. Code above compiles but fails on linker step with 'Error 42 
Symbol Undefined'.
To me, unexpected behaviour as imports arranged to pick up 
symbols (with minimum scope).


Your error is a linker error. Imports have nothing to do with the 
linker. They are for the compiler to know which symbols are 
available in the module it's currently compiling. But every 
symbol that you use needs to be linked by the linker, and that's 
a separate step.




2. Uncommenting the 'import B' in main everything works 
correctly.


That's odd. What's your command line?

To me, particularly unexpected behaviour as no symbol from B 
directly used in main (also undesirable to set scope 
unnecessarily wide).




Whether you use a symbol in main or not is irrelevant to the 
linker. Any symbol accessed anywhere in your program must 
ultimately be linked in.




Scope of import

2021-05-15 Thread DLearner via Digitalmars-d-learn

```
// main
void main() {
   import A;
// import B;
   import std.stdio;

   writeln("Entered main");

   fnA1();

   writeln("Leaving main");
}
```

```
module A;

void fnA1() {

   import B;
   import std.stdio;

   writeln("Entered fnA1");
   fnB1();
   writeln("Leaving fnA1");
}
```

```
module B;

void fnB1() {

   import std.stdio;

   writeln("Entered fnB1");
   writeln("Leaving fnB1");
}
```

1. Code above compiles but fails on linker step with 'Error 42 
Symbol Undefined'.
To me, unexpected behaviour as imports arranged to pick up 
symbols (with minimum scope).


2. Uncommenting the 'import B' in main everything works correctly.
To me, particularly unexpected behaviour as no symbol from B 
directly used in main (also undesirable to set scope 
unnecessarily wide).


Best regards


Re: Any suggestions on dmd error message formatting?

2021-05-15 Thread SealabJaster via Digitalmars-d-learn

On Saturday, 15 May 2021 at 06:12:25 UTC, SealabJaster wrote:

...


Honestly I also kind of wish that the D compilers could format 
functions better on the command line, because these giant blobs 
of "where's ~~wally~~ the difference?" are just horrid when they 
show up.





Re: Any suggestions on dmd error message formatting?

2021-05-15 Thread SealabJaster via Digitalmars-d-learn

On Saturday, 15 May 2021 at 04:54:15 UTC, Chris Piker wrote:

Hi D


T_T My eyes burn.

Anyway, Here it is formatted slightly better:

```d
PriorityRange.this(
DasRange!(
Tuple!(int, int)[],
int function(Tuple!(int, int)) pure nothrow @nogc @safe,
int function(Tuple!(int, int)) pure nothrow @nogc @safe,
Tuple!(int, int),
int
) range,
int function(Tuple!(int, int)) priority
) is not callable using argument types (
DasRange!(
Tuple!(int, int)[],
int function(Tuple!(int, int)) pure nothrow @nogc @safe,
int function(Tuple!(int, int)) pure nothrow @nogc @safe,
Tuple!(int, int),
int
),
int function() pure nothrow @nogc @safe
)
```

Seems the final `int function` parameter needs to accept a 
`Tuple!(int, int)`