Why is phobos so wack?

2017-07-09 Thread FoxyBrown via Digitalmars-d

import string.

...
return str.join(" ");


gives

Error: template std.array.join cannot deduce function from 
argument types !()(string, string), candidates are:
\..\..\src\phobos\std\array.d(1591):std.array.join(RoR, 
R)(RoR ror, scope R sep) if (isInputRange!RoR && 
isInputRange!(Unqual!(ElementType!RoR)) && isInputRange!R && 
is(Unqual!(ElementType!(ElementType!RoR)) == 
Unqual!(ElementType!R)))
\..\..\src\phobos\std\array.d(1668):std.array.join(RoR, 
E)(RoR ror, scope E sep) if (isInputRange!RoR && 
isInputRange!(Unqual!(ElementType!RoR)) && is(E : 
ElementType!(ElementType!RoR)))
\..\..\src\phobos\std\array.d(1754):
std.array.join(RoR)(RoR ror) if (isInputRange!RoR && 
isInputRange!(Unqual!(ElementType!RoR)))


simply trying to join a string[] with a separator. I tend to get 
these types of errors when doing simple things in D. Virtually 
every other programming language just works as expected. You can 
pretty much just jump in there and pretty much guess at the 
function name, the arguments, and it will work. In Phobos, seems 
like it follows an anti-pattern. You always end up having to look 
at documentation unless you are familiar enough with D and use it 
in a regular basis to remember its quirks and odd behavior. Seems 
that the same functions are defined differently in different 
modules and the modules not always the expected ones. (strip is 
another one that throws me for a loop. I always try trim first... 
that is what everyone else uses, yeah, it's just a name, but then 
why strip?)


Phobos seems to be rather unorganized and not logically put 
together. Any hopes of this ever getting fixed or do I need to 
start putting together my own library?


Re: Why is phobos so wack?

2017-07-09 Thread rikki cattermole via Digitalmars-d

import std.array;
import std.stdio;

void main() {
string[] strs = ["abc", "def"];
writeln(strs.join(" "));  
}

Works fine?


Re: Why is phobos so wack?

2017-07-09 Thread Anonymouse via Digitalmars-d

On Sunday, 9 July 2017 at 12:56:55 UTC, FoxyBrown wrote:

[...]


Your example is incomplete but this literally works for me.

import std.stdio;
import std.string;

void main()
{
string[] words = [ "hello", "world", "!" ];
writeln(words.join(" "));
}

You probably passed a string instead of a string[].

Virtually every other programming language just works as 
expected. You can pretty much just jump in there and pretty 
much guess at the function name, the arguments, and it will 
work.


In my experience this simply isn't true. Error messages could be 
worlds better but no language lets you use it for more than toy 
purposes without ever having to look at some form of 
documentation.


Re: Why is phobos so wack?

2017-07-09 Thread Adam D. Ruppe via Digitalmars-d

On Sunday, 9 July 2017 at 12:56:55 UTC, FoxyBrown wrote:

return str.join(" ");
[...]
Error: template std.array.join cannot deduce function from 
argument types !()(string, string)

[...]
simply trying to join a string[] with a separator.


The error message sucks, but you clearly have a string when you 
meant string[]. Even the one line of code you posted gives this 
away `str` is a singular name.


modules not always the expected ones. (strip is another one 
that throws me for a loop. I always try trim first... that is 
what everyone else uses, yeah, it's just a name, but then why 
strip?)


strip is used by Python and Ruby too... of the languages i know, 
it is about half a half.


BTW if you are ever searching, try my website: 
http://dpldocs.info/trim




Re: Why is phobos so wack?

2017-07-09 Thread John Colvin via Digitalmars-d

On Sunday, 9 July 2017 at 12:56:55 UTC, FoxyBrown wrote:

import string.

...
return str.join(" ");


gives

Error: template std.array.join cannot deduce function from 
argument types !()(string, string)


Well there's your mistake? There is no function `join` that takes 
(string, string). Everything after that is more detail that may 
or may not be useful, but reading the error message carefully, in 
order, is generally good enough. That said, it would be nice if 
the errors were less daunting somehow.


Re: Why is phobos so wack?

2017-07-09 Thread bitwise via Digitalmars-d

On Sunday, 9 July 2017 at 13:26:31 UTC, Adam D. Ruppe wrote:
strip is used by Python and Ruby too... of the languages i 
know, it is about half a half.


BTW if you are ever searching, try my website: 
http://dpldocs.info/trim


I find this part of D very annoying as well.

D looks like a C language, with a standard library written by a 
PHP/Python developer. It's a shame for a language with so much 
potential to fall victim to such bad taste =x


I suppose I'm biased, and PHP/Python have a fair following, but 
after a few years of PHP coding (part time as part of a larger 
project) I'm not sure I will ever make a full psychological 
recovery..


Re: Why is phobos so wack?

2017-07-09 Thread Dukc via Digitalmars-d

On Sunday, 9 July 2017 at 13:26:31 UTC, Adam D. Ruppe wrote:
The error message sucks, but you clearly have a string when you 
meant string[].


To answer the part "why" about them sucking, is that they are 
generic.


Were join() just a regular function taking two strings, or two 
interfaces which string would implement, the messages would be 
better. I my experience D compiler is excellent at error messages 
when you don't go generic. Of course, that does not help much 
because the standard library is templated, not object-oriented.


