Re: struct initializer

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

On Wednesday, 29 November 2023 at 16:48:09 UTC, Paul Backus wrote:

... it even supports named arguments:


- Witch version of DMD supports named arguments?  Is it an 
experimental compiler option?







Re: interface inference

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

On Tuesday, 28 November 2023 at 15:46:18 UTC, Paul Backus wrote:

On Thursday, 23 November 2023 at 19:17:20 UTC, Antonio wrote:
Basically, the ternary conditional ```?:``` result type is not 
inferred even if the type returned by the two possibilities 
are the same.


**Is it a bug or the expected behaviour?**


Known bug, first reported in 2009: 
https://issues.dlang.org/show_bug.cgi?id=3543


Thanks Paul (again :-) )

Oh my!!!

I wrote this question ```"On Thursday, 23 November 2023 at 
19:17:20 UTC, Antonio wrote:"```


And the original bug was ```Reported: 	2009-11-23 03:24 UTC by 
nfxjfg ```


***The same date :-)... 14 years before***



Re: interface inference

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

On Tuesday, 28 November 2023 at 14:10:30 UTC, Dom DiSc wrote:

On Tuesday, 28 November 2023 at 11:01:14 UTC, Antonio wrote:

```d
I aOrB(bool check){
  if(check)
return new A();
  else
return new B();
}
```

**Is it the expected behaviour for ternary conditional?**


Here the compiler knows what type to return (from the function 
signature).

But the ternary operator doesn't know this,


Why?... ternary operators should deduce returning type the same 
way


need to be of the same type (or implicitly convert to a common 
type).


It is a common type: the ```I``` interface.

In fact, if you use  ```abstract class``` instead 
```interface```, it works:


```d
abstract class I { bool check(); }
class A : I { override bool check() =>true; }
class B : I { override bool check() =>false;}

I aOrB(bool check) => check ? new A() : new B();

void main()
{
  assert( aOrB(true).check );
}
```

Why ternary operator accepts covariance rules applied to base 
class, but not applied to interface?



About cast(I)... it allows "illegal" castings causing runtime 
segmentation faults if not used carefully:


```d
class X { string xname() =>"I'm x"; }
class Y { string yname() =>"I'm y"; }
void main(){
  (cast(Y) new X()).yname;  // Runtime segmentation fault
}
```

This is another good reason to avoid using cast when possible.




Re: interface inference

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

On Thursday, 23 November 2023 at 19:17:20 UTC, Antonio wrote:

```d
interface I {
bool check();
}
class A : I {
bool check() =>true;
}
class B : I {
bool check() =>false;
}

I aOrB(bool check) => check ? new A() : new B();

void main()
{
  assert( aOrB(true).check );
}
```

Compiler error:

```d
x.d(11): Error: cannot implicitly convert expression `check ? 
new A : new B` of type `object.Object` to `x.I`

```



I'm forced to explicitly write the cast this way

```d
I aOrB(bool check) => check ? cast(I) new A() : cast(I) new B();
```

But it is not necessary when I write same code using 
if/else/return statements


```d
I aOrB(bool check){
  if(check)
return new A();
  else
return new B();
}
```


**Is it the expected behaviour for ternary conditional?**




Re: interface opEquals

2023-11-27 Thread Antonio via Digitalmars-d-learn
On Saturday, 25 November 2023 at 01:15:34 UTC, Alexandru Ermicioi 
wrote:

On Friday, 24 November 2023 at 17:39:10 UTC, Antonio wrote:

...


Dunno if this might help, but I noticed that `==` sometimes 
calls `opEquals(const Object) const` instead of overload 
defined on class/interface, you might try and override it as 
well, and delegate to your overload that deals directly with 
`IOpt`.


Best regards,
Alexandru.


Thangs Alexandru,

It works.

...but why?


Why this compiles?

2023-11-26 Thread Antonio via Digitalmars-d-learn
In this example,  ```a``` and ```b``` vars are not of the same 
type and don't implement the same interface.  **why 
```assert(a==b)``` compiles?**



```d
interface IOpt(T) {
  bool opEquals(const IOpt!T) const @safe pure;
}

class None(T) : IOpt!T {
  bool opEquals(const IOpt!T other) const @safe pure => true;
}

void main() {
  auto a = new None!int();
  auto b = new None!string();

  assert(a==b);
}
```





Re: interface opEquals

2023-11-24 Thread Antonio via Digitalmars-d-learn
On Thursday, 23 November 2023 at 21:52:56 UTC, Jonathan M Davis 
wrote:


I'd have to take the time to study your code in detail to see 
whether what exactly you're seeing makes sense or not ...



My apologies... I should have proposed a more specific example.

```d
interface IOpt {  bool opEquals(IOpt other) const @safe pure;  }

class None : IOpt { bool opEquals(IOpt other) const @safe pure => 
true; }


void main() {
  None
a = new None(),
b = new None();

  IOpt
a2 = a,
b2 = b;

  assert(a == b);
  assert(a2 == a);
  assert(b2 == b);
  assert(a2 == b2); // fails!!!
}

```



== on classes results in the free function, opEquals, in 
object.d being called. That function does a variety of checks 
such as checking whether either reference is null (to avoid 
dereferencing null) and using is to compare the address of the 
class references first (to avoid calling the class' opEquals if 
both references are to the same object). It also makes sure 
that both rhs.opEquals(lhs) and lhs.opEquals(rhs) are true for 
== to be true to avoid subtle bugs that can come into play when 
comparing a base class against a derived class.


https://github.com/dlang/dmd/blob/master/druntime/src/object.d#L269



Replacing ```interface``` by ```abstract class``` removes the 
problem.  But I have not enough D knowledge to discover why 
interface version is not working



Thanks
Antonio





Re: Doubt about type Inference on templates

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

On Wednesday, 22 November 2023 at 19:37:58 UTC, Paul Backus wrote:

This is a bug/limitation in the compiler. I couldn't find an 
existing report on issues.dlang.org, so I've reported it myself 
as [issue 24255][1].


Wow: It is a very concise bug example.

I tested with ```ldc``` ant it fails too.



For now, I think the best way to work around it is to specify 
the type in the lambda, as in `(int i) => i%2 == 0`.


agreed



The reason you see `void` is that when the compiler cannot 
figure out the type of a function literal, it treats it as a 
template function:


