Re: What prevents ImportC from using .h directly?

2024-05-13 Thread Nick Treleaven via Digitalmars-d-learn

On Sunday, 12 May 2024 at 21:34:30 UTC, Chris Piker wrote:
So, why does ImportC need *.c files exclusively?  I'm sure it 
solves a problem, but I don't know what that problem is.


Support for headers has been worked on, but had to be reverted:
https://issues.dlang.org/show_bug.cgi?id=23479


What prevents ImportC from using .h directly?

2024-05-12 Thread Chris Piker via Digitalmars-d-learn

Hi D

Import D is working quite well so far.  One limitation is that 
module definitions require a tiny *.c file which is often just:

```C
#include 
```

Creating this file is trivial and has almost no knock-on effects, 
except when dealing with single file programs. I have quite a few 
small utilities with dub headers. It would be handy if I could 
set an import path and use ImportC on the header file directly, 
skipping the small C file all together.  A specific example in my 
case follows.


Given a C-lib interface defined in the header file:
```
/usr/include/cspice/SpiceUsr.h
```

it would be neat if a dub header similar to the following worked:
```d
#!/usr/bin/env dub
/+ dub.sdl:
   name "some_app"
   cImportPaths "/usr/local/include/cspice"
+/

import SpiceUsr;

// ... source continues
```

So, why does ImportC need *.c files exclusively?  I'm sure it 
solves a problem, but I don't know what that problem is.








Re: What I thought was straightforward blew up in my face..

2024-04-10 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

```c
void SDL_GetVersion(SDL_version * ver);
```

It doesn't return anything.

Its return type is void.

See the argument list where it lists the types of the arguments:

``template writeln is not callable using argument types !()(string, void)``

Which aligns with the arguments you passed to ``writeln``.


What I thought was straightforward blew up in my face..

2024-04-10 Thread WhatMeWorry via Digitalmars-d-learn



import bindbc.sdl;
import bindbc.loader;


SDL_version ver;
SDL_GetVersion();

writeln("version = ", ver);	  // runs and displays: version = 
SDL_version(2, 30, 2)


writeln("version = ", SDL_GetVersion());  // compile fails 
with


// template `writeln` is not callable using argument types 
`!()(string, void)`
// C:\D\dmd2\windows\bin64\..\..\src\phobos\std\stdio.d(4249,6): 
Candidate is: `writeln(T...)(T args)`

// Error C:\D\dmd2\windows\bin64\dmd.exe failed with exit code 1.   

I'll confess I can't make heads or tails out of the error 
messages.  Is this impossible or is there some way to make 
writeln happy?


Re: what was the problem with the old post blit operator already ?

2024-02-15 Thread Kagamin via Digitalmars-d-learn
It was mostly fine, such types are not supposed to be immutable, 
but recently came an idea of reference counted strings, which 
need to be immutable for being strings.


Re: what was the problem with the old post blit operator already ?

2024-02-14 Thread Basile B. via Digitalmars-d-learn
On Thursday, 15 February 2024 at 03:17:11 UTC, Jonathan M Davis 
wrote:
On Wednesday, February 14, 2024 7:17:15 PM MST Basile B. via 
Digitalmars-d- learn wrote:
 From what I remember, it was that there was no reference to 
the

source. Things got blitted and you had to fix the copy, already
blitted. Was that the only issue ?


There were probably some use cases where you needed access to 
both the source and the destination so that you could do 
something to the source as well, but the core problem was 
simply that blitting and then mutating the copy to fix it 
doesn't work with const or immutable objects, since it would 
violate the type system to cast away const or immutable to fix 
the copy. The only way to work properly with const or immutable 
is to construct the object with the changes in the first place 
rather than mutating the copy after the fact.


- Jonathan M Davis


That point was raised by Teoh too, which raises another question. 
Did the "old" postblit exist before the introduction of type 
qualifiers ? I think to D1 obviously.


That would suggest that the introduction of type qualifiers was 
not perfectly executed, i.e some aspects were not mastered, 
until, years after, someone said "wait a minute, there's 
something wrong".


Re: what was the problem with the old post blit operator already ?

2024-02-14 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, February 14, 2024 7:17:15 PM MST Basile B. via Digitalmars-d-
learn wrote:
>  From what I remember, it was that there was no reference to the
> source. Things got blitted and you had to fix the copy, already
> blitted. Was that the only issue ?

There were probably some use cases where you needed access to both the
source and the destination so that you could do something to the source as
well, but the core problem was simply that blitting and then mutating the
copy to fix it doesn't work with const or immutable objects, since it would
violate the type system to cast away const or immutable to fix the copy. The
only way to work properly with const or immutable is to construct the object
with the changes in the first place rather than mutating the copy after the
fact.

- Jonathan M Davis





Re: what was the problem with the old post blit operator already ?

2024-02-14 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Feb 15, 2024 at 02:17:15AM +, Basile B. via Digitalmars-d-learn 
wrote:
> From what I remember, it was that there was no reference to the
> source.  Things got blitted and you had to fix the copy, already
> blitted. Was that the only issue ?

I don't quite remember all of the reasons now. But yeah, one of the
problems with postblit was that you don't have access to the original
copy. That precludes some applications where you need to look up data
from the original or update the original.

And if you have immutable fields they've already been blitted and you
can't fix them anymore, not without casting away immutable and putting
yourself in UB zone.

There may have been other issues with postblit, I don't quite remember
now.


T

-- 
Beware of bugs in the above code; I have only proved it correct, not tried it. 
-- Donald Knuth


Re: Safety is not what you think

2024-02-05 Thread Basile B. via Digitalmars-d-learn

On Monday, 5 February 2024 at 14:26:45 UTC, Basile B. wrote:

On Tuesday, 30 January 2024 at 15:38:26 UTC, Paul Backus wrote:

[...]
This definitely isn't allowed in C or C++. I wonder what the 
rationale is for having this behavior in D?


[1]: https://dlang.org/spec/expression.html


An hypothesis is that this makes codegening the pre and the 
post variants almost identical. The only difference is what is 
yield. 
[Proof](https://gitlab.com/styx-lang/styx/-/blob/master/src/styx/backend/irgen.sx?ref_type=heads#L3383).


Now there's not much to say about the topic, I just thought it 
was amusing to share that (user1234 is my noname nickname here) 
as people might not realize how much certain expressions allows.


In the same vein you have the possibility to select an lvalue 
with a conditional expression. Pretty sure nobody knows that 
the following is legal


```d
int a,b;
int c = rand();
((c & 3) ? a : b) = 42;
```


BTW, "achtung off topic", that's pretty much how the optional 
access can be an lvalue:


```d
struct S {int a};
S* s; // null, by default init
s?.a = 0; // no access violation !! + valgrind is happy
```

You can lower that to a conditional expression:

```d
struct S {int a};
S* s;
typeof(S.a) __fallback; // compiler-generated
(s ? s.a : __fallback) = 0;
```

I've played a lot with that kind of expressions during the two 
last years. They're funny but apparently not good enough for D ;)


To conclude.





Re: Safety is not what you think

2024-02-05 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 30 January 2024 at 15:38:26 UTC, Paul Backus wrote:

[...]
This definitely isn't allowed in C or C++. I wonder what the 
rationale is for having this behavior in D?


[1]: https://dlang.org/spec/expression.html


An hypothesis is that this makes codegening the pre and the post 
variants almost identical. The only difference is what is yield. 
[Proof](https://gitlab.com/styx-lang/styx/-/blob/master/src/styx/backend/irgen.sx?ref_type=heads#L3383).


Now there's not much to say about the topic, I just thought it 
was amusing to share that (user1234 is my noname nickname here) 
as people might not realize how much certain expressions allows.


In the same vein you have the possibility to select an lvalue 
with a conditional expression. Pretty sure nobody knows that the 
following is legal


```d
int a,b;
int c = rand();
((c & 3) ? a : b) = 42;
```


Re: Safety is not what you think

2024-01-30 Thread Steven Schveighoffer via Digitalmars-d-learn

On Tuesday, 30 January 2024 at 15:38:26 UTC, Paul Backus wrote:
This definitely isn't allowed in C or C++. I wonder what the 
rationale is for having this behavior in D?


It isn't allowed in C, but allowed in C++

https://godbolt.org/z/9xTPhsb5G

As for rationale... I don't know why it wouldn't be allowed? You 
clearly need an lvalue to use prefix ++, and the result is the 
value after adding one, so why can't it be bound to a reference? 
I don't see where the problem would arise.


-Steve


Re: Safety is not what you think

2024-01-30 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 30 January 2024 at 02:05:23 UTC, user1234 wrote:
I want to share a stupid program to show you that D safety is 
more complex than you might think:


```d
module test;

void test() @safe
{
int i;
int b = (*&(*&++i))++;
}

void main() @safe
{
test();
}
```

I'm not showing a deficiency of D, that program is undeniably 
safe ;)


I'm surprised `&++i` even compiles in the first place, but 
looking at [the spec][1], it seems to be intentional:


The following expressions, and no others, are called lvalue 
expressions or lvalues:


[...]
4. the result of the following expressions:
   * built-in unary operators + (when applied to an lvalue), *, 
++ (prefix only), -- (prefix only);


Testing it out, the address you get is the same as ``.

This definitely isn't allowed in C or C++. I wonder what the 
rationale is for having this behavior in D?


[1]: https://dlang.org/spec/expression.html


Safety is not what you think

2024-01-29 Thread user1234 via Digitalmars-d-learn
I want to share a stupid program to show you that D safety is 
more complex than you might think:


```d
module test;

void test() @safe
{
int i;
int b = (*&(*&++i))++;
}

void main() @safe
{
test();
}
```

I'm not showing a deficiency of D, that program is undeniably 
safe ;)


Re: D Phobos Library Documentation: What is the Internal API for?

