Re: parallel threads stalls until all thread batches are finished.

2023-08-28 Thread Ali Çehreli via Digitalmars-d-learn

On 8/28/23 15:37, j...@bloow.edu wrote:

> Basically everything is hard coded to use totalCPU's

parallel() is a function that dispatches to a default TaskPool object, 
which uses totalCPUs. It's convenient but as you say, not all problems 
should use it.


In such cases, you would create your own TaskPool object and call 
.parallel on it:


  https://youtu.be/dRORNQIB2wA?t=1611s

Ali



Re: parallel threads stalls until all thread batches are finished.

2023-08-25 Thread Ali Çehreli via Digitalmars-d-learn

On 8/25/23 14:27, j...@bloow.edu wrote:

> "A work unit is a set of consecutive elements of range to be processed
> by a worker thread between communication with any other thread. The
> number of elements processed per work unit is controlled by the
> workUnitSize parameter. "
>
> So the question is how to rebalance these work units?

Ok, your question brings me back from summer hibernation. :)

This is what I do:

- Sort the tasks in decreasing time order; the ones that will take the 
most time should go first.


- Use a work unit size of 1.

The longest running task will start first. You can't get better than 
that. When I print some progress reporting, I see that most of the time 
N-1 tasks have finished and we are waiting for that one longest running 
task.


Ali
"back to sleep"


Re: Bug in usage of associative array: dynamic array with string as a key

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

On 6/30/23 17:42, Cecil Ward wrote:

> https://dlang.org/spec/hash-map.html#testing_membership in the language
> docs, under associative arrays - 13.3 testing membership. Would anyone
> else care to try that example out as that might be quicker?

I tried it by

1) Putting all the code inside a 'void main()' function
2) Pasting the code from the top of that page

and it works:

void main() {
int[string] aa;   // Associative array of ints that are
// indexed by string keys.
// The KeyType is string.
aa["hello"] = 3;  // set value associated with key "hello" to 3
int value = aa["hello"];  // lookup value from a key
assert(value == 3);
int* p;

p = "hello" in aa;
if (p !is null)
{
*p = 4;  // update value associated with key
assert(aa["hello"] == 4);
}
}

> the only substantive
> change being deleting the variable p

Do you mean this:

aa.remove("hello");

That works too.

D's associative arrays have a few quirks but they work just fine. They 
are not buggy as it may be inferred from some of the posts here.


Ali



Re: Bug in usage of associative array: dynamic array with string as a key

2023-06-30 Thread Ali Çehreli via Digitalmars-d-learn

On 6/30/23 13:16, Cecil Ward wrote:

On Friday, 30 June 2023 at 19:58:39 UTC, FeepingCreature wrote:



Note that you can do `uint ordinal = Decls.ordinals.get(str, -1);`.


Is the second argument an ‘else’ then, my friend?


Yes, .get and friends appear in this table:

  https://dlang.org/spec/hash-map.html#properties

Ali



Re: Bug in usage of associative array: dynamic array with string as a key

2023-06-30 Thread Ali Çehreli via Digitalmars-d-learn

On 6/30/23 12:05, Cecil Ward wrote:
> I have code roughly like the following:
>
> dstring str = "name"d;

Aside: One almost never needs dstring.

> uint ordinal =  (( str in Decls.ordinals ) !is null)  ?
> Decls.ordinals[ str ]  :  -1;
>
> struct Decls
> {
> uint[ dstring]   ordinals;

Do you mean 'ordinals' is 'static'? Otherwise, Decls.ordinals does not 
compile.


> }
>
> //and
> Decls.ordinals[ str ] = ordinal_counter++;

Are you doing that *after* you initialize 'ordinal' as you show here? :)

Ali



Re: is Dlang support Uniform initialization like c++

2023-06-30 Thread Ali Çehreli via Digitalmars-d-learn

On 6/30/23 08:18, lili wrote:


How too wirte this: addPoint({4,5}, {4,6})


In this case, arrays are better but only if you don't define a 
constructor, which you don't need for simple types like Point below:


struct Point {
int x;
int y;
}

void main() {
// The type is explicit on the left-hand side
Point[] points = [ {1,2} ];
}

Ali



Re: pragma msg field name?

2023-06-26 Thread Ali Çehreli via Digitalmars-d-learn

On 6/26/23 21:25, Chris Katko wrote:

> How do I get just the field name?

I know .tupleof, which you can typeof() as well:

class myObject{
int field1, field2, field3;

static foreach(field; typeof(this).tupleof)
{
pragma(msg, field.stringof);
}

static foreach(MemberType; typeof(typeof(this).tupleof)) {
pragma(msg, MemberType);
}
}

The output:

field1
field2
field3
int
int
int

I had to consult what I wrote years ago:

  http://ddili.org/ders/d.en/tuples.html#ix_tuples..tupleof

Ali



Re: Large statics

2023-06-25 Thread Ali Çehreli via Digitalmars-d-learn

On 6/25/23 13:41, Cecil Ward wrote:

> The docs say that there is a limit on the size of large statics

Customers (at least Weka) did request larger statics in the past. Since 
they use LDC, the limit was removed for LDC. I did not try it. :)


Ali



Re: A couple of questions about arrays and slices

2023-06-24 Thread Ali Çehreli via Digitalmars-d-learn

On 6/20/23 19:09, Cecil Ward wrote:

> 2.) I have a dynamic array and I wish to preinitialise its alloc cell to
> be a certain large size so that I don’t need to reallocate often

To be complete, 'assumeSafeAppend' must be mentioned here as well. 
Without it, there will be cases where the GC cannot guarantee that there 
are no slices to this particular one; so it has to reallocate:


import std;

void main() {
// An array with room for 100 elements
int[] arr;
arr.reserve(100);

// Take note of current address of the elements
auto ptr = arr.ptr;

foreach (i; 0 .. 80) {
// Add elements
arr ~= i;

// Was there a reallocation?
if (arr.ptr != ptr) {
writeln("relocated to ", arr.ptr, " at ", i);
ptr = arr.ptr;
}

// Let's say our algorithm shrinks the array
if (i == 50) {
arr.length = 0;
// assumeSafeAppend(arr);
}
}
}

Although the array has room for 100 elements, the program will print 
something similar to the following:


relocated to 7F058B02B000 at 51
relocated to 7F058B02C000 at 54
relocated to 7F058B02D000 at 58
relocated to 7F058B02E000 at 62
relocated to 7F058B02F000 at 66
relocated to 7F058B03 at 74

When it's known that there is no other slice to the old elements, the 
programmer calls assumeSafeAppend() by uncommenting that line :o). Now 
there are no relocations. Sweet!


Ali



Re: static if - unexpected results

2023-06-23 Thread Ali Çehreli via Digitalmars-d-learn

On 6/23/23 07:22, DLearner wrote:

>`} else static if (__traits(isPOD, typeof(` ~ VarName ~ `))) {` ~

Regardless, you can also use the 'is' expression with the 'struct' 
keyword. If T is a struct,


  is (T == struct)

that will produce true at compile time.

Ali



Re: How does D’s ‘import’ work?

2023-06-20 Thread Ali Çehreli via Digitalmars-d-learn

On 6/20/23 08:09, Cecil Ward wrote:

> I’m used to slow compilers on fast machines and compiling
> gives me an excuse for more coffee and possibly fruity buns.

Yes, all of us in past projects accepted C++'s slowness. We did get 
coffee, etc. One of my current colleagues regularly plays solitaire when 
waiting for C++ compilations. Not only it's not a professional sight, 
but C++ is proving to be a professional mistake.


Nobody should suffer from such context switches. I have a hunch, without 
any backing research data, that C++'s contribution to humanity may be 
net negative.


D is nothing like that: My turnaround is a few seconds: Write, compile, 
run, see the effect... I use only dmd partly because of laziness: it 
just works. Although I take full advantage D's low level powers, my 
programs have mostly been I/O bound with huge files, so dmd's less-than 
ideal optimization powers are hidden because most threads are waiting 
for file system I/O.


Aside: std.parallelism and std.concurrency have been very helpful.

Ali



Re: class Object with Dependency Injection

2023-06-18 Thread Ali Çehreli via Digitalmars-d-learn

On 6/18/23 07:37, Salih Dincer wrote:

>auto truck = new Truck;
>auto ship = new Ship;
>
>auto services = [ truck, ship ];

The problem is with the deduced type of 'services'. I don't know the 
mechanism behind it but the common type of 'truck' and 'ship' are 
deduced to be Object. Apparently, their interfaces don't take part in 
that decision. I don't know why.


One solution is to help the compiler by casting them to your desired 
interface:


  auto services = [ cast(ITransport)truck, cast(ITransport)ship ];

Or you can put the casts inside a function that could hide the 
complexity below:


  import std.algorithm;
  import std.range;
  auto services = [ truck, ship ].map!(s => cast(ITransport)s).array;

Ali



Re: Como puedo hacer funciones asincronas?

2023-06-18 Thread Ali Çehreli via Digitalmars-d-learn

On 6/17/23 20:20, Cecil Ward wrote:
> On Saturday, 17 June 2023 at 22:05:37 UTC, Danico wrote:
>> hola gente, quisiera saber como es que puedo hacer funciones asincronas.
>> `
>> #!/usr/bin/env dmd
>> import std;
>> import std.stdio;
>> import std.concurrency;
>> //import archivo2;
>>
>> alias print = writeln;
>>
>> void main () {
>>
>> auto tarea1 = spawn();
>> auto tarea2 = spawn();
>>
>> print("realizando tareas ");
>>
>>
>> }
>>
>> void saludo () {
>> print("hola");
>> }
>>
>> async saludo2 () {

Replace that 'async' with 'void':

 void saludo2 () {

>> print("hola2");
>> }
>>
>> `
>
> This is something I have wanted to achieve also.

It just works with that change. std.concurrency appears here in one of 
my presentations:


  https://youtu.be/dRORNQIB2wA?t=1735

And some text here:

  http://ddili.org/ders/d.en/concurrency.html

Ali



Re: C++'s this() equivalent?

2023-06-15 Thread Ali Çehreli via Digitalmars-d-learn

On 6/15/23 08:15, zjh wrote:

> I want `B` to become the following version similar to 'C++'. What should
> I do?

I have difficulty understanding the question. I think the nested 
structs, extern(C), static members, etc. confuse me. I am assuming they 
are not related to this question.


