Re: why is "hello".writeln considered bad?

2020-11-19 Thread Mike Parker via Digitalmars-d-learn

On Friday, 20 November 2020 at 07:39:10 UTC, norm wrote:
I was reading some posts and this was presented as a snippet of 
code and was immediately flagged as bad practice.




Eh, I wouldn't quite put it that way. If we're thinking of the 
same thread, one person said he thought it was a bad idea. That 
doesn't make it bad practice. It's just his opinion. I think UFCS 
is an awesome feature. And it's widely used in D code.


I get some people don't like it but occasionally I prefer this 
syntax. It feels more declarative and fluent in style. Is there 
a good technical reason why it is bad practice, e.g. does it 
make it easier to write bugs? Or is it just what people are 
used to?


I think everyone has their own criteria for when to use UFCS. For 
example, I don't generally write "foo".writeln myself, because I 
don't think of writeln as being a property of strings. And that's 
the lens through which I view UFCS: this operation is akin to a 
property of this type. Other people might not see it that way, 
and one (not me) could make an argument that this specific usage 
is bad practice, but the feature itself rocks.







why is "hello".writeln considered bad?

2020-11-19 Thread norm via Digitalmars-d-learn
I was reading some posts and this was presented as a snippet of 
code and was immediately flagged as bad practice.


I get some people don't like it but occasionally I prefer this 
syntax. It feels more declarative and fluent in style. Is there a 
good technical reason why it is bad practice, e.g. does it make 
it easier to write bugs? Or is it just what people are used to?


Thanks,
norm


Re: DMD -i option, simple question...

2020-11-19 Thread Adam D. Ruppe via Digitalmars-d-learn

On Friday, 20 November 2020 at 03:06:37 UTC, WhatMeWorry wrote:
The "..when this option is enabled..." is exactly the behavior 
I want, but how is it enabled?  Is there an "all inclusive 
pattern" that I'm missing.


dmd -i yourfile.d

that's the default it is describing when you don't specify any 
pattern.


DMD -i option, simple question...

2020-11-19 Thread WhatMeWorry via Digitalmars-d-learn



The DMD forum mentions internal design. This is more of a 
beginner usage question.


-  from Compiler Switches 
-


-I=directory
Look for imports also in directory

-i[=pattern ]

Enables "include imports" mode, where the compiler will 
include imported modules in the compilation, as if they were 
given on the command line. By default, when this option is 
enabled, all imported modules are included except those in 
druntime/phobos




The "..when this option is enabled..." is exactly the behavior I 
want, but how is it enabled?  Is there an "all inclusive pattern" 
that I'm missing.









Re: Calling function within class.

2020-11-19 Thread frame via Digitalmars-d-learn

On Thursday, 19 November 2020 at 19:51:24 UTC, Vino wrote:
the moment we enable
parallelism, it is throwing an error on the SQL part (Fetch the 
username/ password from the table for each account), as it 
could not execute the SQL query in parallel for different 
account.


I see no reason for a SELECT call (UPDATE/INSERT could cause 
locks...). Which error do you get?




Re: Calling function within class.

2020-11-19 Thread Vino via Digitalmars-d-learn

On Wednesday, 18 November 2020 at 21:33:58 UTC, Ali Çehreli wrote:

On 11/18/20 7:01 AM, Vino wrote:

>Request your help on how to call a function(listFile) from
another
> function(getFilelist) within the same class(GetDirlist),
below is an
> example code.

That code looks unnecessarily complex to me. First of all, 
parallel() already executes the loop body in separate threads, 
so I don't see any reason for Task in that code.


std.parallel will appear during my DConf presentation on 
Saturday. The following program applies ideas from some of my 
slides and just works in parallel:


import std.process;
import std.exception;
import std.format;
import std.parallelism;
import std.stdio;

class GetDirlist {

  @system private auto listFile(immutable string st)
  {
auto fl = execute(["ls","-l"]);
enforce(fl.status == 0, format("File not Found: %s", 
fl.status));

return fl.output;
  }

  @system public auto getFilelist()
  {
// I am using D dynamic arrays for simpliticy
auto flstore = [ "/path1/Dir1", "path2/Dir2" ];

// Note preallocated slot for each result:
auto amidata = new string[flstore.length];

// Taking advantage of automatic loop counter
foreach(i, st; parallel(flstore,1)) {
  // Each execution assigns to its own slot
  amidata[i] = listFile(st);
}
return amidata[];
  }
}