2023-11-27 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, November 27, 2023 6:03:22 AM MST BoQsc via Digitalmars-d-learn 
wrote:
> This is pretty basic question.
> If you open [D Library
> Reference](https://dlang.org/phobos/index.html) you are bound to
> see the **Internal API** section in the table of content.
>
> What is the **Internal API** (internal.core, dmd, rt) for and
> when, how and where to use it?
>
> ![](https://i.imgur.com/WyemZsG.png)

They're modules that are supposed to be internal to the implementation. They
should not be accessible to anyone outside of those projects. So, it's
pretty weird that it's up on the website, but my guess is that someone put
it there so that the folks working on the code base could see the rendered
ddoc comments for that code. For instance, I could believe that the dmd
section there is there just to make it easier for some of the folks working
on the compiler to more easily get an overview of the public symbols within
those modules. But if you're not contributing to those projects, there
really isn't any reason to see those modules.

- Jonathan M Davis





D Phobos Library Documentation: What is the Internal API for?

2023-11-27 Thread BoQsc via Digitalmars-d-learn

This is pretty basic question.
If you open [D Library 
Reference](https://dlang.org/phobos/index.html) you are bound to 
see the **Internal API** section in the table of content.


What is the **Internal API** (internal.core, dmd, rt) for and 
when, how and where to use it?


![](https://i.imgur.com/WyemZsG.png)


Re: What is :-) ?

2023-11-21 Thread Antonio via Digitalmars-d-learn

On Monday, 20 November 2023 at 16:47:13 UTC, Paul Backus wrote:



You can put the `delegate` keyword in front of the function 
literal:


```d
auto createCounter = delegate (int nextValue) => () => 
nextValue++;

```

This syntax is documented in the spec's section on [Function 
Literals][2] (look at the grammar box and the examples).


[2]: https://dlang.org/spec/expression.html#function_literals


Thaks Paul


Re: What is :-) ?

2023-11-21 Thread Antonio via Digitalmars-d-learn

On Monday, 20 November 2023 at 16:32:22 UTC, evilrat wrote:



```d
// this is a function returning a delegate
auto createCounter(int nextValue) => auto delegate() => 
nextValue++;




Thank you!!!.

Compiler forces me to omit "auto" keyword

```d
auto createCounter(int nextValue) => delegate () => nextValue++ ;
```

Explicit return must be specified after "delegate" keyword

```d
auto createCounter(int nextValue) => delegate int () => 
nextValue++ ;

```

When declaring a type (variable or parameter) is when keywords 
order must be "inverted"


```d
import std.stdio;
int callWith10( int delegate (int) x) =>x(10);
void main(){
  int j=100;
  // Explicit
  writeln( callWith10( delegate int (int i)=>i+j ) );
  // Inferred
  writeln( callWith10( i=>i+j ) );
  // OMG
  writeln( ( i=>i+j ).callWith10 );
}
```




// this is a function returning a function
auto createCounter(int nextValue) => auto function() => 
nextValue++;

```


I think this will not work, because nextValue is defined out of 
the returned function scope:  you must return a closure 
(delegate).


Thanks a lot evilrat!!!

**From your answer (and other ones too) I have to say that...**

* **D Closures rocks!!!**  It is hard to find something so 
powerful in other natively compiled languages:  **Heap + GC** has 
it's advantages.


* **D offers nice syntax features**:  you can declare arrow 
methods very similar to dart, or assign an arrow 
function/delegate to a variable like Javascript/Typescript 
lambdas.













Re: What parser generator can let me run arbitrary code in its match rules?

2023-11-20 Thread Julian Fondren via Digitalmars-d-learn
On Monday, 20 November 2023 at 23:50:24 UTC, Dmitry Ponyatov 
wrote:

- not abandoned years ago
- documentation and commented samples presenets
- CTFE the best


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


Re: What parser generator can let me run arbitrary code in its match rules?

2023-11-20 Thread Guillaume Piolat via Digitalmars-d-learn
On Monday, 20 November 2023 at 23:56:36 UTC, Dmitry Ponyatov 
wrote:
Or maybe someone advice me some set of books deeply targets for 
learning of binary and symmetric parsing (such as binpac), DCG 
in C or using generators in D, etc to let me write my own lib.


'Crafting Interpreters' book explain recursive descent parser, 
including parsing binary operators with priorities.


Re: What parser generator can let me run arbitrary code in its match rules?

2023-11-20 Thread Dmitry Ponyatov via Digitalmars-d-learn
Or maybe someone advice me some set of books deeply targets for 
learning of binary and symmetric parsing (such as binpac), DCG in 
C or using generators in D, etc to let me write my own lib.


Everething I found (besides the Dragon book) uses black magic 
with Haskell, Lisp etc.


What parser generator can let me run arbitrary code in its match rules?

2023-11-20 Thread Dmitry Ponyatov via Digitalmars-d-learn

- not abandoned years ago
- documentation and commented samples presenets
- CTFE the best


Re: What is :-) ?

2023-11-20 Thread Julian Fondren via Digitalmars-d-learn

On Monday, 20 November 2023 at 16:09:33 UTC, Antonio wrote:

**Why this is a function and not a delegate?**

```auto createCounter = (int nextValue) => (int dummy) => 
nextValue++;```


Syntactically I dont see any difference:


`createCounter` is a function, and not a delegate, as it doesn't 
close over any variables. It returns a delegate as the variable 
`nextValue` is closed over. There's no difference in syntax. The 
difference is however important as an environment must be 
retained for the closed-over variables and passed along with the 
pointer, making delegates both more expensive and incompatible 
with function pointers on the C ABI. Note that `f` and `g` are 
obviously not pointing to the same `nextValue`:


```d
auto createCounter = (int nextValue) => () => nextValue++;

void main() {
import std.stdio : writeln;

auto f = createCounter(5);
auto g = createCounter(0);
writeln(f()); // 5
writeln(g()); // 0
writeln(f()); // 6
writeln(g()); // 1
}
```

What "breaks" my mind is that a compiler decision (treat a 
piece of code as function or delegate) is not completely 
transparent


D is trying to be convenient (by offering delegates at all, and 
by making the syntax so light) while offering fine control (by 
letting you distinguish between function pointers and delegates). 
It'd be a much simpler language if it dropped one of those aims, 
but such languages also already exist.


Similarly D also distinguishes between "numbers" (`int`) and 
"numbers" (`double`) and this can also be transparent and also 
cause 'side effects'. Someone educated in mathematics but not 
familiar with computing might complain about


```d
void main() {
import std.stdio : writefln;
auto n = 1;
writefln!"%d"(n);
}
```

breaking when "all I did was bump n by one-tenth, to 1.1".

I'm not trying to be mean with this example, and I don't think 
it's shameful either to know mathematics but not computing. But D 
expects you to be familiar with such things for you to not be 
surprised by how it behaves.


Re: What is :-) ?

2023-11-20 Thread Paul Backus via Digitalmars-d-learn

On Monday, 20 November 2023 at 16:09:33 UTC, Antonio wrote:
What "breaks" my mind is that a compiler decision (treat a 
piece of code as function or delegate) is not completely 
transparent causing "side" effects on your code  (writeln 
doesn't work the same way:  it shows the delegate signature, 
but not the function signature).


It's certainly surprising that `writeln` treats function pointers 
and delegates differently. My guess is that it's because 
[`isPointer`][1] returns `true` for functions and `false` for 
delegates.


[1]: https://phobos.dpldocs.info/std.traits.isPointer.html

Is there any way to force D compiler to treat this 
"createCounter" declaration as **delegate** instead of 
**function**?


```d
  auto createCounter = (int nextValue) => () => nextValue++;
```


You can put the `delegate` keyword in front of the function 
literal:


```d
auto createCounter = delegate (int nextValue) => () => 
nextValue++;

```

This syntax is documented in the spec's section on [Function 
Literals][2] (look at the grammar box and the examples).


[2]: https://dlang.org/spec/expression.html#function_literals


Re: What is :-) ?

2023-11-20 Thread evilrat via Digitalmars-d-learn

On Monday, 20 November 2023 at 16:09:33 UTC, Antonio wrote:


Is there any way to force D compiler to treat this 
"createCounter" declaration as **delegate** instead of 
**function**?


```d
  auto createCounter = (int nextValue) => () => nextValue++;
```


generally there is a way to tell the compiler specifically that 
you want a delegate or a function, and additionally there is 
`toDelegate` function from std.functional that could be useful in 
some cases.


https://dlang.org/phobos/std_functional.html#toDelegate


the syntax for specifying delegate/function is smth like this, 
IIRC return type can be omitted but for reference I write it here 
as auto.


```d
// this is a function returning a delegate
auto createCounter(int nextValue) => auto delegate() => 
nextValue++;


// this is a function returning a function
auto createCounter(int nextValue) => auto function() => 
nextValue++;

```


Re: What is :-) ?

2023-11-20 Thread Antonio via Digitalmars-d-learn

On Monday, 20 November 2023 at 13:25:48 UTC, Paul Backus wrote:

On Monday, 20 November 2023 at 08:47:34 UTC, Antonio wrote:
- What is the way to do ```writeln``` work with ```Counter``` 
function the same way it works with ```next``` function?


`writeln()` should do it.


It does not do the same:  It shows an address, not the function 
signature.


Because I need to understand "why", I propose a second example 
(with some additional info based on @evilrat proposals :-) ):


```d
import std.stdio;

void main()
{
  auto createCounter = (int nextValue) => (int dummy) => 
nextValue++;

  auto getNext = createCounter(10);

  writeln( "'getNext' is ", getNext );
  writeln( "'createCounter' is ", createCounter );

  writeln( "'typeof(getNext).stringof' is ", 
typeof(getNext).stringof );
  writeln( "'typeof(createCounter).string' is ", 
typeof(createCounter).stringof );

}
```

The output is

```
'next' is int delegate(int) pure nothrow @nogc @safe
'createCounter' is 557FFCC00968
'typeof(getNext).stringof' is int delegate(int dummy) pure 
nothrow @nogc @safe
'typeof(createCounter).string' is int delegate(int dummy) pure 
nothrow @nogc @safe function(int nextValue) pure nothrow @safe

 ```


**Why ```writeln``` doesn't treat the same way ```getNext``` and 
```createCounter```?**


Because   ```getNext``` is a delegate and ```createCounter``` is 
a function.


**Why this is a function and not a delegate?**

```auto createCounter = (int nextValue) => (int dummy) => 
nextValue++;```


Syntactically I dont see any difference:

```auto name = "expression returning a delegate"```

The reason is **D compiler takes the decision**.

If you make ```createCounter``` to depend on an external 
variable, it will be treated as delegate (because it has context 
information associated to the function: a closure)


```d
import std.stdio;

void main()
{
  int diff = 1;
  auto createCounter = (int nextValue) => () { scope(exit) 
nextValue+=diff; return nextValue;};
  writeln( "'typeof(createCounter).string' is ", 
typeof(createCounter).stringof );

}
```

Will output that createCounter is a delegate:

```
'typeof(createCounter).string' is int delegate() pure nothrow 
@nogc @safe delegate(int nextValue) pure nothrow @safe

```


What "breaks" my mind is that a compiler decision (treat a piece 
of code as function or delegate) is not completely transparent 
causing "side" effects on your code  (writeln doesn't work the 
same way:  it shows the delegate signature, but not the function 
signature).


But the decision of the compiler is predictable and you can argue 
different effects are not side effects:   only something you 
should pay attention to.


**This long and winding road toke me to a third and crazzy 
question**


Is there any way to force D compiler to treat this 
"createCounter" declaration as **delegate** instead of 
**function**?


```d
  auto createCounter = (int nextValue) => () => nextValue++;
```






Re: What is :-) ?

2023-11-20 Thread Paul Backus via Digitalmars-d-learn

On Monday, 20 November 2023 at 08:47:34 UTC, Antonio wrote:
- What is the way to do ```writeln``` work with ```Counter``` 
function the same way it works with ```next``` function?


`writeln()` should do it.


Re: What is :-) ?

2023-11-20 Thread Paul Backus via Digitalmars-d-learn

On Monday, 20 November 2023 at 08:47:34 UTC, Antonio wrote:
I understand the problem with UFCS (``next`` is not using UFCS 
because it is a delegate defined in the own main() function,  
and ``Counter``` without () is treated as a function call 
because it is UFCS eligible )


This is not UFCS, it's [optional parentheses][1], which is a 
separate language feature. (Reminder: UFCS only applies when the 
callee has the form `x.y`)


According to the spec, it's disabled for function pointers and 
delegates due to the potential for ambiguity.


[1]: https://dlang.org/spec/function.html#optional-parenthesis


Re: What is :-) ?

2023-11-20 Thread evilrat via Digitalmars-d-learn

On Monday, 20 November 2023 at 09:44:32 UTC, Antonio wrote:


- Why writeln doesn't treat ```next``` and ```Counter``` the 
same way?  (I think I understand why, but it shows a "low" 
level difference of something that syntactically is equivalent)


- What is the way to show Counter signature using ```writeln``` 
(if possible)?




I found no way to tell compiler that I don't want to call Counter 
and instead want to take the function itself, but closest thing 
is just to take the string representation at compile time (same 
as used in pragma msg) and pass it to writeln instead of Counter.


I guess this is one of these bif oof moments with UFCS, a 
function returning a (parameterless) function.


Note that in most cases you should never make runtime decisions 
on .stringof value as it is not standardized.



```
//pragma(msg, typeof(Counter)); // pure nothrow @safe int 
delegate() pure nothrow @nogc @safe(int nextValue)

enum f = typeof(Counter).stringof; // same string as above
writeln( "'Counter' is ", f);
```

Of course this works too
`writeln( "'Counter' is ", typeof(Counter).stringof);`




Re: What is :-) ?

2023-11-20 Thread Antonio via Digitalmars-d-learn

On Monday, 20 November 2023 at 09:11:07 UTC, evilrat wrote:

if you meant to take the function/delegate and not invoke try 
`` instead, otherwise it expects the parameters.


If you execute

```
writeln( "'Counter' is ",  );
```

It shows the Counter address:

```
'Counter' is 557F2567F940
```

Not the function signature like it does with ```next```


I propose a simple change:

```d
void main(){
  auto Counter = (int nextValue) => () => nextValue++;
  auto next = Counter(10);
  writeln( "'next' is ", next );
  writeln( "'Counter' is ", Counter );
}
```

first ```writeln``` shows the signature of next:
```
'next' is int delegate() pure nothrow @nogc @safe
```

second writeln shows the address of Counter
```
'Counter' is 55568953C910
```

- Why writeln doesn't treat ```next``` and ```Counter``` the same 
way?  (I think I understand why, but it shows a "low" level 
difference of something that syntactically is equivalent)


- What is the way to show Counter signature using ```writeln``` 
(if possible)?







```


Re: What is :-) ?