> ```cpp
> struct B{
>  int m;
>  B(){

Do you want to be able to use the name of the user-defined type to mean 
"constructor", "destructor", etc?


If so, no, it's not possible without preprocessing the text potentially 
with a C preprocessor.


And this is by design: In D, we rename the type and be done with it. In 
C++, one needs to rename a number of functions as well.


Ali



Re: Union with bits ?

2023-06-14 Thread Ali Çehreli via Digitalmars-d-learn

On 6/14/23 15:04, Paul wrote:

> Question: Why do you say "may be slower than necessary"?  Do you mean
> compile or runtime or both?

Definitely at compile time because the string that gets mixed-in first 
needs to be generated from your specification. For that, the bitfields() 
function must be compiled and executed at compile-time. Then the 
mixed-in code will be compiled. I remember reading here about lackluster 
compilation performance in that area.


And it may be slow at run time as well depending on certain checks the 
functions perform. For example, you will notice that setting the value 2 
will fail at run time on a 1-bit member. If you would never pass a 2 
value for such a function, than it may be seen as extra cost.


By the way, the string that bitfields() generates can be visualized by 
simply printing it:


const code =
bitfields!(
ubyte, "A", 1,
ubyte, "B", 1,
ubyte, "C", 1,
ubyte, "padding", 5,);
writeln(code);

The output is not pretty for the human eye but those are basically the 
getters and setters that Adam D Ruppe mentioned.


Ali



Re: Union with bits ?

2023-06-14 Thread Ali Çehreli via Digitalmars-d-learn

On 6/13/23 17:59, Paul wrote:
> I would like to have labeled bits in a union with a ubyte. Something
> like this:
> ```d
> struct MyStruct {
>  union {
>  ubyte status;
>  bit A, B, C…etc
>  }
> }
> ```
> Is something like this possible?
>
> Thanks

D's string mixin syntax may not be the best, the implementation may be 
slower than necessary, and the concept may be strange (not macros but 
very similar) but I still find phobos's bifields to be brilliant.


  https://dlang.org/phobos/std_bitmanip.html#bitfields

import std.bitmanip;

struct MyStruct {
union {
ubyte status;
mixin(bitfields!(
  ubyte, "A", 1,
  ubyte, "B", 1,
  ubyte, "C", 1,
  ubyte, "padding", 5,));
}
}

void main() {
auto m = MyStruct();
m.B = 1;
assert(m.status == 2);
}

Ali



Re: byte and short data types use cases

2023-06-09 Thread Ali Çehreli via Digitalmars-d-learn

On 6/9/23 08:07, Murloc wrote:

> Where can I read more about this?

I had written something related:

  http://ddili.org/ders/d.en/memory.html#ix_memory..offsetof

The .offsetof appears at that point. The printObjectLayout() function 
example there attempts to visualize the layout of the members of a struct.


Ali



Re: How does D’s ‘import’ work?

2023-06-07 Thread Ali Çehreli via Digitalmars-d-learn

On 6/7/23 21:17, Cecil Ward wrote:

> I was thinking about the situation in C where I have a rule in a make
> file that lists the .h files as well as the .c all as dependencies in
> creating an object file.

dmd's -makedeps command line switch should be helpful there. (I did not 
use it.)


Ali



Re: How do I generate `setX` methods for all private mutable variables in a class?

2023-06-06 Thread Ali Çehreli via Digitalmars-d-learn

On 6/6/23 09:13, Basile B. wrote:

> yeah I know that opDispatch is disliked because it is tried in a SFINAE
> fashion, as citicized by Adam. But on the other side it's the best 
opover.


I like how it helped in my current project:

  user.someShellCommand("-foo", "-bar");

opDispatch makes a command string, passes it to executeShell, takes care 
of the return code and dumps its output if there was an error.


Ali



Re: Code duplication where you wish to have a routine called with either immutable or mutable arguments

2023-05-29 Thread Ali Çehreli via Digitalmars-d-learn

On 5/29/23 19:57, Cecil Ward wrote:

> I wish to have one routine
> that can be called with either immutable or (possibly) mutable argument
> values.

'const' should take both immutable and mutable. Can you show your case 
with a short example?


> Could I make the one routine into a template?

That could work but give 'in' parameters a try:

  https://dlang.org/spec/function.html#in-params

Ali



Re: How can I use Linker flags using DMD?

2023-05-29 Thread Ali Çehreli via Digitalmars-d-learn

On 5/29/23 17:39, Marcone wrote:

> Can you help me static link dll msvcr120.dll in my x64 dlang program?

Sorry, I haven't been programming on Windows for a very long time now. 
:/ But there are others who program on Windows here.


Ali



Re: How can I use Linker flags using DMD?

2023-05-29 Thread Ali Çehreli via Digitalmars-d-learn

On 5/29/23 07:29, Marcone wrote:

I want send flags to linker when using dmd.exe compiler.


-L does it. Yes, -L-L can happen. :)

  https://dlang.org/dmd-linux.html

Ali



Re: Lockstep iteration in parallel: Error: cannot have parameter of type `void`

2023-05-20 Thread Ali Çehreli via Digitalmars-d-learn

On 5/20/23 04:21, kdevel wrote:
> Thanks for your explications!
>
> On Friday, 19 May 2023 at 21:18:28 UTC, Ali Çehreli wrote:
>> [...]
>> - std.range.zip can be used instead but it does not provide 'ref'
>> access to its elements.
>
> How/why does sort [1] work with zipped arrays?

I don't know but wholesale assignment to zip's elements do transfer the 
effect, which sort does while swapping elements. However, copies of 
those range elements do not carry that effect:


import std;

void main() {
auto a = [ 0, 1 ];
auto z = zip(a);
z[0] = z[1];
writeln("worked: ", a);

zip(a).each!(e => e = 42);
writeln("  nope: ", a);
}

And each does not take (ref e) as a parameter at least in that  use case.

>> The following amap example there may be useful for your case but I
>> could not make the types work:
>
> Do you mean using the function pointer does not work?

I simply copied the example code bet there were mismatches between 
float, real, etc.


And I've just discovered something. Which one of the following is the 
expected documentation?


  https://dlang.org/library/std/parallelism.html

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

What paths did I take to get to those? I hope I will soon be motivated 
enough to fix such quality issues.


Ali



Re: Lockstep iteration in parallel: Error: cannot have parameter of type `void`

2023-05-19 Thread Ali Çehreli via Digitalmars-d-learn

On 5/19/23 02:17, kdevel wrote:


Should this compile? dmd says


Multiple points:

- lockstep works only with foreach loops but it's not a range.

- std.range.zip can be used instead but it does not provide 'ref' access 
to its elements.


- However, since slices are already references to groups of elements, 
you don't need 'ref' anyway.


- You seem to want to assign to elements in parallel; such functionality 
already exists in std.parallelism.


- Phobos documentation is not very useful these days as it's not clear 
from the following page that there are goodies like amap, asyncBuf, etc. 
It just shows parallel() and a few friends at the top:


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

One needs to know to click TaskPool:

  https://dlang.org/phobos/std_parallelism.html#.TaskPool

The following amap example there may be useful for your case but I could 
not make the types work:


// Same thing, but explicitly allocate an array
// to return the results in.  The element type
// of the array may be either the exact type
// returned by functions or an implicit conversion
// target.
auto squareRoots = new float[numbers.length];
taskPool.amap!sqrt(numbers, squareRoots);

// Multiple functions, explicit output range, and
// explicit work unit size.
auto results = new Tuple!(float, real)[numbers.length];
taskPool.amap!(sqrt, log)(numbers, 100, results);
https://dlang.org/phobos/std_parallelism.html#.TaskPool.amap

Ali



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

2023-05-07 Thread Ali Çehreli via Digitalmars-d-learn

On 5/7/23 13:44, Chris Piker wrote:

> to fix the problem I
> just delete the alias this line from dpq2, see what unit tests and app
> code it breaks, then fix each of those.

Yes but I neglected the lvalue/rvalue issue. In some cases the code 
won't compile if the return type of the newly written explicit function 
is not 'ref'. For example, the 'ref' below is essential for the 
following use case:


class C {
int* result;

// HERE
ref asIntPtr() {
return result;
}
}

auto main() {
auto c = new C();

int i;
c.asIntPtr = 
assert(c.result == );
}

> "Programming in D" for a bright young programming
> student I know in appreciation.

Very kind of you! :)

Ali



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

2023-05-07 Thread Ali Çehreli via Digitalmars-d-learn

On 5/7/23 10:55, Chris Piker wrote:

> According to dmd 2.103, alias this is
> deprecated for classes, so I'd like to correct the problem.

alias this is for implicit type conversions, which can be achieved 
explicitly as well. Given the following old code:


class C {
int* result;

alias result this;
}

void foo(int*) {
}

auto main() {
auto c = new C();

// Implicit type conversion from C to int*:
foo(c);
}

One can use a member function instead:

class C {
int* result;

auto asIntPtr() {
return result;
}
}

void foo(int*) {
}

auto main() {
auto c = new C();

// The same type conversion is now explicit:
foo(c.asIntPtr);
}

Ali



Re: A Programmer's Dilema: juggling with C, BetterC, D, Macros and Cross Compiling, etc.

2023-05-02 Thread Ali Çehreli via Digitalmars-d-learn

On 5/1/23 03:23, Mike Parker wrote:

> If you're referring to `rt_init` and `rt_term` are the `extern(C)`
> functions in `core.runtime`. It's not necessary to call those from C. A
> D library with a C interface can provide an `extern(C)` initialization
> function that internally calls `Runtime.initialize`.

Indeed. That appears at the following spot of one of my DConf 
presentations, which touches on several points relevant to writing a C 
library in D:


  https://youtu.be/FNL-CPX4EuM?t=2585

Ali



Re: Cannot get this C++ example migrated to D

2023-04-16 Thread Ali Çehreli via Digitalmars-d-learn

On 4/16/23 00:46, Skippy wrote:

> I wish D had value type classes as well.

That cannot work due to the slicing problem.

C++ cannot have value type classes either for the same reason. The 
difference there is that the enforcement is by guidelines (e.g. "never 
pass class objects by value to functions", not by language).


If you want class objects on the stack, you have two options:

- The scope keyword

- The scoped template from Phobos

Ali



Re: class variable initialization

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

On 4/15/23 09:06, NonNull wrote:

>> struct Wrapper
>> {
>>Object x = new Object();
>>alias x this;
>> }

> Amazing, was this always so?

At least for a long time. However, every Wrapper object will have a 
pointer to that single shared object.


If you think that cost is unnecessary, you can have a static variable:

struct Wrapper
{
   static Object x;
   alias x this;
}

static this() {
Wrapper.x = new Object();
}

However, because such data are thread-local by-default, not the entire 
class, but each thread will have a copy that variable.


When you want a single class variable for all threads, then it must be 
defined as shared:


struct Wrapper
{
   shared static Object x;
   alias x this;
}

shared static this() {
Wrapper.x = new Object();
}

void foo(shared Object o)
{
   assert(o !is null);
}

Note how foo's interface had to be changed as well. And of course you 
may have to provide thread synchronization when that variable needs to 
be mutated at run time.


Ali



Re: Memory leak issue between extern (c) and D function

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

On 4/13/23 20:50, backtrack wrote:

>  mystruct* getmystruct()
>  {
>  mystruct* mystruct = cast(mystruct*)malloc(mystruct.sizeof);
>  return mystruct;
>
>  }

There must be a corresponding function to do the cleaning:

void freemystruct(mystruct* ptr) {
free ptr;
}

You have to make sure on the D side that freemystruct() is called once 
for each getmystruct().


I have the following presentation that covers similar concepts:

  https://www.youtube.com/watch?v=FNL-CPX4EuM

I think this point is most relevant:

  https://www.youtube.com/watch?v=FNL-CPX4EuM=1833s

Ali



Re: Assocative array lookup for object

2023-04-12 Thread Ali Çehreli via Digitalmars-d-learn

On 4/12/23 04:35, Salih Dincer wrote:

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

You asked for it! :)

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

Not every type is null'able but nullable. ;) So, a design may use the 
following:


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

Ali



Re: How come a count of a range becomes 0 before a foreach?

2023-04-09 Thread Ali Çehreli via Digitalmars-d-learn

On 4/8/23 21:38, ikelaiah wrote:

> I will modify the code to construct it twice.

Multiple iterations of dirEntries can produce different results, which 
may or may not be what your program will be happy with.


Sticking an .array at the end will iterate a single time and maintain 
the list forever because .array returns an array. :)


  auto entries = dirEntries(/* ... */).array;

Ali



Re: DlangUI Layout Justification

2023-04-07 Thread Ali Çehreli via Digitalmars-d-learn

On 3/9/23 07:09, Ron Tarrant wrote:


Many thanks, ryuukk. I'll check it out.


I don't know how relevant it is but there is also Hipreme Engine that 
supports Android:


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

Ali



Re: Code organization, dub, etc.

2023-04-07 Thread Ali Çehreli via Digitalmars-d-learn

On 3/13/23 07:30, Joe wrote:

> whether DLang (the Foundation and/or the
> community) would consider working with the CMake and clang-format
> communities to get them to support D in their products

That would be great. I hope it will eventually happen.

I've used CMake on existing projects only as a tool that is better than 
some others. Witnessing CMake being replaced by even better tools like 
Bazel, should CMake be a target or should Bazel, etc. take precedence?


Ali



Re: member func is best choice for pointers?

2023-04-07 Thread Ali Çehreli via Digitalmars-d-learn

On 4/6/23 07:26, a11e99z wrote:
> ```d
> import std, core.lifetime;
>
> struct Node {
>  Node* pNext;
>  void func() { "Node::func %s".writeln( pNext); }

That's a member function, which works with the obj.func() syntax.

However, there is another feature of D that is in play here: Members can 
directly be accessed through pointers without dereferencing.


  pn.func()

has the same effect as

  (*pn).func()

(That's why D does not use C's -> operator).

> }
> void func( Node* p ) { "::func %s(%s)".writeln( p, p == null ? p :
> p.next); }

