Re: What is an rvalue constructor?

2024-07-25 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, July 25, 2024 4:48:06 PM MDT Quirin Schroll via Digitalmars-d-
learn wrote:
> It seems one can’t have one in a struct together with a copy
> constructor, but what is it? When is it called? What is it for?

An rvalue constructor is a constructor that takes the same type as the
struct that it's in, but it takes it as an rvalue (whereas a copy
constructor takes it as an lvalue). So, if you have

struct MyType
{
this(MyType rhs)
{
...
}
}

then you can do stuff like MyType(getMyType()) where getMyType returns a
MyType, whereas if you don't have such a constructor, you can't. This is
particularly useful in generic code. For instance, if you have an algebraic
type that takes a whole bunch of types, you can do something like

this(T)(T rhs)
{
...
}

and then you can happily call MyType(getMyType()) where getMyType() returns
a MyType.

However, without that rvalue constructor, then MyType(getMyType()) can't be
done. So, if MyType has a copy constructor, you're forced to check for
MyType with such a templated constructor, e.g.

this(T)(T rhs)
if(!is(immutable T == immutable MyType))
{
...
}

and you need to create a wrapper function to be able to generically
construct a MyType, e.g.

MyType make(T)(T rhs)
{
static if(is(immutable T == immutable MyType))
return rhs;
else
return MyType(rhs);
}

Of course, for most code, you really don't need to be able to construct a
struct from its own type, so in many cases, you really don't need an rvalue
constructor, but when you do need it, the fact that copy constructors don't
allow them is pretty annoying.

With the current DIP proposal for move constructors, an rvalue constructor
would become a move constructor, though since it's not necessarily obvious
that that's what it is, and such constructors already exist as normal
constructors, there are some objections to making such a change. But of
course, we'll have to see what ultimately happens with that.

- Jonathan M Davis






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 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(&Counter)` 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(&Counter)` 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 
`&Counter` instead, otherwise it expects the parameters.


If you execute

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

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 
`&Counter` 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 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 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 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: 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: What is the difference between a static assert and a unit test?

2022-04-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 4/21/22 6:26 PM, Alain De Vos wrote:

I don't know when to use a static assert and when to use a unit test ?


An assert in general is something that must be true for the program to 
be valid.


A normal assert is some runtime condition that must be true or the 
program will be terminated.


A static assert is some compile-time condition that must be true or the 
compilation will be terminated.


A unittest is a completely different thing -- this is testing generally 
a piece of your program (like a function), to ensure that given known 
inputs it returns known results. A unittest uses asserts to test that 
the results are valid.


-Steve


Re: What is the difference between a static assert and a unit test?

2022-04-21 Thread frame via Digitalmars-d-learn

On Thursday, 21 April 2022 at 22:26:57 UTC, Alain De Vos wrote:
I don't know when to use a static assert and when to use a unit 
test ?


There is `assert()`, `static assert()` and `unittest`.

`static assert()` is used while compiling, to find errors or 
circumstances that can lead to errors in runtime or just show 
type incompatibilities.


`assert()` is used at runtime to allow some checks before 
processing data.  It is evaluated at runtime and removed from 
code in release mode. Except `assert(0)` which will always emit 
an `AssertError` and will be never removed.


`unittest` is a just block that will be only compiled/executed 
when the `-unittest` switch will be applied to compiler command 
line. That's it.




What is the difference between a static assert and a unit test?

2022-04-21 Thread Alain De Vos via Digitalmars-d-learn
I don't know when to use a static assert and when to use a unit 
test ?


What is Machine Learning?

2022-03-23 Thread Armen - Edvard via Digitalmars-d-learn
Machine learning is sanctionative computers to tackle tasks that 
have, until now, completely been administered by folks.


From driving cars to translating speech, machine learning is 
driving accolade explosion among the capabilities of computing – 
serving to package add of the untidy and unpredictable planet.


But what specifically is machine learning and what's creating 
this boom in machine learning possible?


WHAT IS MACHINE LEARNING?
At a awfully high level, machine learning classes in Pune is that 
the strategy of teaching a info method system|ADP 
system|ADPS|system} the due to build correct predictions once fed 
info.


Those predictions might even be responsive whether or not or not 
or not barely of fruit {in a|during a|in accolade exceedingly|in 
a very} photograph might even be a banana or associate apple, 
recognizing folks crossing the road before of a self-driving 
automobile, whether or not or not or not the utilization of the 
word book in associate degree exceedingly} terribly sentence 
relates to a paperback or a building reservation, whether or not 
or not or not accolade email is spam, or recognizing speech 
accurately enough to return make a copy with captions for a 
YouTube video.


The key distinction from ancient microcomputer package is that a 
human developer hasn't written code that instructs the system the 
due to tell the excellence between the banana and so the apple.


Instead a machine-learning model has been instructed the due to 
reliably discriminate between the fruits by being trained on 
associate great amount of information, throughout this instance 
on the face of it a huge vary of pictures tagged as containing a 
banana or accolade apple.


Machine learning might need enjoyed monumental success recently, 
however it's only 1 methodology for achieving computing.


At the birth of the sphere of AI among the nineteen Fifties, AI 
was written as any machine capable of acting a task which can 
typically wish human intelligence.


AI systems can typically demonstrate a minimum of style of the 
subsequent traits: designing, learning, reasoning, flinch 
resolution, knowledge illustration, perception, motion, and 
manipulation and, to a lesser extent, social intelligence and 
talent.


Alongside machine learning, there ar varied all totally different 
approaches accustomed build AI systems, still as process 
computation, wherever algorithms bear random mutations and combos 
between generations throughout an endeavor to "evolve" optimum 
solutions, and adept systems, wherever computers ar programmed 
with rules that permit them to mimic the behavior of a human 
adept in associate degree exceedingly} terribly specific domain, 
{for example|for instance|as accolade example} associate 
autopilot system flying a plane.


WHAT ar the foremost forms of MACHINE LEARNING?
Machine learning is usually split into 2 main categories: 
supervised and unattended learning.


WHAT IS supervised LEARNING?
This approach primarily teaches machines by example.

During work for supervised learning, systems ar exposed to large 
amounts of tagged info, as associate example footage of written 
figures annotated to purpose that change they correspond to. 
Given cosy examples, a supervised-learning system would learn 
acknowledge|to acknowledge} the clusters of pixels and shapes 
related to every vary and eventually be able to acknowledge 
written numbers, able to reliably distinguish between the numbers 
nine and four or vi and eight.


However, work these systems typically wishes huge amounts of 
tagged info, with some systems needing to be exposed to 
numberless examples to master a task.


Machine Learning course in Pune: 
https://www.sevenmentor.com/machine-learning-course-in-pune.php


As a result, the datasets accustomed train these systems is huge, 
with Google's Open footage Dataset having concerning 9 million 
footage, its tagged video repository YouTube-8M linking to seven 
million tagged videos and ImageNet, one in all the first 
databases of this sort, having over fourteen million classified 
footage. the dimensions of labor datasets continues to grow, with 
Facebook spoken communication it had compiled three.5 billion 
footage in public obtainable on Instagram, victimization hashtags 
connected to every image as labels. victimization one billion of 
those photos to teach accolade image-recognition system yielded 
record levels of accuracy – of eighty five.4% – on ImageNet's 
benchmark.