2023-11-20 Thread evilrat via Digitalmars-d-learn

On Monday, 20 November 2023 at 08:47:34 UTC, Antonio wrote:


Now, I uncomment the ```writeln( "'Counter' is ", Counter );``` 
line and compiler says


```
/home/antonio/Devel/topbrokers/whatsapp-srv/admin/x.d(12): 
Error: function `x.Counter(int nextValue)` is not callable 
using argument types `()`
/home/antonio/Devel/topbrokers/whatsapp-srv/admin/x.d(12):  
  too few arguments, expected 1, got 0

```

I understand the problem with UFCS (``next`` is not using UFCS 
because it is a delegate defined in the own main() function,  
and ``Counter``` without () is treated as a function call 
because it is UFCS eligible )



`writeln( "'Counter' is ", Counter );`

this code is actually internally looks like this

`writeln( "'Counter' is ", Counter() );`

if you meant to take the function/delegate and not invoke try 
`` instead, otherwise it expects the parameters.


- What is the way to do ```writeln``` work with ```Counter``` 
function the same way it works with ```next``` function?


Sorry, that's too confusing and I have no idea what you mean, 
maybe if you can explain what you are trying to achieve someone 
might be able to help you.


What is :-) ?

2023-11-20 Thread Antonio via Digitalmars-d-learn

If I run this code

```d
import std.stdio;

void main(){
  auto next = Counter(10);
  next().writeln;
  next().writeln;
  next().writeln;

  // What is "next" function?
  writeln( "'next' is ", next );
  // What is "Counter" function?   This fails
  // writeln( "'Counter' is ", Counter );
}

auto Counter(int nextValue) => () => nextValue++;
```

Executing this code results in:

```
10
11
12
'next' is int delegate() pure nothrow @nogc @safe
```

Now, I uncomment the ```writeln( "'Counter' is ", Counter );``` 
line and compiler says


```
/home/antonio/Devel/topbrokers/whatsapp-srv/admin/x.d(12): Error: 
function `x.Counter(int nextValue)` is not callable using 
argument types `()`
/home/antonio/Devel/topbrokers/whatsapp-srv/admin/x.d(12):
too few arguments, expected 1, got 0

```

I understand the problem with UFCS (``next`` is not using UFCS 
because it is a delegate defined in the own main() function,  and 
``Counter``` without () is treated as a function call because it 
is UFCS eligible )


- What is the way to do ```writeln``` work with ```Counter``` 
function the same way it works with ```next``` function?


Re: What are the best available D (not C) File input/output options?

2023-11-05 Thread confuzzled via Digitalmars-d-learn

On 11/3/23 2:30 AM, Steven Schveighoffer wrote:

On Thursday, 2 November 2023 at 15:46:23 UTC, confuzzled wrote:

You should use a buffering library like iopipe to write properly here 
(it handles the encoding of text for you).




Thanks Steve, I will try that.



Re: What are the best available D (not C) File input/output options?

2023-11-05 Thread confuzzled via Digitalmars-d-learn



Good morning,

First, thanks to you, Steve, and Julian for responding to my inquiry.

On 11/3/23 4:59 AM, Sergey wrote:

On Thursday, 2 November 2023 at 15:46:23 UTC, confuzzled wrote:
I've ported a small script from C to D. The original C version takes 
roughly 6.5 minutes to parse a 12G file while the port originally took 
about 48 minutes.


In my experience I/O in D is quite slow.
But you can try to improve it:

Try to use std.outbuffer instead of writeln. And flush the result only 
in the end.


Unless I did it incorrectly, this did nothing for me. My understanding 
is that I should first prepare an OutBuffer to which I write all my 
output. Once complete, I then write the OutBuffer to file; which still 
requires the use of writeln, albeit not as often.


First I tried buffering the entire thing, but that turned out to be a 
big mistake. Next I tried writing and clearing the buffer every 100_000 
records (about 3000 writeln calls).


Not as bad as the first attempt but significantly worse than what I 
obtained with the fopen/fprintf combo. I even tried writing the buffer 
to disk with fprintf but jumped ship because it took far longer than 
fopen/fprintf. Can't say how much longer because I terminated execution 
at 14 minutes.


Also check this article. It is showing how manual buffers in D could 
speed up the processing of files significantly: 
https://tech.nextroll.com/blog/data/2014/11/17/d-is-for-data-science.html





The link above was quite helpful. Thanks. I am a bit slow on the uptake 
so it took a while to figure out how to apply the idea to my own use 
case. However, once I figured it out, the result was 2 minutes faster 
than the original C implementation and 3 minutes faster than the 
fopen/printf port.


Whether it did anything for the writeln implementation or not, I don't 
know. Wasn't will to wait 45+ minutes for something that can feasibly be 
done in 6 minutes. I gave up at 12.


Haven't played with std.string.representation as suggested by Julian as 
yet but I plan to.



Thank again.
--Confuzzled


Re: What are the best available D (not C) File input/output options?

2023-11-02 Thread Sergey via Digitalmars-d-learn

On Thursday, 2 November 2023 at 15:46:23 UTC, confuzzled wrote:
I've ported a small script from C to D. The original C version 
takes roughly 6.5 minutes to parse a 12G file while the port 
originally took about 48 minutes.


In my experience I/O in D is quite slow.
But you can try to improve it:

Try to use std.outbuffer instead of writeln. And flush the result 
only in the end.


Also check this article. It is showing how manual buffers in D 
could speed up the processing of files significantly: 
https://tech.nextroll.com/blog/data/2014/11/17/d-is-for-data-science.html





Re: What are the best available D (not C) File input/output options?

2023-11-02 Thread Steven Schveighoffer via Digitalmars-d-learn

On Thursday, 2 November 2023 at 15:46:23 UTC, confuzzled wrote:

I tried std.io but write() only outputs ubyte[] while I'm 
trying to output text so I abandoned idea early.


Just specifically to answer this, this is so you understand this 
is what is going into the file -- bytes.


You should use a buffering library like iopipe to write properly 
here (it handles the encoding of text for you).


And I really don't have a good formatting library, you can rely 
on formattedWrite maybe. A lot of things need to be better for 
this solution to be smooth, it's one of the things I have to work 
on.


-Steve


Re: What are the best available D (not C) File input/output options?

2023-11-02 Thread Julian Fondren via Digitalmars-d-learn

On Thursday, 2 November 2023 at 15:46:23 UTC, confuzzled wrote:
I've ported a small script from C to D. The original C version 
takes roughly 6.5 minutes to parse a 12G file while the port 
originally took about 48 minutes. My naïve attempt to improve 
the situation pushed it over an hour and 15 minutes. However, 
replacing std.stdio:File with core.stdc.stdio:FILE* and 
changing my output code in this latest version from:


outputFile.writefln("%c\t%u\t%u\t%d.%09u\t%c", ...)

to
fprintf(outputFile, "%c,%u,%u,%llu.%09llu,%c\n", ...)

reduced the processing time to roughly 7.5 minutes. Why is 
File.writefln() so appallingly slow? Is there a better D 
alternative?


First, strace your program. The slowest thing about I/O is the 
syscall itself. If the D program does more syscalls, it's going 
to be slower almost no matter what else is going on. Both D and C 
are using libc to buffer I/O to reduce syscalls, but you might be 
defeating that by constantly flushing the buffer.




I tried std.io but write() only outputs ubyte[] while I'm 
trying to output text so I abandoned idea early.


string -> immutable(ubyte)[]: alias with 
std.string.representation(st)


'alias' meaning, this doesn't allocate. If gives you a byte slice 
of the same memory the string is using.


You'd still need to do the formatting, before writing.

Now that I've got the program execution time within an 
acceptable range, I tried replacing core.stdc.fread() with 
std.io.read() but that increased the time to 24 minutes. Now 
I'm starting to think there is something seriously wrong with 
my understanding of how to use D correctly because there's no 
way D's input/output capabilities can suck so bad in comparison 
to C's.





What are the best available D (not C) File input/output options?

2023-11-02 Thread confuzzled via Digitalmars-d-learn
I've ported a small script from C to D. The original C version takes 
roughly 6.5 minutes to parse a 12G file while the port originally took 
about 48 minutes. My naïve attempt to improve the situation pushed it 
over an hour and 15 minutes. However, replacing std.stdio:File with 
core.stdc.stdio:FILE* and changing my output code in this latest version 
from:


outputFile.writefln("%c\t%u\t%u\t%d.%09u\t%c", ...)

to
fprintf(outputFile, "%c,%u,%u,%llu.%09llu,%c\n", ...)

reduced the processing time to roughly 7.5 minutes. Why is 
File.writefln() so appallingly slow? Is there a better D alternative?


I tried std.io but write() only outputs ubyte[] while I'm trying to 
output text so I abandoned idea early. Now that I've got the program 
execution time within an acceptable range, I tried replacing 
core.stdc.fread() with std.io.read() but that increased the time to 24 
minutes. Now I'm starting to think there is something seriously wrong 
with my understanding of how to use D correctly because there's no way 
D's input/output capabilities can suck so bad in comparison to C's.


Re: What is a dchar ?

2023-07-27 Thread Cecil Ward via Digitalmars-d-learn
On Wednesday, 26 July 2023 at 01:56:28 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
The spec says they are unsigned, so if ldc is using sign 
extension, that is probably a bug.


My fault, I reread the code and the sign-extension applies to 
something else, coincidentally right where I was looking at this. 
It uses signed 32-bit displacements in a case/switch table of 
offsets into the code segment, and that was what mislead me. It 
could have used unsigned displacements but then all the labels in 
the code would have to be above the reference base point, and 
this allows +/- offsets to anywhere. So my apologies.


Re: What is a dchar ?

2023-07-25 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn
The spec says they are unsigned, so if ldc is using sign extension, that 
is probably a bug.


Re: what is the aftermath of dip74

2023-05-10 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

On 11/05/2023 6:23 AM, Ferhat Kurtulmuş wrote:
Thank you Rikki for the clarification. I think d need this without ugly 
workarounds.


Yeah we do.

Reference counting is expensive, and modern backends have the capability 
to elide pairs of calls. So this would be a massive improvement just 
from the perspective of performance alone.


Re: what is the aftermath of dip74

2023-05-10 Thread Ferhat Kurtulmuş via Digitalmars-d-learn
On Wednesday, 10 May 2023 at 18:15:36 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

We do not, no.

Reference counting is not currently in the language, although 
you can fake it with structs.