Generics, and metaprogramming in general, is extremely hard to 
implement so that the error messages are even close to as good as 
elsewhere. No matter the language. Or rather, it can be made to 
give good messages, C# is a piece of proof for that. But that's 
also a reson why C# templates are so wimpy and ungeneral compared 
to C++ and D.


About C++ from what I've heard, generic error messages there are 
not only much worse than others, they are much worse than even D 
template errors!


Re: Why is phobos so wack?

2017-07-09 Thread Adam D. Ruppe via Digitalmars-d

On Sunday, 9 July 2017 at 17:07:16 UTC, bitwise wrote:
I suppose I'm biased, and PHP/Python have a fair following, but 
after a few years of PHP coding (part time as part of a larger 
project) I'm not sure I will ever make a full psychological 
recovery..


PHP actually is one of the languages that call this `trim`

But I've never had the kind of problems with D's names that I 
have with PHP's assorted weirdness.


Re: Why is phobos so wack?

2017-07-09 Thread Adam D. Ruppe via Digitalmars-d

On Sunday, 9 July 2017 at 17:13:11 UTC, Dukc wrote:
To answer the part "why" about them sucking, is that they are 
generic.


Eh, that's not really why... this is just a crappy 
implementation. We can do a lot better with the library and a lot 
better with the compiler without losing any of the genericness.


Were join() just a regular function taking two strings, or two 
interfaces which string would implement, the messages would be 
better.


Better yes, but still actually a bit crappy. I have one step of 
an improvement in the works: 
https://github.com/dlang/dmd/pull/6806


Consider something similar to that for the constraints too. It 
could highlight that you passed a string instead of a "range of 
ranges" and you'd have a pretty good idea at a glance, even with 
the generic templates.


About C++ from what I've heard, generic error messages there 
are not only much worse than others, they are much worse than 
even D template errors!


Indeed.


Re: Why is phobos so wack?

2017-07-09 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 07/09/2017 06:12 PM, Adam D. Ruppe wrote:

On Sunday, 9 July 2017 at 17:07:16 UTC, bitwise wrote:
I suppose I'm biased, and PHP/Python have a fair following, but after 
a few years of PHP coding (part time as part of a larger project) I'm 
not sure I will ever make a full psychological recovery..


PHP actually is one of the languages that call this `trim`

But I've never had the kind of problems with D's names that I have with 
PHP's assorted weirdness.


It's nowhere remotely as bad as PHP (frankly, nothing else is), but D's 
growth over the years *has* left Phobos with a bit of a..."temporal 
inconsistancy" issue. Some things have been ironed out a bit (like how 
there was a module or two that used to use very unix CLI'ish naming 
conventions instead of D-ish namings), but there's still more to be 
done. And more will continue to be needed, with (ex.) allocators getting 
more and more finalized.


Re: Why is phobos so wack?

2017-07-10 Thread Olivier FAURE via Digitalmars-d

On Sunday, 9 July 2017 at 17:13:11 UTC, Dukc wrote:
About C++ from what I've heard, generic error messages there 
are not only much worse than others, they are much worse than 
even D template errors!


Yeah. You don't want to try reading the GCC message for a 
std::cout error. It's like 80 lines of different template 
overloads of the '<<' operator.


Re: Why is phobos so wack?

2017-07-10 Thread Martin Nowak via Digitalmars-d

On Sunday, 9 July 2017 at 14:22:45 UTC, John Colvin wrote:
That said, it would be nice if the errors were less daunting 
somehow.


Better template constraint errors are on our Agenda for later 
this year.

https://wiki.dlang.org/Vision/2017H2_draft


Re: Why is phobos so wack?

2017-07-10 Thread Dukc via Digitalmars-d

On Sunday, 9 July 2017 at 22:20:02 UTC, Adam D. Ruppe wrote:
Eh, that's not really why... this is just a crappy 
implementation. We can do a lot better with the library and a 
lot better with the compiler without losing any of the 
genericness.


But the more powerful the generics are, the harder it is to make 
good messages, that's what I'm saying. And that compared to the 
power of our metaprogramming, the messages aren't that bad after 
all.


But I agree D can, and I believe will, imporove there regardless.


Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-09 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 07/09/2017 09:26 AM, Adam D. Ruppe wrote:
> On Sunday, 9 July 2017 at 12:56:55 UTC, FoxyBrown wrote:
>> return str.join(" ");
>> [...]
>> Error: template std.array.join cannot deduce function from argument
>> types !()(string, string)
>> [...]
>> simply trying to join a string[] with a separator.
>
> The error message sucks, but you clearly have a string when you meant
> string[].

Related to this, I've been giving some thought lately to a little bit of 
re-designing types themselves. Specifically, type creation tools that go 
beyond what structs and classes give us and allow better handling 
D-style generics.


It's all very incomplete right now, but basically here's the gist:

Awesome as D's generics, ranges, etc all are, they do make two things 
far more convoluted than when using basic straightforward types: 
Function declarations, and error messages when things don't match.


So, why not encapsulate much of that stuff we merely *describe* in 
signatures for generic functions into genuine honest-to-goodness types?