The gruelling technique of labeling the datasets employed in work 
is usually administered victimization crowdworking services, like 
Amazon Mechanical Turki, that provides access to associate giant 
pool of affordable labor unfold across the earth. as associate 
example, ImageNet was place on over 2 years by nearly fifty,000 
people, primarily recruited through Amazon Mechanical Turki. 
However, Facebook's approach of victimization in public 
obtainable i

Re: What is safe to do in an extern (C) function and how can I test this?

2022-01-24 Thread Jaime via Digitalmars-d-learn
On Tuesday, 25 January 2022 at 01:41:03 UTC, Steven Schveighoffer 
wrote:

On 1/24/22 8:31 PM, Jaime wrote:
Can I, for instance, safely call Fiber.yield in a C callback 
that I know will be run in a Fiber?


I would *imagine* it's fine, all the fiber context switch is 
doing (WRT the stack) is swapping out the fiber portion of the 
stack (i.e. back to the `Fiber.call` invokation), which should 
include the C stack portions as well.


There's a lot of low-level details in the Fiber.d file itself:

https://github.com/dlang/druntime/blob/e390ba7e0a1f80f15e72ca773fca7252057ba4c5/src/core/thread/fiber.d#L387

-Steve


On Tuesday, 25 January 2022 at 02:02:27 UTC, H. S. Teoh wrote:

I haven't tested this myself, but I *think* it should be OK.

One thing to watch out for, though, is the size of the Fiber's 
stack (this can be specified when you first create the Fiber).  
If the C part of the code uses up too much stack space (e.g. if 
somewhere in the C code it tries to allocate a large object on 
the stack), you may inadvertently overflow the Fiber's stack 
and cause a crash or abort. Increasing the stack size of the 
Fiber when it is created should fix this problem.



T


The insight and vote of confidence are much appreciated, you two. 
Steven, good call to check out the implementation of Fiber, I'll 
do that.


Re: What is safe to do in an extern (C) function and how can I test this?

2022-01-24 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Jan 25, 2022 at 01:31:29AM +, Jaime via Digitalmars-d-learn wrote:
> **The lede**:
> 
> Can I, for instance, safely call Fiber.yield in a C callback that I
> know will be run in a Fiber?
> 
> The stack will look like:
> Thread
> |- Fiber in D runtime
> | |- Call into a C API (stays on same thread)
> | | |- Extern (C) callback (stays on same thread)
> | | | |- Fiber.yield <-- Is this OK?

I haven't tested this myself, but I *think* it should be OK.

One thing to watch out for, though, is the size of the Fiber's stack
(this can be specified when you first create the Fiber).  If the C part
of the code uses up too much stack space (e.g. if somewhere in the C
code it tries to allocate a large object on the stack), you may
inadvertently overflow the Fiber's stack and cause a crash or abort.
Increasing the stack size of the Fiber when it is created should fix
this problem.


T

-- 
Those who don't understand D are condemned to reinvent it, poorly. -- Daniel N


Re: What is safe to do in an extern (C) function and how can I test this?

2022-01-24 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/24/22 8:31 PM, Jaime wrote:

**The lede**:

Can I, for instance, safely call Fiber.yield in a C callback that I know 
will be run in a Fiber?


The stack will look like:
Thread
|- Fiber in D runtime
| |- Call into a C API (stays on same thread)
| | |- Extern (C) callback (stays on same thread)
| | | |- Fiber.yield <-- Is this OK?

Also, in general, is there a convenient way to know or test if 
particular C callbacks are safe? Or is it just case by case?


**The context I was gonna bury the lede in but thought better of it**:

So, I am a big lame novice. Don't worry, I know this already.

I'm trying to use gtk-d, but I don't even know how to use gtk, so I'm 
learning them both at once. Probably not a good idea, I know.


 From what I can tell so far, it seems like the way gtk works is you 
write your whole application in terms of gtk's event loop. I really 
don't want to do that, so -- and I realize this is probably an even 
worse idea, but I don't know the right thing to do -- I decided I'd try 
writing a worker thread class -- "Rope" -- and run gtk's event loop in a 
Rope.


A Rope runs its given task in a new Fiber in a new thread, and that 
thread repeatedly resumes the fiber and terminates when the fiber 
terminates, but, in the meantime, takes some time to act as an executor 
each time the fiber suspends, accepting work in std.concurrency messages 
and running it on the same thread as its main fiber. My thought was that 
this way, I can call gtk-d's API from any thread, and still have all the 
calls happen on the same thread that the event loop is running on, as 
the API requires.


All I needed, then, was some way to make gtk-d suspend the fiber it's 
running on, to give its rope some time to service external work. My 
first thought was to use glib.Timeout.Timeout.add and put Fiber.yield in 
the timeout callback. The potential problem: the timeout callback, of 
course, has to be extern (C).


Now, I could just drop the more general concept of Rope and rewrite it 
specifically for gtk, and drop the whole Fiber part, and instead 
directly put the calls to std.concurrency.receiveTimeout in the 
glib.Timeout.Timeout.add callback. Assuming, of course, receiveTimeout 
would be any safer to call from extern (C) than Fiber.yield would. But 
that's just the trouble, I can't guess which would be safer, and even a 
minimal test for this question seems daunting.


I would *imagine* it's fine, all the fiber context switch is doing (WRT 
the stack) is swapping out the fiber portion of the stack (i.e. back to 
the `Fiber.call` invokation), which should include the C stack portions 
as well.


There's a lot of low-level details in the Fiber.d file itself:

https://github.com/dlang/druntime/blob/e390ba7e0a1f80f15e72ca773fca7252057ba4c5/src/core/thread/fiber.d#L387

-Steve


What is safe to do in an extern (C) function and how can I test this?

2022-01-24 Thread Jaime via Digitalmars-d-learn

**The lede**:

Can I, for instance, safely call Fiber.yield in a C callback that 
I know will be run in a Fiber?


The stack will look like:
Thread
|- Fiber in D runtime
| |- Call into a C API (stays on same thread)
| | |- Extern (C) callback (stays on same thread)
| | | |- Fiber.yield <-- Is this OK?

Also, in general, is there a convenient way to know or test if 
particular C callbacks are safe? Or is it just case by case?


**The context I was gonna bury the lede in but thought better of 
it**:


So, I am a big lame novice. Don't worry, I know this already.

I'm trying to use gtk-d, but I don't even know how to use gtk, so 
I'm learning them both at once. Probably not a good idea, I know.


From what I can tell so far, it seems like the way gtk works is 
you write your whole application in terms of gtk's event loop. I 
really don't want to do that, so -- and I realize this is 
probably an even worse idea, but I don't know the right thing to 
do -- I decided I'd try writing a worker thread class -- "Rope" 
-- and run gtk's event loop in a Rope.


