Re: varargs when they're not all the same type?

2024-03-16 Thread Andy Valencia via Digitalmars-d-learn

On Friday, 15 March 2024 at 00:11:11 UTC, Andy Valencia wrote:

(varargs & friends)

Which statement leads me to section 77.2 of "Programming in D", 
and now I am deep into the mechanisms behind what you have very 
kindly shared.  Thank you once more.


As some fruits of my labors here, below is a link to a "fmt" 
module which does C-style formatting.  It supports int/long 
signed/unsigned, right/left padding and zero padding, plus 
strings (w. padding).  It's memory and type safe; I ended up 
using unions to tabulate the arguments as I need to access them 
as an array (rather than walking them--I'm walking the format 
string instead).  It adds 6k to an executable, which means dlang 
will work out fine for all of my smaller scripting needs in the 
future.


Calls look like:

auto s = fmt("%d %u - %20s", 123, 456, "Hi, Mom");

https://sources.vsta.org:7100/dlang/file?name=fmt.d=tip

Comments are welcome!  I'd post here, but it seems a little long 
for that?


Andy



Re: varargs when they're not all the same type?

2024-03-14 Thread Andy Valencia via Digitalmars-d-learn

On Thursday, 14 March 2024 at 23:13:51 UTC, Basile B. wrote:

...
However explicit instantiation can take whatever is known at 
compile time, such as constant expressions or even certain 
static variables. So that is rather called an `alias sequence` 
in D.


Which statement leads me to section 77.2 of "Programming in D", 
and now I am deep into the mechanisms behind what you have very 
kindly shared.  Thank you once more.


Andy



Re: varargs when they're not all the same type?

2024-03-14 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Mar 14, 2024 at 08:58:21PM +, Andy Valencia via Digitalmars-d-learn 
wrote:
> On Thursday, 14 March 2024 at 18:05:59 UTC, H. S. Teoh wrote:
> > ...
> > The best way to do multi-type varags in D is to use templates:
> > 
> > import std;
> > void myFunc(Args...)(Args args) {
> 
> Thank you.  The first parenthetical list is of types, is it not?  I
> can't find anywhere which says what "type" is inferred for "Args..."?
> (gdb pretends like "arg" is not a known symbol.)  Is it basically a
> tuple of the suitable type?
[...]

The first set of parenthesis specify compile-time arguments. The
specification `Args...` means "zero or more types".  So it could be any
list of types, which naturally would be chosen according to the
arguments given. For example, to pass an int and a float, you'd do
something like:

myFunc!(int, float)(123, 3.14159f);

and to pass a string, two ints, and a char, you'd write:

myFunc!(string, int, int, char)("abc", 123, 456, 'z');

Having to specify types manually, of course, is a lot of unnecessary
typing, since the compiler already knows what the types are based on
what you write in the second pair of parentheses.  For this reason,
typical D code will omit the first pair of parentheses (the `!(...)`,
that is, the compile-time arguments) and just let the compiler infer the
types automatically:

myFunc(123, 3.14159f); // compiler figures out Args = (int, float)
myFunc("abc", 123, 456, 'z'); // compiler figures out Args = (string, 
int, int, char)


T

-- 
A program should be written to model the concepts of the task it performs 
rather than the physical world or a process because this maximizes the 
potential for it to be applied to tasks that are conceptually similar and, more 
important, to tasks that have not yet been conceived. -- Michael B. Allen


Re: varargs when they're not all the same type?

2024-03-14 Thread Basile B. via Digitalmars-d-learn

On Thursday, 14 March 2024 at 20:58:21 UTC, Andy Valencia wrote:

On Thursday, 14 March 2024 at 18:05:59 UTC, H. S. Teoh wrote:

...
The best way to do multi-type varags in D is to use templates:

import std;
void myFunc(Args...)(Args args) {


Thank you.  The first parenthetical list is of types, is it 
not?  I can't find anywhere which says what "type" is inferred 
for "Args..."?  (gdb pretends like "arg" is not a known 
symbol.)  Is it basically a tuple of the suitable type?


Andy


Most of the time the variadic template parameters are infered 
from the run time parameters. In that case indeed `Args` will be 
a type tuple of `args` types.


```d
void myFunc(Args...)(Args args) {}
myFunc(0,0.1); // is like the more verbose 
`myFunc!(int,double)(0,0.1)`

```

However explicit instantiation can take whatever is known at 
compile time, such as constant expressions or even certain static 
variables. So that is rather called an `alias sequence` in D.


That being said and with the signature of `myFunc` that will 
effectively only work if `Args` is made of types.


About debugging, each individual runtime arg can be inspected 
using a bit of knowledge of D internals.


![](https://i.imgur.com/XW74nke.png)

As you can see the elements are named following this pattern 
`__param_[0-9]+`.
So with gdb used as CLI, `$ p __param_0` will (爛爛) print the 
first variadic element, and so on.


Re: varargs when they're not all the same type?

2024-03-14 Thread Andy Valencia via Digitalmars-d-learn

On Thursday, 14 March 2024 at 18:05:59 UTC, H. S. Teoh wrote:

...
The best way to do multi-type varags in D is to use templates:

import std;
void myFunc(Args...)(Args args) {


Thank you.  The first parenthetical list is of types, is it not?  
I can't find anywhere which says what "type" is inferred for 
"Args..."?  (gdb pretends like "arg" is not a known symbol.)  Is 
it basically a tuple of the suitable type?


Andy



Re: varargs when they're not all the same type?

2024-03-14 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Mar 14, 2024 at 05:57:21PM +, Andy Valencia via Digitalmars-d-learn 
wrote:
> Can somebody give me a starting point for understanding varadic
> functions?  I know that we can declare them
> 
>   int[] args...
> 
> and pick through whatever the caller provided.  But if the caller
> wants to pass two int's and a _string_?  That declaration won't permit
> it.
> 
> I've looked into the formatter, and also the varargs implementation.
> But it's a bit of a trip through a funhouse full of mirrors.  Can
> somebody describe the basic language approach to non-uniform varargs,
> and then I can take it the rest of the way reading the library.
[...]

The best way to do multi-type varags in D is to use templates:

import std;
void myFunc(Args...)(Args args) {
foreach (i, arg; args) {
writefln("parameter %d is a %s with value %s",
i, typeof(arg), arg);
}
}

void main() {
myFunc(123, 3.14159, "blah blah", [ 1, 2, 3 ], new Object());
}

D also supports C-style varags (without templates), but it's not
recommended because it's not type-safe. You can find the description in
the language docs.


T

-- 
"Maybe" is a strange word.  When mom or dad says it it means "yes", but when my 
big brothers say it it means "no"! -- PJ jr.


Re: varargs when they're not all the same type?

2024-03-14 Thread monkyyy via Digitalmars-d-learn

On Thursday, 14 March 2024 at 17:57:21 UTC, Andy Valencia wrote:
Can somebody give me a starting point for understanding varadic 
functions?  I know that we can declare them


  int[] args...

and pick through whatever the caller provided.  But if the 
caller wants to pass two int's and a _string_?  That 
declaration won't permit it.


I've looked into the formatter, and also the varargs 
implementation.  But it's a bit of a trip through a funhouse 
full of mirrors.  Can somebody describe the basic language 
approach to non-uniform varargs, and then I can take it the 
rest of the way reading the library.


Thanks in advance!
Andy


there are 3 (or 4?) variadic functions
try
```d
auto foo(T...)(T args){
  static foreach(arg;args){
...
```


varargs when they're not all the same type?

2024-03-14 Thread Andy Valencia via Digitalmars-d-learn
Can somebody give me a starting point for understanding varadic 
functions?  I know that we can declare them


  int[] args...

and pick through whatever the caller provided.  But if the caller 
wants to pass two int's and a _string_?  That declaration won't 
permit it.


I've looked into the formatter, and also the varargs 
implementation.  But it's a bit of a trip through a funhouse full 
of mirrors.  Can somebody describe the basic language approach to 
non-uniform varargs, and then I can take it the rest of the way 
reading the library.


Thanks in advance!
Andy