```d
static assert(__traits(isTemplate, i => i % 2 == 0));
```

And for silly historical reasons, when the compiler tries to 
determine the type of a template, it returns `void` instead of 
giving an error:


```d
template example() {}
static assert(is(typeof(example) == void)); // what??
```


Thanks Paul!!!





interface opEquals

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

```d
interface IOpt(T)
{
  T value();
  bool empty();
  bool opEquals(IOpt!T other);
}

class None(T) : IOpt!T
{
  bool empty() => true;
  T value(){ throw new Exception("None has not a value"); }
  bool opEquals(IOpt!T other)=>other.empty;
}

class Some(T) : IOpt!T
{
  this(T value)  { this._value = value; }
  bool empty() => false;
  T value()=> _value;
  bool opEquals(IOpt!T other)=>!other.empty && 
other.value==_value;


  private T _value;
}

IOpt!T some(T)(T v)=>new Some!T(v);
IOpt!T none(T)()=>new None!T;

void main()
{
  assert(new Some!int(1) == new Some!int(1));
  assert(new None!int == new None!int);
  assert(none!int.opEquals(none!int));
  assert(none!int == none!int);
}
```

It compiles, but last assertion ```assert(none!int == 
none!int);``` fails


```
core.exception.AssertError@testiface.d(33): Assertion failure
```

To avoid "extrange effects" I test an alternative equality that 
fails too:


```d
  assert( (cast (IOpt!int) new None!int) == (cast (IOpt!int) new 
None!int));

```

What seems strange to me is that 
```none!int.opEquals(none!int)``` works properly.


**Questions**

* Why, when applied to interface, ```opEquals``` called directly 
behavior is not the same that when calling ```==``` ?


* Is it the expected behaviour?



interface inference

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

```d
interface I {
bool check();
}
class A : I {
bool check() =>true;
}
class B : I {
bool check() =>false;
}

I aOrB(bool check) => check ? new A() : new B();

void main()
{
  assert( aOrB(true).check );
}
```

Compiler error:

```d
x.d(11): Error: cannot implicitly convert expression `check ? new 
A : new B` of type `object.Object` to `x.I`

```

Basically, the ternary conditional ```?:``` result type is not 
inferred even if the type returned by the two possibilities are 
the same.


**Is it a bug or the expected behaviour?**



Doubt about type Inference on templates

2023-11-22 Thread Antonio via Digitalmars-d-learn
Just for fun, I'm trying to implement an alternative base library 
to avoid template/mixin/static/traits code with only one 
objective:  make "intelliSense" code analyzers tasks easier.


I need "Generics"... but D has not generics:  I use templates in 
the "simplest" possible way


I.E.:
```d
interface IIterable(T)
{
  bool empty();
  void popFront();
  T front();
}

IIterable!S toIterable(S)(S[] source)
  => new ArrayIterable!S(source);
IIterable!S filter(S)(IIterable!S source, bool delegate(S item) 
predicate)

  => new Filter!S(source, predicate);
IIterable!S filter(S)(S[] source, bool delegate(S item) predicate)
  => toIterable(source).filter(predicate);
// ...

```

Then, in main.d I do
```d
import std.stdio;
void main(){
  
[1,2,3,4,5,6].toIterable!int.filter!int(i=>i%2==0).map!int(i=>i*2).toArray.writeln();

}

```

It works properly... until I remove the ```!int``` from the 
```filter``` method.


```
main.d(3,38): Error: none of the overloads of template `filter` 
are callable using argument types `!()(IIterable!int, void)`
iterable.d(21,13):Candidates are: `filter(S)(IIterable!S 
source, bool delegate(S item) predicate)`
iterable.d(23,13):`filter(S)(S[] source, 
bool delegate(S item) predicate)`

```

Basically, it doesn't know witch version of ```filter``` to use, 
because it is inferring `i=>i%2==0` is `void` ?!?!?!


```
!()(IIterable!int, void)
```

If I explicitly write `(int i)=>i%2==0`, it compiles correctly 
again.


**Is it mandatory to explicitly tell that `S` is `int` when 
```IIterable!S source``` is  `IIterable!int` alredy?**












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 Antonio via Digitalmars-d-learn

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

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


`writeln()` should do it.


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


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


```d
import std.stdio;

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

  auto getNext = createCounter(10);

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

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

}
```

The output is

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

 ```


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


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


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

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


Syntactically I dont see any difference:

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

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

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


```d
import std.stdio;

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

}
```

Will output that createCounter is a delegate:

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

```


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


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


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


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


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






Re: What is :-) ?

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

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

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


If you execute

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

It shows the Counter address:

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

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


I propose a simple change:

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

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

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

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


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







```


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: how to assign multiple variables at once by unpacking array?

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

On Sunday, 8 October 2023 at 06:02:14 UTC, Jonathan M Davis wrote:



The problem is that the compiler needs to be able to verify 
that the types match, and when the return type of a function is 
a dynamic array such as int[], it has no way of knowing how 
many elements the array has and therefore can't verify at 
compile time that the assignment will work. add a runtime check 
to verify that the number of elements match, but that's not the 
sort of thing that you typically do with a statically typed 
language.



I agree.


And solutions like "algebraic types" used by typescript are not 
applicable to D (You cant declare int|undefined)


```typescript
const sorted=([first,...xs]:T[]):T[] =>  first===undefined ? 
[] : [
  ...sorted(xs.filter(x=> x<=first )), first, ...sorted( 
xs.filter(x=> x > first))

];

console.log( sorted([1,2,3,4,-1,-2,-3]) );
```

But it should with pattern matching

```D
auto sorted(T)(T[] entries) =>
  match(entries) {
case [item, ...others] => ...
otherwise => []
  }
```

Or with overloading (patter matching expressions on function 
signature... similar to haskell)


```D
auto sorted(T)(T[] [item, ...others]) => ...;
auto sorted(T)(T[] []) => [];
```

Well, not really:  because compiler can't predict witch "sorted" 
version will be called on compile time.  (May be it should be a 
syntax suggar of an unique sorted method with match in the body)




However, while there are some benefits to being able to do 
this, the response by many programmers from statically typed 
languages is that it's cleaner to create a struct for this sort 
of thing


I completly agree

, since then the values are contained together, and they have 
names associated with them (since they'll be member variables 
of the struct). So, while some programmers definitely want 
tuple types to be built into D, a number of others don't like 
the idea. As such, it's an open question whether we'll ever 
have such tuples in D.


Destructuring is only a **Syntax sugar** applicable to well known 
types (i.e. Structs).  It is not related (exclusively) with 
tuples:


The type of a function call (or a parameter) is perfectly known.

Typescript applies destructuring based on type matching (type 
members names):


```typescript