A Rope runs its given task in a new Fiber in a new thread, and 
that thread repeatedly resumes the fiber and terminates when the 
fiber terminates, but, in the meantime, takes some time to act as 
an executor each time the fiber suspends, accepting work in 
std.concurrency messages and running it on the same thread as its 
main fiber. My thought was that this way, I can call gtk-d's API 
from any thread, and still have all the calls happen on the same 
thread that the event loop is running on, as the API requires.


All I needed, then, was some way to make gtk-d suspend the fiber 
it's running on, to give its rope some time to service external 
work. My first thought was to use glib.Timeout.Timeout.add and 
put Fiber.yield in the timeout callback. The potential problem: 
the timeout callback, of course, has to be extern (C).


Now, I could just drop the more general concept of Rope and 
rewrite it specifically for gtk, and drop the whole Fiber part, 
and instead directly put the calls to 
std.concurrency.receiveTimeout in the glib.Timeout.Timeout.add 
callback. Assuming, of course, receiveTimeout would be any safer 
to call from extern (C) than Fiber.yield would. But that's just 
the trouble, I can't guess which would be safer, and even a 
minimal test for this question seems daunting.


Re: what is going on here?

2022-01-05 Thread H. S. Teoh via Digitalmars-d-learn
On Wed, Jan 05, 2022 at 08:00:45AM +, forkit via Digitalmars-d-learn wrote:
[...]
> Well, in my case, it was nice to see that the oom reaper thread is
> working correctly  ;-)

I'm well-acquainted with the OOM reaper; it and dmd are good friends,
and love to throw parties esp. when CTFE and Recursive Templates are in
town.

:-P


T

-- 
What doesn't kill me makes me stranger.


Re: what is going on here?

2022-01-05 Thread forkit via Digitalmars-d-learn

On Tuesday, 4 January 2022 at 23:37:57 UTC, H. S. Teoh wrote:


Or the compiler would run out of memory before it gets to 
optimizing away those assignments, so it would just outright 
crash. I ran your code on my computer and got this:


uncaught exception
	core.exception.AssertError@src/dmd/common/outbuffer.d(204): 
OutBuffer: out of memory.


??:? _d_assert_msg [0x5616e935648e]
??:? _ZN9OutBuffer7reserveEm [0x5616e9350bda]
	??:? nothrow @trusted void 
dmd.common.outbuffer.OutBuffer.position(ulong, ulong) 
[0x5616e935129c]

??:? _Z11ElfObj_termPKc [0x5616e933bcd6]
Aborted

Which seems to confirm my suspicions.


T


Well, in my case, it was nice to see that the oom reaper thread 
is working correctly  ;-)


Re: what is going on here?

2022-01-04 Thread forkit via Digitalmars-d-learn

On Tuesday, 4 January 2022 at 23:37:57 UTC, H. S. Teoh wrote:


... .. .

Which seems to confirm my suspicions.


T


yes, this sounds like it might be it.

I tried using = void;

.. results:

dmd -m64 -> just results in an 'out of memory' message (but at 
least i get a message this time)


ldc2 -m64 -> again, compiles ok, but this time memory usage 
during compilation never exceeds about 2.1GB (compared to 22GB 
when not using =void;





Re: what is going on here?

2022-01-04 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Jan 04, 2022 at 03:34:41PM -0800, H. S. Teoh wrote:
[...]
> Of course, afterwards the optimizer would merge them into something
> saner, but while the compiler is unfolding all those assignments, its
> memory usage would obviously skyrocket.

Or the compiler would run out of memory before it gets to optimizing
away those assignments, so it would just outright crash. I ran your code
on my computer and got this:

uncaught exception
core.exception.AssertError@src/dmd/common/outbuffer.d(204): OutBuffer: 
out of memory.

??:? _d_assert_msg [0x5616e935648e]
??:? _ZN9OutBuffer7reserveEm [0x5616e9350bda]
??:? nothrow @trusted void 
dmd.common.outbuffer.OutBuffer.position(ulong, ulong) [0x5616e935129c]
??:? _Z11ElfObj_termPKc [0x5616e933bcd6]
Aborted

Which seems to confirm my suspicions.


T

-- 
They say that "guns don't kill people, people kill people." Well I think
the gun helps. If you just stood there and yelled BANG, I don't think
you'd kill too many people. -- Eddie Izzard, Dressed to Kill


Re: what is going on here?

2022-01-04 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Jan 04, 2022 at 10:53:50PM +, forkit via Digitalmars-d-learn wrote:
[...]
> // 
> 
> module test;
> void main(){ static char[2147483646] arr; }
> 
> // 

I bet you it's the same problem I found a couple of years ago, where the
compiler translates the above code to something that individually
initializes every element of the array. I.e., there would be 2.1 billion
assignments, one for each element in the array.  Of course, afterwards
the optimizer would merge them into something saner, but while the
compiler is unfolding all those assignments, its memory usage would
obviously skyrocket.

Try setting `arr = void;` to see if it makes a difference. If it does,
it's probably the same problem.


T

-- 
Skill without imagination is craftsmanship and gives us many useful objects 
such as wickerwork picnic baskets.  Imagination without skill gives us modern 
art. -- Tom Stoppard


what is going on here?

2022-01-04 Thread forkit via Digitalmars-d-learn
strange things happen when I compile (on windows) the code below 
with:


dmd -m64
(compilation just crashes - no error message at all)

or

ldc2 -m64
(compilation works, but memory usage during compilation goes 
completely wild! upto 22GB, then down to 7GB, then finally 
completes.)



// 

module test;
void main(){ static char[2147483646] arr; }

// 



Re: What is pure used for?

2021-11-25 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 25 November 2021 at 07:26:48 UTC, sclytrack wrote:

int * pureFunction()

1) the pointer needs to be the same.
2) the value that the pointer points to needs to be the same. I 
call this the "value

of interest" with relation to pure. The pointer doesn't matter.
3) both the pointer and the value the pointer is pointing too 
needs to be the same.


pureCalloc() satisfies (2)
pureMalloc() violates everything.


There is a special case in the language spec to allow functions 
like `pureMalloc`. They are called "pure factory functions":


A *pure factory function* is a strongly pure function that 
returns a result that has mutable indirections. All mutable 
memory returned by the call may not be referenced by any other 
part of the program, i.e. it is newly allocated by the 
function. Nor may the mutable references of the result refer to 
any object that existed before the function call.


Source:  
(scroll down)



Does the D compiler do any optimizations?


Yes, but those optimizations may result in implementation-defined 
behavior:


**Implementation Defined:** An implementation may assume that a 
strongly pure function that returns a result without mutable 
indirections will have the same effect for all invocations with 
equivalent arguments. It is allowed to memoize the result of 
the function under the assumption that equivalent parameters 
always produce equivalent results. [...] An implementation is 
currently not required to enforce validity of memoization in 
all cases.


The term "equivalent" is not explicitly defined, but as far as I 
can tell it means something like item (2) in your list.