Ok, that function can be called normally as

  func(pn)

or with UFCS as

  pn.func()

However, UFCS takes place only when there is no such member.

I understand how this can be surprising but it is still within spec: 
There does exist a member with the name 'func', so UFCS is not applied.


One can rightly argue that automatic pointer dereferencing should take 
place after UFCS consideration but apparently that's not the case. If 
that were the case, I suspect there would be other programmers who would 
be looking for the current behavior.


Ali



Re: regex matching but not capturing

2023-04-06 Thread Ali Çehreli via Digitalmars-d-learn

On 4/6/23 11:08, Paul wrote:
ways to access 
those repetitive ", cc" s on the end.  I don't think my regex is 
capturing them.


Some internets think you are in parser territory:


https://stackoverflow.com/questions/1407435/how-do-i-regex-match-with-grouping-with-unknown-number-of-groups

Ali



Re: Virtual method call from constructor

2023-04-04 Thread Ali Çehreli via Digitalmars-d-learn

On 4/4/23 00:08, Chris Katko wrote:
> dscanner reports this as a warning:
>
> ```D
> struct foo{
> this()
>{
>/* some initial setup */
>refresh();
>}
> void refresh() { /* setup some more stuff */}
> // [warn] a virtual call inside a constructor may lead to unexpected
> results in the derived classes
>
> }
> ```

I can understand that error for a class. Is that really a struct? If so, 
then it looks like a dscanner bug to me.


> Firstly, are all calls virtual in a struct/class in D?

All functions are by-default virtual only for classes.

To note, not the "call" but the function can be virtual. When calls are 
involved, there can be static binding and dynamic binding. Static 
binding is when a call is resolved at compile time. Dynamic binding is 
resolved at run time through the vtbl pointer.


> Is this any
> different from C++?

Yes. In C++, all functions are non-virtual by-default.

> IIRC, in C++, a struct cannot have virtual calls,

No, structs and classes are functionally exactly the same in C++. The 
only difference is their default member accessibility: public for 
structs and private for classes.


> and virtual methods are explicit keywords in classes.

Yes.

> Second, could you give me some case examples where this problem occurs?
> Is the issue if I override refresh in a derived class, and the base
> class will accidentally use child.refresh()?

Yes. :) Here is what I had learned in my C++ days: The vtbl pointer is 
stamped before the constructor is entered. However, an object is not yet 
complete without its constructor exiting. The base class's constructor 
calling a virtual function of its derived part might be disastrous 
because the derived part is not fully constructed yet. (Well, it is not 
as disastrous in D because all members have default values by-default.)


import std;

class Base {
void foo() {
writeln(__FUNCTION__);
}

this(int i) {
writeln("Entered ", __FUNCTION__);
foo();  // <-- THE PROBLEM
writeln("Exiting ", __FUNCTION__);
}
}

class Derived : Base {
override void foo() {
writeln(__FUNCTION__);
}

this(int i) {
writeln("Entered ", __FUNCTION__);
super(i);
writeln("Exiting ", __FUNCTION__);
}
}

void main() {
auto d = new Derived(42);
}

Here is the (annotated) output:

Entered deneme.Derived.this
Entered deneme.Base.this
deneme.Derived.foo<-- NO!
Exiting deneme.Base.this
Exiting deneme.Derived.this

The highlighted line is a call to a derived function but even the base 
part of the object is not finished its construction yet. The weird thing 
is Base is initiating the call but it has no idea even whether it's a 
part of an inheritance hierarchy, what other types are involved, etc.


Ali



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

2023-04-04 Thread Ali Çehreli via Digitalmars-d-learn

On 4/4/23 02:24, Salih Dincer wrote:

> I don't understand what `foreach()` does :)

Hm. I forgot whether 'parallel' works only with 'foreach'. But there are 
various other algorithms in std.parallelism that may be more useful with 
range algorithm chains:


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

> in Turkish

I don't have time to experiment more at this time but I have the 
following chapters, which includes some of those other algorithms as well:


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

  http://ddili.org/ders/d.en/parallelism.html

Ali



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

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

On 4/1/23 15:30, Paul wrote:

> Is there a way to verify that it split up the work in to tasks/threads
> ...?

It is hard to see the difference unless there is actual work in the loop 
that takes time. You can add a Thread.sleep call. (Commented-out in the 
following program.)


Another option is to monitor a task manager like 'top' on unix based 
systems. It should multiple threads for the same program.


However, I will do something unspeakably wrong and take advantage of 
undefined behavior below. :) Since iteration count is an even number, 
the 'sum' variable should come out as 0 in the end. With .parallel it 
doesn't because multiple threads are stepping on each other's toes (values):


import std;

void main() {
long sum;

foreach(i; iota(0, 2_000_000).parallel) {
// import core.thread;
// Thread.sleep(1.msecs);

if (i % 2) {
++sum;

} else {
--sum;
}
}

if (sum == 0) {
writeln("We highly likely worked serially.");

} else {
writefln!"We highly likely worked in parallel because %s != 
0."(sum);

}
}

If you remove .parallel, 'sum' will always be 0.

Ali



Re: Why are globals set to tls by default? and why is fast code ugly by default?

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

On 3/26/23 13:41, ryuukk_ wrote:

> C, C++, Rust, Zig, Go doesn't do TLS by default for example

C doesn't do because there was no such concept when it was conceived.

C++ doesn't do because they built on top of C.

(D does because it has always been innovative.)

Go doesn't do because it had no innovations anyway.

Does anyone have documentation on why Rust and Zip does not do thread 
local by default? I wonder what experience it was based on.


Speaking of experience, I used to be a C++ programmer. We made use of 
thread-local storage precisely zero times. I think it's because the 
luminaries of the time did not even talk about it.


With D, I take good advantage of thread-local storage. Interestingly, I 
do that *only* for fast code.


void foo(int arg) {
static int[] workArea;

if (workArea.length < nededFor(arg)) {
// increase length
}

// Use workArea
}

Now I can use any number of threads using foo and they will have their 
independent work areas. Work area grows in amortized fashion for each 
thread.


I find the code above to be clean and beautiful. It is very fast because 
there are no synchronization primitives needed because no work area is 
shared between threads.


Finding one example to the contrary does not make TLS a bad idea. 
Engineering is full of compromises. I agree with D's TLS by-default idea.



Since I am here, I want to touch on something that may give the wrong 
idea to newer D programmers: D does not have globals. Every symbol 
belongs to a module.


And copying an earlier comment of yours:

> It's common knowledge that accessing tls global is slow
> http://david-grs.github.io/tls_performance_overhead_cost_linux/

"TLS global is slow" would be misleading because even the article you 
linked explains right at the top, in the TL;DR are that "TLS may be slow".


Ali



Re: The Phobos Put

2023-03-29 Thread Ali Çehreli via Digitalmars-d-learn

On 3/29/23 12:21, ag0aep6g wrote:

> As far as I understand, you're saying that we cannot overload on `ref`.
> But we can. Salih's code demonstrates just that.
>
> void f(ref int x) {}
> void f(int x) {}
> void main() { int x; f(x); f(42); } /* no errors */

