Re: Solving the impossible?

2018-08-31 Thread aliak via Digitalmars-d-learn

On Thursday, 30 August 2018 at 21:40:40 UTC, Everlast wrote:

On Thursday, 30 August 2018 at 00:10:42 UTC, Paul Backus wrote:

[...]


This is not true! You claim that I'm making a blanket statement 
about what mathematicians would view then you do the same.


[...]


If ... implies "an arbitrary number of" and you have:

(A...)(A a)
(A)(A a...)

A... = an arbitrary number of types
A a... = an arbitrary number of parameters *typed* as A.

When you have a list of Ts the type is denoted as "T[]". This is 
consistent with D's type system.


Re: Solving the impossible?

2018-08-30 Thread Everlast via Digitalmars-d-learn

On Thursday, 30 August 2018 at 00:10:42 UTC, Paul Backus wrote:

On Wednesday, 29 August 2018 at 22:18:09 UTC, Everlast wrote:
No it is not! you have simply accepted it to be fact, which 
doesn't make it consistent.


If you take 100 non-programmers(say, mathematicians) and ask 
them what is the natural extension of allowing an arbitrary 
number of parameters knowing that A is a type and [] means 
array and ... means an arbitrary number of, they will NOT 
think A[]... makes sense.


Has anyone actually done such a survey? If not, how can you 
possibly be sure what the result will be?


If I'm wrong, then you have to prove why a syntax such as 
bar(int a...) cannot be interpreted singularly in the way I 
have specified.


Of course, there's no inherent reason why `bar(int a...)` 
couldn't be interpreted the way you've specified. But there's 
also no reason why we couldn't use `bar(int... a)`, like Java, 
or `bar(params int[] a)`, like C#, or any of the other syntaxes 
you can see if you visit the Rosetta Code page on variadic 
functions. [1]


All programming languages are artificial. All syntax is 
arbitrary. What feels "natural" to you is not a universal 
truth, but a matter of personal taste and preference. To an 
experienced Scheme programmer, `(foo . args)` probably feels 
more natural than any of the examples I've mentioned. To an 
experienced APL programmer, the entire idea of a separate 
syntax for variadic functions probably sounds ridiculous.


This is not true! You claim that I'm making a blanket statement 
about what mathematicians would view then you do the same.


Not everything in the universe is arbitrary(if so, prove it! ;)

In any case, even if you were right, there is still a partial 
ordering of nationality based on other things that are 
pre-existing.



Personally, I find the most pragmatic approach to be "when in 
Rome, do as the Romans do." So when I'm programming in D, I 
write `foo(int[] a...)`, and when I'm programming in Python, I 
write `foo(*args)`, and when I'm programming in C, I write 
`foo(...)` and `#include `. If your goal is to solve 
actual problems, arguing about syntactic minutiae is a waste of 
time.


This may be true but it also leads to doing what Romans do such 
as wiping their asses which rocks. It is only necessary if you 
don't have anything else but it doesn't mean there isn't a better 
way. The only reason why programing languages allow flaws(that 
then become "Features") is for "backwards compatibility".


To put this to rest: I'll make a D fork where it simply requires 
all characters of the input to be duplicated(so it simply removes 
every other character in the source then passes it to the D 
compiler)...


You wouldn't claim that the fork is fine because "Do as the 
Romans do" logic would you? You would say that it is a pointless 
syntax... Hence, you would think just like I'm thinking about the 
[]. On some meaningless level you can claim the fork is valid, 
but you wouldnn't program in it for obvious reasons.


So, just because [] is a much less obvious issue doesn't change 
the fact that, at least so far since you haven't pointed out any 
valid reasons why it is necessary, that it is the same 
fundamental problem as the D fork described above.


In both cases they are valid syntaxes w.r.t. to the D compiler 
and fork resp. and in both cases they are unnecessary syntaxes 
that offer nothing new and over complicate things. The the only 
reason they seem different is because variadic types are not used 
as often as having to double every character.


Also, we are talking about the semantics of ... and not [] 
ultimately. My point is that by interpreting ... properly there 
is no reason to express [] and that this is a D flaw in over 
complicating the syntax for no good reason.


If we are just talking about what D requires then there is 
nothing to talk about... and that should be obvious.










Re: Solving the impossible?

2018-08-30 Thread Kagamin via Digitalmars-d-learn