There would be user-defined symbols, such as "InputRange" or 
"SomeString", or "RandomAccessRange!SomeString", which the type system 
sees as actual types. And naturally there would be some mechanism for 
actually defining those types. Then, defining a function like this:


SomeString fizzbar(RandomAccessRange!SomeNumeric r) {...}

...would automatically imply to the compiler all (or at least a lot of) 
the pluming we usually clutter the function declaration with: Defining 
the templated types and calling the appropriate if(isBlahBlah) 
constraints. About the only things remaining would be additional 
constraints not already defined by the next-gen types, and restrictions 
on how the parameters relate to each other.


Even better, having all that encapsulated into genuine types should make 
it easier for the compiler to provide better error messages.


Thought could also be put into additional type-creation tools that cater 
specifically to common things (again, such as ranges) to help streamline 
the process of creating them (ranges are awesome, but let's face it, 
defining them can be a bother - there's gotta be some way to make it 
simpler. For example, input ranges especially would GREATLY benefit from 
being definable in the mannar of C# stackless coroutines).


And of course, Nemerle-like (ML/Haskell-inspired) algebraics would be a 
wonderful capability to encorporate as well.


Another area to explore would be merging the two sets of parameter lists 
(the compile-time list and the run-time list) into one list. Certain 
types would be known to imply "compile-time". A keyword/attr could be 
used to force compile-time or runtime. And for other params, a 
sufficiently-smart compiler could conceivably even choose "runtime" vs 
"compile-time" (or even, "it varies") based on optimization priorities. 
It would simplify the syntax for users, and help get around fear of 
templates.


Obviously this is all very incomplete, but it's an idea I think is 
rather interesting.


Re: Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-09 Thread Meta via Digitalmars-d
On Sunday, 9 July 2017 at 20:22:16 UTC, Nick Sabalausky 
(Abscissa) wrote:

On 07/09/2017 09:26 AM, Adam D. Ruppe wrote:
> On Sunday, 9 July 2017 at 12:56:55 UTC, FoxyBrown wrote:
>> return str.join(" ");
>> [...]
>> Error: template std.array.join cannot deduce function from
argument
>> types !()(string, string)
>> [...]
>> simply trying to join a string[] with a separator.
>
> The error message sucks, but you clearly have a string when
you meant
> string[].

Related to this, I've been giving some thought lately to a 
little bit of re-designing types themselves. Specifically, type 
creation tools that go beyond what structs and classes give us 
and allow better handling D-style generics.


It's all very incomplete right now, but basically here's the 
gist:


Awesome as D's generics, ranges, etc all are, they do make two 
things far more convoluted than when using basic 
straightforward types: Function declarations, and error 
messages when things don't match.


So, why not encapsulate much of that stuff we merely *describe* 
in signatures for generic functions into genuine 
honest-to-goodness types?


There would be user-defined symbols, such as "InputRange" or 
"SomeString", or "RandomAccessRange!SomeString", which the type 
system sees as actual types. And naturally there would be some 
mechanism for actually defining those types. Then, defining a 
function like this:


SomeString fizzbar(RandomAccessRange!SomeNumeric r) {...}

...would automatically imply to the compiler all (or at least a 
lot of) the pluming we usually clutter the function declaration 
with: Defining the templated types and calling the appropriate 
if(isBlahBlah) constraints. About the only things remaining 
would be additional constraints not already defined by the 
next-gen types, and restrictions on how the parameters relate 
to each other.


Even better, having all that encapsulated into genuine types 
should make it easier for the compiler to provide better error 
messages.


I'm sorry if I misunderstood what you're proposing, but isn't 
this exactly what C++ set out to do with concepts? If that's the 
case, I'd recommend you look up some of Andrei's refutation of 
concepts in favour of template guards and `static if`.





Re: Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-09 Thread Nick Sabalausky via Digitalmars-d

On Sunday, 9 July 2017 at 20:42:39 UTC, Meta wrote:


I'm sorry if I misunderstood what you're proposing, but isn't 
this exactly what C++ set out to do with concepts? If that's 
the case, I'd recommend you look up some of Andrei's refutation 
of concepts in favour of template guards and `static if`.


Shit, I hope not :/ I gave up following C++ developments 15 years 
ago. Happen to have a link handy to that refutation?


Re: Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-09 Thread Meta via Digitalmars-d

On Sunday, 9 July 2017 at 21:59:04 UTC, Nick Sabalausky wrote:

On Sunday, 9 July 2017 at 20:42:39 UTC, Meta wrote:


I'm sorry if I misunderstood what you're proposing, but isn't 
this exactly what C++ set out to do with concepts? If that's 
the case, I'd recommend you look up some of Andrei's 
refutation of concepts in favour of template guards and 
`static if`.


Shit, I hope not :/ I gave up following C++ developments 15 
years ago. Happen to have a link handy to that refutation?


There's a couple posts he's made here but a lot of it's spread 
out across various talks, articles (I think) as well as newsgroup 
posts. Here's what I found with a quick google:


https://www.reddit.com/r/cpp/comments/4jqg5z/andrei_alexandrescu_on_c_concepts/
https://www.reddit.com/r/programming/comments/4jlkhv/accu_2016_keynote_by_andrei_alexandrescu/d391585/

And there's a ton of info on the internet about the C++ concepts 
proposal.


Re: Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-09 Thread Nick Sabalausky via Digitalmars-d

On Sunday, 9 July 2017 at 22:02:51 UTC, Meta wrote:


There's a couple posts he's made here but a lot of it's spread 
out across various talks, articles (I think) as well as 
newsgroup posts. Here's what I found with a quick google:


https://www.reddit.com/r/cpp/comments/4jqg5z/andrei_alexandrescu_on_c_concepts/
https://www.reddit.com/r/programming/comments/4jlkhv/accu_2016_keynote_by_andrei_alexandrescu/d391585/

And there's a ton of info on the internet about the C++ 
concepts proposal.


Ah, I guess it is very similar after all, except it'd be based on 
top of and coexist with all of D's design by introspection stuff 
(rather than exist without it as with C++), thus avoiding a lot 
of the downsides and getting best of both worlds.


Re: Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-09 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

 On 07/09/2017 09:21 PM, Nick Sabalausky wrote:
>
> Ah, I guess it is very similar after all, except it'd be based on top of
> and coexist with all of D's design by introspection stuff (rather than
> exist without it as with C++), thus avoiding a lot of the downsides and
> getting best of both worlds.