Re: What is pure used for?

2021-11-25 Thread zjh via Digitalmars-d-learn

On Thursday, 25 November 2021 at 07:26:48 UTC, sclytrack wrote:
My understanding is that pure is used for compiler optimization 
in loops and expressions. It leaves out multiple calls if it 
figures out it is not needed.




[one 
link](https://klickverbot.at/blog/2012/05/purity-in-d/#indirections-in-the-return-type) and [another](https://theartofmachinery.com/2016/03/28/dirtying_pure_functions_can_be_useful.html)


Re: What is pure used for?

2021-11-25 Thread Imperatorn via Digitalmars-d-learn

On Thursday, 25 November 2021 at 07:26:48 UTC, sclytrack wrote:
My understanding is that pure is used for compiler optimization 
in loops and expressions. It leaves out multiple calls if it 
figures out it is not needed.


Is pure used for anything else?


int * pureFunction()

1) the pointer needs to be the same.
2) the value that the pointer points to needs to be the same. I 
call this the "value

of interest" with relation to pure. The pointer doesn't matter.
3) both the pointer and the value the pointer is pointing too 
needs to be the same.


pureCalloc() satisfies (2)
pureMalloc() violates everything.

Does the D compiler do any optimizations?


https://dlang.org/spec/function.html#pure-functions


What is pure used for?

2021-11-24 Thread sclytrack via Digitalmars-d-learn
My understanding is that pure is used for compiler optimization 
in loops and expressions. It leaves out multiple calls if it 
figures out it is not needed.


Is pure used for anything else?


int * pureFunction()

1) the pointer needs to be the same.
2) the value that the pointer points to needs to be the same. I 
call this the "value

of interest" with relation to pure. The pointer doesn't matter.
3) both the pointer and the value the pointer is pointing too 
needs to be the same.


pureCalloc() satisfies (2)
pureMalloc() violates everything.

Does the D compiler do any optimizations?



Re: What is D's "__debugbreak()" equivalent?

2021-10-29 Thread bauss via Digitalmars-d-learn

On Friday, 29 October 2021 at 11:36:13 UTC, Adam D Ruppe wrote:

On Friday, 29 October 2021 at 09:32:07 UTC, bauss wrote:

} else version(D_InlineAsm_X86_64) {


just fyi but `int 3;` works just as well in 32 bit as 64


Yeah, that's why I noted that there's also D_InlineAsm_X86 but I 
just didn't bother adding it.


Re: What is D's "__debugbreak()" equivalent?

2021-10-29 Thread Adam D Ruppe via Digitalmars-d-learn

On Friday, 29 October 2021 at 09:32:07 UTC, bauss wrote:

} else version(D_InlineAsm_X86_64) {


just fyi but `int 3;` works just as well in 32 bit as 64


Re: What is D's "__debugbreak()" equivalent?

2021-10-29 Thread bauss via Digitalmars-d-learn

On Thursday, 28 October 2021 at 09:54:44 UTC, Dennis wrote:

On Wednesday, 27 October 2021 at 16:54:49 UTC, Simon wrote:

What is the equivalent in D?


With LDC, you have:

```D
import ldc.intrinsics: llvm_debugtrap;
```

Combining that with previous answers, you can make something 
like this:

```D
void debugbreak() nothrow @nogc @trusted {
version(D_InlineAsm_X86_64) {
asm nothrow @nogc {
int 3;
}
} else version(LDC) {
import ldc.intrinsics: llvm_debugtrap;
llvm_debugtrap();
} else {
assert(0); // No `breakPoint` for this compiler configuration
}
}
```


Shouldn't it be this instead, unless D_InlineAsm_X86_64 isn't 
available for ldc?


There's also D_InlineAsm_X86 btw.

```D
void debugbreak() nothrow @nogc @trusted {
version(LDC) {
import ldc.intrinsics: llvm_debugtrap;
llvm_debugtrap();
} else version(D_InlineAsm_X86_64) {
asm nothrow @nogc {
int 3;
}
} else {
assert(0); // No `breakPoint` for this compiler configuration
}
}
```


Re: What is D's "__debugbreak()" equivalent?

2021-10-28 Thread Dennis via Digitalmars-d-learn

On Wednesday, 27 October 2021 at 16:54:49 UTC, Simon wrote:

What is the equivalent in D?


With LDC, you have:

```D
import ldc.intrinsics: llvm_debugtrap;
```

Combining that with previous answers, you can make something like 
this:

```D
void debugbreak() nothrow @nogc @trusted {
version(D_InlineAsm_X86_64) {
asm nothrow @nogc {
int 3;
}
} else version(LDC) {
import ldc.intrinsics: llvm_debugtrap;
llvm_debugtrap();
} else {
assert(0); // No `breakPoint` for this compiler configuration
}
}
```


Re: What is D's "__debugbreak()" equivalent?

2021-10-27 Thread Adam D Ruppe via Digitalmars-d-learn

On Wednesday, 27 October 2021 at 17:07:31 UTC, H. S. Teoh wrote:

asm { int 3; }


yeah that's how i do it in dmd too


Re: What is D's "__debugbreak()" equivalent?

2021-10-27 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/27/21 12:54 PM, Simon wrote:
Microsofts C++ compiler provides the __debugbreak function, which on x86 
emits interrupt 3, which will cause the debugger to halt. What is the 
equivalent in D? I tried using raise(SIGINT) from core.stdc.signal, but 
that just closes the debugger (I thought that was the same, seems like I 
was wrong).


SIGINT is not an interrupt, it's a POSIX signal.

Inline asm maybe?  https://dlang.org/spec/iasm.html

-Steve


Re: What is D's "__debugbreak()" equivalent?

2021-10-27 Thread H. S. Teoh via Digitalmars-d-learn
On Wed, Oct 27, 2021 at 04:54:49PM +, Simon via Digitalmars-d-learn wrote:
> Microsofts C++ compiler provides the __debugbreak function, which on
> x86 emits interrupt 3, which will cause the debugger to halt. What is
> the equivalent in D? I tried using raise(SIGINT) from
> core.stdc.signal, but that just closes the debugger (I thought that
> was the same, seems like I was wrong).

Why not just:

asm { int 3; }

?

Just tested in gdb, it worked.


T

-- 
MASM = Mana Ada Sistem, Man!


What is D's "__debugbreak()" equivalent?

2021-10-27 Thread Simon via Digitalmars-d-learn
Microsofts C++ compiler provides the __debugbreak function, which 
on x86 emits interrupt 3, which will cause the debugger to halt. 
What is the equivalent in D? I tried using raise(SIGINT) from 
core.stdc.signal, but that just closes the debugger (I thought 
that was the same, seems like I was wrong).


Re: What is the proper way to outline static-if-conditions ?

2021-10-10 Thread Elmar via Digitalmars-d-learn

On Sunday, 10 October 2021 at 15:15:51 UTC, drug wrote:
It would be nice if one could use pattern-matching for it in 
D. Is this possible?




As I know it's impossible, but you can use a regular template:
...


If anyone is interested in pattern matching, someone provides a 
package "dpmatch" which uses PEG (some parsing grammer which is 
implemented in D) to achieve Haskel-style pattern matching, yet 
for sum-type definitions only. And they use GC + interfaces. 
Hence it cannot be used with BetterC.


Sumtypes can also be created with the `sumtype` package which 
uses D's delegate literals for pattern matching.


Re: What is the proper way to outline static-if-conditions ?

2021-10-10 Thread Elmar via Digitalmars-d-learn

On Sunday, 10 October 2021 at 15:15:51 UTC, drug wrote:


As I know it's impossible, but you can use a regular template:
```d
template isPointedStaticArray(T)
{
static if (isPointer!T)
enum isPointedStaticArray = 
isStaticArray!(PointerTarget!T);

else
enum isPointedStaticArray = false;
}
```
https://run.dlang.io/is/lR7feP
this compiles from 2.086.1 and above


That's indeed close to pattern matching and is probably the best 
answer :-) .