I thought Salih was proposing two more overloads to the existing put(). 
When I copy the existing put(), which takes 'ref R', not R[], then the 
code does not compile:


auto put(R)(R[] range, R[] source)
  => putImpl(range, source);

auto put(R)(ref R[] range, R[] source)
  => putImpl(range, source);

void putImpl(R)(ref R[] range, R[] source)
{
  assert(source.length <= range.length);
  foreach(element; source)
  {
range[0] = element;  // range.front()
range = range[1..$]; // range.popFront()
  }
}

void put(R, E)(ref R r, E e)
{
  // This is from Phobos <---
}

void main() {
  enum data = [1, 0, 0, 4];
  auto arr = data;
  auto slice = arr[1..$-1];

  slice.put([2]);  // <-- ERROR
  assert(arr == [1, 2, 0, 4]);

  slice.put([3]);
  assert(arr == [1, 2, 3, 4]);

  arr[1..$-1].put([0, 0]);
  assert(arr == data);
}

Ali



Re: The Phobos Put

2023-03-29 Thread Ali Çehreli via Digitalmars-d-learn

On 3/29/23 09:27, Salih Dincer wrote:

> In this way,
> it could also be used directly with slices. For example:

> auto put(R)(R[] range, R[] source)
>=> putImpl(range, source);

That's for rvalues.

> auto put(R)(ref R[] range, R[] source)
>=> putImpl(range, source);

That's for lvalues.

If you are proposing keeping the current ref-taking Phobos put() as 
well, then the following call would be ambiguous:


  slice.put([2]);  // Compilation ERROR

That can be remedied by using template constraints for 'slices' vs. 
other output ranges. But that would be against the idea of "D slices are 
most capable ranges". What I mean is, I should be able to write any 
range algorithm and pass a slice to it and it should work. If we go with 
your proposal, then we would have to check for that case for some 
algorithms like put().


Further, I think the user of put() in templates would have to check 
whether they are dealing with a slice or not:


void foo(R)(R range) {
  range.put(/* ... */);

  // If we go with your proposal, whether 'range' changed depends
  // on whether R is a slice or not. Do we have to check with
  // 'static if' in such range algorithms?
}

Note that I am not defending the behavior of put(). I am just trying to 
explain why it is so.


Ali



Re: The Phobos Put

2023-03-29 Thread Ali Çehreli via Digitalmars-d-learn

On 3/29/23 04:48, Dennis wrote:
> On Wednesday, 29 March 2023 at 11:10:42 UTC, Salih Dincer wrote:
>> Why does my `put` work but the Phobos `put` doesn't work with a slice?
>
> Your `put` doesn't take `range` by `ref`, so it allows you to pass an
> rvalue. Consequently, it doesn't advance the range from the callers
> perspective.

And that 'ref' is necessary because not every OutputRange can be sliced 
for further calls to put(). Salih does not have that problem because he 
is working with slices, which are (usually) trivially slicable for the 
next portion to be passed to put().


On the other hand, Phobos's put() works with any OutputRange so it has 
to take a 'ref' to advance to know where it is left off. This behavior 
makes its use with slices weird but sometimes such is life. :)


Ali



Re: Calling assumeSorted on const(std.container.Array)

2023-03-25 Thread Ali Çehreli via Digitalmars-d-learn

On 3/25/23 09:31, Olivier Prat wrote:

On Saturday, 25 March 2023 at 13:45:36 UTC, Olivier Prat wrote:
I'm trying to call assumeSorted on a const(Array) using this code 
snippet:


[...]


In a similar fashion, a number of methods in SortedRange do not compile 
if called on a const(SortedRange) or immutable(SortedRange), such as 
length, or front. Is this on purpose?


There are a number of interesting points in your original post but I 
couldn't find time to answer all of those.


I can inject this for now: :) assumeSorted returns a range object. The 
concept of a const range object is flawed because by nature iteration of 
a range happens by mutating it: For example, popBack has to do that.


So, it's normal that any range algorithm will assume a non-const object.

Ali



Re: Segfault with std.variant

2023-03-25 Thread Ali Çehreli via Digitalmars-d-learn

On 3/24/23 23:07, Mitchell wrote:

>variant["four"] = Variant(4); // Segfault

Today I learned that VariantN forwards to associative array operations. 
Cool I guess. :)


> with a segfault. I'm using LDC2:

Same with dmd. It fails in the destructor of VariantN.

static if (!AllowedTypes.length || 
anySatisfy!(hasElaborateDestructor, AllowedTypes))

{
~this()
{
// Infer the safety of the provided types
static if (AllowedTypes.length)
{
if (0)
{
AllowedTypes var;
}
}
(() @trusted => fptr(OpID.destruct, , null))();
}
}

That @trusted lambda call segfaults.

This looks like a bug to me. Reported:

  https://issues.dlang.org/show_bug.cgi?id=23809

Ali



Re: Implicit type conversion depending on assignment

2023-03-23 Thread Ali Çehreli via Digitalmars-d-learn

On 3/23/23 07:36, Alexander Zhirov wrote:

>  @property auto toString(T)()

The name is misleading because you want types other than string as well.

>  alias toString this;

That should have been a compilation error because 'toString' does not 
have a known type (because it depends on a template parameter). How can 
the compiler accept that 'alias this'?


> int myInt   = a;
> float myFloat   = b;

Since you need to spell out 'int' and 'float' in some form anyway, the 
following would be my choice, which I did use in my code before:


struct MyVal
{
private string value;

auto to(T)()
{
import std.conv : to;
return value.to!T;
}
}

void main() {
auto a = MyVal("100");
auto b = MyVal("11.2");

auto myInt = a.to!int;
auto myFloat = b.to!float;
}

Should it be an error to convert 'a' to float? If so, the following 
modules may be helpful:


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

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

Ali



Re: Implicit type conversion depending on assignment

2023-03-23 Thread Ali Çehreli via Digitalmars-d-learn

On 3/23/23 06:38, Alexander Zhirov wrote:
> Is it possible to convert such records inside the structure to the
> assigned type?

D does not embrace implicit conversions. There is some support like 
'alias this' as you mentioned but what you are looking for is not possible.


Ali



Re: Threads

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

On 3/21/23 22:30, Tim wrote:
> to make a simple multi-threading application.

Unless there is a reason not to, I recommend std.concurrency and 
std.parallelism modules. They are different but much more simpler 
compared to the low-level core.thread.


>  args_copy = args; //Why program name is missing while copy 
arguments?


That doesn't copy. Both args_copy and args will be references to the 
same elements. (They are both array slices.)


The following may work to get a shared argument:

immutable args_copy = args.idup;

idup makes an immutable copy and immutable is implicitly shared.

Even if that works, I still find std.concurrency much easier to deal 
with. :)


Ali



Re: alias Error: need 'this'

2023-03-19 Thread Ali Çehreli via Digitalmars-d-learn

On 3/19/23 06:49, bomat wrote:

> I can live with the `static`
> solution, I guess.

If you could, you would define it 'static' anyway. :) Because you highly 
likely needed a distinct 'variableWithALongName' member for each 
MyStruct object, that wouldn't work.


> Shouldn't it be the exact same underlying mechanism?

I don't know the answer. Luckily, what you describe is available in 
another form in the language:


ref alias2() {
return myStruct.memberWithALongName;
}

Ali

Unrelated: I find 'myObject' a more correct name for a variable because 
if 'struct' is the definition of a type, 'myStruct' attempts to convey a 
misleading meaning.




Re: const in functions

2023-03-17 Thread Ali Çehreli via Digitalmars-d-learn

On 3/12/23 16:14, FozzieBear wrote:
> On Sunday, 12 March 2023 at 15:09:45 UTC, Salih Dincer wrote:
>>
>> ...
>
> So I don't agree with part of this comment (made elsewhere in this 
thread):

>
> "You can live without 'const' until your code interacts with other
> people's code."

My comment was purely technical. What I meant is, if the code is an 
island where there is no single 'const' in sight, then a D programmer 
can live by ignoring 'const'. At a technical level...


This is different from C++ where you have to use references to const in 
order to take rvalue references as parameters. Since D does not allow 
binding rvalues even to references to const, this is a moot point. 
(-preview=in does bind rvalues to references as an optimization but that 
fact is hidden from the programmer.)


So, my comment is correct at a technical level.

> Code interacts with other code. Code should always be clear as to its
> intent.

Absolutely. That's why I always start with 'const' (what should have 
been the default but is not for historical reasons):


  const foo = bar();

I change that 'const' to e.g. 'auto' as needed.

> Who wrote that code, or other code that interacts with that
> code, is irrelvant.

However, there is always the danger of going too far though. To keep the 
fun in the game, a programmer should be free to do whatever they want in 
their own code e.g. in their throw-away script programs.


Here is one line I never include in production code but I very 
frequently use in short programs:


import std;

Removes mental load, frees the mind, and enables flow of programming.

Some code is written for myself, not for people who are not watching 
over my shoulder. There is pride in caring for every character of the 
source code but sometimes freedom from all concerns is good too. 
Luckily, D makes it easy to refactor as requirements change.


Ali



Re: const in functions

2023-03-13 Thread Ali Çehreli via Digitalmars-d-learn

On 3/13/23 08:17, Salih Dincer wrote:

> In this case, using `ref` will increase performance while reducing the
> number of copies.

I am not sure about that. Unless there is an expensive copy 
construction, most objects are simple data copies.


To use 'ref' or not should be guided through semantics. Luckily, we have 
the -preview=in command line switch that removes the cost of copying 
from the equation:


  https://dlang.org/spec/function.html#in-params

Just marking the input parameters 'in' should be sufficient in most cases.

Ali



Re: 'auto' keyword

2023-03-12 Thread Ali Çehreli via Digitalmars-d-learn

On 3/12/23 06:07, DLearner wrote:

> 1. As a shorthand to make the type of the variable being declared the
> same as the type on the right hand side of an initial assignment.

As Adam explained, D already has type inference without a special keyword.

However, some places where 'auto' (or 'const', etc.) appear is not only 
for "shorthand" but for necessity.


Some types cannot be spelled-out at all:

auto foo() {
struct S {}
return S();
}

void main() {
pragma(msg, typeof(foo()));
auto s = foo();
}

The name 'S' is available only inside 'foo', so code outside has no 
choice but to use 'auto' (or 'const', etc.)


Having said that, it is still possible to alias the returned type, which 
may be cumbersome in some cases because you may have to come up with a 
clean expression for attempting to call the function. In this case it's 
trivial because foo does not take any parameter:


alias T = typeof(foo());
T t;// <-- There: I did not need to use 'auto'

Ali



Re: const in functions

2023-03-12 Thread Ali Çehreli via Digitalmars-d-learn

On 3/12/23 08:09, Salih Dincer wrote:

> As someone who has used const very little in my life

You can live without 'const' until your code interacts with other 
people's code. For example, the following program works just fine:


struct S {
int * p;

void foo() {}
}

void bar(S s) {}

void main() {
auto s = S();
s.foo();
bar(s);
}

Now you replace (or a user of your code replaces) 'auto' with 'const' 
and you will get 2 compilation errors:


const s = S();
s.foo();// ERROR 1
bar(s); // ERROR 2

So, if your code will ever interact with other people's code it must be 
const-correct. If foo() is not mutating the object (including through 
the p member), it better be defined as 'const':


void foo() const {}

And if bar() is not mutating the parameter, it better take as const:

void bar(const(S) s) {}

Now the code compiles.

You can (and should) use 'const' everywhere that you can because it 
increases the usability of code: Mutable, 'const', and 'immutable' 
variables can be used with code that takes by 'const'.


This is not the same with code taking by 'immutable'. It can only be 
used with 'immutable' variables.


Ali



Re: How to expand wildchar under dos ?

2023-03-10 Thread Ali Çehreli via Digitalmars-d-learn

On 3/9/23 19:24, John Xu wrote:
> Under dos, how to get wildchar matched file names?

Have you tried dirEntries? It supports glob patterns:

  https://dlang.org/library/std/file/dir_entries.html

Ali



Re: Passing and returning arguments by ref

2023-03-03 Thread Ali Çehreli via Digitalmars-d-learn

On 3/3/23 12:45, Joe wrote:

> I had tried changing B.x1() to:
>
>`ref X x1() { return [0]; }`
>
> but the compiler didn't accept it.

Yeah, that wouldn't work because the return expression is an X*.

Even though 'ref' is implemented as a pointer behind the scenes, that 
syntax is not legal.


> It's a bit weird that by taking the address of calling B.x1() and thus
> getting an X*

Agreed but that's how it is. Taking the address of a reference produces 
an X*.


> I had to *dereference* that to pass it to the helper
> function of A.mfd() which actually takes a `ref C` argument.

Yep, all of that makes sense. :)

Ali



Re: Passing and returning arguments by ref

2023-03-03 Thread Ali Çehreli via Digitalmars-d-learn

On 3/3/23 06:03, Joe wrote:

> My understanding was that since A, B and X[] are all reference types,
> this ought to work, but obviously something is missing.

Think may be due to D not having reference variables. Sometimes one 
needs to use pointers.


I find the following a simpler (and complete ;) ) example. foo() returns 
by ref and indeed, the change made to its return value is visible in main.


However, the same foo() is later called to initialize hopefullyRef but 
not the change made to that variables is not reflected in the array. (By 
the way, the example could be written without an array as well.)


struct S {
int i;

void change() {
++i;
}
}

ref S foo(S[] arr) {
return arr[0];
}

void main() {
auto arr = [ S(1) ];

// Ok, this operation changes arr[0]
foo(arr).change();
assert(arr[0].i == 2);

// This one changes the local variable
auto hopefullyRef = foo(arr);
hopefullyRef.change();
assert(hopefullyRef.i == 3);

// The array is still 2
assert(arr[0].i == 2);
}

hopefullyRef in just an int. The following definition of the 
hopefullyRef variable would cause the array element be changed:


// Now an S* (note & on the rigth-hand side)
auto hopefullyRef = (arr);
// Now hopefullyRef is an S*, not an S

// Same as before
hopefullyRef.change();
assert(hopefullyRef.i == 3);

// Now the array is affected (3, not 2)
assert(arr[0].i == 3);

Ali



Re: Bug in DMD?

2023-03-02 Thread Ali Çehreli via Digitalmars-d-learn

On 3/2/23 15:34, ryuukk_ wrote:

> the problem is not that it can run in the background, the problem is
> figuring out
>
> 1. how to install
> 2. how to setup
> 3. how to run

I haven't used it myself but dustmite seems to be integrated into dub. 
'dub dustmite <...>'


Ali



Re: Deciding one member of iteration chain at runtime

2023-02-17 Thread Ali Çehreli via Digitalmars-d-learn

On 2/17/23 09:30, Chris Piker wrote:

> operatorG needs
> to be of one of two different types at runtime

std.range.choose may be useful but I think it requires creating two 
variables like g1 and g2 below:


import std.range;
import std.algorithm;

void main(string[] args) {
const condition = (args.length > 1);

// The first part of the algorithm
auto r = iota(10)
 .filter!(n => n % 2);

// Two different steps
auto g1 = r.map!((int n) => n * n);
auto g2 = r.map!((int n) => n * 10);

// The rest of the algoritm
auto result = choose(condition, g1, g2)
  .array;
}

Ali



Re: Gneric linkedList range adaptor

2023-02-10 Thread Ali Çehreli via Digitalmars-d-learn

On 2/10/23 14:10, Ben Jones wrote:

> Any idea how to fix the helper method?

I came up with the following solution:

> struct LinkedListAdaptor(alias nextField, T){

In this case nextField will be a callable (a lambda below).

>  void popFront() {
>  current = __traits(child, current, nextField);

I changed that to

current = nextField(current);

>  auto rng1 = LinkedListAdaptor!(Node.next, Node*)(head);

Commented that out.

>  auto rng = linkedListAdaptor!(Node.next)(head);

Replaced that with

auto rng = linkedListAdaptor!(node => node.next)(head);

Now it works but explicitly creating a lambda feels less than ideal. 
Perhaps it can be improved.


Ali



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

2023-02-09 Thread Ali Çehreli via Digitalmars-d-learn

On 2/9/23 15:59, ProtectAndHide wrote:

> some 'key D
> people' (wink wink)
[...]
> So I hand that over to you .. wink wink.

You're trolling[1] again.

Ali

[1] https://www.merriam-webster.com/dictionary/troll#h3



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

2023-02-09 Thread Ali Çehreli via Digitalmars-d-learn

On 2/9/23 15:58, thebluepandabear wrote:
>> In contrast, I use D every day and love its relaxed attitude towards
>> private.
>
> the fact that private stuff is accessible from other classes in the same
> module is really really bad, and it's pretty detrimental to the language.

Not everybody shares that view. So, there must be something deeper here: 
maybe some people are blind (including me), or others have expectations 
that they carry from other languages, or something else... But look at 
the contrast: Some people see the same thing as great and some people 
see it as really really bad.


One thing is clear: We can't agree on this topic at least at this time.

> let's actually think about what `private` means.

It gives implementation freedom: I can change my implementation at will.

The same exact goal can be achieved by convention as well: I can name my 
members with e.g. an underscore and everybody understands that they are 
private. Nobody touches it and they are protected from future 
implementation changes.


If they do, they do it with full understanding that their code may break 
in the future.


> when you come back from work, arrive home, and you close the curtains
> and want some alone, you want to be private to everyone.

I don't agree with that example: Yes, it's the same word but different 
meanings in code.


> you wouldn't want your neighbours (the module) to peek at what you're
> doing.

Yes but I would have no problem other code looking at or using parts of 
my code if they wanted to.


> your neighbours aren't your friends in real life,

There is some friendship with my neighbors! :)

> and they (the module)
> aren't your friends in code

Some of them are and some aren't.

> -- just because they are in your vicinity
> doesn't mean they have a right to violate your privacy.

Right to violate doesn't mean anything will be broken. It means, there 
will be no hurdle if access is needed. Nobody will or does violate 
anything. I haven't seen a single time when D's approach to privacy 
caused harm.


> tbh this whole private behaviour should be changed, it's just so weird

Ok, I like "so weird" more than "really really bad". :)

Ali



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

2023-02-09 Thread Ali Çehreli via Digitalmars-d-learn

On 2/9/23 14:34, ProtectAndHide wrote:

> You mentioned previously that D implements various things in
> unprincipled ways.

I think you will continue misunderstanding that term. What it means is, 
D does not insist on certain programming paradigms over others. For 
example, you can code in structured, functional, object-oriented, etc. 
styles depending on your problem.


> I guess, if one wants to use D, one has to be comfortable with this.

I can't see how being free is something that one needs to be comfortable 
with but I guess you are correct.


> But using a relaxed attitude towards the implementation of such a common
> and important abstraction, that in turn allows me to so easily shoot
> myself in the foot, is not really an attractive feature .. to me ;-)

Thanks for the wink.

> btw. When a newbie to D raises ideas, suggestions, etc... and you
> counter them with (in essence)

That is not the essence at all! There has been numerous responses here 
before I reminded how the path is actually open for language changes.


> 'we don't need that in D, but go write a
> dip if you think we do' attitude, is a real turn off.

What was the alternative? Jumping to implementations of all suggested 
features? A bigger turn off would be forkit!


Ali



Re: staticMap but with two arguments

2023-02-09 Thread Ali Çehreli via Digitalmars-d-learn

On 2/9/23 12:45, John Chapman wrote:
> On Thursday, 9 February 2023 at 19:17:55 UTC, Ali Çehreli wrote:
>> I could not figure out eliminating the hard-coded 4. Can we introspect
>> the parameter list of a template like 'fun' in the example? If we
>> could, then we could get 4 that way.
>
> Thank you for this. I don't mind hard-coding the N argument.
> TemplateArgsOf needs an instantiated template but maybe ```enum N =
> count(fun.stringof, ',') + 1``` is good enough.

Hopefully but very fragile:

template t(int[] T = [ 1, 2 ]) {}

void main() {
import std.algorithm : count;
enum N = count(t.stringof, ',') + 1;
static assert(N == 1); // FAILS
}

Same thing with any other thing with comma in it e.g.

template t(T = anotherTemplate!(1, 2)) {}

Ali



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

2023-02-09 Thread Ali Çehreli via Digitalmars-d-learn

On 2/8/23 04:07, zjh wrote:

> Last time, someone proposed to add `private` like `C++'s`,

We've discussed the 'private' topic very many times already. C++'s 
private necessitate the 'friend' keyword, which comes with it's own 
problems.


Besides, D has zero problems with its private implementation in the 
sense that there has been zero bugs related to it being that way. Given 
the number of individuals who bring this topic up over and over up is so 
few that I don't think there is a common problem.


Do you have actual bugs related to this? "Wanting" the inclusion of a 
feature is sufficient.


In contrast, I use D every day and love its relaxed attitude towards 
private.