void main() {
  // Need an object to call a non-static member function:
  auto g = new GetDirlist();
  writeln(g.getFilelist());
}

Ali


Hi Ali,

Thank you very much, your solution works for my example, but it 
does not work for the main goal, let me explain what we are 
trying to perform.


Nut shell: Try to execute an aws command on sever accounts in 
parallel to get some data.


Noe: each account has as separate username and password store in 
a database table(encrypted).


Cod Logic
Fetch the username/ password from the table for each account.

Get the “awssecrete” key and “accesskey” for each account by 
calling an aws api using the above username/password.


Set the fetched key’s as an environment variable.

Execute the aws command and get the data for each of the account

  As we have many accounts what we are trying is to get the data 
in parallel(execute the aws command in parallel for each account 
and store the result in a array). At present our code is working 
fine(without parallel), the moment we enable parallelism, it is 
throwing an error on the SQL part (Fetch the username/ password 
from the table for each account), as it could not execute the SQL 
query in parallel for different account. If there is any other 
logic please do let me know will give it a try. Below is the SQL 
code.


@trusted public auto getAwsconf(immutable string account)
{
 auto con = new GetConnections();
 Statement stmt = con.db.prepare("SELECT 
username,AES_DECRYPT(b.userpass,b.key,b.vector) AS passwd FROM 
config WHERE account = :account");

 stmt.setParameter("account", account);
 RowSet awsaccount = stmt.query();
 scope(exit) con.db.close();
 return awsaccount;
}

From,
Vino.B


Re: betterC question

2020-11-19 Thread Dibyendu Majumdar via Digitalmars-d-learn
On Thursday, 19 November 2020 at 14:34:38 UTC, Adam D. Ruppe 
wrote:
On Thursday, 19 November 2020 at 00:20:50 UTC, Dibyendu 
Majumdar wrote:

Okay thanks. Bad idea IMO.


That's kinda how I see C taking the address of various things 
implicitly.


To be honest it seems irrelevant what C does.


Re: implementing default opCmp

2020-11-19 Thread Ali Çehreli via Digitalmars-d-learn

On 11/19/20 6:12 AM, Steven Schveighoffer wrote:

On 11/18/20 6:06 PM, ag0aep6g wrote:



 int opCmp(S other)
 {
 import std.typecons: tuple;
 return tuple(this.tupleof).opCmp(tuple(other.tupleof));
 }



Ah, excellent solution! I hadn't thought of that.

-Steve


That's what I use as well.

S can be replaced with something like 'typeof(this)' (or perhaps 'ref 
const(typeof(this))' and throw some inout in there :) ) and the whole 
thing can be mixed-in whereever needed.


Ali



Re: Function Pointer Not Working

2020-11-19 Thread Marcone via Digitalmars-d-learn

I will wait with this code.
WaitForSingleObject(threading, INFINITE);


Re: betterC question

2020-11-19 Thread Jack via Digitalmars-d-learn
On Thursday, 19 November 2020 at 14:34:38 UTC, Adam D. Ruppe 
wrote:
On Thursday, 19 November 2020 at 00:20:50 UTC, Dibyendu 
Majumdar wrote:

Okay thanks. Bad idea IMO.


That's kinda how I see C taking the address of various things 
implicitly.


good example


Re: Function Pointer Not Working

2020-11-19 Thread Marcone via Digitalmars-d-learn

On Thursday, 19 November 2020 at 15:51:09 UTC, Kagamin wrote:
The delegate is stored on the stack of the calling thread, the 
created thread loads it from there, but the calling thread 
doesn't wait for that and clobbers the stack right away. If you 
were lucky your code would crash.


The thread that I do wait ultil function is finished. Using a 
while with 3 seconds to verify if thread id is in running list, 
and break if not finishing owner thread.


Re: Function Pointer Not Working

2020-11-19 Thread Kagamin via Digitalmars-d-learn
The delegate is stored on the stack of the calling thread, the 
created thread loads it from there, but the calling thread 
doesn't wait for that and clobbers the stack right away. If you 
were lucky your code would crash.


Re: betterC question

2020-11-19 Thread Adam D. Ruppe via Digitalmars-d-learn
On Thursday, 19 November 2020 at 00:20:50 UTC, Dibyendu Majumdar 
wrote:

Okay thanks. Bad idea IMO.


That's kinda how I see C taking the address of various things 
implicitly.


Re: implementing default opCmp

2020-11-19 Thread Steven Schveighoffer via Digitalmars-d-learn

On 11/18/20 6:06 PM, ag0aep6g wrote:

On Wednesday, 18 November 2020 at 22:29:17 UTC, Steven Schveighoffer wrote:
How do I do something really simple for opCmp? I tried this it didn't 
work:


return this == other ? 0 :
    this.tupleof < other.tupleof ? -1 : 1;


std.typecons.Tuple has opCmp. So this works:

     int opCmp(S other)
     {
     import std.typecons: tuple;
     return tuple(this.tupleof).opCmp(tuple(other.tupleof));
     }



Ah, excellent solution! I hadn't thought of that.

-Steve


Re: implementing default opCmp

2020-11-19 Thread Steven Schveighoffer via Digitalmars-d-learn

On 11/18/20 6:02 PM, Paul Backus wrote:

On Wednesday, 18 November 2020 at 22:29:17 UTC, Steven Schveighoffer wrote:

I have a struct like this:

struct S
{
   int x;
   int y;
}

and I want a default comparison. The problem is, that comparison 
doesn't have a default, and requires I implement opCmp. While this is 
useful for the compiler, there's no default I know of that is an easy 
one-liner.


Here's a stab at a totally generic version that I haven't unit tested at 
all, except to verify that it works for your example struct S:


auto cmp(T, U)(auto ref T lhs, auto ref U rhs)
{
     import core.lifetime: forward;

     static if (__traits(compiles, lhs.opCmp(rhs)))
     return forward!lhs.opCmp(forward!rhs);
     else static if (__traits(compiles, rhs.opCmp(lhs)))
     return -forward!rhs.opCmp(forward!lhs);
     else
     return lhs < rhs ? -1 : lhs > rhs ? 1 : 0;
}

mixin template defaultOpCmp()
{
     import std.traits: isAggregateType;

     static assert(isAggregateType!(typeof(this)),
     "opCmp can only be overloaded for aggregate types.");

     auto opCmp()(auto ref typeof(this) other)
     {
     import std.traits: ReturnType, CommonType, Fields;
     import std.meta: Map = staticMap;

     alias cmpType(T) = ReturnType!((T lhs, T rhs) => cmp(lhs, rhs));
     alias Result = CommonType!(Map!(cmpType, Fields!(typeof(this;

     Result result;

     static foreach (i, _; typeof(this).tupleof)
     if (result == 0)
     result = cmp(this.tupleof[i], other.tupleof[i]);

     return result;
     }
}


Yeah, something like this might be useful in druntime. But it makes you 
wonder if we wouldn't be better off without opCmp but instead with 
opBinary(string s : "<") and friends.


One thing that sucks is that opCmp might do more operations than are 
necessary for the actual comparison, because it has to generate the 
numeric result.


-Steve


Re: Function Pointer Not Working

2020-11-19 Thread Marcone via Digitalmars-d-learn

Solved replacing this line:

CreateThread(null, 0, &_fun, , 0, null);

to this code:
task!({CreateThread(null, 0, &_fun, , 0, 
null);}).executeInNewThread();


Re: betterC question

2020-11-19 Thread Basile B. via Digitalmars-d-learn
On Thursday, 19 November 2020 at 00:07:12 UTC, Dibyendu Majumdar 
wrote:

I have simple test program:

import core.stdc.stdio : printf;

void test() {
int* a;
printf("a == null %d\n", a == null);
}

int function() fp = test;

extern (C) void main() {
fp();
}

Why do I get:

\d\dmd-2.092.1\windows\bin64\dmd.exe -betterC tests.d
tests.d(5): Error: printf cannot be interpreted at compile 
time, because it has no available source code


This is on Windows


IMO another problem here is that `function` and `delegate` are 
special cases of the `*` postfix. With a syntax like


int()* fp = test

it would be more obvious to new comers that `&` is missing.
This is a syntax I experiment in STYX for example [1].


Note that then there's also the problem with functions pointers 
requiring a context. This context is not necessarily a `this` 
(for closures it's a frame obviously).


[1] 
https://gitlab.com/basile.b/styx/-/blob/master/tests/backend/function_pointers.sx#L10


Re: betterC question

2020-11-19 Thread Dibyendu Majumdar via Digitalmars-d-learn
On Thursday, 19 November 2020 at 09:23:25 UTC, Jacob Carlborg 
wrote:
Yes, calling `writeln` like that is a bad idea. That was a bad 
example.


But the actual reason is, this is how D implements properties 
[1]. Any function that doesn't take an argument can be called 
without parentheses. Any function which takes a single argument 
can be called like setting a field.


I think that properties on an object are a special case - but 
treating an random function identifier as callable is still bad.


Re: betterC question

2020-11-19 Thread Dibyendu Majumdar via Digitalmars-d-learn

On Thursday, 19 November 2020 at 01:42:16 UTC, Mike Parker wrote:
On Thursday, 19 November 2020 at 00:20:50 UTC, Dibyendu 
Majumdar wrote:
On Thursday, 19 November 2020 at 00:18:54 UTC, rikki 
cattermole wrote:




You don't need the brackets to call a function (and with a 
little help from UFCS):


void main() {
import std.stdio;

"Hello!".writeln;
writeln;
}


Okay thanks. Bad idea IMO.


Imagine what range pipelines would look like without it. This 
is one of my favorite D features.


Well Java and C# have streams and it looks perfectly fine without 
this kind of syntax.





Re: betterC question

2020-11-19 Thread Jacob Carlborg via Digitalmars-d-learn
On Thursday, 19 November 2020 at 00:20:50 UTC, Dibyendu Majumdar 
wrote:

On Thursday, 19 November 2020 at 00:18:54 UTC, rikki cattermole


You don't need the brackets to call a function (and with a 
little help from UFCS):


void main() {
import std.stdio;

"Hello!".writeln;
writeln;
}


Okay thanks. Bad idea IMO.


Yes, calling `writeln` like that is a bad idea. That was a bad 
example.


But the actual reason is, this is how D implements properties 
[1]. Any function that doesn't take an argument can be called 
without parentheses. Any function which takes a single argument 
can be called like setting a field. Here's an example:


struct Color
{
private uint hex;

int red()
out(result; result >= 0 && result <= 255) // assert that the 
result is within bounds

{
return (hex & 0xFF) >> 16;
}

void red(int value)
in(value >= 0 && value <= 255) // assert that the value is 
within bounds

{
hex = (hex & 0x00) | (value << 16);
}

// similar functions for green and blue
}

void main()
{
Color color;
color.red = 255;
assert(color.red == 255);
}

[1] https://en.wikipedia.org/wiki/Property_(programming)

--
/Jacob Carlborg


Re: Calling function within class.

2020-11-19 Thread frame via Digitalmars-d-learn

On Wednesday, 18 November 2020 at 19:25:06 UTC, Vino wrote:

  The above code is a sample code, but the logic is same, 
correct me if my understanding is wrong, in the above code 
"obj" is a an object for the class GetDirlist, so we are 
accessing the class member using "obj.listFile(st)" , so why do 
we need the "(this)" and also why is this so complicated in D 
where as in PHP it is simple like below


You need to understand that you cannot use "this" in a function 
that you call in a new thread but task! starts a kind of new 
thread. That's not allowed by the runtime.


Your PHP code does not show any threading and PHP does not 
support threading without extensions. Also PHP does not allow 
$this for real threading extensions like parallel.


For D that means...

// before that statement you can call "this" - it points to your 
GetDirlist class.


auto fltask = task!(

   // this function is called in the new thread
   // and it's enclosed in the body of task! but could be also 
just a pointer to another
   // function. This is valid as long as the compiler do not need 
to access outside

   // variables/scope. "this" would also access the outside scope.

   function(GetDirlist obj, string st) {
obj.listFile(st);
   }

   // end of function and thread
)

// after that statement you can call "this" again
// so we pass "this" (your object) as argument to the function 
that cannot access "this"

// and the string that the function is expecting

(this, "foo");




Re: Can't pass [] to extern function object method

2020-11-19 Thread frame via Digitalmars-d-learn
On Thursday, 19 November 2020 at 07:46:20 UTC, Bastiaan Veelo 
wrote:

On Wednesday, 18 November 2020 at 10:50:12 UTC, frame wrote:
I found the "bug". It was caused by a debug {} statement 
within a struct method. I assume that the debug symbol is just 
incompatible called from the DLL context.


Were the DLL and main program built in different modes 
(debug/release)? Then this problem is understandable. Otherwise 
I find this surprising, and probably worth a bug report?


— Bastiaan.


No, but the DLL was compiled with -debug flag which enables an 
additional member that the main program cannot see. I think that 
is the explaination. In fact the flag was not set on the main 
program.