Its a huge shame, but it should be added at some point because 
the compiler would tell the backend that it is possible to 
elide pair calls.


However it'll have to wait for the DIP queue to reopen (slight 
process adjustment to make things easier is incoming).


Thank you Rikki for the clarification. I think d need this 
without ugly workarounds.


Re: what is the aftermath of dip74

2023-05-10 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

We do not, no.

Reference counting is not currently in the language, although you can 
fake it with structs.


Its a huge shame, but it should be added at some point because the 
compiler would tell the backend that it is possible to elide pair calls.


However it'll have to wait for the DIP queue to reopen (slight process 
adjustment to make things easier is incoming).


Re: What do you think about using Chat GPT to create functions in D?

2023-04-14 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

On Monday, 3 April 2023 at 23:38:52 UTC, Marcone wrote:
What do you think about using Chat GPT to create functions in 
D? I asked Chat-GPT to create a function in D that was similar 
to the rsplit() function in Python. It returned this code to me:



import std.algorithm;
import std.array;
import std.string;

string[] rsplit(string input, string separator, size_t maxsplit 
= size_t.max) {
auto splitter = splitter(input, separator, 
SplitterFlag.all);

auto results = splitter.array;
if (maxsplit < results.length - 1)
results = results[results.length - maxsplit - 1 .. $];
return results;
}


Recently, it helped me figure out an OpenGL task using d.

This is the code it suggests after I provide some details to 
it about the case and the error I get:

```d
Slice!(RCI!ubyte, 3LU, Contiguous) plot2imslice() @nogc 
nothrow

{
import mir.rc;

Slice!(RCI!ubyte, 3LU, Contiguous) imgslice = 
rcslice!ubyte([height, width, 3], 0);


glfwMakeContextCurrent(_glfwWindow);

// create and bind framebuffer
GLuint fbo;
glGenFramebuffers(1, );
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

// create and bind texture
GLuint texture;
glGenTextures(1, );
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, 
GL_RGB, GL_UNSIGNED_BYTE, null);
glFramebufferTexture2D(GL_FRAMEBUFFER, 
GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);


// render scene to framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
// render your scene here

// read pixel data from framebuffer
glReadPixels(0, 0, width, height, GL_RGB, 
GL_UNSIGNED_BYTE, imgslice.ptr);


// flip image vertically
for (size_t y = 0; y < height / 2; y++) {
for (size_t x = 0; x < width; x++) {
// swap rows
swap(imgslice[y][x], imgslice[height - y - 1][x]);
}
}

// unbind framebuffer and cleanup
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteTextures(1, );
glDeleteFramebuffers(1, );

return imgslice;
}
```

And this is the code after required modifications:
```d
auto plot2imslice() @nogc nothrow
{
import mir.rc;

Slice!(RCI!ubyte, 3LU, Contiguous) imgslice = 
rcslice!ubyte([height, width, 3], 0);


glfwMakeContextCurrent(_glfwWindow);

// create and bind framebuffer
GLuint fbo;
glGenFramebuffers(1, );
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

// create and bind texture
GLuint texture;
glGenTextures(1, );
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 
0, GL_RGB, GL_UNSIGNED_BYTE, null);
glFramebufferTexture2D(GL_FRAMEBUFFER, 
GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);


// render scene to framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

// render scene here
render();

// read pixel data from framebuffer
glReadPixels(0, 0, width, height, GL_RGB, 
GL_UNSIGNED_BYTE, imgslice.ptr);


import mir.utility : swap;
// flip image vertically to correct generated image
foreach (y; 0..height / 2) {
each!swap(imgslice[y], imgslice[height - y - 1]);
}
// unbind framebuffer and cleanup
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteTextures(1, );
glDeleteFramebuffers(1, );

return imgslice;
}
```

This comment of chatGPT saved the day :) // render your scene here


Re: What do you think about using Chat GPT to create functions in D?

2023-04-04 Thread Guillaume Piolat via Digitalmars-d-learn

On Monday, 3 April 2023 at 23:38:52 UTC, Marcone wrote:

What do you think about using Chat GPT to create functions in D?


Well you can use GitHub Copilot in VSCode, and it is kind of 
interesting but at the current time seems like a distracting 
waste of time. It will probably get more useful in a few years.


LLMs repeats commonly accepted lies as gospel, so do not expect a 
well adjusted human-like opinion on anything.


Re: What do you think about using Chat GPT to create functions in D?

2023-04-03 Thread cgenie via Digitalmars-d-learn
I once tested ChatGPT to generate Common Lisp code (a simple 
Redis client). They had a warning that this is not a code 
generation tool nevertheless it tried to do so. All the code it 
had was incorrect: it imported foreign libraries that didn't 
exist and when I complained about it, it apologized and then 
proposed other libraries that didn't exist. Overall I had the 
impression that I'm working with some dumb person who pasted me 
stuff from stackoverflow that seemed to solve my issue.


Let me mention that I once asked ChatGPT what is 11 plus 11 and 
when it responded 22, I told it that it's wrong, it should be 30. 
It apologized and said that I'm right, it's 30. I tried to do the 
same experiment again after one day to show off my friends, but 
it became more resilient to such suggestions.


What do you think about using Chat GPT to create functions in D?

2023-04-03 Thread Marcone via Digitalmars-d-learn
What do you think about using Chat GPT to create functions in D? 
I asked Chat-GPT to create a function in D that was similar to 
the rsplit() function in Python. It returned this code to me:



import std.algorithm;
import std.array;
import std.string;

string[] rsplit(string input, string separator, size_t maxsplit = 
size_t.max) {

auto splitter = splitter(input, separator, SplitterFlag.all);
auto results = splitter.array;
if (maxsplit < results.length - 1)
results = results[results.length - maxsplit - 1 .. $];
return results;
}



Re: what is the difference between AliasAssign and AliasReassignment

2023-03-27 Thread FabArd via Digitalmars-d-learn

On Monday, 27 March 2023 at 16:59:29 UTC, FabArd wrote:

Hi,

I don't understand a point in the grammar :

5.4.6 AliasAssign:
Identifier = Type

5.4.7 AliasReassignment:
Identifier = StorageClasses(optional) Type

AliasAssign rule is included in the AliasReassignment rule.

Why there are two rules in the grammar to describe the same 
thing?


It seems that AliasReassignment rule is an orphan rule. Indeed it 
is not used anywhere else in the whole grammar.


what is the difference between AliasAssign and AliasReassignment

2023-03-27 Thread FabArd via Digitalmars-d-learn

Hi,

I don't understand a point in the grammar :

5.4.6 AliasAssign:
Identifier = Type

5.4.7 AliasReassignment:
Identifier = StorageClasses(optional) Type

AliasAssign rule is included in the AliasReassignment rule.

Why there are two rules in the grammar to describe the same thing?



Re: What makes vibe.d Incredibly Slow on a VPS?

2023-03-18 Thread Steven Schveighoffer via Digitalmars-d-learn

On 3/18/23 9:36 AM, seany wrote:

But on a VPS server, the program outputs the first writeln line (not 
even the consequent req.form printouts), then apparently stops for 
several seconds ( 10 to 16) , and then suddenly starts working again. I 
see this in the log outputs.


Why does this happen? How can I start debugging?


Before getting into it any further, try flushing output after every writeln.

This is true in D and C too -- if your `stdout` stream is connected to a 
log file, it will *not* flush upon every newline. However, if it's 
connected to a terminal, it *will* flush upon every newline.


It's possible it is running just as fast as you expect, but the buffered 
output has not yet been flushed.


So just add `stdout.flush()` after every `writeln` call and see if it 
helps. If not, then it needs more investigation.


-Steve


What makes vibe.d Incredibly Slow on a VPS?

2023-03-18 Thread seany via Digitalmars-d-learn

Consider this fraction of code Please:



void createNewOwner(HTTPServerRequest req, 
HTTPServerResponse res) {	

writeln("NEW OWNER requests are : -");


writeln(req.form);
			writeln(req.files); 
writeln("==");



	// TASK EXTRACT the data from the POST variable// 
--//

// TODO check security with req.form["loginToken"];

string avatarPath ;

if( req.files.length != 0) {

// HERE we only check if file is supplied...
// no "existing avatar" yet, as fresh new user.

auto file = "file" in req.files;

if (file.filename != "" ) {

		string k = genNonce();// Generate a random 
number to ensure there is no conflict


			string rp = req.form["username"].replace(" ", 
"-").replace("@", "-")~"-"~k~"-"~(file.filename.name).replace(" 
", "-").replace("@", "-");
			// replaced spaces with "-" and @ with 
-, to avoid loading problems

try {

moveFile(file.tempPath.toString(), 
"assets/images/avatars/" ~ rp);			writeln("Uploaded 
successfully!");

avatarPath = "/" ~ "assets/images/avatars/" ~ 
rp;
} catch (Exception e) {
			writeln("Exception thrown, trying 
copy");
copyFile(file.tempPath.toString(), 
"assets/images/avatars/" ~ rp);

avatarPath = "/" ~ "assets/images/avatars/" ~ 
rp;
}
}
} else {

		avatarPath = 
"assets/images/avatars/noFace.png";		// Here it is 
allowed. IF no image, then set a default.

}


	avatarPath = avatarPath.replace(" ", "");	// 
should not be needed, but just in case

avatarPath = avatarPath.replace("@", "-");

string e2fa = "";
	req.form["en2fa"] == "true" ? (e2fa = "1") : (e2fa = 
"0");// converted e2FA to 0 or 1, in string format



	// TASK confirm no conclict // 
--//


	auto check_existingUser = loginRoutines.get_userAllInfo( 
req.form["username"]);


	if (check_existingUser.length != 0) {		// 
username already exists The only valid value here is 0
			// = no records. anything  != 0 will 
be rejected


		res.writeBody("ERROR: 30LX-USEREX. Username existiert 
schon... Verwenden Sie bitte einen anderen Username.");

return;
}



	// TASK set entry details // 
//


	int usrCnt  = 
loginRoutines.get_userCount();write("user count is: 
"); writeln(usrCnt);

if (usrCnt < 0) {
		res.writeBody("ERROR: 71QM-UKNDBR. Unbekannter 
Datenbankfehler. Versuchen Sie später erneut.");

return;

}
	string cntr = to!string(usrCnt +1);		// next 
item in file.


	string[string] nuInfo ;	// container for new 
user Info


nuInfo["username"]= req.form["username"];
nuInfo["fName"]   = req.form["fName"];
nuInfo["lName"]   = req.form["lName"];
nuInfo["avatarPath"]= avatarPath;
nuInfo["mail"]= req.form["mail"];
nuInfo["tel"] = req.form["tel"];
nuInfo["mob"] = req.form["mob"];


string[string] lgInfo;

lgInfo["username"]= req.form["username"];
lgInfo["role"]= "owner";
	lgInfo["active"]	= "-1";	write("going to add 
signUp line in user dtls : "); writeln(lgInfo);



	string loginInfo = cntr ~ "," ~ req.form["username"] ~ "," ~ 
"++" ~ "," ~ e2fa ~ ", 0";
			// enter new user with supplied 2FA, 
but set the last field = 0,



// as not yet paired.



	// TASK insert the data // 
--//



	bool stat;write("going to add signUp 
line in owner dtls : "); writeln(nuInfo);
	stat = 

Re: dub.sdl bindbc-glfw is returning a deprecation warming. So what do I do now?

2023-03-09 Thread WhatMeWorry via Digitalmars-d-learn

On Thursday, 9 March 2023 at 06:36:18 UTC, IchorDev wrote:

On Thursday, 9 March 2023 at 00:21:02 UTC, WhatMeWorry wrote:

[...]


Sorry about that. Try updating to bindbc-glfw 1.0.2, should be 
fixed now. If you see any other deprecation warnings from 
BindBC bindings you can silence them with `-d` until they're 
updated.


No problem :)  Thanks!


Re: dub.sdl bindbc-glfw is returning a deprecation warming. So what do I do now?

2023-03-08 Thread IchorDev via Digitalmars-d-learn

On Thursday, 9 March 2023 at 00:21:02 UTC, WhatMeWorry wrote:

my small dub.sdl project uses:

dependency "bindbc-glfw"  version="~>1.0.1"
versions "GLFW_33"

and returns

Building bindbc-glfw 1.0.1: building configuration [dynamic]
C:\Users\Admin\AppData\Local\dub\packages\bindbc-glfw-1.0.1\bindbc-glfw\source\bindbc\glfw\binddynamic.d(557,11):
 Deprecation: variable `bindbc.loader.system.bindWindows` is deprecated


So now what?  I'm pretty sure deprecation means to replace with 
something better
but what would that be?   I looked on github code in 
binddynamic.d at line 557 and

the package info at the DUB web site and I'm still clueless.


Sorry about that. Try updating to bindbc-glfw 1.0.2, should be 
fixed now. If you see any other deprecation warnings from BindBC 
bindings you can silence them with `-d` until they're updated.


Re: dub.sdl bindbc-glfw is returning a deprecation warming. So what do I do now?

2023-03-08 Thread Steven Schveighoffer via Digitalmars-d-learn

On 3/8/23 7:21 PM, WhatMeWorry wrote:

my small dub.sdl project uses:

dependency "bindbc-glfw"  version="~>1.0.1"
versions "GLFW_33"

and returns

Building bindbc-glfw 1.0.1: building configuration [dynamic]
C:\Users\Admin\AppData\Local\dub\packages\bindbc-glfw-1.0.1\bindbc-glfw\source\bindbc\glfw\binddynamic.d(557,11):
 Deprecation: variable `bindbc.loader.system.bindWindows` is deprecated


So now what?  I'm pretty sure deprecation means to replace with 
something better
but what would that be?   I looked on github code in binddynamic.d at 
line 557 and

the package info at the DUB web site and I'm still clueless.


It's newly deprecated, without much explanation:

https://github.com/BindBC/bindbc-loader/commit/d13d7f246f325472b26282cfac8d2b02b26eccac

Last commit to bindbc-glfw is from last year, so it makes sense why it 
is triggering this.


I feel it was in error to deprecate symbols without bumping the major 
revision.


-Steve


dub.sdl bindbc-glfw is returning a deprecation warming. So what do I do now?

2023-03-08 Thread WhatMeWorry via Digitalmars-d-learn

my small dub.sdl project uses:

dependency "bindbc-glfw"  version="~>1.0.1"
versions "GLFW_33"

and returns

Building bindbc-glfw 1.0.1: building configuration [dynamic]
C:\Users\Admin\AppData\Local\dub\packages\bindbc-glfw-1.0.1\bindbc-glfw\source\bindbc\glfw\binddynamic.d(557,11):
 Deprecation: variable `bindbc.loader.system.bindWindows` is deprecated


So now what?  I'm pretty sure deprecation means to replace with 
something better
but what would that be?   I looked on github code in 
binddynamic.d at line 557 and

the package info at the DUB web site and I'm still clueless.





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

2023-01-20 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Jan 20, 2023 at 12:49:54PM +, Ruby The Roobster via 
Digitalmars-d-learn wrote:
[...]
> Thank you.  I didn't know that there was such a property `.array`.

It's not a property, it's a Phobos function from std.array.


T

-- 
INTEL = Only half of "intelligence".


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

2023-01-20 Thread Ruby The Roobster via Digitalmars-d-learn

On Friday, 20 January 2023 at 03:39:48 UTC, H. S. Teoh wrote:
On Fri, Jan 20, 2023 at 03:34:43AM +, Ruby The Roobster via 
Digitalmars-d-learn wrote:
On Friday, 20 January 2023 at 03:30:56 UTC, Steven 
Schveighoffer wrote:

> On 1/19/23 10:11 PM, Ruby The Roobster wrote:
> ...
> 
> The point is to be a range over the original input, 
> evaluated lazily. Using this building block, you can create 
> an array, or use some other algorithm, or whatever you want. 
> All without allocating more space to hold an array.

[...]
I get the point that it is supposed to be lazy.  But why are 
these basic cases not implemented?  I shouldn't have to go 
write a wrapper for something as simple as casting this type 
to the original type. This is one of the things that one 
expects the standard library to do for you.


There's no need to write any wrappers.  Just tack `.array` to 
the end of your pipeline, and you're good to go.



T


Thank you.  I didn't know that there was such a property `.array`.


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

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

On Friday, 20 January 2023 at 04:46:07 UTC, Ali Çehreli wrote:
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.


In general, the ranges are compatible with each other because 
they use the empty, front, popFront interface. In the example 
below, different types (one of which is double) but the same 
ranges can be combined with chain(). However, it is necessary to 
convert it to array because of the opCmp() compatibility from 
algorithms such as sorting.


```d
  import std.algorithm : sort;
  import std.conv  : to;
  import std.range;
  import std.stdio;


  enum limit = 5;
  enum step = limit / 10.0;/*
  enum step = 1; //*/

void main()
{
  TypeInfo rangeType;   

  auto a = iota(limit);
  auto b = iota(step, limit, step);

  /* <- toggle comment, please add -> /
  auto ab = chain(a, b);
  rangeType = typeid(ab);/*/
  auto arrA = a.array.to!(double[]);
  auto arrB = b.array;
  auto ab = chain(arrA, arrB);
  rangeType = typeid(ab.sort);//*/

  ab.writeln(": ", rangeType);
} /*
current print:
==
[0, 0.5, 1, 1, 1.5, 2, 2, 2.5, 3, 3, 3.5, 4, 4, 4.5]: 
std.range.SortedRange!(std.range.chain!(double[], 
double[]).chain(double[], double[]).Result, "a < b", 
0).SortedRange


other print:

[0, 1, 2, 3, 4, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5]: 
std.range.chain!(std.range.iota!(int, int).iota(int, int).Result, 
std.range.iota!(double, int, double).iota(double, int, 
double).Result).chain(std.range.iota!(int, int).iota(int, 
int).Result, std.range.iota!(double, int, double).iota(double, 
int, double).Result).Result

```
SDB@79


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: What is the 'Result' type even for?

2023-01-19 Thread Salih Dincer via Digitalmars-d-learn
On Friday, 20 January 2023 at 03:11:33 UTC, Ruby The Roobster 
wrote:


What is the purpose of this 'Result' type?  To serve as a 
generic range?  Because, it seems to only cause problems...


No.

When I first started learning this language, I thought the same 
thing.  However, such a designm consisting of structs was 
preferred because it is necessary for the ranges to be used as a 
whole (connected end-to-Znd like a pipe). qWalter has a very old 
[article](https://www.drdobbs.com/cpp/voldemort-types-in-d/232901591) about Voldemort which is the basis of D, pllease read it. D's ranges are very strong for those who know how to use it.


SDB@79


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

2023-01-19 Thread Basile B. via Digitalmars-d-learn
On Friday, 20 January 2023 at 03:11:33 UTC, Ruby The Roobster 
wrote:

Take this example:
[...]
What is the purpose of this 'Result' type?  To serve as a 
generic range?


Yes this is a lazy input range. Use `.array` to yield directly as 
a concrete value,

then you can append using `~=`.

Note that there are special functions to keep the laziness, e.g 
`chain` to happen an input range to another element-compatible 
input range


```
import std;
void main()
{
auto c = "a|b|c|d|e".splitter("|").chain(["f"]);
string[] e = ["a", "b", "c", "d", "e", "f"];
assert(c.equal(e));
}
```


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

2023-01-19 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/19/23 10:34 PM, Ruby The Roobster wrote:

On Friday, 20 January 2023 at 03:30:56 UTC, Steven Schveighoffer wrote:

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

The point is to be a range over the original input, evaluated lazily. 
Using this building block, you can create an array, or use some other 
algorithm, or whatever you want. All without allocating more space to 
hold an array.




I get the point that it is supposed to be lazy.  But why are these basic 
cases not implemented?  I shouldn't have to go write a wrapper for 
something as simple as casting this type to the original type.  This is 
one of the things that one expects the standard library to do for you.


A range simply does not provide the API you are seeking. It provides 3 
methods:


front
popFront
empty

That's it. It does not provide appending. If you want appending or 
random access, use an array:


```d
auto c = "a|b|c|d|e".split('|');
static assert(is(typeof(c) == string[]));
// or:
auto c2 = "a|b|c|d|e".splitter('|').array; // convert range to an array
```

-Steve


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

2023-01-19 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Jan 20, 2023 at 03:34:43AM +, Ruby The Roobster via 
Digitalmars-d-learn wrote:
> On Friday, 20 January 2023 at 03:30:56 UTC, Steven Schveighoffer wrote:
> > On 1/19/23 10:11 PM, Ruby The Roobster wrote:
> > ...
> > 
> > The point is to be a range over the original input, evaluated
> > lazily. Using this building block, you can create an array, or use
> > some other algorithm, or whatever you want. All without allocating
> > more space to hold an array.
[...]
> I get the point that it is supposed to be lazy.  But why are these
> basic cases not implemented?  I shouldn't have to go write a wrapper
> for something as simple as casting this type to the original type.
> This is one of the things that one expects the standard library to do
> for you.

There's no need to write any wrappers.  Just tack `.array` to the end of
your pipeline, and you're good to go.


T

-- 
My father told me I wasn't at all afraid of hard work. I could lie down right 
next to it and go to sleep. -- Walter Bright


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

2023-01-19 Thread Ruby The Roobster via Digitalmars-d-learn
On Friday, 20 January 2023 at 03:30:56 UTC, Steven Schveighoffer 
wrote:

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

The point is to be a range over the original input, evaluated 
lazily. Using this building block, you can create an array, or 
use some other algorithm, or whatever you want. All without 
allocating more space to hold an array.


-Steve


I get the point that it is supposed to be lazy.  But why are 
these basic cases not implemented?  I shouldn't have to go write 
a wrapper for something as simple as casting this type to the 
original type.  This is one of the things that one expects the 
standard library to do for you.


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

2023-01-19 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Jan 20, 2023 at 03:11:33AM +, Ruby The Roobster via 
Digitalmars-d-learn wrote:
> Take this example:
> 
> ```d
> import std;
> void main()
> {
> auto c = "a|b|c|d|e".splitter('|');
> c.writeln;
> string[] e = ["a", "b", "c", "d", "e"];
> assert(c.equal(e));
> typeof(c).stringof.writeln;
> }
> ```
> 
> The program prints:
> 
> ["a", "b", "c", "d", "e"]
> Result
> 
> What is the purpose of this 'Result' type?  To serve as a generic
> range?

It's a Voldemort type, representing a range that iterates over its
elements lazily.


> Because, it seems to only cause problems.  For example, you cannot
> assign or cast the result type into a range, even when the type has
> the same inherent function:
> 
> ```d
> string[] c = "a|b|c|d|e".splitter('|'); // fails
> string[] d = cast(string[])"a|b|c|d|e".splitter('|'); // also fails
> ```

You're confusing arrays and ranges.  A "range" isn't any specific type,
it refers to *any* type that behaves a certain way (behaves like a
range).  Each `Result` you get back has its own unique type (arguably,
it's a compiler bug to display it as merely `Result` without
distinguishing it from other identically-named but distinct Voldemort
types), so you cannot just assign it back to an array.

You can either create an array from it using std.array.array, use a
function that eagerly creates its results instead of a lazy result (in
the above instance, use std.string.split instead of .splitter), or use
std.algorithm.copy to copy the contents of the lazy range into an array:

// Option 1
string[] c = "a|b|c|d|e".splitter('|').dup;

// Option 2
string[] c = "a|b|c|d|e".split('|');

// Option 3
// Caveat: .copy expects you to have prepared the buffer
// beforehand to be large enough to hold the contents; it does
// not reallocate the result array for you.
string[] result = new string[5];
"a|b|c|d|e".splitter('|').copy(result);


[...]
> Then what is the point of this type, if not to just make things
> difficult?  It cannot be casted, and vector operations cannot be
> performed, and it seems to just serve as an unnecessary
> generalization.

It serves to chain further range operations into a pipeline:

string[] c = "a|b|c|d|e".splitter('|')
.filter!(c => c >= 'b' && c <= 'd')
.map!(c => c+1)
.array;

Because ranges are lazily iterated, the .array line only allocates the 3
elements that got through the .filter. Whereas if you created the
intermediate result array eagerly, you'd have to allocate space for 5
elements only to discard 2 of them afterwards.

One way to think about this is that the intermediate Result ranges are
like the middle part of a long pipe; you cannot get stuff from the
middle of the pipe without breaking it, you need to terminate the pipe
with a sink (like .array, .copy, etc.) first.


T

-- 
I am Pentium of Borg. Division is futile; you will be approximated.


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

2023-01-19 Thread Steven Schveighoffer via Digitalmars-d-learn

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

Take this example:

```d
import std;
void main()
{
     auto c = "a|b|c|d|e".splitter('|');
     c.writeln;
     string[] e = ["a", "b", "c", "d", "e"];
     assert(c.equal(e));
     typeof(c).stringof.writeln;
}
```

The program prints:

["a", "b", "c", "d", "e"]
Result

What is the purpose of this 'Result' type?  To serve as a generic 
range?  Because, it seems to only cause problems.  For example, you 
cannot assign or cast the result type into a range, even when the type 
has the same inherent function:


```d
string[] c = "a|b|c|d|e".splitter('|'); // fails
string[] d = cast(string[])"a|b|c|d|e".splitter('|'); // also fails
```


The `Result` type is an internal type that provides a lazily-evaluated 
range of the original string. That is, no array is allocated, and the 
actual searching of the `|` character isn't done until you start 
fetching each element.


It returns windows into the *original* string, and builds each window 
one element at a time (via slicing).


So when you say "cast to a range", you are incorrectly stating the type 
`string[]` as a "range", when you are trying to cast to an array of 
strings. The `Result` type *is* a range, it's a range of strings. But it 
is not an array. If you want an array, you can use the `split` function, 
which allocates an array to hold all the slices.



And if you need to perform a set operation?

```d
c[] ~= "lolno"; // fails, as [] isn't defined for Result.
```


Right, because a `Result` is not an array. Appending is an array 
operation, not a range operation.


Then what is the point of this type, if not to just make things 
difficult?  It cannot be casted, and vector operations cannot be 
performed, and it seems to just serve as an unnecessary generalization.


The point is to be a range over the original input, evaluated lazily. 
Using this building block, you can create an array, or use some other 
algorithm, or whatever you want. All without allocating more space to 
hold an array.


-Steve


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

2023-01-19 Thread Ruby The Roobster via Digitalmars-d-learn
On Friday, 20 January 2023 at 03:11:33 UTC, Ruby The Roobster 
wrote:

Take this example:

```d
import std;
void main()
{
auto c = "a|b|c|d|e".splitter('|');
c.writeln;
string[] e = ["a", "b", "c", "d", "e"];
assert(c.equal(e));
typeof(c).stringof.writeln;
}
```

The program prints:

["a", "b", "c", "d", "e"]
Result

What is the purpose of this 'Result' type?  To serve as a 
generic range?  Because, it seems to only cause problems.  For 
example, you cannot assign or cast the result type into a 
range, even when the type has the same inherent function:


```d
string[] c = "a|b|c|d|e".splitter('|'); // fails
string[] d = cast(string[])"a|b|c|d|e".splitter('|'); // also 
fails

```

And if you need to perform a set operation?

```d
c[] ~= "lolno"; // fails, as [] isn't defined for Result.
```

Then what is the point of this type, if not to just make things 
difficult?  It cannot be casted, and vector operations cannot 
be performed, and it seems to just serve as an unnecessary 
generalization.


Furthermore, it can also be confirmed that each member of c is a 
string, further solidifying my opinion of 'Result' as just being 
a generic range template, that cannot be casted to an array of 
the original type.


What is the 'Result' type even for?

2023-01-19 Thread Ruby The Roobster via Digitalmars-d-learn

Take this example:

```d
import std;
void main()
{
auto c = "a|b|c|d|e".splitter('|');
c.writeln;
string[] e = ["a", "b", "c", "d", "e"];
assert(c.equal(e));
typeof(c).stringof.writeln;
}
```

The program prints:

["a", "b", "c", "d", "e"]
Result

What is the purpose of this 'Result' type?  To serve as a generic 
range?  Because, it seems to only cause problems.  For example, 
you cannot assign or cast the result type into a range, even when 
the type has the same inherent function:


```d
string[] c = "a|b|c|d|e".splitter('|'); // fails
string[] d = cast(string[])"a|b|c|d|e".splitter('|'); // also 
fails

```

And if you need to perform a set operation?

```d
c[] ~= "lolno"; // fails, as [] isn't defined for Result.
```

Then what is the point of this type, if not to just make things 
difficult?  It cannot be casted, and vector operations cannot be 
performed, and it seems to just serve as an unnecessary 
generalization.


Re: what wrong with this alias

2023-01-09 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/8/23 12:42 AM, Qusatlegadus wrote:

     auto s = 1234.to!string.map!q{a - '0'}.sum;
works fine.


but if i do an alias

     alias comb = to!string.map!q{a - '0'}

     Error: unknown, please file report on issues.dlang.org

What's wrong with this alias?


Aside from the problem with the code, that error alone deserves a bug 
report so...


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

-Steve


Re: what wrong with this alias

2023-01-08 Thread Salih Dincer via Digitalmars-d-learn
On Sunday, 8 January 2023 at 09:45:09 UTC, Krzysztof Jajeśnica 
wrote:

## Simple explanation

`to!string` is a function expecting 1 argument, which you're 
not providing in your alias. Convert your alias to a lambda 
expression:


```D
alias comb = x => x.to!string.map!q{a - '0'}
```


A logical solution...

Since your goal is to manipulate numbers, it is possible to 
convert directly to char type:


```d
import std.algorithm : map, sum;
import std.conv : toChars;

alias comb = (uint x) => x.toChars.map!"a - '0'";
void main()
{
    auto s = 2234.comb.sum;
    assert(s.comb.sum == 2);
}
```

SDB@79


Re: what wrong with this alias

2023-01-08 Thread Krzysztof Jajeśnica via Digitalmars-d-learn

On Sunday, 8 January 2023 at 05:42:46 UTC, Qusatlegadus wrote:

auto s = 1234.to!string.map!q{a - '0'}.sum;
works fine.


but if i do an alias

alias comb = to!string.map!q{a - '0'}

Error: unknown, please file report on issues.dlang.org

What's wrong with this


## Simple explanation

`to!string` is a function expecting 1 argument, which you're not 
providing in your alias. Convert your alias to a lambda 
expression:


```D
alias comb = x => x.to!string.map!q{a - '0'}
```

## Complicated explanation

`to` is a template defined like this:

```D
// https://github.com/dlang/phobos/blob/master/std/conv.d
template to(T)
{
T to(A...)(A args)
if (A.length > 0)
{
return toImpl!T(args);
}
// some overloads omitted for brevity
}
```

`to` needs at least 2 template arguments - the first one for the 
outer template is passed explicitly (what you did with 
`to!string`), the other ones are inferred from the arguments 
passed to the `to` function. Since you did not pass an argument 
to `to!string`, the inner template doesn't get instantiated.


Basically what happens is you're trying to pass an uninstantiated 
template as argument to `map`. This is quite an exotic situation, 
so probably there isn't a dedicated error message for it or 
you're hitting a bug in the compiler (hence the unknown error 
message).


Re: what wrong with this alias

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

On Sunday, 8 January 2023 at 05:42:46 UTC, Qusatlegadus wrote:

What's wrong with this alias?


```d
import std;
alias comb = map!q{a - '0'};
void main()
{
    auto s = 2234.to!string.map!q{a - '0'}.sum;
    s.to!string.comb.sum.writeln;
    // thiS works: "2"
}
```
SDB@79



what wrong with this alias

2023-01-07 Thread Qusatlegadus via Digitalmars-d-learn

auto s = 1234.to!string.map!q{a - '0'}.sum;
works fine.


but if i do an alias

alias comb = to!string.map!q{a - '0'}

Error: unknown, please file report on issues.dlang.org

What's wrong with this alias?


Re: Compile time vs run time -- what is the difference?

2022-12-31 Thread H. S. Teoh via Digitalmars-d-learn
On Sun, Jan 01, 2023 at 02:18:23AM +, Salih Dincer via Digitalmars-d-learn 
wrote:
> On Sunday, 1 January 2023 at 01:20:02 UTC, Ali Çehreli wrote:
> > On 12/31/22 16:42, H. S. Teoh wrote:
> > 
> > - runtime: The D runtime.
> 
> Sometimes I see runtime facilities used as compile time and I'm having
> a hard time distinguishing that. It is even possible to use it with
> meta-programming facilities.
[...]
> Do you have a solid recommendation about distinguishing?
[...]

https://wiki.dlang.org/Compile-time_vs._compile-time

;-)


T

-- 
MACINTOSH: Most Applications Crash, If Not, The Operating System Hangs


Re: Compile time vs run time -- what is the difference?

2022-12-31 Thread Salih Dincer via Digitalmars-d-learn

On Sunday, 1 January 2023 at 01:20:02 UTC, Ali Çehreli wrote:

On 12/31/22 16:42, H. S. Teoh wrote:

- runtime: The D runtime.


Sometimes I see runtime facilities used as compile time and I'm 
having a hard time distinguishing that. It is even possible to 
use it with meta-programming facilities.


It is a powerful feature that can help to improve the 
expressiveness and efficiency of D programs, but it can also make 
code more difficult to understand and maintain.


Do you have a solid recommendation about distinguishing?

SDB@79


Re: Compile time vs run time -- what is the difference?

2022-12-31 Thread Ali Çehreli via Digitalmars-d-learn

On 12/31/22 16:42, H. S. Teoh wrote:

> "runtime"

Going off topic, I've settled on three different spelling of that 
(those? :) ):


- run time: As in this topic, things can happen at run time.

- run-time: Adjective, as in run-time value of something.

- runtime: The D runtime.

Ali



Re: Compile time vs run time -- what is the difference?

2022-12-31 Thread H. S. Teoh via Digitalmars-d-learn
On Wed, Dec 28, 2022 at 02:31:45AM +, thebluepandabear via 
Digitalmars-d-learn wrote:
> I am reading through the free book on learning D by Ali Çehreli and I
> am having difficulties understanding the difference between compile
> time execution and run time execution in D language.

It's very simple: in a compiled language like D, your program goes
through 3 stages:

1) Source code: the human-readable text that you write.

2) Compilation: this is when the compiler is compiling your program.
   IOW, "compile time". Compile time happens once when you compile your
   program.

3) Binary executable: the result of compilation.  When you run this
   executable, that's "runtime".  Runtime happens every time you run the
   program.


Stage (2) is transient, and only happens inside the compiler. It can be
broken down into several steps:

a) Lexing & parsing: the compiler reads the source code, breaks it into
   tokens (keywords, identifiers, operators, etc.), and constructs from
   them an abstract syntax tree (AST) that represents your program. Here
   is where typos and syntax errors are detected.

b) Semantic analysis: the compiler processes the AST and assigns meaning
   to each corresponding programming construct. Here is where (some)
   logic errors are detected (reference to an undefined identifier,
   invalid operations on a data type, calling a function with the wrong
   number of arguments, etc.).

c) Code generation: based on the semantics the compiler assigned to your
   program, it emits a series of CPU instructions that implement these
   semantics.  These instructions are generally saved into either
   intermediate object files that must later be linked together, or
   directly into the final executable.