type ICounter = {
  inc: ()=>void
  dec: ()=>void
  value: ()=>number
}


function Counter(n:number=0):ICounter {
  return {
inc: ()=>{ n++ };
dec: ()=>{ n-- }
value: ()=> n;
  }
}

const {inc,value} = Counter();
inc();
inc();
console.assert( value() === 2 );
inc();
console.assert( value() === 3 );

```

It could be portable with Structs in D.

Personally, I found it is specially useful with parameters for 
"dependencies injection":


```typescript
function CarsDAO( {db:{ withTransaction }, logger:{ info }}: 
IContext ):ICarsDao {

  return {
createCar,
updateCar
  }

  function createCar(data:CarDto):Promise {
info("Lets create a car");
return withTransaction( trx=> trx.executeQuery("insert . 
returning key") );

  }

}

const context:IContext = {
  logger: Singleton(logger),
  db: Singleton(Db),
  carsDao: Singleton(CarsDao),
}

(async ({ carsDAO:{ createCar }, logger }:IContext)=>{
  data:CarDTO = { registration: "ASD1232", model: "Citroën XS" };
  const key = await createCar( data )
  logger.info( `Car ${key} has been registered`);
})(context);

```
This kind of destructuring is semantically rich.

Note: The "hard" part for this kind of solutions (dependency 
injection not based on classes) is the clousures management, and 
D solves it magnificently...



Either way, the unpacking of dynamic arrays likely stands no 
chance whatsoever of ever being added, > because it would 
require runtime checks to determine whether the unpacking was 
valid.


This is what pattern matching, some day, at runtime, should solve 
:-)



-- Antonio


Re: My programs issues

2022-08-12 Thread Antonio via Digitalmars-d-learn

On Wednesday, 10 August 2022 at 13:13:20 UTC, Adam D Ruppe wrote:

On Wednesday, 10 August 2022 at 12:36:42 UTC, pascal111 wrote:
1) I used "exit()" from "core.stdc.stdlib;" module, but 
someone can say this isn't the D way to exit the program.


It is better to simply return a value from main instead.

2) I used "goto", I heard from someone before that using 
"goto" isn't good programming feature.


Don't listen to people who are wrong.


"goto" is a bad "structured programming" feature, but not a bad 
programming feature.





Re: BASIC "sgn" function equivalent

2022-07-28 Thread Antonio via Digitalmars-d-learn

On Thursday, 28 July 2022 at 15:03:34 UTC, H. S. Teoh wrote:

Just use the source, Luke!  Phobos is open source for a reason.


https://github.com/dlang/phobos/blob/8280b1e7de6cca4dc9a593431591054a5b3aa288/std/math/traits.d#L694


T


:-)

```d
// @@@TODO@@@: make this faster
```



Re: BASIC "sgn" function equivalent

2022-07-28 Thread Antonio via Digitalmars-d-learn

On Thursday, 28 July 2022 at 12:13:31 UTC, Antonio wrote:




Use isFloating!T and isIntegral!T traits.

The standard library **sng** function is a good example:

https://dlang.org/library/std/math/traits/sgn.html


```d
import std.traits : isFloatingPoint, isIntegral;

int sgn(T)(T x) if (isFloatingPoint!T || isIntegral!T)
{
  if(x<0)
return -1;
  else if(x>0)
return 1;
  else
return 0;
}

void main()
{
   import std.stdio;

   writeln(sgn(-1234));
   sgn(-1213.32).writeln;
   1234.sgn.writeln;
}
```


Re: BASIC "sgn" function equivalent

2022-07-28 Thread Antonio via Digitalmars-d-learn

On Thursday, 28 July 2022 at 12:02:54 UTC, pascal111 wrote:
I'm making an equivalent of "sgn" function of BASIC language, 
and I used "(T)" in its definition, but the function can 
receive wrong data by passing string data to it, how we can 
solve it?



Use isFloating!T and isIntegral!T traits.

The standard library **sng** function is a good example:

https://dlang.org/library/std/math/traits/sgn.html


Re: null == "" is true?

2022-07-20 Thread Antonio via Digitalmars-d-learn

On Wednesday, 20 July 2022 at 13:35:14 UTC, Kagamin wrote:

On Tuesday, 19 July 2022 at 18:05:34 UTC, Antonio wrote:
In a relational database, `NULL` is not the same that `""`... 
and `NULL` is not the same that `0`.  Are semantically 
different and there are database invariants (like foreign 
keys) based on it.   Trying to "mix" this concepts in a 
database is a mistake.


So, it's an implementation detail or a relational database that 
leaks into business logic because nobody thought about it? Just 
because a relational database has many features, it doesn't 
mean business logic must use them all, it must use only what 
makes sense for business logic.


It is not about "so many fetaures"... it is about entity model 
and how relational database stores it.   General purpose 
programming languages include their own representation to the 
NULL concept that is not "relational model" dependent:  Optional, 
Maybe, Nullable, Union types


What semantics your domain models implement? Is it semantics of 
all features of a relational database or is semantics of 
business logic?


Database is an **strict repository**:  it stores the entity model 
with relational semantics including strict invariant management 
(primary keys, foreign keys, field types, nullablility, ...) and 
following normalization rules (3th normal form, at least).  It 
is, basically, a "consistent" model.


Business logic **trust on database repository invariants** and 
implements whatever your Business Model require (i.e.:  complex 
model operations involving multiple repository operations).  
Business works using Objects/Entities of the domain and it is 
required a way to map this to relational model (ORM or manual 
SQL)... Usually in a specific "Data" or "DAO" layer.  
Transactions are your friend (The only way to ensure that high 
level invariants are enforced)


If you can't be confident with database invariants (because you 
are using NoSQL repository like MongoDB or DynamoDB or an Old 
ISAM MySQL or "trash" models over relational engine) then you 
need to "move" all these "consistency" control to the business 
layer developing workflows/processes that must be ready to work 
with "inconsistent" data...  (You can read this article I wrote 2 
years ago about SQL/NoSQL solutions and Brewer's conjecture: 
https://qr.ae/pvklQA)



Business "architecture" based on a single repository is the 
simplest one...  But the pleasure of trusting on a relational 
database is always welcome.


Re: null == "" is true?

2022-07-20 Thread Antonio via Digitalmars-d-learn

On Tuesday, 19 July 2022 at 16:55:39 UTC, Kagamin wrote:


As I understand, in your scenario there's no difference between 
null string and empty string, they both work like empty string, 
and D treats them as empty string. That's what I mean when I 
said that distinction between null and empty is meaningless.



Sorry Kagamin... I dindn't read this comment and I added a very 
large answer to the next one that has no sense :-p. I miss being 
able to delete answers from the forum :-)


**Yes... I decided to treat the same way internally** for strings.

Previously

*  `DtoVal!(Null, string)( null)` was equivalent to 
`DtoVal!(Null,string)( Null() )`
*  `DtoVal!(Null, Person)( null)` was equivalent to 
`DtoVal!(Null,string)( Null() )`


Currently

* `DtoVal!(Null, string)( null )` is equivalent to 
`DtoVal!(Null,string)( "" )`;
* For other types this will raise a runtime exception:  
`DtoVal!(Null, Person)( null )`.

  * The correct way of is `DtoVal!(Null, Person)( Null() )`

Basically, **`null` is completely useless and out of my code** 
with the exception of strings.



Best regards
Antonio


Re: null == "" is true?

2022-07-19 Thread Antonio via Digitalmars-d-learn

On Tuesday, 19 July 2022 at 17:05:27 UTC, Kagamin wrote:

Also what's the difference between null and empty phone number?



In a relational database, `NULL` is not the same that `""`... and 
`NULL` is not the same that `0`.  Are semantically different and 
there are database invariants (like foreign keys) based on it.   
Trying to "mix" this concepts in a database is a mistake.


When you treat with Domain Models, you try to represent this 
semantics in all levels of your software... including APIs


If your address has not a reference to the city... then there is 
a `city_code` field with `NULL` value in your database and the 
Address model object has a city property representing this Null 
value with the tools that language/library offers to you:  
`Nullable!City` or `Sumtype!(Null, City)` or `Optional` or 
...).


`Null` is then a valid value state that has nothing related to 
*`null` pointers*... to avoid confusion, I talk about `Null` 
instead `null`.


I, personally, prefer to use Union types (algebraic types) like   
`int | Null | ...` because it is the best option to introduce the 
Undefined state (that allows statically typed data to represent 
the absence of a property).


`Sumtype!(Undefined,Null,int)`  instead  `Optional!(Nullable!int)`

Then there is the `match!` syntax, the unified way to treat JSON 
serialization and the easy way to implement a custom "dot" 
accessor that propagates the Null or Undefined state in a chain 
of references:


```d
person.ns.address.ns.city.ns.name.match!(
  (string name){ ... }
  (Null) {...}
  (Undefined) { ... }
)

```






Re: null == "" is true?

2022-07-19 Thread Antonio via Digitalmars-d-learn

On Tuesday, 19 July 2022 at 08:10:25 UTC, Kagamin wrote:

On Monday, 18 July 2022 at 21:23:32 UTC, Antonio wrote:
I will study it in detail and report (if required). May be, I 
will write the DTO problem with D article if I find time in 
august.


In my experience null and empty in DTOs usually play the same 
logical role. It's a very contrived technical difference 
without practical usage, such distinction is way beyond any 
business logic. Even if you implement this distinction, I'm not 
sure anybody will carefully pay attention to it. In languages 
that make difference between null and empty, null is often 
replaced with empty to work around problems with null, such 
codebase can't properly preserve null values.



When you have to "patch" information partially (i.e.: update only 
the name and the phonenumber, but not the birthdate) or you must 
return in a REST partial information (because graphql or custom 
REST) there is only 2 ways to represent this "possible missing 
properties"


* Maps (key->value) or similiar (i.e.:JSon objects):  You can 
include or not keys in the map:  If you don't want to update the 
birthdate, don't include the birthdate key in the DTO.


* Structs (or any kind of structured data that can be validated 
at compile time):  There is no possibility to say that some 
properties of the struct can be not present... Well, you can if 
you begin to manage Algebraic Types (Union types):   `height:  
int | undefined`


NULL is not the same that UNDEFINED

The distintion is really important:  NULL is a valid value (i.e.: 
The person phonenumber is NULL in database)... Of course, you can 
represent this concept natively in you language (Nullable, 
Optional, Maybe ...) but it is not the same that UNDEFINED... 
because UNDFINED says "This property has not been assigned to 
DTO... do not take it into account".


The summary is that a DTO that works like a Map needs to 
represent the absent key ant this is not the same that the Null 
value


Example:
```d
struct Null { /*...*/ }
struct Undefined { /*...*/ }
struct ContactDto {
 DtoVal!(Undefined, string) name
 DtoVal!(Undefined, Null, string) phonenumber,
 DtoVal!(Undefined, AddressDto) address
}
// ...
ContactDto data = {phonenumber:Null(), 
address:{city:{code:"BCN"}}};

updateContact(id, data);

```





Re: null == "" is true?

2022-07-18 Thread Antonio via Digitalmars-d-learn

On Monday, 18 July 2022 at 17:20:04 UTC, Kagamin wrote:
... If you want such difference, use the Nullable wrapper or 
Algebraic.


I do :-)  In fact, I use algebraic types supporting Null and 
Undefined for DTOs representation (and REST APIs).  But I 
discovered some "rare" side effects in libraries like vibe.d and 
structs where, sometimes, am empty string is deserialized as null 
(value is null) and I have to assume that null in an string is 
always "" for avoiding this weird effects


I'm under pressure to meet deadlines and a team that is telling 
me "Why D instead typescript, Antonio?"... One month ago I 
reported some questions in forums or git repos... but I have to 
finish my work and 2 hours stoppers are not acceptable now.


I will study it in detail and report (if required). May be, I 
will write the DTO problem with D article if I find time in 
august.








Re: null == "" is true?

2022-07-12 Thread Antonio via Digitalmars-d-learn

On Tuesday, 12 July 2022 at 20:36:03 UTC, Antonio wrote:
Honestly, it is difficult to understand for newcomers... there 
is a reason, but there is a reason in javascript for `0 == ''` 
too


Correction

```d
string a = null;
assert(a is null);
assert(a == "");

string b = "";
assert(b !is null);
assert(b == null);
```



Re: null == "" is true?

2022-07-12 Thread Antonio via Digitalmars-d-learn

On Tuesday, 12 July 2022 at 18:56:43 UTC, Paul Backus wrote:

On Tuesday, 12 July 2022 at 16:40:38 UTC, H. S. Teoh wrote:
Because an empty string is, by default, represented by an 
empty slice of the null pointer.


Do not rely on this, however; it's possible sometimes to get 
an empty string that isn't null, e.g., if you incrementally 
shrink a slice over a string until it's empty. In that case, 
.ptr will not be null, but the string will still be empty.  
Always compare strings against "" rather than null, because 
the latter may not do what you think it does sometimes.


This is actually 100% reliable when comparing with the `==` 
operator because two empty strings always compare equal with 
`==`, regardless of what they point to.


string s = "hello";
string empty1 = s[0 .. 0];
string empty2 = s[1 .. 1];
assert(empty1 == null);
assert(empty2 == null);
assert(empty1 == empty2);

The real problem is that `s == null` looks like it does one 
thing (test for a null pointer) while actually doing something 
slightly different (test for an empty string).



Then:

```d
string a = null;
assert(a is null);
assert(a == "");

string b = "");
assert(b !is null);
assert(b == "");

```

Honestly, it is difficult to understand for newcomers... there is 
a reason, but there is a reason in javascript for `0 == ''` too


null == "" is true?

2022-07-12 Thread Antonio via Digitalmars-d-learn

It works

```d
void main()
{
   assert(null=="");
}
```

why?


vibe.d Serialize/Deserialize SumType to/from json

2022-07-04 Thread Antonio via Digitalmars-d-learn

D offers `SumType` struct to manage tagged Union types.

But there is no support for managing it's Json 
serialization/deserialization (using vibe.d)


Is it a way to add `fromRepresentation` and `toRepresentation` to 
`SumType` (or a way for creating a custom struct "inheriting" 
SumType with serialization capabilities)?


Thank you for advanced.



Re: How to check if something can be null

2022-07-01 Thread Antonio via Digitalmars-d-learn

On Friday, 1 July 2022 at 15:35:00 UTC, Adam D Ruppe wrote:

On Friday, 1 July 2022 at 13:48:25 UTC, Antonio wrote:
I has been using this pattern each time something needs 
special treatment when it can be null:


i'd prolly check `static if(is(typeof(null) : T))` which means 
if the null literal implicitly converts to type T.


Perfect!!!  Thanks Adam.


there's also the bludgeon __traits(compiles, v is null) too lol



love it X-) !!!  may be this is the Swiss knife I was waiting 
for...




Re: How to check if something can be null

2022-07-01 Thread Antonio via Digitalmars-d-learn

On Friday, 1 July 2022 at 13:48:25 UTC, Antonio wrote:

-Why?


I realized Json is an struct (not an object)... and I supose, it 
is managing null asignation manually (as a way to build 
Json(null)).



-Whats the correct whay to test if something can be null?


That's my question :-p





How to check if something can be null

2022-07-01 Thread Antonio via Digitalmars-d-learn
I has been using this pattern each time something needs special 
treatment when it can be null:


```d
void doSomething(T)(T v)
{
  import std.traits: isAssignable;
  static if( isAssignable!(T, typeof(null))) {
if(v is null)
  writeln("This is null");
else
  writeln("This is not null");
  } else {
writeln("This can't be null");
  }
}
```

and then

```d
void main(){
  // output: This is null
  doSomething!string(null);
  // output: This is not null
  doSomething("Hello");
  // output: This can't be null
  soSomething!int(1);
}
```

Problem appears with `vibe-d` `Json`.

```d
void main(){
  doSomething!Json(null);
}
```
Compiler outputs

`Error: incompatible types for `(v) is (null)`: `Json` and 
`typeof(null)`


-Why?
-Whats the correct whay to test if something can be null?


Re: int | missing | absent

2022-06-27 Thread Antonio via Digitalmars-d-learn
On Monday, 27 June 2022 at 23:05:46 UTC, Steven Schveighoffer 
wrote:

On 6/27/22 9:03 AM, Antonio wrote:
On Wednesday, 22 June 2022 at 01:09:22 UTC, Steven 
Schveighoffer wrote:

On 6/2/22 9:24 AM, bauss wrote:

I feel it's too loose to make a best effort, and leave the 
rest up to initial values, or just ignore possibly important 
information during parsing.




May be for your case Steve.

I need to represent in a "typed" way complex structures where 
some properties can be "undefined" (not present in json) and 
where null value is a valid value (and not the same that 
"undefined" ones)... basically,  the algebraic type Undefined 
| Null | T


I see what you are saying. What needs to happen is first, you 
need a type wrapper that does this, which defaults to 
undefined. Then mark it optional so it's OK if it doesn't 
appear. Then only if the field is not present will it be marked 
as undefined.


It may even be useful to make the type wrapper itself always 
optional, rather than having to mark it optional.




Exactly.

This issue/example in vibe-d treats about this solution and the 
annoying change of behavior treating "null" when @optional 
attribute is present:


https://github.com/vibe-d/vibe.d/issues/2673

The code is a "simplification" of something more complex (Special 
wrappers for **Null | T**, **Undefined | T**  and  **Undefined | 
Null | T**  with some functional stuff for match! and null-safe 
access (well, trying to:  It's really complex and I'm not enought 
experienced).


I Tried to base my solution in SumType, but I didn't know how to 
add the required fromRepresentation/toRepresentation methods for 
custom serialization/deserialization...





Re: int | missing | absent

2022-06-27 Thread Antonio via Digitalmars-d-learn
On Monday, 27 June 2022 at 23:05:46 UTC, Steven Schveighoffer 
wrote:

...
Maybe you can provide an example, and there may be a solution 
that you haven't thought of.


-Steve


I first posted this "issue" to vibe-d:

https://github.com/vibe-d/vibe.d/issues/2673


Re: int | missing | absent

2022-06-27 Thread Antonio via Digitalmars-d-learn
On Wednesday, 22 June 2022 at 01:09:22 UTC, Steven Schveighoffer 
wrote:

On 6/2/22 9:24 AM, bauss wrote:

I feel it's too loose to make a best effort, and leave the rest 
up to initial values, or just ignore possibly important 
information during parsing.


-Steve


May be for your case Steve.

I need to represent in a "typed" way complex structures where 
some properties can be "undefined" (not present in json) and 
where null value is a valid value (and not the same that 
"undefined" ones)... basically,  the algebraic type Undefined | 
Null | T


It isinefficient in memory terms (because D offers only 
"structs", not the Typescript object equivalent where properties 
accepts to be not present nativelly as part of the type 
definition)


But it is, in my opinion, a needed feature:  What if you want to 
"patch" an entity or query an entity requiring only some of the 
properties?... I don't want to build results using Json 
objects... D is typed language and results should be built in a 
rich typed structure (like:   {id:"1324123", name:"peter", 
age:18} or {id:"1234123", age:18 } **validated by compiler**.


When implementing rich REST services (with some complexity), 
undefined native management is a must (and not the same than null 
management).


I am currently using vibe-d json and the way it manages @optional 
forces me to write custom serialization for all entities (to 
properly manage undefined vs null)... it is anoying!!!







Re: Static Initialization of Structs syntax

2022-06-22 Thread Antonio via Digitalmars-d-learn

On Wednesday, 22 June 2022 at 09:41:55 UTC, Antonio wrote:

I'm so sorry, I know that the above example doesn't work:

```d

main(){
  Struct PersonDTO {
string name;
string surname;
  }

  void create(PersonDTO personData){
   // ...
  }
  create( {name: "Peter", surname: "Ustinov"} );

}

```

-Is it there any alternative to initialize "inline" de struct 
(using the name:value syntax for the properties) without 
declaring an intermediate variable?


Thanks
Antonio


I see now:  DIP 1033 will solve this (i.e., using named arguments 
in struct constructor...  similar to how dart/flutter works)


Static Initialization of Structs syntax

2022-06-22 Thread Antonio via Digitalmars-d-learn

I'm so sorry, I know that the above example doesn't work:

```d

main(){
  Struct PersonDTO {
string name;
string surname;
  }

  void create(PersonDTO personData){
   // ...
  }
  create( {name: "Peter", surname: "Ustinov"} );

}

```

-Is it there any alternative to initialize "inline" de struct 
(using the name:value syntax for the properties) without 
declaring an intermediate variable?


Thanks
Antonio


Re: int | missing | absent

2022-06-21 Thread Antonio via Digitalmars-d-learn

On Thursday, 2 June 2022 at 13:24:08 UTC, bauss wrote:

On Thursday, 2 June 2022 at 08:27:32 UTC, Antonio wrote:

JSON properties can be
- a value
- null
- absent

What's the standard way to define a 
serialziable/deserializable structs supporting properties of 
any of this 4 kinds?:


* int
* int | null
* int | absent
* int | null | absent


Whats the best library to manage this JSON requirements? (all 
the 4 cases)?



Thanks


null and absent should be treated the same in the code, it's 
only when serializing you should define one or the other, if 
you need to have null values AND absent values then attributing 
accordingly is the solution.




The main problem is when you need to use DTO struct that 
"patches" data (not all the data) and absent vs null 
discrimination is really mandatory.


A good approximation could be using SumTypes  (what in Typescript 
or Scala is named Union Types...), an incredible example of D 
template power that could be used in Json 
serialization/deserialization without the need of custom 
properties attributes.


Here an example of how to define DTOs discriminating absent 
(Undefined in javascrip) and null.


i.e.

```d

import std.sumtype: SumType, match;
import std.datetime.date: Date;

void main()
{
  struct Undefined {}
  struct Null {}
  struct PersonPatchDTO {
SumType!(long) id;
SumType!(Undefined, string ) name;
SumType!(Undefined, string, string[]) surname;
SumType!(Undefined, Null, Date) birthday;
SumType!(Undefined, Null, long) partner_id;
  }
  auto patchPerson(PersonPatchDTO patch){
import std.stdio: writeln;
writeln( "Patching person in database ", patch );
  }

  // This should come from a JSON deserialization;
  PersonPatchDTO patch = {
id:12334,
partner_id: Null()
  };
  patchPerson(patch);
}

```

Or the typical upset operation some people love to do
```d
void main(){
  ...
  struct PersonUpsetDTO {
SumType!(Undefined, long) id;
SumType!(Undefined, string ) name;
SumType!(Undefined, string, string[]) surname;
SumType!(Undefined, Null, Date) birthday;
SumType!(Undefined, Null, long) partner_id;
  }
  auto upsetPerson(PersonUpsetDTO patch){
import std.stdio: writeln;
patch.id.match!(
  (long l) => writeln("Updating person with id ", l),
  (_) => writeln("Creating a new person")
);
  }
  ...
}
```

D ha not "union types" native support, but SumType is a nice 
substitution (with some overhead in generated code).


**Problems?**
- It is not the "standard" way expected by D Json 
serializers/deserializers.  It requires a custom one

- May be it's hard to inspect with debugger (I haven't tried yet)


Re: destroy and @safe

2022-06-21 Thread Antonio via Digitalmars-d-learn

On Tuesday, 21 June 2022 at 16:20:32 UTC, Antonio wrote:


My code starts to be a @safe/@trusted mess (because external 
libraries). The only solution I have is to "wrap" them or to 
trust all code by default (I'm using vibe.d that forces @safe 
code)


Only as a comment: I can remember now when dart/flutter 
incorporated "sound null safety" and most of the third-party 
libraries where ported by authors... everybody assumed this 
will be the way of.   D @safe "optional" adoption is a problem


As a personal advice, I would change the scoring system of the 
packages to penalize when they are not "safe"


Reading this I realize that the tone is out of place (especially 
because of the great disinterested effort behind the code of 
these libraries and the level of example they provide to those of 
us who are interested in the language).


My apologies.


Re: destroy and @safe

2022-06-21 Thread Antonio via Digitalmars-d-learn
On Tuesday, 21 June 2022 at 15:14:43 UTC, Steven Schveighoffer 
wrote:


 You delegate doesn't seem to be marked @safe as well.



Thanks a lot Steve,

I didn't found a way (or example) to specify the delegate must be 
@safe until I have found vibe.d.db.postgress implementation (that 
you maintain :-)








Re: destroy and @safe

2022-06-21 Thread Antonio via Digitalmars-d-learn

On Tuesday, 21 June 2022 at 15:13:36 UTC, Paul Backus wrote:

If the destructor is `@system`, then the only way to call 
`destroy` in `@safe` code is to (1) determine the conditions 
necessary to call the destructor without violating memory 
safety, (2) ensure that those conditions are met (using compile 
time and/or runtime checks), and (3) wrap the call to `destroy` 
in a `@trusted` function.


Since step (1) depends on the specific details of the 
destructor you want to call, I can't give any more specific 
advice unless you show a complete example that includes the 
destructor.


Thanks Paul.

The problem appears when destroying a dpq2 query result object 
(not @safe).  I supose I can accept postgres PGClean(result) is 
safe "enought".


My code starts to be a @safe/@trusted mess (because external 
libraries). The only solution I have is to "wrap" them or to 
trust all code by default (I'm using vibe.d that forces @safe 
code)


Only as a comment: I can remember now when dart/flutter 
incorporated "sound null safety" and most of the third-party 
libraries where ported by authors... everybody assumed this will 
be the way of.   D @safe "optional" adoption is a problem


As a personal advice, I would change the scoring system of the 
packages to penalize when they are not "safe"









destroy and @safe

2022-06-21 Thread Antonio via Digitalmars-d-learn
I'm using explicitly destroy!false(obj) for a "deterministic" 
resources release.


I replicate the c# "using" pattern, or the python "with" pattern 
with my own "use" template supposing object are RAII


i.e.:

```d
Item[] items = query("...").use( (Answer a) =>
  a.rangify.map!(rowToItem).array()
);

```

The problem:

"use" can't be @safe because it contains a call to "destroy".

For better understanding of the idea, I include the "use" 
template code


```d
R use(R, T)(T obj, R delegate(T) fT)
{
  scope (exit)
destroy!false(obj);

  return fT(obj);
}
```

What's the way to ensure @safe using destroy? (if possible)


Re: Enforce not null at compile time?

2022-06-20 Thread Antonio via Digitalmars-d-learn

On Monday, 20 June 2022 at 19:08:32 UTC, max haughton wrote:

On Monday, 20 June 2022 at 17:48:48 UTC, Antonio wrote:
Is there any way to specify that a variable, member or 
parameter can't be null?


You can use an invariant if it's a member of an aggregate but 
be warned that these are only checked at the boundaries of 
public member functions.


I'm using preconditions when calling functions

```d
auto readByCredentiasl(CredentialsDTO credentials)
in (credentials !is null)
in (credentias.username !is null)
...
{
 ...
}
```

But it's runtime validation, not formally validated by compiler.


Enforce not null at compile time?

2022-06-20 Thread Antonio via Digitalmars-d-learn
Is there any way to specify that a variable, member or parameter 
can't be null?




Re: UFCS limit

2022-06-17 Thread Antonio via Digitalmars-d-learn

On Friday, 17 June 2022 at 12:26:05 UTC, Antonio wrote:

UFCS vs Functional curring... nice battle :-)


**UFCS & CFTE** vs **Functional currying**... nice battle :-)