On Wednesday, 29 August 2018 at 22:18:09 UTC, Everlast wrote:
If you take 100 non-programmers(say, mathematicians) and ask 
them what is the natural extension of allowing an arbitrary 
number of parameters knowing that A is a type and [] means 
array and ... means an arbitrary number of, they will NOT think 
A[]... makes sense.


A mathematician wouldn't see much difference between different 
types of sequences. D supports the mathematical notion of a 
sequence of duck typed objects in the form of variadic templates:


void f(A...)(A args){...}


Re: Solving the impossible?

2018-08-29 Thread Paul Backus via Digitalmars-d-learn

On Wednesday, 29 August 2018 at 22:18:09 UTC, Everlast wrote:
No it is not! you have simply accepted it to be fact, which 
doesn't make it consistent.


If you take 100 non-programmers(say, mathematicians) and ask 
them what is the natural extension of allowing an arbitrary 
number of parameters knowing that A is a type and [] means 
array and ... means an arbitrary number of, they will NOT think 
A[]... makes sense.


Has anyone actually done such a survey? If not, how can you 
possibly be sure what the result will be?


If I'm wrong, then you have to prove why a syntax such as 
bar(int a...) cannot be interpreted singularly in the way I 
have specified.


Of course, there's no inherent reason why `bar(int a...)` 
couldn't be interpreted the way you've specified. But there's 
also no reason why we couldn't use `bar(int... a)`, like Java, or 
`bar(params int[] a)`, like C#, or any of the other syntaxes you 
can see if you visit the Rosetta Code page on variadic functions. 
[1]


All programming languages are artificial. All syntax is 
arbitrary. What feels "natural" to you is not a universal truth, 
but a matter of personal taste and preference. To an experienced 
Scheme programmer, `(foo . args)` probably feels more natural 
than any of the examples I've mentioned. To an experienced APL 
programmer, the entire idea of a separate syntax for variadic 
functions probably sounds ridiculous.


Personally, I find the most pragmatic approach to be "when in 
Rome, do as the Romans do." So when I'm programming in D, I write 
`foo(int[] a...)`, and when I'm programming in Python, I write 
`foo(*args)`, and when I'm programming in C, I write `foo(...)` 
and `#include `. If your goal is to solve actual 
problems, arguing about syntactic minutiae is a waste of time.


[1] https://rosettacode.org/wiki/Variadic_function




Re: Solving the impossible?

2018-08-29 Thread Everlast via Digitalmars-d-learn

On Wednesday, 29 August 2018 at 21:14:59 UTC, Paul Backus wrote:

On Wednesday, 29 August 2018 at 19:56:31 UTC, Everlast wrote:
One of the things that makes a good language is it's internal 
syntactic consistency. This makes learning a language easier 
and also makes remembering it easier. Determinism is a very 
useful tool as is abstraction consistency. To say "Just except 
D the way it is" is only because of necessity since that is 
the way D is, not because it is correct. (There are a lot of 
incorrect things in the world such as me "learning" D... since 
I've been programming in D on and off for 10 years, I just 
never used a specific type for variadics since I've always use 
a variadic type parameter)


To justify that a poor design choice is necessary is precisely 
why the poor design choice exists in the first place. These 
are blemishes on the language not proper design choices.  For 
example, it is necessary for me to pay taxes, but it does not 
mean that taxes are necessary.


The syntax *is* consistent. In `foo(int[] a...)`, `int[]` is 
the type of the parameter, and `a` is its name. This is 
consistent with how all other function parameters are declared. 
The only difference is in how arguments are bound to that 
parameter. That's what the `...` signifies: that a single 
parameter will accept multiple arguments. It's really quite 
straightforward and orthogonal.


No it is not! you have simply accepted it to be fact, which 
doesn't make it consistent.


If you take 100 non-programmers(say, mathematicians) and ask them 
what is the natural extension of allowing an arbitrary number of 
parameters knowing that A is a type and [] means array and ... 
means an arbitrary number of, they will NOT think A[]... makes 
sense.


... itself already includes the concept of an array(list or 
sequence) so having both [] and ... is either redundant or 
implies a different meaning.



To prove you are wrong in one fell swoop:

Suppose you you want to create a function that takes an arbitrary 
number of arrays of ints, e.g.,


