Re: how to assign multiple variables at once by unpacking array?

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

On Saturday, 7 October 2023 at 07:31:45 UTC, mw wrote:

https://stackoverflow.com/questions/47046850/is-there-any-way-to-assign-multiple-variable-at-once-with-dlang

How to do this Python code in D:
...
...
Is there a better way (since 2017)?


Each programming language has their pros and cons. They all have 
their way of solving the problem. A higher level language, 
generally, allows you to write less code compared to a lower 
level one.


ie - A Python program thats 20 LOC could be 50 LOC in C99 or much 
much more.


The downside to (something like) python is that writing less code 
has its drawbacks. What does it do in background? Can there be a 
huge performance penalty once inside a loop?


D provides you the power of being low level like C, or high level 
that can be comparable in a number of ways to C#. I have a choice 
to turn off the GC, if I want to!


My response to this is, without sounding rude, who cares about 
your example?


- Could D be able to achieve this? Maybe.
- If not, could it in the future? Maybe.
- Would you still have to write an extra line or two compared to 
the Python example? Maybe.


You are just splitting a string to 3 variables as ints.



```

s = "1 2 3"
A,B,C = map(int, s.split(" "))
A,B,C

(1, 2, 3)

```


"What if" s has more than 3 numbers?
"What if" s includes characters?

Python will spit out an error - "not enough values" or "invalid 
literal"


To build reliable code in your example add more LOC.


I can do this in D. May not be the best example. Is stores them 
in int arrays and

handles potentials characters:-

```d
void main()
{
import std.stdio;
import std.array;
import std.string;
import std.algorithm;
import std.conv;

auto s = "1 2 a 3";
auto abc = s.split(' ').map!(s => isNumeric(s) ? s.to!int : 
-1);


writeln(abc);   // [1, 2, -1, 3]
}
```

I will leave it there.



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

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

On Monday, 9 October 2023 at 01:15:21 UTC, Salih Dincer wrote:
the staticMapN() template implemented by Ali Çehreli, which is 
not in the standard library, is needed:




It would be great if the unlimited version was added to std.meta. 
 This template seeded/sprouted in here:


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

SDB@79




Re: how to assign multiple variables at once by unpacking array?

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

On Saturday, 7 October 2023 at 16:12:47 UTC, mw wrote:
Interesting: in terms of easy of coding, clarity and future 
maintenance, which one is superior?


The one liner in Python, or your "solution" with dozen lines of 
code? BTW, is that a solution at all? Did it achieved what the 
original goal asked in the OP question?


So, who should learn from whom?


If you don't expect to do a single line of coding, there are many 
methods in D that can do this kind of thing (but at compile time).


**Your snippet with struct and tupple:**

```d
import std;

struct MyVariables
{
  int age, phone, country;
}

void main()
{
  enum sep = ", ";
  enum str = "21, 3149474, 90";
  enum arr = str.split(sep)
                .map!(x => x.to!int)
.array//*/
;
  alias MrSmith = AliasSeq!(arr[0],
                            arr[1],
                            arr[2]);

  auto mv = MyVariables(MrSmith);
  assert(mv == MyVariables(21, 3149474, 90));
}
```

and **worksheet example:**


```d
import std;

struct DATA(string str, T, size_t s)
{
  enum title = str;
  T[s] data;
}

void main()
{
  alias Columns = AliasSeq!("Stock Name", "PN Codes", "P.Prices");
  alias T = AliasSeq!(string, int, double);
  alias Items = AliasSeq!(4, 8, 8);
  
  staticMapN!(3, DATA, Columns, T, Items) worksheet;
  
  // inputs first column:
  worksheet[0].data = ["capacitor", "transistor", "resistor", 
"varistor"];

  
  // prints column titles:
  foreach(s; worksheet)
    s.title.writef!"%14s";
  
  "=".repeat(42).writefln!"\n%-(%s%)";
  
  // prints first column:
  foreach(name; worksheet[0].data)
    name.writefln!"%14s";
    //...
  "=".repeat(42).writefln!"%-(%s%)";
}/* Prints:
Stock Name  PN Codes  P.Prices
==
 capacitor
transistor
  resistor
  varistor
==
*/
```

By the way, in order for the above code snippet to work, the 
staticMapN() template implemented by Ali Çehreli, which is not in 
the standard library, is needed:


```d
template staticMapN(size_t N, alias fun, args...)
if(args.length % N == 0)
{
  alias staticMapN = AliasSeq!();
  static foreach (i; 0..args.length / N)
  {
static if (N == 1)
{
  staticMapN = AliasSeq!(staticMapN, fun!(
args[i]
      ));}
  
    else static if (N == 2)
{
staticMapN = AliasSeq!(staticMapN, fun!(
args[0..$ / N][i],
args[$ / N..($ / N) * 2][i]
      ));}
  
else static if (N == 3)
{
  staticMapN = AliasSeq!(staticMapN, fun!(
args[0..$ / N][i],
args[$ / N..($ / N) * 2][i],
args[($ / N) * 2..($ / N) * 3][i]
  ));}
  }
}
```
SDB@79




Re: how to assign multiple variables at once by unpacking array?

2023-10-08 Thread mw via Digitalmars-d-learn

On Sunday, 8 October 2023 at 07:45:56 UTC, Andrea Fontana wrote:

On Sunday, 8 October 2023 at 07:44:04 UTC, Andrea Fontana wrote:


```
int a,b,c;

"1,2,3"
.splitter(',')
.zip(only(, , ))
.each!(x => *x[1] = x[0].to!int);

writeln(a, b, c);
```


or:

```
int a,b,c;

only(, , )
.zip("1,2,3".splitter(','))
.each!(x => *x[0] = x[1].to!int);

writeln(a, b, c);
```


Nice.


Re: how to assign multiple variables at once by unpacking array?

2023-10-08 Thread Nick Treleaven via Digitalmars-d-learn

On Saturday, 7 October 2023 at 17:23:40 UTC, ryuukk_ wrote:


there was a DIP for tuple/deconstruction prior to that 
question, sadly nothing came out of it,


I don't think it was formally submitted.


and now the language is frozen...


The DIP process is temporarily suspended, it may be modified. The 
priority for (most of) this year is fixing bugs. However language 
changes do happen, e.g. just this weekend switch can now declare 
a variable in the condition. Atila is working on a DIP for 
editions.


Re: how to assign multiple variables at once by unpacking array?

2023-10-08 Thread Andrea Fontana via Digitalmars-d-learn

On Sunday, 8 October 2023 at 07:44:04 UTC, Andrea Fontana wrote:


```
int a,b,c;

"1,2,3"
.splitter(',')
.zip(only(, , ))
.each!(x => *x[1] = x[0].to!int);

writeln(a, b, c);
```


or:

```
int a,b,c;

only(, , )
.zip("1,2,3".splitter(','))
.each!(x => *x[0] = x[1].to!int);

writeln(a, b, c);
```


Re: how to assign multiple variables at once by unpacking array?

2023-10-08 Thread Andrea Fontana via Digitalmars-d-learn

On Saturday, 7 October 2023 at 07:31:45 UTC, mw wrote:

https://stackoverflow.com/questions/47046850/is-there-any-way-to-assign-multiple-variable-at-once-with-dlang

How to do this Python code in D:

```

s = "1 2 3"
A,B,C = map(int, s.split(" "))
A,B,C

(1, 2, 3)

```

Is there a better way (since 2017)?


Ranges for the win!

```
int a,b,c;

"1,2,3"
.splitter(',')
.zip(only(, , ))
.each!(x => *x[1] = x[0].to!int);

writeln(a, b, c);
```


Re: how to assign multiple variables at once by unpacking array?

2023-10-08 Thread Jonathan M Davis via Digitalmars-d-learn
On Saturday, October 7, 2023 1:31:45 AM MDT mw via Digitalmars-d-learn wrote:
> https://stackoverflow.com/questions/47046850/is-there-any-way-to-assign-mult
> iple-variable-at-once-with-dlang
>
> How to do this Python code in D:
>
> ```
>
> >>> s = "1 2 3"
> >>> A,B,C = map(int, s.split(" "))
> >>> A,B,C
>
> (1, 2, 3)
>
> ```
>
> Is there a better way (since 2017)?

This is the sort of feature that you're much more likely to see in a
dynamically typed language than a statically typed one, and you will almost
certainly never see it in D.

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. At
best, it could 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.

This is in stark contrast to a dynamically typed language where such things
are often done, because everything is already being checked at runtime
anyway, and checking whether the number of elements match then isn't really
any different from checking that the actual types of the variables match
what you're trying to do with them. But statically typed languages expect to
be able to do all of those kinds of checks at compile time, which means that
they're typically not going to do something like convert an array of
arbitrary length to a set of variables like that.

Now, what D might gain the ability to do at some point is to return
language-defined tuples, meaning that you'd be able to do something like

(int, string, float) foo(string bar, int baz)
{
...
return (i * 2, "hello", 2.7 * x);
}

and

(a, b, c) = foo("whatever", 42);

This would work with a statically typed language, because the types are all
known at compile time.

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, 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.