Ha ha, I still feel more than a little silly for pitching what amounts 
to contracts as "an out-there idea I've been mulling over", but indulge 
in a little (partially-baked) taste to show this at least has some merit 
anyway. Hell, call it "concepts++" or "concepts, the D way" (note: I'm 
NOT pitching this as a suggestion for something D should do. Not saying 
D should or should'nt, just speaking purely in the realm of "langauge 
design brainstorming" here...Just because it's been on my mind and the 
"Why is phobos so wack?" thread brought some relevence)


Behold! The power of combining constraints/design-by-introspection 
*with* concepts:


Current declaration of std.array.join:

---
ElementEncodingType!(ElementType!RoR)[] join(RoR, R)(RoR ror, scope R sep)
if (isInputRange!RoR && isInputRange!(Unqual!(ElementType!RoR)) && 
isInputRange!R && is(Unqual!(ElementType!(ElementType!RoR)) == 
Unqual!(ElementType!R)));


ElementEncodingType!(ElementType!RoR)[] join(RoR, E)(RoR ror, scope E sep)
if (isInputRange!RoR && isInputRange!(Unqual!(ElementType!RoR)) && is(E 
: ElementType!(ElementType!RoR)));


ElementEncodingType!(ElementType!RoR)[] join(RoR)(RoR ror)
if (isInputRange!RoR && isInputRange!(Unqual!(ElementType!RoR)));
---

(ie, completely incomprehensible at-a-glance)

Just one possibility of an entirely hypothetical D++ (assuming I'm even 
interpreting the D version correctly):


---
// Note: This assumes the "ElementEncodingType vs ElementType" distinction
// is nothing but a colossal mistake caused purely by the existance of
// auto-decoding, which was (as an assumption this psuedo-code is predicated
// upon) a complete clusterf*** of misdesign (Ie, *such* a huge stretch of
// the imagination ;)), which in this hypothetical ideal langauge has
// been killed dead with nuclear fire, and then beaten some more with
// spiked crowbars, just to be sure.

/++
  Params:
ror: an input range (or better) of input ranges (or better) of
 any type (shorthand for 'InputRange!InputRange!Type')
sep: a separator that can be any input range ('InputRange!Type').
  Returns: Shorthand for 'InputRange!Type': Ie, an input range (or better).
  Note: This is implicitly templated on typeof(ror) and typeof(sep).
+/
InputRange join(InputRange!InputRange ror, InputRange sep)
  // Relationship constraints:
  if(UnqualTypeMatch!(ror, sep, return))

/++
  Like above, but sep is 'Type' instead of 'InputRange!Type'.
  Since 'Type' is less specific than 'InputRange!Type', the prior overload
  is preferred.
+/
InputRange join(InputRange!InputRange ror, Type sep)
  // Relationship constraints:
  if(unqualTypeMatch!(ror, InputRange!sep, return))

// No separator
InputRange join(InputRange!InputRange ror)
  // Relationship constraints:
  if(unqualTypeMatch!(ror, return))

// Extra-special specialization:
// Why multiple if() allowed? Because it makes the formatting less
// of a mess, thus better readability. Good enough reason to me!
InputRange join(InputRange!InputRange ror, Type sep)
  if(unqualTypeMatch!(ror, sep, return))
  if(hasLength!typeof(sep))
  {  /+...take advantage of sep.length...+/ }

// Note: Those constraints have further room for syntactical improvement.
---

That example involves some additional things defined by the
stdlib (*extremely* hypothetical syntax):

---
concept InputRange(Element)
{
this()
{
// Current body of isInputRange here
}

// Most of isInputRange can *optionally* be replaced with:
Element front();
void popFront();
bool empty();
}

concept ForwardRange : InputRange // Builds upon InputRange
{
// Author can opt to do this (more powerful):
this()
{
super.this();
typeof(this) x = this.save;
}

// Or this (more succinct):
ForwardRange save();
}

// *Anything*: A concrete (instatiable) type, or a templated
// stand-in for a type (ie "T"), or an alias, or nothing at all.
// Types *themselves* are first-class types! But implemented as
// templates, rather than as runtime-OO.
algebraic Any : Bottom;

// An actual concrete type
algrbraic Type : Any
if(isType!this);