Re: What is the proper way to outline static-if-conditions ?

2021-10-10 Thread drug via Digitalmars-d-learn

On 10.10.2021 18:01, Elmar wrote:


Well, I just wondered why your code would compile and mine wouldn't. The 
`version(all)` variant will not compile on my computer with `rdmd` 
because `PointerTarget` only allows pointers.


It depends on compiler version. This variant is compiled on version 
2.092.1 and above




But the 2nd one will compile. The `is()` expression catches the 
compilation error which is nice. This is sufficient:


```d
enum isPointedStaticArray(T) = is(PointerTarget!T : P[N], P, size_t N);
```

It would be nice if one could use pattern-matching for it in D. Is this 
possible?


```d
 enum isPointedStaticArray(X : P*, P) = 
.isStaticArray!(PointerTarget!X);

 enum isPointedStaticArray(X : else) = false;
```



As I know it's impossible, but you can use a regular template:
```d
template isPointedStaticArray(T)
{
static if (isPointer!T)
enum isPointedStaticArray = isStaticArray!(PointerTarget!T);
else
enum isPointedStaticArray = false;
}
```
https://run.dlang.io/is/lR7feP
this compiles from 2.086.1 and above


Re: What is the proper way to outline static-if-conditions ?

2021-10-10 Thread Elmar via Digitalmars-d-learn

On Sunday, 10 October 2021 at 15:01:17 UTC, Elmar wrote:


```d
enum isPointedStaticArray(T) = is(PointerTarget!T : P[N], P, 
size_t N);

```

```d
	enum isPointedStaticArray(X : P*, P) = 
.isStaticArray!(PointerTarget!X);

```



`isStaticArray` is a good example that makes me ask how to 
outline an `is()` expression without losing the error catching 
semantics of the inlined `is()` expression.




Re: What is the proper way to outline static-if-conditions ?

2021-10-10 Thread Elmar via Digitalmars-d-learn

On Sunday, 10 October 2021 at 14:36:50 UTC, Elmar wrote:

On Sunday, 10 October 2021 at 14:08:13 UTC, drug wrote:

You just need to check if T is a pointer:
```D
import std;

alias DA = int[];
alias SA = int[3];

alias PSA = SA*;
alias PDA = DA*;

version(all)
	enum isPointedStaticArray(T) = isPointer!T && 
isStaticArray!(PointerTarget!T);

else
	enum isPointedStaticArray(T) = isPointer!T && 
is(PointerTarget!T : P[N], P, size_t N);  // this way you can 
get array length


static assert(!isPointedStaticArray!DA);
static assert(!isPointedStaticArray!SA);
static assert(!isPointedStaticArray!PDA);
static assert( isPointedStaticArray!PSA);

void main()
{
}
```
https://run.dlang.io/is/qKdx1D

Also you can use another way to detect static array - it can 
be useful if you need to get its length


Wow, this is a fine solution. I gonna use it, thank you :-) .


Well, I just wondered why your code would compile and mine 
wouldn't. The `version(all)` variant will not compile on my 
computer with `rdmd` because `PointerTarget` only allows pointers.


But the 2nd one will compile. The `is()` expression catches the 
compilation error which is nice. This is sufficient:


```d
enum isPointedStaticArray(T) = is(PointerTarget!T : P[N], P, 
size_t N);

```

It would be nice if one could use pattern-matching for it in D. 
Is this possible?


```d
	enum isPointedStaticArray(X : P*, P) = 
.isStaticArray!(PointerTarget!X);

enum isPointedStaticArray(X : else) = false;
```



Re: What is the proper way to outline static-if-conditions ?

2021-10-10 Thread Elmar via Digitalmars-d-learn

On Sunday, 10 October 2021 at 14:08:13 UTC, drug wrote:

You just need to check if T is a pointer:
```D
import std;

alias DA = int[];
alias SA = int[3];

alias PSA = SA*;
alias PDA = DA*;

version(all)
	enum isPointedStaticArray(T) = isPointer!T && 
isStaticArray!(PointerTarget!T);

else
	enum isPointedStaticArray(T) = isPointer!T && 
is(PointerTarget!T : P[N], P, size_t N);  // this way you can 
get array length


static assert(!isPointedStaticArray!DA);
static assert(!isPointedStaticArray!SA);
static assert(!isPointedStaticArray!PDA);
static assert( isPointedStaticArray!PSA);

void main()
{
}
```
https://run.dlang.io/is/qKdx1D

Also you can use another way to detect static array - it can be 
useful if you need to get its length


Wow, this is a fine solution. I gonna use it, thank you :-) .


Re: What is the proper way to outline static-if-conditions ?

2021-10-10 Thread drug via Digitalmars-d-learn

You just need to check if T is a pointer:
```D
import std;

alias DA = int[];
alias SA = int[3];

alias PSA = SA*;
alias PDA = DA*;

version(all)
	enum isPointedStaticArray(T) = isPointer!T && 
isStaticArray!(PointerTarget!T);

else
	enum isPointedStaticArray(T) = isPointer!T && is(PointerTarget!T : 
P[N], P, size_t N);  // this way you can get array length


static assert(!isPointedStaticArray!DA);
static assert(!isPointedStaticArray!SA);
static assert(!isPointedStaticArray!PDA);
static assert( isPointedStaticArray!PSA);

void main()
{
}
```
https://run.dlang.io/is/qKdx1D

Also you can use another way to detect static array - it can be useful 
if you need to get its length




Re: What is a "comma expression"?

2021-10-10 Thread rempas via Digitalmars-d-learn

On Sunday, 10 October 2021 at 12:19:39 UTC, Adam D Ruppe wrote:

On Sunday, 10 October 2021 at 12:01:33 UTC, rempas wrote:

[...]


The comma expression in C is a combination of two things but in 
the context of another thing. Well that's not very good, but 
like there's statements and expressions. Statements do 
something but do not have a value. So `if() {}` and `return` 
and `for() {}` are statements, because they don't have a value 
you can assign to a variable.


[...]