> and then it
> was the same,they are always unwilling to add facilities useful

That is not correct. The truth is, nobody is jumping to implementations 
just because some people think they are useful. There are always valid 
reasons for including a feature or not.


Ali



Re: Sort Associative Array by Key

2023-02-09 Thread Ali Çehreli via Digitalmars-d-learn

On 2/8/23 23:19, Alexander Zhirov wrote:
>> foo.byPair
>>  .array
>>  .sort!((a, b) => a.key < b.key)
>>  .map!(a => a.value);
>
> Is it possible to specify in `map` to return the result `[a.key] =
> a.value`? To make the result look like `[key:[val], key:[val]]`

map can return a tuple and std.array.assocArray can make an associative 
array from those tuples:


import std;

void main() {
auto aa = iota(10)
  .map!(n => tuple(n, n * n))
  .assocArray;
writeln("Necessarily unsorted:\n", aa);
}

However, as the original question started with an associative array 
anyway, I don't think I understand your question correctly. :)


If you are asking whether an associative array can store in sorted key 
order, then no, it's impossible because associative arrays are hash 
tables, which can't provide that.


But we can visit the elements in sorted order if we sort those keys 
ourselves:


auto keys = aa
.keys  // <- Makes an array by copying the keys
.sort;

writeln("In order:");
foreach (k; keys) {
writeln(k, ": ", aa[k]);
}

Ali



Re: How to debug/set breakpoint a dynamic library.so ?

2023-02-09 Thread Ali Çehreli via Digitalmars-d-learn

On 2/9/23 06:00, mw wrote:

The dynamic library.so is built from D (with pyd), and invoked from Python.

I'm just wondering How to debug/set breakpoint a dynamic library.so ?

Can someone give an example?

Thanks.


I may be totally off on this but I think it is as simple as the following:

  gdb --args your_python_program

Once inside, set a break point on the dynamic library symbol. Then run.

Ali



Re: staticMap but with two arguments

2023-02-09 Thread Ali Çehreli via Digitalmars-d-learn

On 2/8/23 12:04, John Chapman wrote:

> rather than write it manually for each N?

import std.meta : AliasSeq;

template pickArgs(size_t totalElements,
  size_t argsPerElement,
  size_t whichElement,
  args...) {
alias pickArgs = AliasSeq!();
static foreach (a; 0 .. argsPerElement) {
pickArgs = AliasSeq!(pickArgs, args[whichElement + a * 
totalElements]);

}
}

template staticMapN(size_t N, alias fun, args...)
{
static assert(N != 0, "N must be non-zero.");
static assert((args.length % N) == 0,
  "Mismatched number of arguments");

enum totalElements = args.length / N;

alias staticMapN = AliasSeq!();
static foreach (e; 0 .. totalElements) {
staticMapN = AliasSeq!(staticMapN,
   fun!(pickArgs!(totalElements, N, e, args)));
}
}

// An example struct with some template parameters
struct S(T, size_t length, size_t foo, size_t bar) {
}

// An example template that creates instantiations of the S template
template Instantiate(T, size_t length, size_t foo, size_t bar) {
alias Instantiate = S!(T, length, foo, bar);
}

// Compile-time argument sets for three instantiations of the S template
alias myTypes = AliasSeq!(int, double, long);
alias mySizes = AliasSeq!(1, 2, 3);
alias myFoos = AliasSeq!(42, 43, 44);
alias myBars = AliasSeq!(100, 200, 300);

// A test with those 4 sets of template arguments
alias result = staticMapN!(4, Instantiate, myTypes, mySizes, myFoos, 
myBars);

pragma(msg, result);

void main() {
}

I could not figure out eliminating the hard-coded 4. Can we introspect 
the parameter list of a template like 'fun' in the example? If we could, 
then we could get 4 that way.


Ali



Re: Comparison of multidimensional associative arrays

2023-02-08 Thread Ali Çehreli via Digitalmars-d-learn

On 2/8/23 11:04, Alexander Zhirov wrote:

> That is, the result is arrays of table B that are missing OR not equal
> to arrays in table A.

This should do it:

alias MyType = string[string][int];

// 'a' is subtracted from 'b'
MyType difference(MyType b, MyType a) {
MyType result;

foreach (kv; b.byKeyValue) {
auto existing = kv.key in a;

if (!existing || (*existing != kv.value)) {
result[kv.key] = kv.value;
}
}

return result;
}

void main() {
auto a = [
4:["id":"4", "deleted":"f", "name":"6.2"],
3:["id":"3", "deleted":"f", "name":"5.6_hwlister"],
2:["id":"2", "deleted":"t", "name":"6.2"],
1:["id":"1", "deleted":"f", "name":"5.6"]
];

auto b = [
6:["id":"6", "deleted":"f", "name":"6.2_test"],
5:["id":"5", "deleted":"f", "name":"5.6_test"],
4:["id":"4", "deleted":"f", "name":"6.2_hwlister"],
3:["id":"3", "deleted":"f", "name":"5.6_hwlister"],
2:["id":"2", "deleted":"f", "name":"6.2"],
1:["id":"1", "deleted":"f", "name":"5.6"]
];

auto expected = [
6:["id":"6", "deleted":"f", "name":"6.2_test"],
5:["id":"5", "deleted":"f", "name":"5.6_test"],
4:["id":"4", "deleted":"f", "name":"6.2_hwlister"],
2:["id":"2", "deleted":"f", "name":"6.2"]
];

auto diff = difference(b, a);

import std.format;
assert(diff == expected, format!"UNEXPECTED: %s"(diff));
}

Ali



Re: Comparison of multidimensional associative arrays

2023-02-08 Thread Ali Çehreli via Digitalmars-d-learn

On 2/8/23 09:55, Alexander Zhirov wrote:
> the differences

Is it considered a difference if a key exists but the value is 
different? Or is that an error case if you encounter that?


> return them when comparing:

The representation seems difficult as well. When given this:

>  6:["id":"6", "deleted":"f", "name":"6.2_test"],

and that:

>  6:["id":"6", "deleted":"f" ],

Should the difference be

  6:["name":"6.2_test"] ?

And how to represent "missing from inner AA"?

Just because this sounds complicated, I hope the data structure can be 
designed differently to be more friendly to this operation. (?)


Ali



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

2023-02-07 Thread Ali Çehreli via Digitalmars-d-learn

On 2/6/23 23:33, ProtectAndHide wrote:
> On Monday, 6 February 2023 at 21:46:29 UTC, Ali Çehreli wrote:

>> And as 'static class' and 'static struct' are already usable in D, a
>> newcomer would definitely be confused with your "terrible" conclusion.

> You being a little agressive don't you think?

I see how wrong that came out. Apologies! What I meant was "your 
conclusion [about something here being] terrible".


> My observation is very reasonable, and correct,

Agreed.

> The compiler will allow you to do all these things

Agreed.

> I can see no reason why anyone would want to do these things, in this
> context.

Agreed.

> Nor can I see any reason, whatsoever, why the compiler would allow you
> to do these things, in this context.

My understanding is that these are side-effects of trying to have 
orthogonal features. Some combinations don't make sense.


Having said that, since D does not use 'static class' for namespacing, 
should it go out of its way to implement logic to ban that combination 
at module scope? Perhaps. People have been discovering meaningless 
combinations of attributes in D all the time. (I forgot why that is so.)


If D disallowed 'static' at module scope, we wouldn't be having this 
discussion anyway. If that happened, then 'class' would be accepted for 
being used for creating objects.


Ali



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

2023-02-07 Thread Ali Çehreli via Digitalmars-d-learn

On 2/6/23 23:45, ProtectAndHide wrote:

> Well I don't agree that D should boast about things that's its
> implemented in an unprincipled way.

Here, "unprincipled"[1] is just a descriptive word meaning that D does 
not insist on certain software engineering methodologies e.g. unlike 
Java where "everything is a class" or unlike some functional programming 
languages where "everything must be immutable".[2]


> an unprincipled
> implementation of something that just allows you do make mistakes, then
> it should be looked at further, so see if it can be improved.

Agreed. But the lack of 'static class' in D or its approximations are 
not in that category. I can imagine someone coming up ingeniously with a 
harmful way of using 'static class' but unless that is a real problem 
that affects D users then there is no issue.


Ali

[1] I remember reading or hearing "unprincipled" from Andrei 
Alexandrescu long time ago.


[2] Actually, const and immutable being transitive can be seen as 
counter examples of D having a strong point on something. I think this 
"turtles all the way down" is not agreed by many users.




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

2023-02-06 Thread Ali Çehreli via Digitalmars-d-learn

On 2/6/23 12:56, ProtectAndHide wrote:

> I'm not going to 'go write a
> DIP'.

Nobody will write a DIP about it because very few people ever mentioned 
this issue over the years.


And as 'static class' and 'static struct' are already usable in D, a 
newcomer would definitely be confused with your "terrible" conclusion.


Ali



Re: staticMap but with two arguments

2023-02-06 Thread Ali Çehreli via Digitalmars-d-learn

On 2/5/23 17:20, John Chapman wrote:

> staticMap's "fun" can only be
> instantiated with a single argument, while I need it to work with two.

I adapted staticMap's implementation to two sets of arguments:

import std.meta : AliasSeq;

// The first half of 'args' is the "first arguments" and
// the second half is the "second arguments".
//
// (This can be generalized to N sets of arguments.)
template staticMap2(alias fun, args...)
{
alias firsts = args[0 .. $ / 2];
alias seconds = args[$ / 2 .. $];

static assert(firsts.length == seconds.length,
  "Mismatched number of first and second arguments");

alias staticMap2 = AliasSeq!();
static foreach (i; 0 .. firsts.length) {
staticMap2 = AliasSeq!(staticMap2, fun!(firsts[i], seconds[i]));
}
}

// An example struct with two template parameters
struct S(T, size_t length) {
}

// An example template that creates instantiations of the S template
// (This can be generalized to instantiation of any template.)
template Instantiate(T, size_t length) {
alias Instantiate = S!(T, length);
}

// An example use
alias myTypes = AliasSeq!(int, double, long);
alias mySizes = AliasSeq!(1, 2, 3);
alias result = staticMap2!(Instantiate, myTypes, mySizes);

pragma(msg, result);

void main() {
}

Ali



Re: ImportC "no include path set"

2023-02-06 Thread Ali Çehreli via Digitalmars-d-learn

On 2/5/23 22:55, Elfstone wrote:

> So how am I supposed to set the include path?

I am not familiar with D in Windows but my first guess would be the -I 
compiler switch:


  dmd -I=/my/c/headers ...