Re: UFCS limit

2022-06-17 Thread Antonio via Digitalmars-d-learn

On Friday, 17 June 2022 at 01:04:28 UTC, Paul Backus wrote:

On Thursday, 16 June 2022 at 23:59:06 UTC, Antonio wrote:
Is it there any way to apply UFCS on the returned method in 
the same expression?


Nope. The way UFCS works is that allows you to call free 
functions using member-function syntax, and member-function 
syntax is always `object.memberName`, so UFCS only works for 
functions that have a name, not anonymous functions.


Lets tray with a name :-)

```d
auto doSomething(string text)
{
  return (string text2)
  {
import std.stdio;
writeln(text,",",text2);
  };
}

void main()
{
  auto doHello = doSomething("Hello");
  doHello("X");
  "X".doHello();
}
```

Error:  onlineapp.d(16): Error: no property `doHello` for type 
`string`


It's true... the favomous "Rationale: Local function symbols are 
not considered by UFCS to avoid unexpected name conflicts."  (I 
consider it absurd... but I'n no-one)


Well lets try another possibility taking in account the power of 
CTFE


```d
auto doSomething(string text)
{
  return (string text2)
  {
import std.stdio;
writeln(text,",",text2);
  };
}

auto doHello = doSomething("Hello");

void main()
{
  doHello("X");
  "X".doHello();
}

```