D's compile-time capabilities are mainly of two categories:

i) AST manipulation: templates, static if, static foreach, and
   pragma(msg) belong to this category. This generally happens between
   steps (a) and (b).

ii) CTFE (compile-time function evaluation): this happens somewhere
   around step (c), and mainly consists of the compiler interpreting
   part of the program using an internal interpreter in order to compute
   the value of a function at compile-time.  This is triggered when this
   value is required in order to resolve something that's needed during
   compilation.

For more details, see:

https://wiki.dlang.org/Compile-time_vs._compile-time


T

-- 
If you think you are too small to make a difference, try sleeping in a closed 
room with a mosquito. -- Jan van Steenbergen


Re: Compile time vs run time -- what is the difference?

2022-12-28 Thread areYouSureAboutThat via Digitalmars-d-learn
On Wednesday, 28 December 2022 at 12:42:24 UTC, thebluepandabear 
wrote:


Before even running the code I get an IDE warning (IntelliJ). 
Does IntelliJ compile the code in the background?


It will NOT compile successfully unless you do one of these 
things:


(1) ensure the result of the 'static assert' is true.
(2) comment out the static assert.

Once you do either of (1) or (2) above, it will compile to an 
executable format.


When you execute it, the runtime will catch the 'assert' failure 
(ie. assertion == false), and the runtime will bring your program 
to an immediate halt.