Ali



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

2023-02-06 Thread Ali Çehreli via Digitalmars-d-learn

On 2/5/23 18:15, ProtectAndHide wrote:

> I do not agree, that a compiler that allows a programmer to misuse a
> type

Types normally have objects. If a programmer found a way to use objects 
of a memberless type why stop them?


> should be seen as 'a feature'.

I am not saying I already see those uses as features. I am questioning 
why the compiler should ban certain features. Rather, why would a 
programmer decide that another programmer should not have objects of a 
certain type?


What is the actual insurmountable problem here? C#'s having 'static 
class' cannot be an answer because I can't imagine somebody even in C# 
wanted to have such a thing. For all I know, they wanted something else 
(namespacing in this case) and implemented it as 'static class'.


On the other hand, it is possible that C# brings different semantics 
that I don't know yet. What is that semantics? How does D already solve 
that?


> If that's the kind of 'power' D programmers want,

The trait here is orthogonality: Let's say A, B, C, etc. are features of 
a language. Some combination of those features work together for various 
reasons.


On the other hand, some combinations may not work well and people don't 
or can't use them for various reasons:


- The language may ban them because there may be dangerous ambiguities 
with that combination


- There may be technical impossibilities for that combination

- That combination can have no agreeable semantics (your earlier 
examples are in this category)


- People would never think about that combination (to me, at least some 
of your examples are in this category)


- People may decide not to use that combination in coding guidelines

- etc.

So, what I am understanding is that thebluepandabear and you are asking 
the compiler to ban certain combinations. For example, using a struct 
for namespacing (A) and being able to create objects (B) used together 
should not be allowed.


What other combinations can we come up with for such a list? As you 
said, certain uses of the 'static' keyword at module scope has no effect 
in D ('statis this' and 'shared static this' should be considered 
multi-word keywords and I think 'static const' has a meaning). Should 
the D spec enumerate all ineffective uses of 'static' (and others) and 
ban them? I don't agree.


In contrast, D delivers some features in an unprincipled way and the 
programmers use combinations of those features the way the see fit.


I really don't care if D had 'static class' to be used only as a 
namespace but I don't see how this issue is terrible. If the programmers 
ever need to use a struct (or a class) for namespacing then they 
wouldn't need objects of such types either. So, they wouldn't do that.


Ali



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

2023-02-06 Thread Ali Çehreli via Digitalmars-d-learn

On 2/5/23 17:50, thebluepandabear wrote:

> I don't see why you'd want

I am not saying it would be wanted or needed.

> to expose a static class/namespace as a
> variable, or any of such similar things. That would give no benefits to
> the programmer?

Perhaps. As I responded to ProtectAndHide, if there is a benefit then it 
is useful by definition; if there is no benefit then it wouldn't be used 
anyway.


Ali



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

2023-02-05 Thread Ali Çehreli via Digitalmars-d-learn

On 2/5/23 14:40, ProtectAndHide wrote:

> On Sunday, 5 February 2023 at 10:51:51 UTC, thebluepandabear wrote:
>>
>> It's not a terrible workaround to be honest.
>> 
>
> The 'terrible' part is this:
>
> - the compiler will allow you to declare a variable of type Algo
> - the compiler will allow you to declare an array with elements of type
> Algo
> - the compiler will allow you to use Algo as a type argument
> - the compiler will allow you to use Algo as a parameter
> - the compiler will allow you to use Algo as a return type

I understand disabling the programmer to do certain things are 
beneficial e.g. to prevent bugs but those above can all be seen as 
features. What is so terrible about giving the programmer those powers?


Ali



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

2023-02-05 Thread Ali Çehreli via Digitalmars-d-learn

On 2/5/23 02:57, thebluepandabear wrote:

> When dealing with contexts, or for when you want a clear context in your
> codebase, namespaces can be a life saver

Can you give an example of a D problem that namespaces could solve? I 
have been with D for 14 years and haven't missed namespaces from C++ ever.


The reason I ask is, mentioning lack of features of other programming 
languages is not the right way to go. We have to understand what problem 
they were trying to solve with that feature and then see how D already 
tackels it.


In this case, it is namespacing and D solves it with the following 
feature and perhaps others that I can't think of:


- modules
- structs
- classes
- templates

I don't consider myself a maintainer of D but I don't agree that yet 
another feature for namespacing is needed. I feel that it would bring 
complications.


I don't think it is practical to bring all features of all languages 
into D or any other language.


> we've seen it used in the D
> library, so there's no excuse for why this shouldn't be added, in my
> opinion.

If I'm not mistaken you've counted five such instances. Were they really 
necessary? Could they be coded in a different way? What is the cost of 
missing namespaces? I think you are the first person raising this issue.


You must have a strong case for this feature; so, I recommend you write 
a DIP for it. It is likely that the mere act of doing that will expose 
hidden costs and usage problems.


Ali



Re: Are there some helpers in Phobos equivalent to std::set_difference of ugly c++

2023-02-03 Thread Ali Çehreli via Digitalmars-d-learn

On 2/3/23 09:11, Ali Çehreli wrote:


'fold' is


Ha ha! :) Make that 'reduce' of course.

Ali



Re: Are there some helpers in Phobos equivalent to std::set_difference of ugly c++

2023-02-03 Thread Ali Çehreli via Digitalmars-d-learn

On 2/3/23 08:01, Richard (Rikki) Andrew Cattermole wrote:

All good, I'm glad it'll work for you :)

I used the word difference to search the phobos docs with.


'fold' is doing much better in that department because it mentions other 
names: "Implements the homonym function (also known as accumulate, 
compress, inject, or foldl) present in various programming languages of 
functional flavor."


  https://dlang.org/library/std/algorithm/iteration/reduce.html

Ali



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

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

On 1/29/23 22:09, RTM wrote:
> On Saturday, 28 January 2023 at 23:19:35 UTC, ProtectAndHide wrote:
>
>> That is, you can do OOP without classes
>
> How so?

OOP is about putting objects (data) and behavior (functions) together.

> Every OOP definition includes classes

OOP is possible in C, which does not have classes:

  void sing(Animal * animal);

That top-level sing function will do something like this:

  animal->sing(animal);

Every object has their own sing function pointer as a member. (Or one 
can go to a vtbl pointer approach with different pros and cons; I used 
all of this as an interview topic at some point.)


Programming languages just make it easy.

> (encapsulation + inheritance).

Encapsulation is available even in C as well. Inheritance can be 
achieved manually.


And I used C just because it does not provide any special OOP features.

Ali



Re: How to get the body of a function/asm statement in hexadecimal

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

On 1/29/23 14:19, max haughton wrote:

> it is not trivial to find where the *end* of a
> function is

I suspected as much and did run ...

> objdump

... to fool myself into thinking that 0xc3 was . Well, arguments 
e.g. pointer values can have 0xc3 bytes in them. So, yes, I am fooled! :)


Ali



Re: How to get the body of a function/asm statement in hexadecimal

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

On 1/29/23 13:45, Ruby the Roobster wrote:

> Of course, function pointers cannot be dereferenced.

Since you want to see the bytes, just cast it to ubyte*. The following 
function dumps its own bytes:


import std;

void main() {
enum end = 0xc3;
for (auto p = cast(ubyte*)&_Dmain; true; ++p) {
writefln!" %02x"(*p);
if (*p == end) {
break;
}
}
}

(It can be written more elegantly as a range expression.)

> Furthermore, I would like to be able to do the same for an `asm` 
statement.


I don't know how to get the address of asm blocks.

Ali



Re: std.logger issue

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

On 1/26/23 12:08, Krzysztof Jajeśnica wrote:
> On Thursday, 26 January 2023 at 17:17:28 UTC, o3o wrote:
>> how can I enable `trace` level?
>
> Set `sharedLog.logLevel` instead of `globalLogLevel`.

Good catch. I had tried the following without success:

   stdThreadLocalLog.logLevel = LogLevel.all;

> // Note: the cast is needed because sharedLog is shared
> (cast()sharedLog).logLevel = LogLevel.all;

I did not think casting that way would be the right thing to do.

Although I've never used std.logger, and without remembering who 
implemented it (sincere aplogies), given how simple the use cases of 
logging are, I found its implementation very complicated. For example, 
the following function is one I stumbled upon while debugging the OP's 
issue:


bool isLoggingEnabled()(LogLevel ll, LogLevel loggerLL,
LogLevel globalLL, lazy bool condition = true) @safe
{
return ll >= globalLL
&& ll >= loggerLL
&& ll != LogLevel.off
&& globalLL != LogLevel.off
&& loggerLL != LogLevel.off
&& condition;
}

I don't think it is possible to entagle usage issues with functions with 
that semantic complexity.


Ali



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: 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-20 Thread Ali Çehreli via Digitalmars-d-learn

On 1/20/23 07:01, torhu wrote:

> But why not have drawLine just be a free function?

Exactly.

If I'm not mistaken, and please teach me if I am wrong, they are 
practically free functions in Java as well. That Java class is working 
as a namespace. So, the function above is the same as the following 
free-standing function in D, C++, C, and many other languages:


  void Algo_drawLine(Canvas c, Pos from, Pos to) { .. };

Ali



Re: What is the 'Result' type even for?

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

On 1/19/23 19:11, Ruby The Roobster wrote:

>  typeof(c).stringof.writeln;

> The program prints:
>
> ["a", "b", "c", "d", "e"]
> Result
>
> What is the purpose of this 'Result' type?

Just to make sure, 'Result' is what the programmer of a Phobos algorithm 
chose to name a struct type. It could be anything.


I will try to demonstrate it by naming my struct 'MyResult' below. The 
following range algorithm alternates between the two values it is called 
with.


The pragma(msg) inside 'main' prints MyResult.

auto alternate(T)(T a, T b) {
// This function will return an object
// of the following nested struct.
// (Note: This is for demonsration
// purposes only. Yes, this can be
// be more optimal.)
struct MyResult {
bool useB = false;

enum empty = false; // Infinite

T front() {
return useB ? b : a;
}

void popFront() {
// Flip the selector
useB = !useB;
}
}

// Here, an object of the struct is
// returned. It has single member (useB)
// that it uses as a selector.
// The values 'a' and 'b' are the actual
// function arguments.
return MyResult();
}

import std;

void main() {
auto myRange = alternate(42, 7);

// This prints 'MyResult' at compile time
pragma(msg, typeof(myRange));

const expected = [ 42, 7, 42, 7, 42 ];
assert(myRange.take(5).equal(expected));
}