Error: onlineapp.d(3): Error: closures are not yet supported in 
CTFE


:-/

UFCS vs Functional curring... nice battle :-)







UFCS limit

2022-06-16 Thread Antonio via Digitalmars-d-learn

```d
auto doSomething(string text)
{
  return (string text2)
  {
import std.stdio;
writeln(text,",",text2);
  };
}

void main()
{
  doSomething("Hello")("X");
  "X".doSomething("Hello")();
}
```
Compiler error:

```
...
onlineapp.d(13):expected 1 argument(s), not 2
```

I tried with some syntax change:

```d
void main()
{
  doSomething("Hello")("X");
  (doSomething("Hello"))("X"); // it works
  "X".(doSomething("Hello"))(); // fails!!!
}
```

```onlineapp.d(14): Error: identifier or `new` expected following 
`.`, not `(


Is it there any way to apply UFCS on the returned method in the 
same expression?





Re: map! evaluates twice

2022-06-12 Thread Antonio via Digitalmars-d-learn
On Friday, 10 June 2022 at 20:47:14 UTC, Steven Schveighoffer 
wrote:

On 6/10/22 4:33 PM, Antonio wrote:
...

`map` calls the lambda for each call to `front`. If you want a 
cached version, use `cache`:


Thank you very much, Steve



map! evaluates twice

2022-06-10 Thread Antonio via Digitalmars-d-learn
When mapping and filtering, the last mapped element is evaluated 
twice... Is it the expected behaviour?


```d
void main()
{
import std.algorithm, std.stdio;

[1,2,3,4,5].
map!((x){
writeln("mapping ", x);
return x;
}).
filter!(x=>x>2).
front.
writeln();
}
```

Output
```
mapping 1
mapping 2
mapping 3
mapping 3
3

```


Re: Range to Nullable conversion

2022-06-10 Thread Antonio via Digitalmars-d-learn

On Friday, 10 June 2022 at 18:00:20 UTC, Paul Backus wrote:

On Friday, 10 June 2022 at 17:22:53 UTC, Antonio wrote:
Can this code be written as a **simple** expression?  (without 
having to write helper methods).


```d
import std.range, std.typecons;

Nullable!(ElementType!R) maybeFront(R)(auto ref R r)
if (isInputRange!R)
{
if (r.empty)
return typeof(return)();
else
return nullable(r.front);
}

unittest
{
int[] a = [1, 2, 3];
int[] b;

assert(a.maybeFront == nullable(1));
assert(b.maybeFront.isNull);
}
```


Nice (and simple) helper method.

Thank you Paul


Re: Range to Nullable conversion

2022-06-10 Thread Antonio via Digitalmars-d-learn

On Friday, 10 June 2022 at 17:37:13 UTC, Ali Çehreli wrote:

On 6/10/22 10:22, Antonio wrote:
> Is there any alternative to ***range front*** that returns a
Nullable
> (i.e. **frontAsMonad** or **frontAsNullable**)?

import std;

// Spelling? :)
auto nullablelize(R)(R range) {
  ...
}

void main() {
  // Wow! We can take 10 elements without error. :)
  writeln(iota(5)
  .filter!(i => i % 2)
  .nullablelize
  .take(10));
}

Ali


That's cheating :-p... you used a helper method+structure.

Nice example, Thank you Ali.


Range to Nullable conversion

2022-06-10 Thread Antonio via Digitalmars-d-learn
Is there any alternative to ***range front*** that returns a 
Nullable (i.e. **frontAsMonad** or **frontAsNullable**)?


I'm using Vibe.d and Nullable is the standard way to return an 
optional element:


```d
  @safe Nullable!Item getItem(int _id)
  {
import std.algorithm : filter;

with (items.filter!(item => item.id == _id))
{
  if (empty)
return Nullable!Item.init;
  else
return front.nullable;
}
  }
```

Can this code be written as a **simple** expression?  (without 
having to write helper methods).




int | missing | absent

2022-06-02 Thread Antonio via Digitalmars-d-learn

JSON properties can be
- a value
- null
- absent

What's the standard way to define a serialziable/deserializable 
structs supporting properties of any of this 4 kinds?:


* int
* int | null
* int | absent
* int | null | absent


Whats the best library to manage this JSON requirements? (all the 
4 cases)?



Thanks



Re: UFCS doubt

2021-07-08 Thread Antonio via Digitalmars-d-learn

On Thursday, 8 July 2021 at 22:31:49 UTC, Dennis wrote:

On Thursday, 8 July 2021 at 22:24:26 UTC, Antonio wrote:
I supossed  that ```mfp(c,20)``` and ```c.mfp(20)``` should be 
equivalent because UFCS in second example, but it is not... 
why?


UFCS does not work for nested functions.

Functions declared in a local scope are not found when 
searching for a matching UFCS function.

...
Rationale: Local function symbols are not considered by UFCS 
to avoid unexpected name conflicts. See below problematic 
examples.


https://dlang.org/spec/function.html#pseudo-member


Thanks.

I read the example and the assumption of "name conflict" does not 
seem to be justified (from my point of view)


i.e. Without dot notation, this example must fail
```
int front(int[] arr) { return arr[0]; }
void main()
{
int[] a =[1,2,3];
auto front = 1;   // front is now a variable
auto y = front(a);   // Error, front is not a function
}
```
Changing to y = a.front() should not change the behavior (it is 
only a notation change )... but it does!!!

```
int front(int[] arr) { return arr[0]; }
void main()
{
int[] a =[1,2,3];
auto front = 1;   // front is now a variable
auto y = a.front() // NO ERROR!!!
}
```

"It works as described in the manual, not as expected" (from 
MySQL haters club :-p) .




UFCS doubt

2021-07-08 Thread Antonio via Digitalmars-d-learn
In this example (extracted from 
https://digitalmars.com/articles/b68.html), this works:

```
class C {
  int a;
  int foo(int i) { return i + a; }
}

auto mfp = (C self, int i)=>self.foo(i);

void main(){
  auto c = new C;
  assert( c.mfp(20)==20);
}
```

but this fails

```
class C {
  int a;
  int foo(int i) { return i + a; }
}

void main(){
  auto mfp = (C self, int i)=>self.foo(i);
  auto c = new C;
  assert( c.mfp(20)==20);
}
```

onlineapp.d(9): Error: no property `mfp` for type `onlineapp.C`

I supossed  that ```mfp(c,20)``` and ```c.mfp(20)``` should be 
equivalent because UFCS in second example, but it is not... why?





github copilot and dlang

2021-07-05 Thread Antonio via Digitalmars-d-learn
Has someone tried github copilot (https://copilot.github.com/) 
with dlang? Access to the preview could be requested and, I 
think, main dlang team members could bypass the waitlist easily.


I suspect that the "low" volume of dlang code (used to train 
OpenAI) compared to other languages could impact in the support 
(if there is any).  Anyway, it could be really interesting to see 
how Copilot faces templates, traits, ...






Re: Fix gtkD api display

2017-08-11 Thread Antonio via Digitalmars-d-learn

On Thursday, 10 August 2017 at 14:59:52 UTC, Adam D. Ruppe wrote:

On Thursday, 10 August 2017 at 14:55:06 UTC, Mike Wey wrote:

[...]


Oh, I see. My generator lists them on the index, but doesn't 
recreate it each time, it just links. For example:


http://dpldocs.info/experimental-docs/gtk.ApplicationWindow.ApplicationWindow.html

it lists inherited members again, but not all their docs.


[...]


kewl


[...]


It is a lot easier to link to individual pages from the outside 
which means search is more reliable, the back button works, 
stuff like that.


Hi,

The way valadoc.org exposes the docs makes them very easy to read 
and find things (at least for me).


A. Corbi