What we do currently have is Tuple and tuple in std.typecons. Tuple allows
you to create a struct with a given set of fields without explicitly
declaring it. e.g.

alias Foo = Tuple!(string, "name", int, "x", int, "y");
foo = Foo("Bob", 12, 22);
assert(foo.name == "Bob");
assert(foo.x == 12);
assert(foo.y == 22);
assert(foo[0] == "Bob");
assert(foo[1] == 12);
assert(foo[2] == 22);

and tuple allows you to create such a struct (without the field names)
simply by calling a function. e.g.

auto foo = tuple("Bob", 12, 22);
assert(foo[0] == "Bob");
assert(foo[1] == 12);
assert(foo[2] == 22);

So, it becomes possible to create a new struct type to return from a
function simply by calling tuple. e.g.

auto doStuff(string str, float f)
{
...
return tuple(x, str[i .. $]);
}

And thanks to some magic in Tuple, you even get unpacking of a sort by using
AliasSeq. E.G.

AliasSeq!(a, b) = doStuff(bar, 2.7);

So, for many programmers, Tuple and tuple from std.typecons are good enough,
and whether we ever get tuples added to the language will largely depend on
whether anyone can come up with a proposal for them that convinces Walter
and Atila that they're worth adding.

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.

- Jonathan M Davis





Re: how to assign multiple variables at once by unpacking array?

2023-10-07 Thread ryuukk_ via Digitalmars-d-learn

On Saturday, 7 October 2023 at 17:23:40 UTC, ryuukk_ wrote:

On Saturday, 7 October 2023 at 07:31:45 UTC, mw wrote:

https://stackoverflow.com/questions/47046850/is-there-any-way-to-assign-multiple-variable-at-once-with-dlang

How to do this Python code in D:

```

s = "1 2 3"
A,B,C = map(int, s.split(" "))
A,B,C

(1, 2, 3)

```

Is there a better way (since 2017)?


You can't, there was a DIP for tuple/deconstruction prior to 
that question, sadly nothing came out of it, and now the 
language is frozen...


Priorities are sadly outside of the language these days..


Tuple DIP in question: 
https://github.com/tgehr/DIPs/blob/tuple-syntax/DIPs/DIP1xxx-tg.md


Re: how to assign multiple variables at once by unpacking array?

2023-10-07 Thread ryuukk_ via Digitalmars-d-learn

On Saturday, 7 October 2023 at 07:31:45 UTC, mw wrote:

https://stackoverflow.com/questions/47046850/is-there-any-way-to-assign-multiple-variable-at-once-with-dlang

How to do this Python code in D:

```

s = "1 2 3"
A,B,C = map(int, s.split(" "))
A,B,C

(1, 2, 3)

```

Is there a better way (since 2017)?


You can't, there was a DIP for tuple/deconstruction prior to that 
question, sadly nothing came out of it, and now the language is 
frozen...


Priorities are sadly outside of the language these days..



Re: how to assign multiple variables at once by unpacking array?

2023-10-07 Thread Sergey via Digitalmars-d-learn

On Saturday, 7 October 2023 at 16:12:47 UTC, mw wrote:
Interesting: in terms of easy of coding, clarity and future 
maintenance, which one is superior?


There is no superior languages. They can successfully co-exist 
and play in different areas.


The one liner in Python, or your "solution" with dozen lines of 
code? BTW, is that a solution at all? Did it achieved what the 
original goal asked in the OP question?


AFAIK No, D doesn’t have this feature (still). But you can write 
some kind of workaround code that will do similar thing, but not 
exactly what you want. Probably solution in SO is the closest one.


Re: how to assign multiple variables at once by unpacking array?

2023-10-07 Thread mw via Digitalmars-d-learn
Interesting: in terms of easy of coding, clarity and future 
maintenance, which one is superior?


The one liner in Python, or your "solution" with dozen lines of 
code? BTW, is that a solution at all? Did it achieved what the 
original goal asked in the OP question?


So, who should learn from whom?


On Saturday, 7 October 2023 at 12:01:07 UTC, Salih Dincer wrote:

On Saturday, 7 October 2023 at 07:31:45 UTC, mw wrote:

https://stackoverflow.com/questions/47046850/is-there-any-way-to-assign-multiple-variable-at-once-with-dlang

How to do this Python code in D:

```

s = "1 2 3"
A,B,C = map(int, s.split(" "))
A,B,C

(1, 2, 3)

```

Is there a better way (since 2017)?


My words to those who come from Python:

If you are making money from Python, please stay there, but if 
you want to learn new things and a modern language, "Welcome to 
D"


and please use Tuples :)

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