// An actual concrete type?
bool isType(Any any) {/+...introspection magic lies

Re: Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-10 Thread Jacob Carlborg via Digitalmars-d

On 2017-07-10 07:54, Nick Sabalausky (Abscissa) wrote:

  On 07/09/2017 09:21 PM, Nick Sabalausky wrote:
 >
 > Ah, I guess it is very similar after all, except it'd be based on top of
 > and coexist with all of D's design by introspection stuff (rather than
 > exist without it as with C++), thus avoiding a lot of the downsides and
 > getting best of both worlds.

Ha ha, I still feel more than a little silly for pitching what amounts 
to contracts as "an out-there idea I've been mulling over", but indulge 
in a little (partially-baked) taste to show this at least has some merit 
anyway. Hell, call it "concepts++" or "concepts, the D way" (note: I'm 
NOT pitching this as a suggestion for something D should do. Not saying 
D should or should'nt, just speaking purely in the realm of "langauge 
design brainstorming" here...Just because it's been on my mind and the 
"Why is phobos so wack?" thread brought some relevence)


Behold! The power of combining constraints/design-by-introspection 
*with* concepts:


Current declaration of std.array.join:

---
ElementEncodingType!(ElementType!RoR)[] join(RoR, R)(RoR ror, scope R sep)
if (isInputRange!RoR && isInputRange!(Unqual!(ElementType!RoR)) && 
isInputRange!R && is(Unqual!(ElementType!(ElementType!RoR)) == 
Unqual!(ElementType!R)));


ElementEncodingType!(ElementType!RoR)[] join(RoR, E)(RoR ror, scope E sep)
if (isInputRange!RoR && isInputRange!(Unqual!(ElementType!RoR)) && is(E 
: ElementType!(ElementType!RoR)));


ElementEncodingType!(ElementType!RoR)[] join(RoR)(RoR ror)
if (isInputRange!RoR && isInputRange!(Unqual!(ElementType!RoR)));
---

(ie, completely incomprehensible at-a-glance)

Just one possibility of an entirely hypothetical D++ (assuming I'm even 
interpreting the D version correctly):


---
// Note: This assumes the "ElementEncodingType vs ElementType" distinction
// is nothing but a colossal mistake caused purely by the existance of
// auto-decoding, which was (as an assumption this psuedo-code is 
predicated

// upon) a complete clusterf*** of misdesign (Ie, *such* a huge stretch of
// the imagination ;)), which in this hypothetical ideal langauge has
// been killed dead with nuclear fire, and then beaten some more with
// spiked crowbars, just to be sure.

/++
   Params:
 ror: an input range (or better) of input ranges (or better) of
  any type (shorthand for 'InputRange!InputRange!Type')
 sep: a separator that can be any input range ('InputRange!Type').
   Returns: Shorthand for 'InputRange!Type': Ie, an input range (or 
better).

   Note: This is implicitly templated on typeof(ror) and typeof(sep).
+/
InputRange join(InputRange!InputRange ror, InputRange sep)
   // Relationship constraints:
   if(UnqualTypeMatch!(ror, sep, return))

/++
   Like above, but sep is 'Type' instead of 'InputRange!Type'.
   Since 'Type' is less specific than 'InputRange!Type', the prior overload
   is preferred.
+/
InputRange join(InputRange!InputRange ror, Type sep)
   // Relationship constraints:
   if(unqualTypeMatch!(ror, InputRange!sep, return))

// No separator
InputRange join(InputRange!InputRange ror)
   // Relationship constraints:
   if(unqualTypeMatch!(ror, return))

// Extra-special specialization:
// Why multiple if() allowed? Because it makes the formatting less
// of a mess, thus better readability. Good enough reason to me!
InputRange join(InputRange!InputRange ror, Type sep)
   if(unqualTypeMatch!(ror, sep, return))
   if(hasLength!typeof(sep))
   {  /+...take advantage of sep.length...+/ }

// Note: Those constraints have further room for syntactical improvement.
---

That example involves some additional things defined by the
stdlib (*extremely* hypothetical syntax):

---
concept InputRange(Element)
{
 this()
 {
 // Current body of isInputRange here
 }

 // Most of isInputRange can *optionally* be replaced with:
 Element front();
 void popFront();
 bool empty();
}

concept ForwardRange : InputRange // Builds upon InputRange
{
 // Author can opt to do this (more powerful):
 this()
 {
 super.this();
 typeof(this) x = this.save;
 }

 // Or this (more succinct):
 ForwardRange save();
}

// *Anything*: A concrete (instatiable) type, or a templated
// stand-in for a type (ie "T"), or an alias, or nothing at all.
// Types *themselves* are first-class types! But implemented as
// templates, rather than as runtime-OO.
algebraic Any : Bottom;

// An actual concrete type
algrbraic Type : Any
 if

Re: Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-10 Thread Martin Nowak via Digitalmars-d
On Sunday, 9 July 2017 at 20:22:16 UTC, Nick Sabalausky 
(Abscissa) wrote:

SomeString fizzbar(RandomAccessRange!SomeNumeric r) {...}


Looks like concepts.

We've settled on leveraging the already useful template 
constraints (at best in CNF [¹]) for better error messages. It's 
on the Agenda for later this year [²].