This was just meant to be an example of differentiating compile 
time from runtime, as per you question.


With static assert, your logic testing is traversed during 
compilation, and your compilation will come to a stop when the 
assertion is found to be false, whereas your asserts are 
traversed during program execution, and if they are found to be 
false, your program comes to a stop.


https://dlang.org/spec/version.html#static-assert
https://tour.dlang.org/tour/en/gems/contract-programming




Re: Compile time vs run time -- what is the difference?

2022-12-28 Thread Ali Çehreli via Digitalmars-d-learn

On 12/28/22 08:04, Ali Çehreli wrote:

> I don't think any of them can run the program though because
> the program can be in a state that could harm its environment
> like deleting unwanted files.

I was too eager there. Likely no IDE goes that far. All they need is to 
understand the code enough to give help. They must stop at some point in 
the following steps of compilation:


- preprocessing (does not exist for D)

- lexical analysis

- parsing

- semantic analysis

I copied those items from Wikipedia:

  https://en.wikipedia.org/wiki/Compiler

It lists the later stages of compilation as

- intermediate representation

- code optimization

- code generation

Ali



Re: Compile time vs run time -- what is the difference?

2022-12-28 Thread Ali Çehreli via Digitalmars-d-learn

On 12/27/22 18:31, thebluepandabear wrote:

> What I do understand is that compile time and run time are the two
> processes that your code goes through to be executed natively.

There is a confusion: Compile time ends when the compiler generates the 
executable program, one that will be executed natively.


Run time is each time when the user starts the executable program by 
typing its name followed by the Enter key, double clicking on it, etc.


For a program that was extremely simple, bug-free, lucky, etc. there may 
be as few as a single compilation and infinite number of executions (run 
times).


On the other hand, for a program that could never be compiled 
successfully, there may be infinite number of compilations and zero run 
times.


> In Java and some other languages, during compile time the code gets
> executed into Java bytecode. This also happens for C#. I don't know if
> there is an equivalent 'intermediate' language for D that your code gets
> translated to.

No, D does not use that model.

Copying a comment of yours:

> Before even running the code I get an IDE warning
> (IntelliJ). Does IntelliJ compile the code in the background?

Yes, many IDEs continuously compile the code as you type the source code 
to understand it to give you such help. I don't think any of them can 
run the program though because the program can be in a state that could 
harm its environment like deleting unwanted files.


Ali



Re: Compile time vs run time -- what is the difference?

2022-12-28 Thread thebluepandabear via Digitalmars-d-learn
On Wednesday, 28 December 2022 at 09:10:38 UTC, 
areYouSureAboutThat wrote:
On Wednesday, 28 December 2022 at 02:31:45 UTC, 
thebluepandabear wrote:


..
Other errors are only able to be spotted during run time such 
as exceptions, dividing by zero, assert blocks.


With regards to the 'assert blocks' you mention, D (like C++) 
has both static assert and runtime assert.


// ---
module test;
@safe:

import std;

void main()
{
  string val = "some string";
  static assert(is(typeof(x) : int)); // assertion fails at 
compile time.
  assert(val == "some other string"); // assertion fails at 
runtime.

}
// ---


Before even running the code I get an IDE warning (IntelliJ). 
Does IntelliJ compile the code in the background?


Re: Compile time vs run time -- what is the difference?

2022-12-28 Thread areYouSureAboutThat via Digitalmars-d-learn
On Wednesday, 28 December 2022 at 02:31:45 UTC, thebluepandabear 
wrote:


..
Other errors are only able to be spotted during run time such 
as exceptions, dividing by zero, assert blocks.


With regards to the 'assert blocks' you mention, D (like C++) has 
both static assert and runtime assert.


// ---
module test;
@safe:

import std;

void main()
{
  string val = "some string";
  static assert(is(typeof(x) : int)); // assertion fails at 
compile time.
  assert(val == "some other string"); // assertion fails at 
runtime.

}
// ---


Re: Compile time vs run time -- what is the difference?

2022-12-27 Thread Mike Parker via Digitalmars-d-learn
On Wednesday, 28 December 2022 at 02:31:45 UTC, thebluepandabear 
wrote:





In Java and some other languages, during compile time the code 
gets executed into Java bytecode. This also happens for C#. I 
don't know if there is an equivalent 'intermediate' language 
for D that your code gets translated to.


With statically compiled languages like D, C, and C++, the 
compiler ultimately translates your source code to what's 
referred to as "machine code". Compilers output object files, 
which are in turn linked into an executable file by a linker.


Static compilers can use intermediate representations like Java 
bytecode. For example, compilation could consist of two steps 
handled by two different programs, one that translates the source 
to bytecode, and one that translates the bytecode to an object 
file.


This is how LLVM-based compilers like Clang and LDC work. Clang 
translates C source to LLVM IR (Intermediate Representation). LDC 
translated C source to LLVM IR. Both pass the generated IR to the 
LLVM compiler, which outputs the object files that are then given 
to a linker. Static Java compilers do the same thing with Java 
bytecode. Java JIT compilers built into Java VMs translate Java 
bytecode to machine code while the program is running.


So compilation is just the act of translating from one source 
format to another (e.g., raw source code to machine code, or raw 
source code to bytecode, or bytecode to machine code).




In general, I have a very vague understanding of these 
concept.s I don't understand the basics of how compile time and 
run time works in D language, it wasn't really explained in the 
book so when I see terms like 'compile time' and 'run time' I 
only have a very vague idea of what these things mean and how 
the process works for D language when compared to other high 
level languages.




Anything that happens at compile time means it happens while the 
compiler is translating the source. Anything that happens at run 
time happens while the compiled program is running.


So take this example:

```d
uint fourcc(char a, char b, char c, char d)
{
return (a << 0) | (b << 8) | (c << 16) | (d << 24);
}

// Here, fourcc is evaluated at compile time
enum nv12 = fourcc('N', 'V', '1', '2');

void main()
{
writeln(nv12);

// Here, fourcc is evaluated at runtime
writeln(fourcc('Y', 'V', '1', '2'));
}
```

When the compiler is processing this source code, it encounters 
the declaration of `nv12`. Since this is an `enum`, it's a 
compile-time constant that cannot be changed at run time.  That 
means that any value used to initialize it must also be known at 
compile time. One way to do that would be to use a literal, but 
in this case it's initialized with a call to the `fourcc` 
function. So the compiler evaluates the fourcc function and uses 
the result as the initializer of `nv12`.


In other words, the end result is just the same as if I had 
written `enum nv12 = 842094158`.


The second call to `fourcc` in the main function is not in a 
compile-time context, so it does not happen at compile time. It 
happens at run time, i.e., when you double click the executable 
that the compiler and linker generated (or type its name on the 
command line).


The general rule is: if a function call is in a context such that 
it *must* be evaluated at compile time, then the compiler will 
evaluate it. Otherwise, it's a normal run-time evaluation.






Re: Compile time vs run time -- what is the difference?

2022-12-27 Thread Steven Schveighoffer via Digitalmars-d-learn

On 12/27/22 9:31 PM, thebluepandabear wrote:
I am reading through the free book on learning D by Ali Çehreli and I am 
having difficulties understanding the difference between compile time 
execution and run time execution in D language.


Compile time execution is running your code being compiled *while being 
compiled*. It allows you to generate compile-time data without having to 
write specialized "compile time only" constructs like templates or 
explicitly marked functions (as other languages typically do).


Compile time data doesn't consume any runtime to execute, it's already 
done by the time your binary is running. It also is usable *at compile 
time*, for things like `static if`, or `mixin`.


The intermediate language being executed is the parsed and semantically 
analyzed AST nodes.


-Steve



Compile time vs run time -- what is the difference?

2022-12-27 Thread thebluepandabear via Digitalmars-d-learn
I am reading through the free book on learning D by Ali Çehreli 
and I am having difficulties understanding the difference between 
compile time execution and run time execution in D language.


What I do understand is that compile time and run time are the 
two processes that your code goes through to be executed 
natively. Compile time is the first stage. During compile time, 
the compiler checks for basic syntax errors such as a missing 
semicolon, typos throughout the codebase. Then the run time stage 
begins. Other errors are only able to be spotted during run time 
such as exceptions, dividing by zero, assert blocks.


In Java and some other languages, during compile time the code 
gets executed into Java bytecode. This also happens for C#. I 
don't know if there is an equivalent 'intermediate' language for 
D that your code gets translated to.


In general, I have a very vague understanding of these concept.s 
I don't understand the basics of how compile time and run time 
works in D language, it wasn't really explained in the book so 
when I see terms like 'compile time' and 'run time' I only have a 
very vague idea of what these things mean and how the process 
works for D language when compared to other high level languages.


Any help would be appreciated.



Re: Find out what type my class is being converted to for comparisons

2022-10-19 Thread ryuukk_ via Digitalmars-d-learn
On Tuesday, 18 October 2022 at 18:53:41 UTC, Matthew Rushworth 
wrote:
I am in the process of building a matrix class (uni project, 
with my choice of programming language) and appear to have run 
into a problem that I'm not too sure how to fix.