foo([1,2,3], [4,2], [4,5,6,7])
foo([1,2,3])
foo([4,56,64], [4324,43,43], [4,2,2], [4,4,2,4,4,3,4], ...) // 
where ... has a specific mathematical notation(that all people 
familiar with mathematics understands as " continues in the same 
manner").


How is foo defined in the most direct type specified way?

Of course, you will give me the D way, because you assume the D 
way is the correct natural way... simply because you start with 
your conclusion that what D does is the correct and natural way.


The real natural way is:

foo(int[] a...)

but in D we have to do

foo(int[][] a...)

by your logic

Now, the natural way is

foo(int[] a...)

Why?

because bar(int a...) is the natural way to create a function bar 
that accepts an arbitrary(the ... tells us this) of ints)


Why? because bar(int a) would take one int, and bar(int a, int b) 
takes two, and bar(int a, int b, int c) takes three and therefor 
bar(int a...) takes an arbitrary number of ints.


Having to add [] only adds an extra set of symbols that means 
nothing if ... would be correctly interpreted.


If I'm wrong, then you have to prove why a syntax such as bar(int 
a...) cannot be interpreted singularly in the way I have 
specified.


Again, just because D does it this way doesn't mean it is the 
best way.


If you want to start from your conclusion that everything that D 
does is perfectly correct then there is little point in debating 
this...









Re: Solving the impossible?

2018-08-29 Thread Paul Backus via Digitalmars-d-learn

On Wednesday, 29 August 2018 at 19:56:31 UTC, Everlast wrote:
One of the things that makes a good language is it's internal 
syntactic consistency. This makes learning a language easier 
and also makes remembering it easier. Determinism is a very 
useful tool as is abstraction consistency. To say "Just except 
D the way it is" is only because of necessity since that is the 
way D is, not because it is correct. (There are a lot of 
incorrect things in the world such as me "learning" D... since 
I've been programming in D on and off for 10 years, I just 
never used a specific type for variadics since I've always use 
a variadic type parameter)


To justify that a poor design choice is necessary is precisely 
why the poor design choice exists in the first place. These are 
blemishes on the language not proper design choices.  For 
example, it is necessary for me to pay taxes, but it does not 
mean that taxes are necessary.


The syntax *is* consistent. In `foo(int[] a...)`, `int[]` is the 
type of the parameter, and `a` is its name. This is consistent 
with how all other function parameters are declared. The only 
difference is in how arguments are bound to that parameter. 
That's what the `...` signifies: that a single parameter will 
accept multiple arguments. It's really quite straightforward and 
orthogonal.


Re: Solving the impossible?

2018-08-29 Thread vit via Digitalmars-d-learn

On Wednesday, 29 August 2018 at 19:56:31 UTC, Everlast wrote:

On Tuesday, 28 August 2018 at 22:01:45 UTC, Paul Backus wrote:

[...]


One of the things that makes a good language is it's internal 
syntactic consistency. This makes learning a language easier 
and also makes remembering it easier. Determinism is a very 
useful tool as is abstraction consistency. To say "Just except 
D the way it is" is only because of necessity since that is the 
way D is, not because it is correct. (There are a lot of 
incorrect things in the world such as me "learning" D... since 
I've been programming in D on and off for 10 years, I just 
never used a specific type for variadics since I've always use 
a variadic type parameter)


To justify that a poor design choice is necessary is precisely 
why the poor design choice exists in the first place. These are 
blemishes on the language not proper design choices.  For 
example, it is necessary for me to pay taxes, but it does not 
mean that taxes are necessary.


Actual syntax work with more then slices...:

import std.algorithm : equal;

void foo(size_t N)(int[N] args...){
assert(args[].equal([1, 2, 3, 4, 5]));

}

void main(){
foo(1, 2, 3, 4, 5);
}


Re: Solving the impossible?

2018-08-29 Thread Everlast via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 22:01:45 UTC, Paul Backus wrote:

On Tuesday, 28 August 2018 at 20:37:05 UTC, Everlast wrote:
Also, the biggest complaint is that when we use [] attached to 
a type it has a specific meaning as "an array of". e.g., int[] 
means an array of int's.


But int[] a... then changes as we don't have an array of int's 
any more but simply a sequence of ints. While internally it 
might not matter it just doesn't jive with normal type syntax 
IMO.


The parameter `int[] a...` is an an array of ints just like any 
other `int[]` in D. If you don't believe me, see for yourself 
here: https://run.dlang.io/is/IJdovg