[¹]: https://github.com/dlang/phobos/pull/5461
[²]: https://wiki.dlang.org/Vision/2017H2_draft



Re: Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-10 Thread bpr via Digitalmars-d
On Sunday, 9 July 2017 at 20:22:16 UTC, Nick Sabalausky 
(Abscissa) wrote:
Obviously this is all very incomplete, but it's an idea I think 
is rather interesting.


You've seen this, right?

https://wiki.dlang.org/User:9rnsr/DIP:_Template_Parameter_Constraint

A small step in one such direction, influenced by C++ concepts. 
That proto-DIP also raises a question I always had about why D 
doesn't allow chained template instantiation, but that's another 
DIP for another time.




Re: Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-10 Thread bpr via Digitalmars-d

On Monday, 10 July 2017 at 01:21:08 UTC, Nick Sabalausky wrote:
Ah, I guess it is very similar after all, except it'd be based 
on top of and coexist with all of D's design by introspection 
stuff (rather than exist without it as with C++), thus avoiding 
a lot of the downsides and getting best of both worlds.


You've seen this, right?

https://wiki.dlang.org/User:9rnsr/DIP:_Template_Parameter_Constraint

A small step in one such direction, influenced by C++ concepts. 
That proto-DIP also raises a question I always had about why D 
doesn't allow chained template instantiation, but that's another 
DIP for another time.




Re: Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-10 Thread bpr via Digitalmars-d

On Monday, 10 July 2017 at 01:21:08 UTC, Nick Sabalausky wrote:
Ah, I guess it is very similar after all, except it'd be based 
on top of and coexist with all of D's design by introspection 
stuff (rather than exist without it as with C++), thus avoiding 
a lot of the downsides and getting best of both worlds.


You've seen this, right?

https://wiki.dlang.org/User:9rnsr/DIP:_Template_Parameter_Constraint

A small step in one such direction, influenced by C++ concepts. 
That proto-DIP also raises a question I always had about why D 
doesn't allow chained template instantiation, but that's another 
DIP for another time.




Re: Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-10 Thread bpr via Digitalmars-d

On Monday, 10 July 2017 at 01:21:08 UTC, Nick Sabalausky wrote:
Ah, I guess it is very similar after all, except it'd be based 
on top of and coexist with all of D's design by introspection 
stuff (rather than exist without it as with C++), thus avoiding 
a lot of the downsides and getting best of both worlds.



You've seen this, right?

https://wiki.dlang.org/User:9rnsr/DIP:_Template_Parameter_Constraint

A small step in one such direction, influenced by C++ concepts. 
That proto-DIP also raises a question I always had about why D 
doesn't allow chained template instantiation, but that's another 
DIP for another time.




Re: Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-10 Thread bpr via Digitalmars-d

On Monday, 10 July 2017 at 16:16:40 UTC, bpr wrote:

On Monday, 10 July 2017 at 01:21:08 UTC, Nick Sabalausky wrote:
Ah, I guess it is very similar after all, except it'd be based 
on top of and coexist with all of D's design by introspection 
stuff (rather than exist without it as with C++), thus 
avoiding a lot of the downsides and getting best of both 
worlds.



You've seen this, right?

https://wiki.dlang.org/User:9rnsr/DIP:_Template_Parameter_Constraint

A small step in one such direction, influenced by C++ concepts. 
That proto-DIP also raises a question I always had about why D 
doesn't allow chained template instantiation, but that's 
another DIP for another time.


Sorry about the repeat posting, I could observe the software 
hiccuping on my browser...


Re: Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-10 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 07/10/2017 07:32 AM, Jacob Carlborg wrote:


Something like this has been proposed several times before, but Andrei 
doesn't seem to like it. He think it's a failure that all the conditions 
need to have a name, or something like that. I prefer your approach.




Well, the nice thing about this approach (basing a concept-ish system 
*on top* of existing D-style design-by-introspection, as opposed to a 
C++-like concepts with no D-like features to complement it), is that it 
*doesn't* require every little variation to be named.


For example, in the same psuedo-code I posted, there's a function (the 
last join() overload) that takes an input range, but requires the input 
range to support hasLength. But notice that there is NO symbol created 
or used anywhere for InputRangeWithLength. IIUC, it sounds like C++ 
concepts would require such a symbol to be created. But with this, that 
would not be needed.


One thing to keep in mind is that we're ALREADY creating names for many 
(not all, but definitely some) of these things. In effect, *every* time 
we have an 'isX' function (isSomeString, isForwardRange, etc), we're 
already creating a name for it. We already implicitly understand that 
just because it's unrealisting to name *everything* (which, 
indicentally, reminds me of old Java class hierarchies), doesn't mean we 
can't or shouldn't name some things.


The other important thing I want to emplasize yet again (just in case, 
because I know from experience in the past it's exactly this kind of 
point that rarely gets noticed), I'm not proposing D do this. It'd be 
far too big a change and it's far too incomplete to even think of trying 
to push. (Even tiny straightforward improvements to D face dowwnright 
epic levels of resistance any more.) So again, it's just some 
brainstorming. Maybe D several decades from now, maybe some other 
language inspired by D, maybe nothing ever, whatever.


Re: Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-10 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 07/10/2017 11:58 AM, bpr wrote:


You've seen this, right?