My class uses templates to define the shape of the matrix, 
although I'm not sure if that matters. As part of my class, I 
included a opEquals, but when I try to assert that a matrix 
created by multiplying with the identity matrix matches the 
output (I checked with liberal writeln()s to make sure they do) 
but my opEquals() function (I moved it out of the class as I 
kept getting errors saying it was supposed to be non-const, and 
couldn't figure out how to fix that either) just isn't called.


---

Matrix code (the only bit of the class used by opEquals):

```
class Matrix(size_t X, size_t Y = X){
const size_t x_length = X;
const size_t y_length = Y;

double[X*Y] data;

...
}
```

The entirety of opEquals:

```
/// both matrices have to have an identical shape to compare
/// each element must be identical to match
bool opEquals(size_t X, size_t Y)(const Matrix!(X,Y) m1, const 
Matrix!(X,Y) m2) {
for (int i = 0; i < m1.data.length; ++i) if (m1.data[i] != 
m2.data[i]) return false;

return true;
}
```

and the code that excepts:

```
void main() {
auto m = new Matrix!(2)();
m.data = [1.0,0.0,0.0,1.0].dup;
auto n = new Matrix!(2)();
n.data = [2.0,3.0,4.0,5.0].dup;

auto u = mult(m,n);
writeln("u.data vs n.data:");
for (int i = 0; i < u.data.length; ++i)
writeln(u.data[i], "\t", n.data[i]);


// using opEquals() directly is working, but it doesn't 
seem to be being used
//assert(opEquals(u,n),"\"opEquals(u, n)\" is 
failing."); // this works fine
assert(u == n,"\"u == n\" is failing."); // this fails. 
Why?

}
```

---

Any help would be very much appreciated. A way to figure out 
what the '==' is converting its arguments to would also be 
great, but I'm not sure it exists (beyond just sitting down and 
trying to work it out myself, of course)


What's the reason for it being a class? struct makes more sense 
here, plus it'll be faster


If it were a struct, you'd not need any of that, and you can also 
have operator overloading for your mult while also being able to 
check how many row/col at compile time, here an example:


```D
import std;

struct Matrix(size_t X, size_t Y = X)
{
enum x_length = X; // enum so it's available only at compile 
time

enum y_length = Y;
double[X * Y] data;

// operator overloading
Matrix opBinary(string op)(Matrix rhs)
{
static if (op == "*")
{
//
// ** ADD YOUR MULT OPERATION HERE **
//
static if (X == 2)
{
return Matrix();
}
else
static assert("not supported");
}
else
static assert(0, "Operator " ~ op ~ " not 
implemented");

}
}

void main()
{
// check equality by value:
auto a = Matrix!(2)();
a.data = 0;
auto b = Matrix!(2)();
b.data = 0;

writeln("are they the same?: ", a == b); // it'll check for 
equality by value


auto m = Matrix!(2)();
m.data = [1.0, 0.0, 0.0, 1.0];
auto n = Matrix!(2)();
n.data = [2.0, 3.0, 4.0, 5.0];

// here we can use the * operator!
auto u = m * n;

writeln("u.data vs n.data:");

for (int i = 0; i < u.data.length; ++i)
writeln(u.data[i], "\t", n.data[i]);
}
```


Re: Find out what type my class is being converted to for comparisons

2022-10-19 Thread rassoc via Digitalmars-d-learn

On 10/19/22 00:43, Matthew Rushworth via Digitalmars-d-learn wrote:

Thank you, that worked perfectly, not sure exactly what I did wrong, I'm 
assuming I forgot to make the parameter a const variable


Object, the root of the class object hierarchy already defines an opEquals [1] 
and you need to overload/overwrite that for it to work properly. Only class 
methods are considered, hence ag0aep6g's suggestion.

[1] https://dlang.org/library/object/object.op_equals.html


Re: Can someone tell me what the compiler thought I was trying to do?

2022-10-19 Thread zjh via Digitalmars-d-learn

On Wednesday, 19 October 2022 at 05:41:26 UTC, zjh wrote:


Why always afraid to `add features`?
C++ is `so complicated` ,but that people are not afraid to 
continue to `add features`.


Look at the `emerging` languages, which are not crazy about 
`adding features`. Even `go` is adding generics.





Re: Can someone tell me what the compiler thought I was trying to do?

2022-10-19 Thread zjh via Digitalmars-d-learn

On Wednesday, 19 October 2022 at 05:50:18 UTC, zjh wrote:

In my opinion, as long as `users` have reasonable needs, 
languages should added corresponding features, instead of 
becoming religions.


`Some features` are very popular for users,I really don't know 
why they didn't add it.



When you show `prejudice`, users are lost.
Like `class`, when it can be used as the smallest `encapsulation 
unit`, it can provide `this feature` but intentionally does not.


Just like when you ride a bicycle, but it has a `square` tire.




Re: Can someone tell me what the compiler thought I was trying to do?

2022-10-18 Thread zjh via Digitalmars-d-learn

On Wednesday, 19 October 2022 at 05:41:26 UTC, zjh wrote:


Why can't do it `in one step`?
Why always afraid to `add features`?
C++ is `so complicated` ,but that people are not afraid to 
continue to `add features`.


There is also `class level private`. I saw someone start it by 
himself, and he felt very happy. It completely conforms to the 
encapsulation, but it seems that the latest D has no switch about 
it.
In my opinion, as long as `users` have reasonable needs, 
languages should added corresponding features, instead of 
becoming religions.


`Some features` are very popular for users,I really don't know 
why they didn't add it.





Re: Can someone tell me what the compiler thought I was trying to do?

2022-10-18 Thread zjh via Digitalmars-d-learn

On Wednesday, 19 October 2022 at 04:59:40 UTC, mw wrote:


...


Why can't do it `in one step`?
Why always afraid to `add features`?
C++ is `so complicated` ,but that people are not afraid to 
continue to `add features`.




Re: Can someone tell me what the compiler thought I was trying to do?

2022-10-18 Thread mw via Digitalmars-d-learn
@mustuse as a function attribute was in the original version of 
the DIP. It was vetoed by Walter. Thus, only the type attribute 
remains in the accepted version.


Let's continue the discussion here:

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

in general, it's about: command query separation principle


Re: Can someone tell me what the compiler thought I was trying to do?

2022-10-18 Thread Mike Parker via Digitalmars-d-learn

On Wednesday, 19 October 2022 at 03:10:29 UTC, Mike Parker wrote:



It's right there in the summary of the Final Review of the DIP 
that I linked above:


https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1038.md#final-review


I meant to say the summary of the formal assessment. One of the 
conditions of acceptance was this one:


develop rules for handling covariance and contravariance when 
applied to functions.


Paul opted instead to do just have it apply to types for now. A 
future enhancement can take on extending it to functions. As he 
noted above, that's the approach Rust took as well.


Re: Can someone tell me what the compiler thought I was trying to do?

2022-10-18 Thread Mike Parker via Digitalmars-d-learn

On Wednesday, 19 October 2022 at 01:34:54 UTC, mw wrote:

On Wednesday, 19 October 2022 at 01:30:23 UTC, H. S. Teoh wrote:

On Wed, Oct 19, 2022 at 01:15:37AM +, Adam D Ruppe via


it only applies to types, not to functions.


Wat... so what's the use of it then?  So it's not possible to 
mark the return value of an int function @mustUse without 
making, in theory, *all* ints @mustUse?


I must confess I'm baffled as to the purpose of this strange 
design.




Same, can't believe it.

Is there any (design) doc about this?


It's right there in the summary of the Final Review of the DIP 
that I linked above:


https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1038.md#final-review


Re: Can someone tell me what the compiler thought I was trying to do?

2022-10-18 Thread Paul Backus via Digitalmars-d-learn

On Wednesday, 19 October 2022 at 01:49:26 UTC, mw wrote:
On Wednesday, 19 October 2022 at 01:38:27 UTC, Adam D Ruppe 
wrote:

On Wednesday, 19 October 2022 at 01:34:54 UTC, mw wrote:

Is there any (design) doc about this?


scroll up, click the link from this very thread.

https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1038.md#design-goals-and-possible-alternatives


"""
Rather than make either sacrifice, this DIP proposes a design 
that allows both rigor and simplicity to be maintained, and 
reserves the possibility for a future DIP to allow @mustUse as 
a function attribute.

"""

Another future DIP? I think this DIP is flawed for not using 
"@mustUse as a function attribute"


@mustuse as a function attribute was in the original version of 
the DIP. It was vetoed by Walter. Thus, only the type attribute 
remains in the accepted version.


FWIW, this is the same path that #[must_use] took in Rust. It was 
added originally as a type attribute only, and later had its 
usage extended to functions.


Re: Can someone tell me what the compiler thought I was trying to do?

2022-10-18 Thread mw via Digitalmars-d-learn

On Wednesday, 19 October 2022 at 01:38:27 UTC, Adam D Ruppe wrote:

On Wednesday, 19 October 2022 at 01:34:54 UTC, mw wrote:

Is there any (design) doc about this?


scroll up, click the link from this very thread.

https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1038.md#design-goals-and-possible-alternatives


"""
Rather than make either sacrifice, this DIP proposes a design 
that allows both rigor and simplicity to be maintained, and 
reserves the possibility for a future DIP to allow @mustUse as a 
function attribute.

"""

Another future DIP? I think this DIP is flawed for not using 
"@mustUse as a function attribute"




Re: Can someone tell me what the compiler thought I was trying to do?

2022-10-18 Thread Adam D Ruppe via Digitalmars-d-learn

On Wednesday, 19 October 2022 at 01:34:54 UTC, mw wrote:

Is there any (design) doc about this?


scroll up, click the link from this very thread.

https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1038.md#design-goals-and-possible-alternatives



Re: Can someone tell me what the compiler thought I was trying to do?

2022-10-18 Thread rikki cattermole via Digitalmars-d-learn

On 19/10/2022 2:30 PM, H. S. Teoh wrote:

On Wed, Oct 19, 2022 at 01:15:37AM +, Adam D Ruppe via Digitalmars-d-learn 
wrote:

On Wednesday, 19 October 2022 at 00:57:31 UTC, H. S. Teoh wrote:

Has it really been implemented?  I tested the latest git master, the
following code doesn't compile:


it only applies to types, not to functions.


Wat... so what's the use of it then?  So it's not possible to mark the
return value of an int function @mustUse without making, in theory,
*all* ints @mustUse?

I must confess I'm baffled as to the purpose of this strange design.


Oh but it gets better:

From C23 draft:

The nodiscard attribute shall be applied to the identifier in a function 
declaration or to the definition
of a structure, union, or enumeration type. If an attribute argument 
clause is present, it shall have

the form:
( string-literal )


Re: Can someone tell me what the compiler thought I was trying to do?

2022-10-18 Thread mw via Digitalmars-d-learn

On Wednesday, 19 October 2022 at 01:30:23 UTC, H. S. Teoh wrote:

On Wed, Oct 19, 2022 at 01:15:37AM +, Adam D Ruppe via


it only applies to types, not to functions.


Wat... so what's the use of it then?  So it's not possible to 
mark the return value of an int function @mustUse without 
making, in theory, *all* ints @mustUse?


I must confess I'm baffled as to the purpose of this strange 
design.




Same, can't believe it.

Is there any (design) doc about this?



Re: Can someone tell me what the compiler thought I was trying to do?

2022-10-18 Thread H. S. Teoh via Digitalmars-d-learn
On Wed, Oct 19, 2022 at 01:15:37AM +, Adam D Ruppe via Digitalmars-d-learn 
wrote:
> On Wednesday, 19 October 2022 at 00:57:31 UTC, H. S. Teoh wrote:
> > Has it really been implemented?  I tested the latest git master, the
> > following code doesn't compile:
> 
> it only applies to types, not to functions.

Wat... so what's the use of it then?  So it's not possible to mark the
return value of an int function @mustUse without making, in theory,
*all* ints @mustUse?

I must confess I'm baffled as to the purpose of this strange design.


T

-- 
Doubt is a self-fulfilling prophecy.


Re: Can someone tell me what the compiler thought I was trying to do?

2022-10-18 Thread Adam D Ruppe via Digitalmars-d-learn

On Wednesday, 19 October 2022 at 00:57:31 UTC, H. S. Teoh wrote:
Has it really been implemented?  I tested the latest git 
master, the following code doesn't compile:


it only applies to types, not to functions.


  1   2   3   4   5   6   7   8   9   10   >