> even when the type
> has the same inherent function:

Different instantiations of templates are distinct types. For example, 
if I called 'alternate' with two 'long' values, both alternate!int (as 
instantiated by the code above) and alternate!long would have different 
MyResult struct types.


Although they would have the same functionality, they would be compiled 
potentially with very different CPU instructions and would not be 
assignable.


Ali



Re: Problem with ImportC example?

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

On 1/18/23 08:04, DLearner wrote:

> Unfortunately, neither works:
> ```
> C:\Users\SoftDev>cl.exe
> 'cl.exe' is not recognized as an internal or external command,
> operable program or batch file.

That supports the theory that you don't have a C compiler installed that 
dmd can use for preprocessing C files.


Ali



Re: Problem with ImportC example?

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

On 1/17/23 12:02, DLearner wrote:

 C:\Users\SoftDev\Documents\BDM\D\ImportC>dmd ex01.c
 failed launching cl.exe /P /Zc:preprocessor [...]

I don't use Windows for development but that error message makes me 
think cl.exe is not found to be executed.


dmd relies on system compiler programs for its ImportC feature. cl.exe 
seems to be the compiler. I think it is the compiler.


Can you run that program from the command line?

Internet makes me think Visual Studio does not install it by default. 
(?) You may have to select C++ (or C?) when installing. (?)


> FWIW, now tried a few standard D programs, work fine.
> Suggesting VS is not the problem?

Standard D programs don't need a C compiler; dmd is the D compiler. It 
needs a C compiler (to preprocess C sources) for ImportC.


Ali



Re: Mixin helper help

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

On 1/13/23 18:51, bauss wrote:


That's a good one!


It looks like you liked it four years ago as well. :) I found where I 
remembered it from:


  https://forum.dlang.org/post/pvdoq2$1e7t$3...@digitalmars.com

Ali



Re: Mixin helper help

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

On 1/13/23 00:48, bauss wrote:

> 1. Change your mixin template to something like this:

There was a technique as a workaround for this template mixin limitation 
but I can't find it right now.


> 2. Change the place where you instantiate to this:

I think the workaround I am trying to remember would not require any 
change for the users.


Ok, it was something like this:

mixin template myStatement() {
auto doIt() {
import std.stdio : writeln;
writeln("hi");
return 0;
}

auto ignoreThis = doIt();
}

void main() {
mixin myStatement!();
mixin myStatement!();
}

Ali



Re: Creating a pointer/slice to a specific-size buffer? (Handing out a page/frame from a memory manager)

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

On 1/13/23 07:22, Gavin Ray wrote:
> Maybe it would be better to wrap the slice in a new class with an
> invariant?

Possibly but please check before using because I think 'invariant' 
requires presence of member functions:


  https://dlang.org/spec/struct.html#Invariant

> Because what I want to do is:
>
> 1. Ensure that the length of the underlying referenced/pointed-to data
> is `PAGE_SIZE`

My first thought was why not use a slice anyway?

Worth noting that static arrays are value types. Also, they all have 
different types from each other and have the potential to cause template 
bloat.


> class BufferPool

Off-topic, most D programmers use struct unless they need class.

>  Frame[BUF_POOL_NUM_PAGES] frames;

Makes sense to me.

Ali



Re: Creating a pointer/slice to a specific-size buffer? (Handing out a page/frame from a memory manager)

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

On 1/13/23 07:07, Gavin Ray wrote:

> This is "valid" D I hope?

Yes because static arrays are just elements side-by-side in memory. You 
can cast any piece of memory to a static array provided the length and 
alignment are correct.


However, such a cast is not allowed in @safe code.

Ali



Re: Creating a pointer/slice to a specific-size buffer? (Handing out a page/frame from a memory manager)

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

On 1/13/23 06:49, Gavin Ray wrote:

> I am curious if you can return something like `ubyte[PAGE_SIZE]*` or
> `ref ubyte[PAGE_SIZE]`?

A simple cast seems to work:

enum PAGE_SIZE = 4096;
enum BUF_POOL_NUM_PAGES = 1024;
alias frame_idx_t = size_t;

ubyte[10_000] data;

ubyte[PAGE_SIZE]* get_page(frame_idx_t frame_idx)
{
auto ptr = data.ptr + frame_idx * PAGE_SIZE;
return cast(ubyte[PAGE_SIZE]*)ptr;
}

void main() {
}

Ali



Re: enum functions

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

 TLDR 

Eponymous templates that define a function pointer does not transfer the 
function call parameter to the enclosing template for type deduction. 
(Note: The term "deduction" is used with template parameters, not 
"inference".)


Also note that I am replacing 'enum' with 'auto' below to show this is 
not related to 'enum' vs 'auto'.


template foo (T) {
auto foo = (T i) => i >> 1;
}

void main() {
foo(42); // <-- Compilation ERROR
}

Error: none of the overloads of template `deneme.foo` are callable using 
argument types `!()(int)`

   Candidate is: `foo(T)`

I am not sure whether this limitation is a bug.

 TLDR 

On 1/11/23 10:01, Salih Dincer wrote:

> void main()
> {
>  enum foo : char { a = 'H', b = 'i' }

That defines two values: foo.a is 'H' and foo.b is 'i'.

>  enum bar() { return new foo; }

That is a function that returns a dynamically allocated foo value. Since 
'new' makes pointers for value types like int and enum, I think the 
return type of 'bar' is foo*.


And that pointer is pointing at a foo.init, which happens to be the 
first value defined: 'H'.


>
>  import std.stdio;
>  foreach(char f; [bar.a, bar.b])

'bar' is a function call that returned a pointer. Hm. Finally I see what 
you are talking about.


Normally, one might have written (*bar) to get the value. Let's try by 
using the following array:


  [(*bar), (*bar)]

Ok, it's what I expect:

HH

Now the interesting part is what does (*bar).a and (*bar).b mean? Let's try:

  [(*bar).a, (*bar).b]

Ok, it gives

Hi

The interesting thing is, foo.a does not print 'H' but 'a':

writeln(foo.a);
writeln(foo.b);

a
b

Ah! Finally I see your explicit 'char' in the foreach loop. That is what 
makes your code print 'H' and 'i'. :)


>  f.write;
>
>  writeln; // Hi
> }

I've just learned something: You can reach different enum values 
directly from an value itself:


import std;

void main()
{
// A type:
enum foo : char { a = 'H', b = 'i' }

// A variable:
enum x = foo.a;

// Really?
writeln(x.b);
}

Ok, it kind of makes sense but I would have written the following e.g. 
in template code. (?)


writeln(typeof(x).b);

> I think this use of enums should be prohibited. So, can I get an answer
> about not being able to make a type inference? So I'm very curious about
> the second part of the my post.

Before looking at your example, here is what I tested. The code proves 
that type inference is the same for 'auto' and 'enum' functions:


auto foo(T)(T t) {
return t;
}

enum bar(T)(T t) {
return t;
}

struct S {}

import std.meta;

void main() {
alias functions = AliasSeq!(foo, bar);
alias types = AliasSeq!(int, double, S, string, const(float));

static foreach (type; types) {
pragma(msg, "Testing ", type);
static foreach (func; functions) {
static assert (is (typeof(func(type.init)) == type));
}
}
}

It uses two function templates and a few types and as expected, the 
return types of the functions are the same.


Ok, back to your code:

> template foo (T) {
> enum foo = (T i) => i >> 1;
> }

That local 'foo' is a literal value of an anonymous function. (The local 
'foo' is not a template.) Reminding myself: Literals are rvalues and 
they are not variables. For example, they don't have addresses.


> template bar (T) {
> auto bar (T i) => i >> 1;
> }

That's different: There was an equals sign after 'foo' but not here. So 
your example is different from e.g. the following two definitions:


auto x() {}
enum y() {}

If you are curious about this case, as Adam said, there is no difference 
between 'auto' and 'enum'.
But again, your code has that extra '=' character for 'foo' and that 
makes a difference.


Getting back to 'bar', so that local 'bar' is a function definition. 
Now, calling bar from the outside as bar(42) is the same as writing 
bar!int.bar(42). (This is the eponymous template convenience.)


> import std;

> void main()
> {
> assert(oneHalf(42) == 21);
> 42.foo!int.writeln; // no inference: "21"

Your "no inference" comment was confusing me. Now I see that you meant 
that you can't write the following:


  42.foo.writeln; // <-- Compilation ERROR

Although you can write the following:

> 42.bar.writeln; // "21"
> }

Ok, let's look at the problem with the understanding of 'foo' being a 
literal. Yes, I can demonstrate the issue that mix it with the concept 
of type inference:


import std;

void main() {
enum foo = {   // Note '='
writeln("foo");
};

auto bar() {
writeln("bar");
}

foo;  // <-- Compilation ERROR
bar;
}

foo line has a compilation error:

Error: `__lambda1` has no effect

Because it's a function pointer, one needs to call it with parenthesis:

foo();
bar;

Now it works.

The reason why 'bar' does not need the parenthesis is because functions 
have that 

Re: Coding Challenges - Dlang or Generic

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

On 1/9/23 16:17, Paul wrote:

> coding challenges

Perhaps the following two?

  https://rosettacode.org/

  https://adventofcode.com/

Ali



Re: Bug or feature? iota has different semantics for integer and float arguments

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

On 1/6/23 17:50, Arredondo wrote:

> Would anyone volunteer to file a bug report?

Me! Me! :)

  https://issues.dlang.org/show_bug.cgi?id=23604

Ali



Re: Bug or feature? iota has different semantics for integer and float arguments

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

On 1/6/23 15:23, Arredondo wrote:

> then you get an exception (incorrect startup parameters).

Although that difference is a bug, iota does have a special floating 
point implementation to prevent the accumulation of floating point 
errors. I mention it as item 4 here:


  https://www.youtube.com/watch?v=gwUcngTmKhg=634s

Briefly, iota's regular popFront() is a trivial

  front += step

but it is

  ++n

for floating types so that front can be

  begin + (n * step)

for them.

The iota discussion starts at an earlier point in the video here:

  https://www.youtube.com/watch?v=gwUcngTmKhg=558s

Ali



Re: Address of a class object

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

On 1/4/23 20:04, Paul wrote:
>> (Again, there is no problem here; we are just learning.)
>> Ali
>
> Do I have this much right?

> ..with this output?

Looks good to me.

While we're here, you can force the class objects to be on the stack as 
well:


scope MyClassVar1 = new MyClass();

I replaced 'auto' with 'scope'.

Ali



  1   2   3   4   5   6   7   8   9   10   >