struct DICT(C, F, S)
{
  S[C] dict;
  C[F] freq;

  void opAssign(Tuple!(C, F, S) chr) {
dict[chr[0]] = chr[2];
freq[chr[1]] = chr[0];
  }

  string toString() const
  {
import std.array : appender;
import std.algorithm : sort;
import std.format : formattedWrite;

auto r = appender!string;
foreach(f; freq.keys.sort!"a>b") {
  auto key = freq[f];
  r.formattedWrite("(%c) %s, %.1f\n",
key, dict[key], f);
}
return r.data;
  }
}

void main()
{
  alias index = char;
  alias rank = float;
  alias name = string;

  alias Dict = DICT!(index, rank, name);
  alias chr = Tuple!(index, rank, name);

  auto chrs = [ chr(44, 61.3, "Comma"),
chr(34, 26.7, "Doublequote"),
chr(39, 24.3, "Apostrophe"),
chr(45, 15.3, "Hyphen"),
chr(63,  5.6, "Question"),
chr(58,  3.4, "Colon"),
chr(33,  3.3, "Exclamation"),
chr(59,  3.2, "Semicolon")
  ];

  Dict enDict;
  foreach(tup; chrs) //multiple insertion
enDict = tup;

  writeln("Frequency distributions of punctuation marks used in 
English: ");

  enDict = chr(46, 65.3, "Dot"); // single insertion
  enDict.writeln;
}
```

SDB@79





Re: how to assign multiple variables at once by unpacking array?

2023-10-07 Thread Salih Dincer via Digitalmars-d-learn

On Saturday, 7 October 2023 at 07:31:45 UTC, mw wrote:

https://stackoverflow.com/questions/47046850/is-there-any-way-to-assign-multiple-variable-at-once-with-dlang

How to do this Python code in D:

```

s = "1 2 3"
A,B,C = map(int, s.split(" "))
A,B,C

(1, 2, 3)

```

Is there a better way (since 2017)?


My words to those who come from Python:

If you are making money from Python, please stay there, but if 
you want to learn new things and a modern language, "Welcome to D"


and please use Tuples :)

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

struct DICT(C, F, S)
{
  S[C] dict;
  C[F] freq;

  void opAssign(Tuple!(C, F, S) chr) {
dict[chr[0]] = chr[2];
freq[chr[1]] = chr[0];
  }

  string toString() const
  {
import std.array : appender;
import std.algorithm : sort;
import std.format : formattedWrite;

auto r = appender!string;
foreach(f; freq.keys.sort!"a>b") {
  auto key = freq[f];
  r.formattedWrite("(%c) %s, %.1f\n",
key, dict[key], f);
}
return r.data;
  }
}

void main()
{
  alias index = char;
  alias rank = float;
  alias name = string;

  alias Dict = DICT!(index, rank, name);
  alias chr = Tuple!(index, rank, name);

  auto chrs = [ chr(44, 61.3, "Comma"),
chr(34, 26.7, "Doublequote"),
chr(39, 24.3, "Apostrophe"),
chr(45, 15.3, "Hyphen"),
chr(63,  5.6, "Question"),
chr(58,  3.4, "Colon"),
chr(33,  3.3, "Exclamation"),
chr(59,  3.2, "Semicolon")
  ];

  Dict enDict;
  foreach(tup; chrs) //multiple insertion
enDict = tup;

  writeln("Frequency distributions of punctuation marks used in 
English: ");

  enDict = chr(46, 65.3, "Dot"); // single insertion
  enDict.writeln;
}
```

SDB@79


Re: how to assign multiple variables at once by unpacking array?

2023-10-07 Thread bachmeier via Digitalmars-d-learn

On Saturday, 7 October 2023 at 07:31:45 UTC, mw wrote:

https://stackoverflow.com/questions/47046850/is-there-any-way-to-assign-multiple-variable-at-once-with-dlang

How to do this Python code in D:

```

s = "1 2 3"
A,B,C = map(int, s.split(" "))
A,B,C

(1, 2, 3)

```

Is there a better way (since 2017)?


That functionality exists, you just have to put things in 
different places, but there are no more keystrokes:


```
import std;

void main() {
int x;
double y;
string z;

foo(x, y, z);
writeln(x);
writeln(y);
writeln(z);
}

void foo(ref int x, ref double y, ref string z) {
x = 4;
y = 2.6;
z = "hello world";
}
```

Maybe there is an argument for `x, y, z = foo();` but it's not 
that it's easier to read or write. If the goal is to not have to 
specify the types of the variables, it's hard for me to see the 
advantage of


```
auto x, y, z = foo();
```

over returning a struct.