I understand that the syntax does not align with your 
expectations. Instead of complaining about it, I would urge you 
to set your preconceptions aside and learn D with an open mind. 
You'll be less frustrated, more productive, and more successful.


One of the things that makes a good language is it's internal 
syntactic consistency. This makes learning a language easier and 
also makes remembering it easier. Determinism is a very useful 
tool as is abstraction consistency. To say "Just except D the way 
it is" is only because of necessity since that is the way D is, 
not because it is correct. (There are a lot of incorrect things 
in the world such as me "learning" D... since I've been 
programming in D on and off for 10 years, I just never used a 
specific type for variadics since I've always use a variadic type 
parameter)


To justify that a poor design choice is necessary is precisely 
why the poor design choice exists in the first place. These are 
blemishes on the language not proper design choices.  For 
example, it is necessary for me to pay taxes, but it does not 
mean that taxes are necessary.




Re: Solving the impossible?

2018-08-29 Thread Kagamin via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 20:37:05 UTC, Everlast wrote:
the second one seems better. Simpler, more direct, more 
obvious, and inline with the standard non variadic syntax. The 
ellipses pretty much state that we are dealing with an array, 
no reason to add redundancy.


That's not obvious, e.g. C variadic arguments are not an array, 
and variadic template arguments are not an array either, so a 
proper type hint is desirable. Also D variadic arguments are not 
limited to arrays.


Re: Solving the impossible?

2018-08-28 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 20:37:05 UTC, Everlast wrote:
Also, the biggest complaint is that when we use [] attached to 
a type it has a specific meaning as "an array of". e.g., int[] 
means an array of int's.


But int[] a... then changes as we don't have an array of int's 
any more but simply a sequence of ints. While internally it 
might not matter it just doesn't jive with normal type syntax 
IMO.


The parameter `int[] a...` is an an array of ints just like any 
other `int[]` in D. If you don't believe me, see for yourself 
here: https://run.dlang.io/is/IJdovg


I understand that the syntax does not align with your 
expectations. Instead of complaining about it, I would urge you 
to set your preconceptions aside and learn D with an open mind. 
You'll be less frustrated, more productive, and more successful.


Re: Solving the impossible?

2018-08-28 Thread Everlast via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 19:40:36 UTC, Paul Backus wrote:

On Tuesday, 28 August 2018 at 19:09:38 UTC, Everlast wrote:
Yeah, I see the link paul posted. The actual syntax seems a 
bit strange to me...


We don't do

A[] a 

So it is not "logical".

foo(A...)(A a)

but if A is a specific type we must do

foo(int[] a ...)

The actual syntax then looks like we have an variadic set of 
parameters of type int[] rather than int.


In `foo(A...)(A a)`, a variadic set of template *arguments* is 
collected into a single template *parameter*, called `A`. In 
`foo(int[] a ...)`, a variadic set of runtime *arguments* is 
collected into a single runtime *parameter* called `a`.


(If you've used Python, it's also similar to how `*args` and 
`**kwargs` collect variadic positional and named arguments into 
a single list or dictionary parameter, respectively.)


It really is the same underlying principle in both cases. It 
just looks different because `foo(A...)(A a)` is a template, 
and `foo(int[] a...)` isn't, and templates use a different 
syntax than regular functions.


In fact, if you wanted to, you could combine the two and do 
something like this:


// All args must have the same type,
// but it can be any type you want.
foo(T)(T[] t...)



Yes, it is the same underlying principle but it is not visually 
consistent IMO.


e.g.,

foo(int[] a)

a is an array of int

foo(int[] a...)

suggests a is an array of an array of int.

I see ... as a generalization of the parameters simply extending 
it to an arbitrary number(which cannot be represented except in 
an arbitrary way).


so

a... means there is an arbitrary number of a's.

int a... means there is an arbitrary number of int.

T a... means there is an arbitrary number of T's

T[] a... means there is an arbitrary number of T[]'s.


For example, to represent an arbitrary number of arrays using the 
current syntax one must do T[][] a...


which looks funky.

Now, it's all not a big deal in the sense that it all works out 
by design, but the question is, is it really needed? It seems 
that requiring [] just adds extra unnecessary symbols that add no 
useful information.



Also, the biggest complaint is that when we use [] attached to a 
type it has a specific meaning as "an array of". e.g., int[] 
means an array of int's.