Thanks a lot for the detailed explanation! Have a nice day!


Re: What is a "comma expression"?

2021-10-10 Thread rempas via Digitalmars-d-learn

On Sunday, 10 October 2021 at 12:13:47 UTC, Elmar wrote:


Hello rempas.

The comma-operator `,` is like `;` but results in an expression 
value, not a statement like `;` would. The left side of `,` is 
executed like a statement and the value of the right side of 
`,` is returned. Comma-expressions are merely used to pack 
additional instructions into places where only expressions are 
allowed.


[...]


Thanks, that's the second time you are helping me today!


Re: What is the proper way to outline static-if-conditions ?

2021-10-10 Thread Elmar via Digitalmars-d-learn
PS: the title is a misnomer. `is(T : P*, P) && isStaticArray!P` 
doesn't either compile when inlined because `P` is not defined 
when not matched.


What is the proper way to outline static-if-conditions ?

2021-10-10 Thread Elmar via Digitalmars-d-learn

Hey D people.

Currently in my project I have worked on a unified type interface 
for all arrays which requires fixed-size arrays to be stored as 
pointer (in correspondence to dynamic and associative arrays) and 
allow them being allocated with any selected allocator.


There can be code like this:

```d
enum isPointedStaticArray(T) = (is(T : P*, P) && 
.isStaticArray!P);


//...
static if (.isPointedStaticArray!T)
{
// ...
}
```

It won't compile when the argument of `isPointedStaticArray()` is 
NO pointer.


The compiler complains, about **`P` being undefined**.

What is the best workaround for this?
It's crazy. I can reverse the problem that it only fails if the 
argument IS a pointer:


```d
enum isPointedStaticArray(T) =
(){
		enum condition = `is(`~T.stringof~` : P*, P) && 
.isStaticArray!P`;

static if (__traits(compiles, mixin(condition)) )
return mixin(condition);  // "P already defined" error
else
return false;
}();
```

Types defined in `__traits(compiles, ...)` are emitted to the 
outside?!


Okay, this is my current workaround:

```d
enum isPointedStaticArray(T) =
(){
static if (is(T : P*, P))
return .isStaticArray!(P);
else
return false;
}();

// ...
static if (isPointedStaticArray!T)
{

}
```

for outlining an expression `is(...) && ...`


Is there a simpler way in D to do this? If there only would be a 
`&&&` short circuit operator which doesn't compile the right side 
if the left side wouldn't compile to true.


Did someone already had the idea of a `static-try-catch` which 
catches compilation errors?


Re: What is a "comma expression"?

2021-10-10 Thread Adam D Ruppe via Digitalmars-d-learn

On Sunday, 10 October 2021 at 12:01:33 UTC, rempas wrote:

return *ret = v, 1;


The comma expression in C is a combination of two things but in 
the context of another thing. Well that's not very good, but like 
there's statements and expressions. Statements do something but 
do not have a value. So `if() {}` and `return` and `for() {}` are 
statements, because they don't have a value you can assign to a 
variable.


Expressions do something but DO have a value and thus you can 
assign it to a variable.


a = if (true) { a } ; // not permitted because if is a statement

a = 5 + 4; // OK, 5+4 is an expression and thus has a value


This is a slight simplification but generally true. You'll notice 
in some languages the if assign does work; in those languages you 
have an if expression rather than an if statement.


The language grammar has rules for where statements are allowed 
and where expressions are allowed and you can't mix and match 
(unless the grammar has two rules, one allowing each type).



Anyway, the C comma expression is a combination of two other 
expressions where the first one is evaluated, but its value 
discarded, then the second part becomes the value of the whole 
expression.


a = 1, 2; // the 1 is discarded, so a == 2


It is actually the same as writing out:

1; // evaluate this then discard it
a = 2; // eval this and actually keep the value


The difference being that it is allowed in an expression context.


So that `return *ret = v, 1;`

Could just be written

*ret = v; // this is eval'ed and value discarded
return 1; // second part value is kept


And idk why they didn't just do that here. But the C thing is 
most commonly seen in a for loop:


for(a = 0, b = 0; a < 5; a++, b++) {}


because the grammar only allows an expression in each piece of 
the for loop, so you can't separate the two steps by semicolons 
like you do in different contexts.


Can someone explain what comma expressions are and why they 
don't work in D (or if the only doesn't work as returned values 
from a function)?


D considers it a bit obscure and special-case to use the comma 
for. There was talk a while ago about making the comma do 
something else instead, but this never materialized.


But you can always write it out longer form, perhaps wrapping it 
in a function.


// what I would do here:
*ret = v;
return 1;

// or if you absolutely had to have it in an expression context:

return (){ *ret = v; return 1; }();


The nested function there explicitly does what the comma operator 
does and is allowed in expression context as well.


Re: What is a "comma expression"?

2021-10-10 Thread Elmar via Digitalmars-d-learn

On Sunday, 10 October 2021 at 12:01:33 UTC, rempas wrote:
This is the first time I'm finding something like that. I'm 
having the following code in C:


```
  if (0 == (i >> 7)) {
if (len < 1) return -1;
v = i;
return *ret = v, 1;
  }
```

This is part of a function that returns an `int`. When I'm 
running this in C, it works. However in D, I'm getting the 
following error message:


```
Error: Using the result of a comma expression is not allowed
```

Can someone explain what comma expressions are and why they 
don't work in D (or if the only doesn't work as returned values 
from a function)?


Hello rempas.

The comma-operator `,` is like `;` but results in an expression 
value, not a statement like `;` would. The left side of `,` is 
executed like a statement and the value of the right side of `,` 
is returned. Comma-expressions are merely used to pack additional 
instructions into places where only expressions are allowed.


```d
if (x = y, myNiceFunction(), yay(x), x > 5)
{
   // ...
}
```

or

```d
if (hasFancyFunkyStuff)
x = z, fancy(x), funkyUpdate(z);   // too lazy for braces
```

Many consider the `,` operator to be a design-flaw because it 
makes expressions difficult to read and can be easily abused 
because the above should actually be:


```d
x = y;
myNiceFunction();
yay(x);
if (x > 5)
{
// ...
}
```

In `D` you can still write the second example of code but not the 
first example of code. The designers of D thought they could make 
it less painful by just forbidding comma-expressions to be used 
as expression value and only as statement. This is because then 
comma-expressions can still be used in `for`-loops:


```d
for (x = y, z = a; x < z; x++, z--)
{
;
}
```

In conclusion, your C snippet should actually look like:

```c
  if (0 == (i >> 7))
  {
if (len < 1)
  return -1;
*ret = v = i;
return 1;
  }
```

The previous snippet even could mislead readers to think that it 
would return a tuple of two elements which it doesn't.


What is a "comma expression"?

2021-10-10 Thread rempas via Digitalmars-d-learn
This is the first time I'm finding something like that. I'm 
having the following code in C:


```
  if (0 == (i >> 7)) {
if (len < 1) return -1;
v = i;
return *ret = v, 1;
  }
```