https://wiki.dlang.org/User:9rnsr/DIP:_Template_Parameter_Constraint

A small step in one such direction, influenced by C++ concepts. That 
proto-DIP also raises a question I always had about why D doesn't allow 
chained template instantiation, but that's another DIP for another time.




Yea, I've seen that. It'd be a nice improvent for D and I'm definitely 
in favor of it.


It doesn't especially excite me though just because it's a small 
incremental change and creates further syntactical differences between 
handling runtime-oriented symbols and compile-time-oriented symbols. Ie, 
I'd prefer "InputRange r" over "T r if InputRange" because it's vastly 
simpler and more consistent with non-templated variable declarations. 
But in a practical sense, that's be a much more major and difficult to 
retrofit that onto D, so the DIP sounds like an appropriate (if 
unexciting) direction for D to take.


But what I find much more interesting than that DIP (again, from a 
purely academic standpoint) is taking all of these abilities and finding 
a way simplify them, while retaining all of their power, and create more 
overall consistency[1]. (That was *exactly* one of my big original draws 
to D in the first place - it took C++, then cleaned it all up and 
enhanced it. I have interest in brainstorming the same for D. I think 
there's been enough practical experience using D at this point for more 
streamlined designs to now be possible.)


[1] Heck, on the consistency front, it even bugs the hell out of me when 
people do "foo()" to call/define a function, but then deliberately stick 
with "if ()"-style instead for keywords. Both are "identifier followed 
by parens", but whether or not a space is added between is *different* 
depending on whether the identifier is a symbol or a keyword. 
Unnecessary inconsistency. Maybe it's all the puzzle games I've played 
over my lifetime, but...want...to...simplify... ;)


Re: Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-10 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 07/10/2017 09:16 AM, Martin Nowak wrote:

On Sunday, 9 July 2017 at 20:22:16 UTC, Nick Sabalausky (Abscissa) wrote:

SomeString fizzbar(RandomAccessRange!SomeNumeric r) {...}


Looks like concepts.

We've settled on leveraging the already useful template constraints (at 
best in CNF [¹]) for better error messages. It's on the Agenda for later 
this year [²].


[¹]: https://github.com/dlang/phobos/pull/5461
[²]: https://wiki.dlang.org/Vision/2017H2_draft



Sounds nice.

But I'm getting the distinct impression people are missing that I never 
actually proposed that D itself should do this. It's just academic 
brainstorming.


Re: Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-10 Thread Jacob Carlborg via Digitalmars-d

On 2017-07-10 19:54, Nick Sabalausky (Abscissa) wrote:


Well, the nice thing about this approach (basing a concept-ish system
*on top* of existing D-style design-by-introspection, as opposed to a
C++-like concepts with no D-like features to complement it), is that it
*doesn't* require every little variation to be named.

For example, in the same psuedo-code I posted, there's a function (the
last join() overload) that takes an input range, but requires the input
range to support hasLength. But notice that there is NO symbol created
or used anywhere for InputRangeWithLength. IIUC, it sounds like C++
concepts would require such a symbol to be created. But with this, that
would not be needed.

One thing to keep in mind is that we're ALREADY creating names for many
(not all, but definitely some) of these things. In effect, *every* time
we have an 'isX' function (isSomeString, isForwardRange, etc), we're
already creating a name for it. We already implicitly understand that
just because it's unrealisting to name *everything* (which,
indicentally, reminds me of old Java class hierarchies), doesn't mean we
can't or shouldn't name some things.


I agree, it's not me that need convincing :)


The other important thing I want to emplasize yet again (just in case,
because I know from experience in the past it's exactly this kind of
point that rarely gets noticed), I'm not proposing D do this. It'd be
far too big a change and it's far too incomplete to even think of trying
to push. (Even tiny straightforward improvements to D face dowwnright
epic levels of resistance any more.) So again, it's just some
brainstorming. Maybe D several decades from now, maybe some other
language inspired by D, maybe nothing ever, whatever.


Here I disagree. I think that D should have something like this.

--
/Jacob Carlborg


Re: Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-10 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 07/10/2017 02:55 PM, Jacob Carlborg wrote:

On 2017-07-10 19:54, Nick Sabalausky (Abscissa) wrote:

The other important thing I want to emplasize yet again (just in case,
because I know from experience in the past it's exactly this kind of
point that rarely gets noticed), I'm not proposing D do this. It'd be
far too big a change and it's far too incomplete to even think of trying
to push. (Even tiny straightforward improvements to D face dowwnright
epic levels of resistance any more.) So again, it's just some
brainstorming. Maybe D several decades from now, maybe some other
language inspired by D, maybe nothing ever, whatever.


Here I disagree. I think that D should have something like this.