But int[] a... then changes as we don't have an array of int's 
any more but simply a sequence of ints. While internally it might 
not matter it just doesn't jive with normal type syntax IMO.


int[] a...

vs

int a...

the second one seems better. Simpler, more direct, more obvious, 
and inline with the standard non variadic syntax. The ellipses 
pretty much state that we are dealing with an array, no reason to 
add redundancy.


I'm only talking about syntax here and not semantics.

Of course, if you see a problem with int a... not being 
well-formed then that would be a case against it, but I don't 
think it has that issue.









Re: Solving the impossible?

2018-08-28 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 19:09:38 UTC, Everlast wrote:
Yeah, I see the link paul posted. The actual syntax seems a bit 
strange to me...


We don't do

A[] a 

So it is not "logical".

foo(A...)(A a)

but if A is a specific type we must do

foo(int[] a ...)

The actual syntax then looks like we have an variadic set of 
parameters of type int[] rather than int.


In `foo(A...)(A a)`, a variadic set of template *arguments* is 
collected into a single template *parameter*, called `A`. In 
`foo(int[] a ...)`, a variadic set of runtime *arguments* is 
collected into a single runtime *parameter* called `a`.


(If you've used Python, it's also similar to how `*args` and 
`**kwargs` collect variadic positional and named arguments into a 
single list or dictionary parameter, respectively.)


It really is the same underlying principle in both cases. It just 
looks different because `foo(A...)(A a)` is a template, and 
`foo(int[] a...)` isn't, and templates use a different syntax 
than regular functions.


In fact, if you wanted to, you could combine the two and do 
something like this:


// All args must have the same type,
// but it can be any type you want.
foo(T)(T[] t...)


Re: Solving the impossible?

2018-08-28 Thread bauss via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 19:09:38 UTC, Everlast wrote:

On Tuesday, 28 August 2018 at 12:00:50 UTC, bauss wrote:

On Sunday, 26 August 2018 at 02:26:58 UTC, Everlast wrote:

in fact, I'd rather see

void print(T)(T t, int... a)


You were actually close.

void print(T)(T t, int[] a ...);


Yeah, I see the link paul posted. The actual syntax seems a bit 
strange to me...


We don't do

A[] a 

So it is not "logical".

foo(A...)(A a)

but if A is a specific type we must do

foo(int[] a ...)

The actual syntax then looks like we have an variadic set of 
parameters of type int[] rather than int.


Yeah I agree with that, but unfortunately it cannot be changed.


Re: Solving the impossible?

2018-08-28 Thread Everlast via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 12:00:50 UTC, bauss wrote:

On Sunday, 26 August 2018 at 02:26:58 UTC, Everlast wrote:

in fact, I'd rather see

void print(T)(T t, int... a)


You were actually close.

void print(T)(T t, int[] a ...);


Yeah, I see the link paul posted. The actual syntax seems a bit 
strange to me...


We don't do

A[] a 

So it is not "logical".

foo(A...)(A a)

but if A is a specific type we must do

foo(int[] a ...)

The actual syntax then looks like we have an variadic set of 
parameters of type int[] rather than int.





Re: Solving the impossible?

2018-08-28 Thread bauss via Digitalmars-d-learn

On Sunday, 26 August 2018 at 02:26:58 UTC, Everlast wrote:

in fact, I'd rather see

void print(T)(T t, int... a)


You were actually close.

void print(T)(T t, int[] a ...);


Re: Solving the impossible?

2018-08-25 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 26 August 2018 at 02:26:58 UTC, Everlast wrote:

The problem is, suppose one wants to specify A

void print(T, int... A)(T t, A a)

while tricks can be used, why doesn't D support such an obvious 
syntax? We can specify an arbitrary type but can't restrict it 
in an obvious way, in fact, I'd rather see


void print(T)(T t, int... a)


https://dlang.org/spec/function.html#typesafe_variadic_functions


Solving the impossible?

2018-08-25 Thread Everlast via Digitalmars-d-learn

void print()
{
}

void print(T, A...)(T t, A a)
{
import std.stdio;
writeln(t);
print(a);
}

The problem is, suppose one wants to specify A

void print(T, int... A)(T t, A a)

while tricks can be used, why doesn't D support such an obvious 
syntax? We can specify an arbitrary type but can't restrict it in 
an obvious way, in fact, I'd rather see


void print(T)(T t, int... a)