October 08, 2023

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

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

or:

    int a,b,c;

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

    writeln(a, b, c);
October 08, 2023

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.

October 08, 2023

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

    writeln(a, b, c);

or:

    int a,b,c;

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

    writeln(a, b, c);

Nice.

October 09, 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?

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:

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:

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:

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

October 09, 2023
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/vwxilrqgjqtvjrnjjwbt@forum.dlang.org

SDB@79


October 11, 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)

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

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

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

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


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

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

October 11, 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:
...
...
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:-

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.

1 2
Next ›   Last »