This is part of a function that returns an `int`. When I'm 
running this in C, it works. However in D, I'm getting the 
following error message:


```
Error: Using the result of a comma expression is not allowed
```

Can someone explain what comma expressions are and why they don't 
work in D (or if the only doesn't work as returned values from a 
function)?


Re: Modules ... "import" vs. "compilation" ... what is the real process here?

2021-09-28 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/28/21 1:59 AM, james.p.leblanc wrote:

On Tuesday, 28 September 2021 at 05:26:29 UTC, Ali Çehreli wrote:

On 9/27/21 10:38 AM, james.p.leblanc wrote:




In addition to what Mike Parker said, templates do complicate matters 
here: Templates are instantiated (i.e. compiled for a specific set of 
template arguments) by modules that actually use those templates.





Ali, this is great! ...I had been tempted to also ask about how templates
figure into this, but realized that including this in my question would be
over complicating the question, so it remained unasked.

But, now I have this part answered as well.  I very much appreciate the
mind-reading tricks going on here on the forum!



Be aware that the compiler might not include the code for the template 
in the instantiating module if it detects that the instantiation could 
already have been generated in an imported module (not one passed on the 
command line).


For example, if Ali's module `a` contained an alias:

```d
module a;

auto doubled(T)(T value) {
   return value * 2;
}

alias doubleInt = doubled!int;
```

Now the compiler might say "hey, a.d already has instantiated that one, 
and it's not being built by me, so I'll assume it has already generated 
the code" and doesn't do it.


-Steve


Re: Modules ... "import" vs. "compilation" ... what is the real process here?

2021-09-27 Thread james.p.leblanc via Digitalmars-d-learn

On Tuesday, 28 September 2021 at 05:26:29 UTC, Ali Çehreli wrote:

On 9/27/21 10:38 AM, james.p.leblanc wrote:




In addition to what Mike Parker said, templates do complicate 
matters here: Templates are instantiated (i.e. compiled for a 
specific set of template arguments) by modules that actually 
use those templates.



Ali


Ali, this is great! ...I had been tempted to also ask about how 
templates
figure into this, but realized that including this in my question 
would be

over complicating the question, so it remained unasked.

But, now I have this part answered as well.  I very much 
appreciate the

mind-reading tricks going on here on the forum!

Thank You, and Best Regards,
James




Re: Modules ... "import" vs. "compilation" ... what is the real process here?

2021-09-27 Thread james.p.leblanc via Digitalmars-d-learn

On Tuesday, 28 September 2021 at 02:05:43 UTC, Mike Parker wrote:

On Monday, 27 September 2021 at 17:38:29 UTC, james.p.leblanc
mpilations".



Does that help?


**Yes!...**
===
 ... this helped immensely!


This explanation gave me a much better understanding of how the
whole process works.

Mike, thanks very much for the time and thought you put into this.

Best Regards,
James







Re: Modules ... "import" vs. "compilation" ... what is the real process here?

2021-09-27 Thread Ali Çehreli via Digitalmars-d-learn

On 9/27/21 10:38 AM, james.p.leblanc wrote:

> I have trouble understanding "module imports" vs. "module compilations".

In addition to what Mike Parker said, templates do complicate matters 
here: Templates are instantiated (i.e. compiled for a specific set of 
template arguments) by modules that actually use those templates.


So, if no non-template definition is used from a module, that module 
need not appear separately on the build line.


For example, 'module a' defines just a function template:

```
module a;

auto doubled(T)(T value) {
  return value * 2;
}
```

The main module imports 'a' and uses and instantiation of a template 
from that module:


```
module main;

import a;

void main() {
  assert(42.doubled == 84);
}
```

The build line may be confusing because in this case a.d need not appear 
on the build line:


$ dmd main.d

Everything works because the compilation of instance doubled!int is 
compiled when compiling main.d and the linker happily finds all symbols 
that are called in the program.


Ali



Re: Modules ... "import" vs. "compilation" ... what is the real process here?

2021-09-27 Thread Mike Parker via Digitalmars-d-learn
On Monday, 27 September 2021 at 17:38:29 UTC, james.p.leblanc 
wrote:

Dear D-ers,

I have trouble understanding "module imports" vs. "module 
compilations".


A module is implemented in a source file. Though we often use the 
term "module" to refer to both, it may help to think in terms of 
importing modules and compiling source files.


Given the source files `A.d` and `B.d`, which implement the 
modules A and B respectively, and given that module A uses 
symbols from module B, then we can say the following:


1. When the compiler is compiling `A.d`, it must be aware of 
which symbols from module B are accessible from module A. This is 
what imports are for and has no relation to the compilation 
status of `B.d`.
2. The compiler will produce a `A.o/obj` object file that it will 
then pass to the linker,  including references to the symbols in 
module B. At that point, the linker will also need an object file 
from a compiled `B.d` in order to fix up the symbol references 
and produce the final executable.


To achieve #1, the compiler needs to read either the source file 
`B.d` or a D interface file, `B.di`, in order to know which 
symbols are available to module A. There are a couple of ways 
this can happen:


```
dmd A.d B.d
```

Here, when the compiler encounters `import B` in `A.d`, it will 
recognize that `B.d` has been passed on the command line. If 
`B.d` has no module statement, then the file name `B` is used as 
the module name. If it has a module statement, it the file can be 
named anything when it's passed on the command line like this. It 
could be `foo.d`, but as long as it has a `module B` at the top, 
then `A.d` can `import B`.


```
dmd -c A.d
```

Here, when the compiler encounters `import B` in `A.d`, it will 
see that no `module B` declaration has been encountered in any 
other files on the command line, so it will search for `B.di` 
and, if it's not found, `B.d` on the import path (to which we can 
append directories with `-I`). I've included `-c` here, which 
will just compile `A.d` and not attempt to link it, because 
without it the linker will spew errors for every missing symbol 
from module B.


This is how D supports separate compilation. Assuming object 
files with the `.obj` extension on Windows, you could do this:


```
dmd -c B.d
dmd A.d B.obj
```

Now, the compiler uses the source of `B.d` to assess symbol 
accessibility as before, and it will pass both `A.obj` and 
`B.obj` to the linker to produce the executable.


Or you could compile `B.d` into `B.lib` and pass that on the 
command line as well.




Finally, there have been discussions about allowing new ways of 
"compiling a module" by including its name on the command line. 
 For example this from 2017:


https://forum.dlang.org/post/tcrdpvqvwxffnewzo...@forum.dlang.org


This is what resulted in the `-i` compiler switch. Modifying the 
example above:


```
dmd -i A.d
```

Now, when the compiler encounters `import B` in `A.d`, if there 
is no `B.di` and it finds `B.d`, it will compile `B.d` alongside 
`A.d`, just as if the command line had been `dmd A.d B.d`.


Does that help?




Modules ... "import" vs. "compilation" ... what is the real process here?

2021-09-27 Thread james.p.leblanc via Digitalmars-d-learn

Dear D-ers,

I have trouble understanding "module imports" vs. "module 
compilations".


