how to assign multiple variables at once by unpacking array?

Antonio antoniocabreraperez at gmail.com
Wed Oct 11 09:32:12 UTC 2023


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=<T>([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<string> {
     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


More information about the Digitalmars-d-learn mailing list