Oh, I didn't mean to imply that I wouldn't love to have it in D 
(assuming it was all well-fleshed out and didn't have big problems). I 
just wanted to be crystal clear that I'm merely discussing a langauge 
design idea here rather than coming in saying "Hey, you people should 
all like this idea and go implement it put it into D!!!" It's easy for 
things to get taken that way here, and can result in knee-jerk reactions 
and otherwise derailing of what's really only intended as a theoretical 
academic discussion. If something *were* to come of it, and it worked 
great, and everybody was happy, then fantastic. That's just not what I'm 
bringing it up for, that's all.


Re: Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-10 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 07/10/2017 04:14 PM, Nick Sabalausky (Abscissa) wrote:


Oh, I didn't mean to imply that I wouldn't love to have it in D 
(assuming it was all well-fleshed out and didn't have big problems). I 
just wanted to be crystal clear that I'm merely discussing a langauge 
design idea here rather than coming in saying "Hey, you people should 
all like this idea and go implement it put it into D!!!" It's easy for 
things to get taken that way here, and can result in knee-jerk reactions 
and otherwise derailing of what's really only intended as a theoretical 
academic discussion. If something *were* to come of it, and it worked 
great, and everybody was happy, then fantastic. That's just not what I'm 
bringing it up for, that's all.


I especially wanted to avoid any the "How dare you even consider 
speaking of something without fully implementing it first!" that tends 
to be common here. (Speaking of, *that* sort of thing is far more 
unprofessional than the mere "bad words" some people are so terrified of).


Re: Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-10 Thread Marco Leise via Digitalmars-d
Am Sun, 9 Jul 2017 16:22:16 -0400
schrieb "Nick Sabalausky (Abscissa)"
:

> […] a sufficiently-smart compiler could conceivably even
> choose "runtime" vs "compile-time" (or even, "it varies")
> based on optimization priorities.

GCC already does this, i.e. find runtime arguments of constant
value and generate a second instance of the function with that
argument optimized out.

-- 
Marco



Re: Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-10 Thread Jacob Carlborg via Digitalmars-d

On 2017-07-10 22:19, Nick Sabalausky (Abscissa) wrote:

On 07/10/2017 04:14 PM, Nick Sabalausky (Abscissa) wrote:


Oh, I didn't mean to imply that I wouldn't love to have it in D 
(assuming it was all well-fleshed out and didn't have big problems). I 
just wanted to be crystal clear that I'm merely discussing a langauge 
design idea here rather than coming in saying "Hey, you people should 
all like this idea and go implement it put it into D!!!" It's easy for 
things to get taken that way here, and can result in knee-jerk 
reactions and otherwise derailing of what's really only intended as a 
theoretical academic discussion. If something *were* to come of it, 
and it worked great, and everybody was happy, then fantastic. That's 
just not what I'm bringing it up for, that's all.


I especially wanted to avoid any the "How dare you even consider 
speaking of something without fully implementing it first!" that tends 
to be common here. (Speaking of, *that* sort of thing is far more 
unprofessional than the mere "bad words" some people are so terrified of).


Fair enough.

--
/Jacob Carlborg


Re: Types: The Next Generation (Was: Why is phobos so wack?)

2017-07-15 Thread Mark via Digitalmars-d
On Sunday, 9 July 2017 at 20:22:16 UTC, Nick Sabalausky 
(Abscissa) wrote:
So, why not encapsulate much of that stuff we merely *describe* 
in signatures for generic functions into genuine 
honest-to-goodness types?


There would be user-defined symbols, such as "InputRange" or 
"SomeString", or "RandomAccessRange!SomeString", which the type 
system sees as actual types. And naturally there would be some 
mechanism for actually defining those types. Then, defining a 
function like this:


SomeString fizzbar(RandomAccessRange!SomeNumeric r) {...}

...would automatically imply to the compiler all (or at least a 
lot of) the pluming we usually clutter the function declaration 
with: Defining the templated types and calling the appropriate 
if(isBlahBlah) constraints. About the only things remaining 
would be additional constraints not already defined by the 
next-gen types, and restrictions on how the parameters relate 
to each other.


Even better, having all that encapsulated into genuine types 
should make it easier for the compiler to provide better error 
messages.


This reminds me of the "RAII vs. scope" arguments that came up on 
the forum a few times (see e.g. [1]). Many of the features in D 
(and other programming languages) can be theoretically (and 
practically, in some languages) implemented using the type 
system: resource management, template constraints, in/out 
contracts, function attributes (pure, nothrow, etc.), I/O 
streams, error handling, and probably others. This is sometimes 
profitable and sometimes not so much.


If you're using some concept all over your code then 
encapsulating it in a type can reduce code duplication, improve 
readability and let you exploit various features of the type 
system to your benefit (e.g. subtyping: A RandomAccessRange being 
a subtype of InputRange, exception hierarchies, etc.). But if 
you're only using it once or twice then it's probably not worth 
the hassle. That is, the issue is scale.


My general impression is that C++ tries (and often succeeds, 
pyrrhically) to do pretty much everything using the type system 
(specifically, classes): Resources, exceptions, iterators, 
interfaces, initialization lists, ... Almost everything is 
encapsulated in a type. Concepts (Lite) seem to me like a way to 
further enrich the type system, although concepts aren't exactly 
types.


My opinion, in a nutshell, is that "ad-hocish" facilities like 
template constraints, the scope statement, contracts, etc. don't 
scale up, while more formal facilities like concepts, RAII, etc. 
don't scale *down*. As such, there is a need for both of them.


With respect to the specific issue of ranges, I don't know Phobos 
well enough to have an opinion as to whether or not they should 
be made more formal (as types/concepts/...). The error messages 
should be more clear and precise, but I'm not convinced that an 
overhaul of the system is necessary to achieve that.


[1] 
https://forum.dlang.org/post/tlsrpqvfeepcfbyfq...@forum.dlang.org