For example, in the dlang.org/tour, we have:

**"The import statement makes all public functions and types from 
the given module available."**


And from the dlang.org/spec we have:

**"Modules are always compiled at global scope and are unaffected 
by surrounding attributes or other modifiers."**


Finally, there have been discussions about allowing new ways of 
"compiling a module" by including its name on the command line.  
For example this from 2017:


https://forum.dlang.org/post/tcrdpvqvwxffnewzo...@forum.dlang.org

The more I look into this, the more that I realize that I do not 
understand this as well as I had hoped.


So, when we specify the module name on the command line, then it 
gets compiled along with the other files on the command line 
(seems reasonable).


But, if it is NOT a command line argument, then when does it get 
compiled??
(I believe that at first cut, only the public functions and types 
are "grabbed").


But, when and how are the subsequent and necessary module 
compilation (and linking) steps performed?


Finally, we use a "-I" for telling dmd to look for imports in a 
directory, but why only
"look for imports", and not "grab anything from there that is 
used, AND compile them"?


(This question is prompted by some recent desires to use ldc and 
"fastmath"... which, if I
understand correctly, will require me to include all of the 
related modules on the command
line for immediate compilation).  But, in a broader sense, I need 
to understand the related issues better.


Thank for all responses, as well as continued patience with my 
questions.


Best Regards,
James




Re: What is the meaning of @future ?

2021-09-18 Thread Ali Çehreli via Digitalmars-d-learn

On 9/18/21 1:27 AM, evilrat wrote:

> IIRC they went out of business for inability to compete

Yes, but not Sociomantic but Dunhumby[1], who had acquired Sociomantic, 
shut down that business because of changes in the ad market.


Ali



Re: What is the meaning of @future ?

2021-09-18 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/18/21 7:49 AM, Steven Schveighoffer wrote:

add buys


"ad buys" of course :P

-Steve


Re: What is the meaning of @future ?

2021-09-18 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/18/21 4:02 AM, Dylan Graham wrote:

On Friday, 17 September 2021 at 14:37:29 UTC, Meta wrote:

On Friday, 17 September 2021 at 10:31:34 UTC, bauss wrote:

On Thursday, 16 September 2021 at 20:53:34 UTC, Elmar wrote:

[...]


It's just another "useless" attribute that the language has added 
before fixing any of the real problems :)


Basically it reserves a symbol for the future.

It's similar to creating ex. an empty function that throws an error 
or something like "Not implemented"


While I understand why it was added and what purpose it serves then I 
fail to see why that  was prioritized over actual issues.


It's solving an almost non-existing issue.


I think the main reason it was added is because Sociomantic asked for 
it, but they are of course not around anymore.


Off topic: what happened to them, out of curiosity?


Google changed the rules for add buys. Which either killed their 
business model, or made them far less competitive than they were originally.


-Steve


Re: What is the meaning of @future ?

2021-09-18 Thread evilrat via Digitalmars-d-learn
On Saturday, 18 September 2021 at 08:02:13 UTC, Dylan Graham 
wrote:

On Friday, 17 September 2021 at 14:37:29 UTC, Meta wrote:

On Friday, 17 September 2021 at 10:31:34 UTC, bauss wrote:

On Thursday, 16 September 2021 at 20:53:34 UTC, Elmar wrote:

[...]


It's just another "useless" attribute that the language has 
added before fixing any of the real problems :)


Basically it reserves a symbol for the future.

It's similar to creating ex. an empty function that throws an 
error or something like "Not implemented"


While I understand why it was added and what purpose it 
serves then I fail to see why that  was prioritized over 
actual issues.


It's solving an almost non-existing issue.


I think the main reason it was added is because Sociomantic 
asked for it, but they are of course not around anymore.


Off topic: what happened to them, out of curiosity?


IIRC they went out of business for inability to compete OR it was 
consumed by a another advertising company, there was a thread on 
a forum from Sonke about that event.


Re: What is the meaning of @future ?

2021-09-18 Thread Dylan Graham via Digitalmars-d-learn

On Friday, 17 September 2021 at 14:37:29 UTC, Meta wrote:

On Friday, 17 September 2021 at 10:31:34 UTC, bauss wrote:

On Thursday, 16 September 2021 at 20:53:34 UTC, Elmar wrote:

[...]


It's just another "useless" attribute that the language has 
added before fixing any of the real problems :)


Basically it reserves a symbol for the future.

It's similar to creating ex. an empty function that throws an 
error or something like "Not implemented"


While I understand why it was added and what purpose it serves 
then I fail to see why that  was prioritized over actual 
issues.


It's solving an almost non-existing issue.


I think the main reason it was added is because Sociomantic 
asked for it, but they are of course not around anymore.


Off topic: what happened to them, out of curiosity?


Re: What is the meaning of @future ?

2021-09-17 Thread Meta via Digitalmars-d-learn

On Friday, 17 September 2021 at 10:31:34 UTC, bauss wrote:

On Thursday, 16 September 2021 at 20:53:34 UTC, Elmar wrote:

Hello D community.

I was browsing the `__traits` keywords and I found `isFuture` 
whose descriptions says something about `@future`-annotated 
variables.


[link](https://dlang.org/spec/traits.html#isFuture)

I didn't find anything about `@future` for the D programming 
language. I only found that this annotation is used in Apex to 
denote futures (a.k.a. promises) as programming concept.


Is this something which exists, existed, was abandoned early 
as an idea? I remember I had read that D uses a "fiber" 
library to provide coroutines and such.


Maybe somebody knows an answer for this.


It's just another "useless" attribute that the language has 
added before fixing any of the real problems :)


Basically it reserves a symbol for the future.

It's similar to creating ex. an empty function that throws an 
error or something like "Not implemented"


While I understand why it was added and what purpose it serves 
then I fail to see why that  was prioritized over actual issues.


It's solving an almost non-existing issue.


I think the main reason it was added is because Sociomantic asked 
for it, but they are of course not around anymore.


Re: What is the meaning of @future ?

2021-09-17 Thread bauss via Digitalmars-d-learn

On Thursday, 16 September 2021 at 20:53:34 UTC, Elmar wrote:

Hello D community.

I was browsing the `__traits` keywords and I found `isFuture` 
whose descriptions says something about `@future`-annotated 
variables.


[link](https://dlang.org/spec/traits.html#isFuture)

I didn't find anything about `@future` for the D programming 
language. I only found that this annotation is used in Apex to 
denote futures (a.k.a. promises) as programming concept.


Is this something which exists, existed, was abandoned early as 
an idea? I remember I had read that D uses a "fiber" library to 
provide coroutines and such.


Maybe somebody knows an answer for this.


It's just another "useless" attribute that the language has added 
before fixing any of the real problems :)


Basically it reserves a symbol for the future.

It's similar to creating ex. an empty function that throws an 
error or something like "Not implemented"


While I understand why it was added and what purpose it serves 
then I fail to see why that  was prioritized over actual issues.


It's solving an almost non-existing issue.


  1   2   3   4   5   6   7   8   9   10   >