Jump to page: 1 2
Thread overview
how to assign multiple variables at once by unpacking array?
Oct 07, 2023
mw
Oct 07, 2023
Imperatorn
Oct 07, 2023
bachmeier
Oct 07, 2023
Salih Dincer
Oct 07, 2023
mw
Oct 07, 2023
Sergey
Oct 09, 2023
Salih Dincer
Oct 09, 2023
Salih Dincer
Oct 07, 2023
ryuukk_
Oct 07, 2023
ryuukk_
Oct 08, 2023
Nick Treleaven
Oct 08, 2023
Jonathan M Davis
Oct 11, 2023
Antonio
Oct 08, 2023
Andrea Fontana
Oct 08, 2023
Andrea Fontana
Oct 08, 2023
mw
Oct 11, 2023
Martyn
October 07, 2023

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)?

October 07, 2023

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)?

Structs are favored. But I guess tuples? But if you're talking about deconstruction then D doesn't do that for you that way.

October 07, 2023

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.

October 07, 2023

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 :)

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

October 07, 2023

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 :)

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

October 07, 2023

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.

October 07, 2023

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

October 07, 2023

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

October 08, 2023
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



October 08, 2023

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(&a, &b, &c))
        .each!(x => *x[1] = x[0].to!int);

    writeln(a, b, c);
« First   ‹ Prev
1 2