www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - The new, new phobos sneak preview

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Hi everybody,


I just committed all of Phobos into svn on dsource.org. That is not an
official release and has known and unknown bugs, limitations, and
rhinodemons. I expect some ripples before we stabilize, but when we will
we'll stabilize at a higher potential.

For convenience, I've also uploaded pre-built libraries for Windows and
Linux here:

http://www.erdani.dreamhosters.com/d/

The updated documentation is here:

http://www.erdani.dreamhosters.com/d/web/phobos/phobos.html

Finally, the whole shebang with source and all as dumped from my disk is
to be found here:

http://www.erdani.dreamhosters.com/d/src/

If you want to build Phobos yourself, check out the Makefile (not
linux.mak; that won't work). That GNU Makefile, hosted on Linux, can
build the Linux lib and also the Windows lib by using wine. (I'm very
happy about this; now I can test on Windows and Linux without switching
more than a command line tweak.)

Below are highlights of the additions and changes:

*** std.path

* getDrive now works with all string types
* isabs accepts in char[]
* join accepts variadic in char[]
* fnmatch works with in char[]

*** std.regexp

* Scheduled for deprecation. Use std.regex instead.

*** std.regex (new file)

* Regular expression library with wide char support, simplified
interface, better speed etc.

*** std.format

* Added vector parsing and printing with the specifier "%()". For
example, writefln("[%(s; )]", [1, 2, 3][]) writes "[1; 2; 3]". This
support is experimental and may be changed in the future.
* Added a formattedRead function (i.e., scanf that doesn't suck). The
implementation is incomplete but common cases are supported.

*** std.random

* Added RandomCover that covers a given range in a random manner
* Eliminated the old-fashioned random functions
* Defined a default random object that simplifies calls to the random
functions
* Changed generators to obey the range interface. So now you can write:

Random r;
foreach (n; take(100, uniform(0, 100)) { ... }


*** std.file

* read, write, append, rename, remove, getSize, getTimes, getAttributes,
isfile, isdir, chdir, mkdir, mkdirRecurse, rmdir, listdir, copy, take
filename(s) by "in char[]"
* Added function readText that reads and validates a text file
* Added function slurp that reads a file into an array of tuples. Example:

auto a = slurp!(int, double)("filename", "%s, %s");

Each line in the file looks like e.g. "1, 2.3". slurp returns an array
of Tuple!(int, double) with the parsed content.

*** std.mmfile

* Minor cosmetic changes

*** std.conv

* Rewrote conversions with constrained templates.
* Added text() function that transforms everything into text.

*** std.typecons

* Added constructors, assignment operator, length, toString, and slice
to Tuple.

** std.bitmanip

* Bitfields of length 0 are defined to be always 0.
* The read functions for bitfields are const.

*** std.numeric

* Added type CustomFloat that allows defining specialized floating-point
numbers (e.g. 16-bit floats, positive floats etc.)
* Added FPTemporary as the best type to store temporary values.
* Templatized oppositeSigns
* Added Euclidean distance
* Added dotProduct
* Added cosineSimilarity
* Added normalize
* Added string kernel functions gapWeightedSimilarity,
gapWeightedSimilarityNormalized, gapWeightedSimilarityIncremental.

*** std.outbuffer

* Added a few missing overloads of write()

*** std.contracts

* enforce accepts const(char)[] instead of string
* Added enforce overload that invokes a delegate on failure
* Added assumeSorted template
* Added structuralCast that implements, well, structural casting
(incomplete).

*** std.c.stdio

* Added fopen64 and friends

*** std.utf

* toUTF16z accepts in char[]

*** std.algorithm

* Everything converted to ranges. Big disruption. Algorithms added.

*** std.getopt

* Added support for parameterless delegates

*** std.functional

* Improved error messages
* Added configurable parameter names for functions as strings
* Added Adjoin template

*** std.variant

* Added support for Variants that contain vectors and hashes of themselves

*** std.string

* strip, stripl, stripr, startsWith, endsWith now work with any string type

*** std.array

* Range primitives for arrays
* Appender template
* insert, replace functions

*** std.date

* Added a benchmark function that allows for simple timing measurements.

*** std.stdio

* Major breaking changes: introduced the File struct.  Now stdin,
stdout, stderr are instances of the File struct.
* Due to bugs in the compiler, the copy constructor and destructor of
File are commented out. Walter will look into fixing the issues soon.
File should work fine, but you need to close it manually.
* A byRecord iteration mode makes it pretty easy to iterate structured
text files.

*** std.range (new file)

* Range manipulation stuff.


Andrei

P.S. If you have any troubles with the website, I'd appreciate if you
let me know. This is my first experiment with a new provider.
Apr 06 2009
next sibling parent reply BCS <ao pathlink.com> writes:
Reply to Andrei,

 auto a = slurp!(int, double)("filename", "%s, %s");
 
 Each line in the file looks like e.g. "1, 2.3". slurp returns an array
 of Tuple!(int, double) with the parsed content.
 

It would be nice to have a version that would slurp into pre defined structs. struct S{ int i; double d } S[] a = slurp!(S)("filename", "%s, %s");
Apr 06 2009
next sibling parent reply Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
BCS wrote:
 Reply to Andrei,
 
 auto a = slurp!(int, double)("filename", "%s, %s");

 Each line in the file looks like e.g. "1, 2.3". slurp returns an array
 of Tuple!(int, double) with the parsed content.

It would be nice to have a version that would slurp into pre defined structs. struct S{ int i; double d } S[] a = slurp!(S)("filename", "%s, %s");

And maybe a burp that spits a tuple back into a file?
Apr 06 2009
parent reply BCS <none anon.com> writes:
Hello Ellery,

 BCS wrote:
 
 Reply to Andrei,
 
 auto a = slurp!(int, double)("filename", "%s, %s");
 
 Each line in the file looks like e.g. "1, 2.3". slurp returns an
 array of Tuple!(int, double) with the parsed content.
 

structs. struct S{ int i; double d } S[] a = slurp!(S)("filename", "%s, %s");


I seconds the name!
Apr 06 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
BCS wrote:
 Hello Ellery,
 
 BCS wrote:

 Reply to Andrei,

 auto a = slurp!(int, double)("filename", "%s, %s");

 Each line in the file looks like e.g. "1, 2.3". slurp returns an
 array of Tuple!(int, double) with the parsed content.

structs. struct S{ int i; double d } S[] a = slurp!(S)("filename", "%s, %s");


I seconds the name!

I wonder what fart and sniff would do. :o| On a more (well, only slightly) serious note, the name slurp() is taken from perl (google perl slurp), and incidentally burp is around there too. Andrei
Apr 06 2009
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
BCS wrote:
 Reply to Andrei,
 
 auto a = slurp!(int, double)("filename", "%s, %s");

 Each line in the file looks like e.g. "1, 2.3". slurp returns an array
 of Tuple!(int, double) with the parsed content.

It would be nice to have a version that would slurp into pre defined structs. struct S{ int i; double d } S[] a = slurp!(S)("filename", "%s, %s");

doesn't get forgotten. Andrei
Apr 06 2009
prev sibling next sibling parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Tue, 07 Apr 2009 01:23:20 +0400, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:

 Hi everybody,

 [snip]
 Random r;
 foreach (n; take(100, uniform(0, 100)) { ... }

Warning: unreferenced variable 'r'. :)
 [snip]

Apr 06 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Denis Koroskin wrote:
 On Tue, 07 Apr 2009 01:23:20 +0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> wrote:
 
 Hi everybody,

 [snip]
 Random r;
 foreach (n; take(100, uniform(0, 100)) { ... }

Warning: unreferenced variable 'r'. :)

Rats :o). Now uniform doesn't need an explicit Random object, but I still created one out of reflex. Andrei
Apr 06 2009
prev sibling next sibling parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 Hi everybody,
 I just committed all of Phobos into svn on dsource.org. That is not an
 official release and has known and unknown bugs, limitations, and
 rhinodemons. I expect some ripples before we stabilize, but when we will
 we'll stabilize at a higher potential.

Is this pretty much everything, or is there even more to come? I want to start porting some code to the new Phobos, or at least thinking about how to change the code to best make use of the new Phobos, but I don't want to do it until at least the more radical, earthquake-like changes have been unveiled. P.S. It looks fantastic!
Apr 06 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
dsimcha wrote:
 == Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 Hi everybody,
 I just committed all of Phobos into svn on dsource.org. That is not an
 official release and has known and unknown bugs, limitations, and
 rhinodemons. I expect some ripples before we stabilize, but when we will
 we'll stabilize at a higher potential.

Is this pretty much everything, or is there even more to come? I want to start porting some code to the new Phobos, or at least thinking about how to change the code to best make use of the new Phobos, but I don't want to do it until at least the more radical, earthquake-like changes have been unveiled. P.S. It looks fantastic!

Thanks! This is all I have, and I think from here on there will be more additions instead of big changes. There is one major change not effected yet, which affects both the compiler and phobos: the renaming of head, toe, next, and retreat to (respectively) front, back, popFront, and popBack. Also in foreach we will make the following change: foreach (e; range) body from: for (auto copy = range; !copy.empty; copy.popFront) { auto e = copy.front; body } with: for (auto copy = range[]; !copy.empty; copy.popFront) { auto e = copy.front; body } Notice the extra [] when getting the copy of the range. The reason is that people want to do: foreach (e; container) {} when the container is actually not a range. Operator [] for a range will simply return the range itself. For a container, it will return that container's preferred range. Andrei
Apr 06 2009
parent Michel Fortin <michel.fortin michelf.com> writes:
On 2009-04-06 18:29:50 -0400, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 for (auto copy = range[]; !copy.empty; copy.popFront)
 {
      auto e = copy.front;
      body
 }

Perhaps it's a little off topic, but... Wouldn't it be better if the language was made so that evaluating an array as a bool would yeild false when empty and true when not? This would avoid forcing the !empty double negation at many places like this one. while (range) range.popFront; instead of while (!range.empty) range.popFront; and for (auto copy = range[]; copy; copy.popFront) instead of for (auto copy = range[]; !copy.empty; copy.popFront) -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Apr 06 2009
prev sibling next sibling parent reply Alan Knowles <alan akbkhome.com> writes:
Really Sweet,

Any chance of fixing one of my pet peeves of std.stream
writeLine() - using platform dependant line endings

Almost all the socket work I've done with this has made it a rather 
annoying pointless method (as it's totally non-portable).  perhaps 
implementing
writeCR() writeLF() writeCRLF(), then letting writeLine call them, 
dependant on which platform would be better?

I guess in-line comments in the manual are a bit outside your scope at 
present.

Anyway great work.
Regards
Alan


Andrei Alexandrescu wrote:
 Hi everybody,
 
 
 I just committed all of Phobos into svn on dsource.org. That is not an
 official release and has known and unknown bugs, limitations, and
 rhinodemons. I expect some ripples before we stabilize, but when we will
 we'll stabilize at a higher potential.
 
 For convenience, I've also uploaded pre-built libraries for Windows and
 Linux here:
 
 http://www.erdani.dreamhosters.com/d/
 
 The updated documentation is here:
 
 http://www.erdani.dreamhosters.com/d/web/phobos/phobos.html
 
 Finally, the whole shebang with source and all as dumped from my disk is
 to be found here:
 
 http://www.erdani.dreamhosters.com/d/src/

Apr 06 2009
parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Tue, 07 Apr 2009 03:34:37 +0400, Alan Knowles <alan akbkhome.com> wrote:

 Really Sweet,

 Any chance of fixing one of my pet peeves of std.stream
 writeLine() - using platform dependant line endings

 Almost all the socket work I've done with this has made it a rather  
 annoying pointless method (as it's totally non-portable).  perhaps  
 implementing
 writeCR() writeLF() writeCRLF(), then letting writeLine call them,  
 dependant on which platform would be better?

write(text, '\r'); write(text, '\n');
 I guess in-line comments in the manual are a bit outside your scope at  
 present.

 Anyway great work.
 Regards
 Alan

Apr 06 2009
parent Alan Knowles <alan akbkhome.com> writes:
Denis Koroskin wrote:
 On Tue, 07 Apr 2009 03:34:37 +0400, Alan Knowles <alan akbkhome.com> wrote:
 
 Really Sweet,

 Any chance of fixing one of my pet peeves of std.stream
 writeLine() - using platform dependant line endings

 Almost all the socket work I've done with this has made it a rather 
 annoying pointless method (as it's totally non-portable).  perhaps 
 implementing
 writeCR() writeLF() writeCRLF(), then letting writeLine call them, 
 dependant on which platform would be better?

write(text, '\r'); write(text, '\n');

writeString(text ~ "\r\n"); as the polymorphism of write is a blessing and a curse, I've had a few really annoying bugs occur by sending the wrong type to write()... hence writeCRLF - etc. seemed alot clearer
 
 I guess in-line comments in the manual are a bit outside your scope at 
 present.

 Anyway great work.
 Regards
 Alan


Apr 06 2009
prev sibling next sibling parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 Hi everybody,
 I just committed all of Phobos into svn on dsource.org. That is not an
 official release and has known and unknown bugs, limitations, and
 rhinodemons. I expect some ripples before we stabilize, but when we will
 we'll stabilize at a higher potential.

Two things that had been discussed on this NG that I noticed are conspicuously absent: eager(), which converts a lazy range to an array, and range-oriented streams. Are these still in the works?
Apr 06 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
dsimcha wrote:
 == Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 Hi everybody,
 I just committed all of Phobos into svn on dsource.org. That is not an
 official release and has known and unknown bugs, limitations, and
 rhinodemons. I expect some ripples before we stabilize, but when we will
 we'll stabilize at a higher potential.

Two things that had been discussed on this NG that I noticed are conspicuously absent: eager(), which converts a lazy range to an array, and range-oriented streams. Are these still in the works?

Good questions. I forgot about eager(), and would like to think a bit more about the range-oriented streams. Andrei
Apr 06 2009
prev sibling next sibling parent reply Lutger <lutger.blijdestijn gmail.com> writes:
This is looking very impressive, will you be covering some of these concepts 
and idioms used in phobos in your upcoming TDPL?

This url returns a 404:

http://www.erdani.dreamhosters.com/d/web/phobos/std_patterns.html
Apr 07 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Lutger wrote:
 This is looking very impressive, will you be covering some of these concepts 
 and idioms used in phobos in your upcoming TDPL?
 
 This url returns a 404:
 
 http://www.erdani.dreamhosters.com/d/web/phobos/std_patterns.html

Sorry, that module is not meant to be visible yet. Andrei
Apr 07 2009
prev sibling next sibling parent Sergey Gromov <snake.scaly gmail.com> writes:
Mon, 06 Apr 2009 14:23:20 -0700, Andrei Alexandrescu wrote:

 I just committed all of Phobos into svn on dsource.org. That is not an
 official release and has known and unknown bugs, limitations, and
 rhinodemons. I expect some ripples before we stabilize, but when we will
 we'll stabilize at a higher potential.

Looks scary, but great. :D ----- * There are two std.regexp and no std.regex in the package list * std.range.advance docs mention 'drop' instead of 'advance' * std.range.retreatN docs metnion 'advanceRight' instead of 'retreatN'
Apr 07 2009
prev sibling next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Andrei Alexandrescu wrote:

 I just committed all of Phobos into svn on dsource.org. That is not an
 official release and has known and unknown bugs, limitations, and
 rhinodemons. I expect some ripples before we stabilize, but when we will
 we'll stabilize at a higher potential.

Will the final release support "osx" [sic] and "freebsd" too, or is the new Phobos going to be "Windows" and "linux" only ?
 If you want to build Phobos yourself, check out the Makefile (not
 linux.mak; that won't work). That GNU Makefile, hosted on Linux, can
 build the Linux lib and also the Windows lib by using wine. (I'm very
 happy about this; now I can test on Windows and Linux without switching
 more than a command line tweak.)

For instance, things like these look a bit hardcoded to linux: EXTRA_MODULES_posix = $(addprefix std/c/linux/, linux socket) --anders
Apr 08 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Anders F Bj÷rklund wrote:
 Andrei Alexandrescu wrote:
 
 I just committed all of Phobos into svn on dsource.org. That is not an
 official release and has known and unknown bugs, limitations, and
 rhinodemons. I expect some ripples before we stabilize, but when we will
 we'll stabilize at a higher potential.

Will the final release support "osx" [sic] and "freebsd" too, or is the new Phobos going to be "Windows" and "linux" only ?
 If you want to build Phobos yourself, check out the Makefile (not
 linux.mak; that won't work). That GNU Makefile, hosted on Linux, can
 build the Linux lib and also the Windows lib by using wine. (I'm very
 happy about this; now I can test on Windows and Linux without switching
 more than a command line tweak.)

For instance, things like these look a bit hardcoded to linux: EXTRA_MODULES_posix = $(addprefix std/c/linux/, linux socket) --anders

I'll need to defer such testing and answers to Walter; I don't have access to OSX and FreeBSD. Andrei
Apr 08 2009
parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Andrei Alexandrescu wrote:
 Will the final release support "osx" [sic] and "freebsd" too,
 or is the new Phobos going to be "Windows" and "linux" only ?


 I'll need to defer such testing and answers to Walter; I don't have 
 access to OSX and FreeBSD.

Think I was just looking in the wrong place, the svn did have them. So I'm assuming it's just a merge away and it'll be the same as now. Strange with how "Unix" became "Posix" and "darwin" became "OSX" and "freebsd" became "FreeBSD", but I guess that is evolution for ya... --anders
Apr 08 2009
prev sibling next sibling parent reply Lars Kyllingstad <public kyllingen.NOSPAMnet> writes:
Andrei Alexandrescu wrote:
 Hi everybody,
 
 
 I just committed all of Phobos into svn on dsource.org. That is not an
 official release and has known and unknown bugs, limitations, and
 rhinodemons. I expect some ripples before we stabilize, but when we will
 we'll stabilize at a higher potential.

This looks very impressive, and makes me want to switch to D2. :) When do you expect the new Phobos (and the new rdmd) to be shipped with DMD? Do you plan to add to std.functional the 'curry' and 'bind' templates that were discussed in the NG recently? Thanks for putting in the hard work! -Lars
Apr 08 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Lars Kyllingstad wrote:
 Andrei Alexandrescu wrote:
 Hi everybody,


 I just committed all of Phobos into svn on dsource.org. That is not an
 official release and has known and unknown bugs, limitations, and
 rhinodemons. I expect some ripples before we stabilize, but when we will
 we'll stabilize at a higher potential.

This looks very impressive, and makes me want to switch to D2. :) When do you expect the new Phobos (and the new rdmd) to be shipped with DMD?

This month.
 Do you plan to add to std.functional the 'curry' and 'bind' templates 
 that were discussed in the NG recently?
 
 Thanks for putting in the hard work!

I'll add curry, but bind seems to be a lot less popular. Andrei
Apr 08 2009
prev sibling next sibling parent reply novice2 <sorry noem.ail> writes:
Andrei Alexandrescu Wrote:

 
 *** std.format
 
 * Added vector parsing and printing with the specifier "%()". For
 example, writefln("[%(s; )]", [1, 2, 3][]) writes "[1; 2; 3]". This
 support is experimental and may be changed in the future.

oh, please, don't remove this feature in future! it is helpfull. change if need, but not remove please.
Apr 08 2009
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
novice2 wrote:
 Andrei Alexandrescu Wrote:
 
 *** std.format
 
 * Added vector parsing and printing with the specifier "%()". For 
 example, writefln("[%(s; )]", [1, 2, 3][]) writes "[1; 2; 3]". This
  support is experimental and may be changed in the future.

oh, please, don't remove this feature in future! it is helpfull. change if need, but not remove please.

I love it too. In all likelihood we'll only add to it. Andrei
Apr 08 2009
parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:
 writefln("[%(s; )]", [1, 2, 3][]) writes "[1; 2; 3]"

Most times you don't want to change the separator. For the uncommon cases where you want a different separator, you can use a map plus a std.string.join. So I don't like it. Bye, bearophile
Apr 08 2009
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
bearophile wrote:
 Andrei Alexandrescu:
 writefln("[%(s; )]", [1, 2, 3][]) writes "[1; 2; 3]"

Most times you don't want to change the separator. For the uncommon cases where you want a different separator, you can use a map plus a std.string.join. So I don't like it.

How about parsing? Andrei
Apr 08 2009
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Jarrett Billingsley:
 Wow, talk about inefficient.  Consider you have to write out a 100,000
 element array.  What a waste of memory.

There are three parameters to consider here: flexibility, speed, and complexity. In most situations you don't need speed and flexibility (because you have to print few data and a comma is OK for most printing situations), so I think it's better to minimize complexity. If you need flexibility but speed isn't necessary, use a generator or list comprehension or a map, plus a join. So the "complexity" is low still because you don't need to learn more syntax. Then there is the large data case. Often you need to print it with commas, so the default printing is fine. For the uncommon situation you talk about, where you have both large data and you need flexibility, then write a small for loop with many write() inside. ----------------------- Andrei:
How about parsing?<

How about using a module of the standard library designed for such simple parsing purposes? Anyway, do as you like. I'm just thinking aloud here. I'll probably rewrite my dlibs for 2.0 anyway. Later, bearophile
Apr 08 2009
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
bearophile:
I'll probably rewrite my dlibs for 2.0 anyway.<

Ignore this part, please, it's not good. Bye, bearophile
Apr 08 2009
parent reply grauzone <none example.net> writes:
bearophile wrote:
 bearophile:
 I'll probably rewrite my dlibs for 2.0 anyway.<

Ignore this part, please, it's not good.

Huh, is this some kind of feel-good community?
 Bye,
 bearophile

Apr 08 2009
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
grauzone:
 Huh, is this some kind of feel-good community?

Brutal environments kill playful mood and don't lead to creative thinking and good ideas, and also keep away gentle but potentially useful people (think about women too). A good place keeps your blood pressure lower, and makes you live longer. Be well, bearophile
Apr 08 2009
prev sibling parent reply superdan <super dan.org> writes:
grauzone Wrote:

 bearophile wrote:
 bearophile:
 I'll probably rewrite my dlibs for 2.0 anyway.<

Ignore this part, please, it's not good.

Huh, is this some kind of feel-good community?

ignore. crybaby wanna attention. new releases piss him off. with each phobos bearophile comes all 'i told ya' &'finally u do like my dlibs' & primedonne nitpicks & shit. feels not reco or sumth'n. relax dood. u didnt invent all tat shit. anyway. found time 2 look over phobos & got some nits myself andre. std.algorithm is big. should be more orthogonal. why fill. i can do copy with repeat. some other fns can go. std.range is incomplete. theres tons of ranges tat r useful. std.numeric is a motley crew of vaguely related shit. theres no containers. u got all bananas w range but only test with arrays. no good solution for array append. fuck appender. no matrices & u promised tem. fptemporary dont make sense. anyway. this shit is dope. ranges r cool & simple in hindsight. tats a good sign. ill get hands dirty n maybe report more.
Apr 08 2009
parent reply Derek Parnell <derek psych.ward> writes:
On Wed, 08 Apr 2009 19:24:10 -0400, superdan wrote:

 ill get hands dirty n maybe report more.

If you do, can you report back using English. I'm not very good at translating your, presumably excellent, insights otherwise. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Apr 08 2009
parent superdan <super dan.org> writes:
Derek Parnell Wrote:

 On Wed, 08 Apr 2009 19:24:10 -0400, superdan wrote:
 
 ill get hands dirty n maybe report more.

If you do, can you report back using English. I'm not very good at translating your, presumably excellent, insights otherwise.

watch out. the comma police is lookin' fer ya.
Apr 08 2009
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
bearophile wrote:
 Jarrett Billingsley:
 Wow, talk about inefficient.  Consider you have to write out a
 100,000 element array.  What a waste of memory.

There are three parameters to consider here: flexibility, speed, and complexity. In most situations you don't need speed and flexibility (because you have to print few data and a comma is OK for most printing situations), so I think it's better to minimize complexity. If you need flexibility but speed isn't necessary, use a generator or list comprehension or a map, plus a join. So the "complexity" is low still because you don't need to learn more syntax. Then there is the large data case. Often you need to print it with commas, so the default printing is fine. For the uncommon situation you talk about, where you have both large data and you need flexibility, then write a small for loop with many write() inside. ----------------------- Andrei:
 How about parsing?<

How about using a module of the standard library designed for such simple parsing purposes?

std.format. There is formattedWrite that looks and works complementary to formattedRead. About the speed/complexity/flexibility tradeoff, I think it's a good point in spirit but kind of misapplied. I can't bring myself to advocate a solution that involves memory allocation and the such when the task is to dump out an array, and I also need to write and parse sequences all the time, so I extended the formatting strings to make that comfortable and consistent for both parsing and writing. That doesn't preclude using join et al, and also doesn't affect existing code (currently "%(" is invalid), so I don't quite understand the complaint. Andrei
Apr 08 2009
prev sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Wed, Apr 8, 2009 at 5:00 PM, bearophile <bearophileHUGS lycos.com> wrote:
 Most times you don't want to change the separator. For the uncommon cases
where you want a different separator, you can use a map plus a std.string.join.
So I don't like it.

Wow, talk about inefficient. Consider you have to write out a 100,000 element array. What a waste of memory.
Apr 08 2009
prev sibling next sibling parent reply Steve Teale <steve.teale britseyeview.com> writes:
Andrei Alexandrescu Wrote:

 Hi everybody,
 
 
 I just committed all of Phobos into svn on dsource.org. That is not an
 official release and has known and unknown bugs, limitations, and
 rhinodemons. I expect some ripples before we stabilize, but when we will
 we'll stabilize at a higher potential.

So, it is in svn. Does that mean we can check things out and make alterations that we've already coded and wanted for some time? What are the rules? Steve
Apr 08 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Steve Teale wrote:
 Andrei Alexandrescu Wrote:
 
 Hi everybody,
 
 
 I just committed all of Phobos into svn on dsource.org. That is not
 an official release and has known and unknown bugs, limitations,
 and rhinodemons. I expect some ripples before we stabilize, but
 when we will we'll stabilize at a higher potential.

So, it is in svn. Does that mean we can check things out and make alterations that we've already coded and wanted for some time? What are the rules? Steve

Phobos has been in svn on dsource.org for a while. As with any project, there's no specific rules unless you have write access to the repository. We'd be glad to receive bug reports, fixes, additions, and patches. Andrei
Apr 08 2009
prev sibling next sibling parent reply Piotrek <starpit tlen.pl> writes:
Hi,

I looked at std.algorithm. Wow, what a piece of art.

BTW. What about your book on D? Any known dates? I know nothing about 
publishing business, so forgive my ignorance in advance.

Cheers
Apr 08 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Piotrek wrote:
 Hi,
 
 I looked at std.algorithm. Wow, what a piece of art.
 
 BTW. What about your book on D? Any known dates? I know nothing about 
 publishing business, so forgive my ignorance in advance.
 
 Cheers

Thanks. It's a good question. The book has 121 pages written out of the projected 350. The bottleneck is how soon we'll have a reasonably complete threading model. I don't have an exact date at the moment. In wake of the incredibly good experience with luring reviewers off this group for "The Case For D", I might try a similar trick for getting parts of the book reviewed. TCFD got probably 20% value added by reviewers alone. Many thanks to (list copied from the draft I submitted) Bill Baxter, Jason House, John ``Eljay'' Love-Jensen, Denis Koroskin, leonardo maffi (sic), Petru Marginean, Bartosz Milewski, Derek Parnell, Brad Roberts, Joel Salomon, Benjamin Shropshire, David Simcha, Florin Trofin, Cristian Vlasceanu, and Walter Bright. By the way, TCFD is coming to a website near you too. It's received publication approval from both the Overload magazine in England and the online magazine Doctor Dobb's Journal (which will make it available online for free). Publication dates to be announced soon. Andrei
Apr 08 2009
parent reply The Anh Tran <trtheanh gmail.com> writes:
One of my favorite book is Modern C++ design :thumbup:

May i ask: will the next D book have some design pattern chapters; or 
some 1-to-1 equivalent between C++ and D metaprogramming, to convert 
hardcore C++ disciple? :)

Best regards.

Andrei Alexandrescu wrote:
 Piotrek wrote:
 Hi,

 I looked at std.algorithm. Wow, what a piece of art.

 BTW. What about your book on D? Any known dates? I know nothing about 
 publishing business, so forgive my ignorance in advance.

 Cheers

Thanks. It's a good question. The book has 121 pages written out of the projected 350. The bottleneck is how soon we'll have a reasonably complete threading model. I don't have an exact date at the moment. ..... Andrei

Apr 09 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Thanks. I will be light on pattern specifics because I want the book to 
be reasonably short and focused. But metaprogramming will be an integral 
part of the book. In fact, I introduce a template function as soon as I 
introduce functions. There's no necessity to save templates for advanced 
chapters.

Andrei

The Anh Tran wrote:
 One of my favorite book is Modern C++ design :thumbup:
 
 May i ask: will the next D book have some design pattern chapters; or 
 some 1-to-1 equivalent between C++ and D metaprogramming, to convert 
 hardcore C++ disciple? :)
 
 Best regards.
 
 Andrei Alexandrescu wrote:
 Piotrek wrote:
 Hi,

 I looked at std.algorithm. Wow, what a piece of art.

 BTW. What about your book on D? Any known dates? I know nothing about 
 publishing business, so forgive my ignorance in advance.

 Cheers

Thanks. It's a good question. The book has 121 pages written out of the projected 350. The bottleneck is how soon we'll have a reasonably complete threading model. I don't have an exact date at the moment. ..... Andrei


Apr 09 2009
prev sibling next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
This C++0x article is relevant for comparison:

http://www.reddit.com/r/programming/comments/8bijk/gcc_c0x_features_exploration/
Apr 10 2009
parent reply bearophile <bearophileHUGS lycos.com> writes:
Walter Bright:
 This C++0x article is relevant for comparison:
 http://www.reddit.com/r/programming/comments/8bijk/gcc_c0x_features_exploration/

"Advanced" features have to be used only if they improve the code. I don't like that little article and the following discussion. The following D1 code shows two ways to solve that problem with my dlibs. The first code to try is the simplest, that is to scan the data three (or even four times): double avg = cast(double)sum(data) / len(data); putr("min, max, avg: ", min(data), " ", max(data), " ", avg); It works with most kind of eager/lazy numerical data, for example a lazy generator that has no length. Note that sum() is sometimes faster than a simple loop. In many situations that code (plus some safety against division by zero) is good enough. If you know data is huge or you have found that code to be a bottleneck, and you want a single pass you can use something like the following (code written on the fly, no unittests present, it may contain bugs): import d.templates: IsAA, BaseType1, Record; import d.func: putr, min, max, sum, record, len; import d.exceptions: EmptyException; Record!(BaseType1!(TSeq), BaseType1!(TSeq), double) minMaxAvg1(TSeq)(TSeq seq, double start=0.0) { auto nitems = len(seq); if (!nitems) throw new EmptyException("minMaxAvg(): 'seq' can't be empty"); return record(min(seq), max(seq), sum(seq, start) / nitems); } Record!(BaseType1!(TSeq), BaseType1!(TSeq), double) minMaxAvg2(TSeq)(TSeq seq, double start=0.0) { BaseType1!(TSeq) dmin, dmax; double dtot = start; int nitems; static if (IsAA!(TSeq)) { foreach (el, _; seq) { if (nitems == 0) { dmin = el; dmax = el; } if (dmin > el) dmin = el; if (dmax < el) dmax = el; dtot += el; nitems++; } } else { foreach (el; seq) { if (nitems == 0) { dmin = el; dmax = el; } if (dmin > el) dmin = el; if (dmax < el) dmax = el; dtot += el; nitems++; } } if (!nitems) throw new EmptyException("minMaxAvg(): 'seq' can't be empty"); return record(dmin, dmax, dtot / nitems); } void main() { int[] data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; putr("<min, max, avg>: ", minMaxAvg1(data)); putr("<min, max, avg>: ", minMaxAvg2(data)); } (Notice the ugly code duplication caused by the AAs). The output: min, max, avg: 1 10 5.5 <min, max, avg>: record(1, 10, 5.5) Bye, bearophile
Apr 10 2009
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
For even bigger data you may use muds:
"On the Complexity of Processing Massive, Unordered, Distributed Data", by Jon
Feldman, S. Muthukrishnan, Anastasios Sidiropoulos, Cliff Stein, Zoya Svitkina:
http://arxiv.org/abs/cs.CC/0611108

Bye,
bearophile
Apr 10 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
bearophile wrote:
 For even bigger data you may use muds:
 "On the Complexity of Processing Massive, Unordered, Distributed Data", by Jon
Feldman, S. Muthukrishnan, Anastasios Sidiropoulos, Cliff Stein, Zoya Svitkina:
 http://arxiv.org/abs/cs.CC/0611108

I've developed a skepticism towards arxiv.org. My understanding is that it's not high-quality so a paper that only appears of it is highly questionable. Andrei
Apr 10 2009
parent reply Lars Kyllingstad <public kyllingen.NOSPAMnet> writes:
Andrei Alexandrescu wrote:
 bearophile wrote:
 For even bigger data you may use muds:
 "On the Complexity of Processing Massive, Unordered, Distributed 
 Data", by Jon Feldman, S. Muthukrishnan, Anastasios Sidiropoulos, 
 Cliff Stein, Zoya Svitkina:
 http://arxiv.org/abs/cs.CC/0611108

I've developed a skepticism towards arxiv.org. My understanding is that it's not high-quality so a paper that only appears of it is highly questionable. Andrei

I'm not sure how it is in CS, but at least in physics, *everything* is posted on arXiv -- papers, talks, lectures, etc. Since it (usually) takes quite a while to get a paper published in a peer-reviewed journal, it allows for rapid communication of research results. For each paper on arXiv there is a "journal-ref" field that can be filled in when the paper is quality-assured and published. Another nice thing about arXiv is that it's free. Scientific journals usually require subscriptions -- expensive ones, at that, normally paid for by university libraries. Therefore, when I want to send someone a link to a paper of mine, I usually direct them to the arXiv version, since then I'm sure they can actually read it. So I guess my point is: don't diss arXiv. :) -Lars
Apr 11 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Lars Kyllingstad wrote:
 Andrei Alexandrescu wrote:
 bearophile wrote:
 For even bigger data you may use muds:
 "On the Complexity of Processing Massive, Unordered, Distributed 
 Data", by Jon Feldman, S. Muthukrishnan, Anastasios Sidiropoulos, 
 Cliff Stein, Zoya Svitkina:
 http://arxiv.org/abs/cs.CC/0611108

I've developed a skepticism towards arxiv.org. My understanding is that it's not high-quality so a paper that only appears of it is highly questionable. Andrei

I'm not sure how it is in CS, but at least in physics, *everything* is posted on arXiv -- papers, talks, lectures, etc. Since it (usually) takes quite a while to get a paper published in a peer-reviewed journal, it allows for rapid communication of research results. For each paper on arXiv there is a "journal-ref" field that can be filled in when the paper is quality-assured and published. Another nice thing about arXiv is that it's free. Scientific journals usually require subscriptions -- expensive ones, at that, normally paid for by university libraries. Therefore, when I want to send someone a link to a paper of mine, I usually direct them to the arXiv version, since then I'm sure they can actually read it. So I guess my point is: don't diss arXiv. :)

Thank you, this is very useful information. Andrei
Apr 11 2009
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
bearophile wrote:
 Walter Bright:
 This C++0x article is relevant for comparison:
 http://www.reddit.com/r/programming/comments/8bijk/gcc_c0x_features_exploration/

"Advanced" features have to be used only if they improve the code. I don't like that little article and the following discussion.

Then please vote up my comment which shows a solution that is simple *and* efficient :o). Andrei
Apr 10 2009
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:

 Then please vote up my comment which shows a solution that is simple 
 *and* efficient :o).

I am not registered there, so I can't vote, I guess. Generally I don't like reduce() HOF, because it generally leads to less readable code (and often people use it only to compute a sum or product of items), but this time it's a good enough usage. You have forgotten to compute the average, as requested by the original article. Regarding field access: assert(r.field[0] == 2); // minimum assert(r.field[1] == 11); // maximum I've found that sometimes a shorter syntax is nice, I use d0, d1, etc: assert(r.d0 == 2); assert(r.d1 == 11); (It doesn't replace the general [] access).
I've developed a skepticism towards arxiv.org. My understanding is that it's
not high-quality so a paper that only appears of it is highly questionable.<

There some papers are very good, and some papers are ugly. I generally mostly care for the contents, so I like that source of knowledge. Bye, bearophile
Apr 10 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
bearophile wrote:
 Andrei Alexandrescu:
 
 Then please vote up my comment which shows a solution that is simple 
 *and* efficient :o).

I am not registered there, so I can't vote, I guess. Generally I don't like reduce() HOF, because it generally leads to less readable code (and often people use it only to compute a sum or product of items), but this time it's a good enough usage. You have forgotten to compute the average, as requested by the original article. Regarding field access: assert(r.field[0] == 2); // minimum assert(r.field[1] == 11); // maximum I've found that sometimes a shorter syntax is nice, I use d0, d1, etc: assert(r.d0 == 2); assert(r.d1 == 11); (It doesn't replace the general [] access).

Yah, I had _0 but removed it. The plan is to use alias this to get rid of field altogether so you write r[0], r[1] etc. but it turns out alias this still has a few bugs. Andrei
Apr 10 2009
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:
 Then please vote up my comment which shows a solution that is simple 
 *and* efficient :o).

Does it work with (the keys of) an AA too? For example: int[double] aa = [3.0:0, 4:0, 7:0, 11:0, 3:0, 2:0, 5:0]; auto r = reduce!(min, max)(aa); Bye, bearophile
Apr 10 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
bearophile wrote:
 Andrei Alexandrescu:
 Then please vote up my comment which shows a solution that is simple 
 *and* efficient :o).

Does it work with (the keys of) an AA too? For example: int[double] aa = [3.0:0, 4:0, 7:0, 11:0, 3:0, 2:0, 5:0]; auto r = reduce!(min, max)(aa);

No, AAs are poorly designed (no iteration etc.) so std.algorithm is not even attempting to support them. My plan is to cajole Walter and Sean into making AA real types, after which I can add the appropriate functionality. Andrei
Apr 10 2009
prev sibling next sibling parent reply Lars Kyllingstad <public kyllingen.NOSPAMnet> writes:
Andrei Alexandrescu wrote:
 Hi everybody,
 
 
 I just committed all of Phobos into svn on dsource.org. That is not an
 official release and has known and unknown bugs, limitations, and
 rhinodemons. I expect some ripples before we stabilize, but when we will
 we'll stabilize at a higher potential.

Some corrections/suggestions to std.range, if you are ready for such yet: From the documentation it seems that the function series() is meant to be called recurrence(). (Personally I think recursiveSequence() is more fitting.) The function sequence() is missing from the documentation, only struct Sequence is listed. Guess there should be a ///ditto in there. I think isInfinite!() should be called isInfiniteRange!(). The current name is, in my opinion, too general. -Lars
Apr 11 2009
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Lars Kyllingstad wrote:
 Andrei Alexandrescu wrote:
 Hi everybody,


 I just committed all of Phobos into svn on dsource.org. That is not an
 official release and has known and unknown bugs, limitations, and
 rhinodemons. I expect some ripples before we stabilize, but when we will
 we'll stabilize at a higher potential.

Some corrections/suggestions to std.range, if you are ready for such yet:

Thanks!
  From the documentation it seems that the function series() is meant to 
 be called recurrence(). (Personally I think recursiveSequence() is more 
 fitting.)

Fixed. (I'm trying to stay with one-word names when possible.)
 The function sequence() is missing from the documentation, only struct 
 Sequence is listed. Guess there should be a ///ditto in there.

Oops... fixed.
 I think isInfinite!() should be called isInfiniteRange!(). The current 
 name is, in my opinion, too general.

I'm undecided about this (and similar cases). isInfinite sits inside std.range, so std.range.isInfinite is clear and std.range.isInfiniteRange feels redundant. On the other hand, I don't want to use too common symbols because then the user will be forced to prefix them whenever they clash. I fixed everything and checked in. Speaking of which, I'd be glad if interested people could take a look at std.file and compare it against the old: http://dsource.org/projects/phobos/browser/trunk/phobos/std/file.d Previously many phobos modules, e.g. std.file, looked like this: version(Windows) { ... big chunk ... } version(Posix) { ... big chunk ... } The advantage of this approach is that it keeps platform-specific code together. The disadvantage is that it encourages code duplication. I found that about 25% of the functions inside std.file actually were not platform dependent; they essentially were duplicated verbatim. So I suggest we change this to per-declaration granularity where it makes sense: /** Doc for read... */ version(Windows) void[] read(in char[] filename, void[] data) { ... } version(Posix) void[] read(in char[] filename, void[] data) { ... } The current std.file implements this alternative factoring and initial experience seems to suggest it works fine. Also, the code got smaller by 18%. This must also because I got rid of all goto's :o). By the way, here's a neat trick I think may be used in other situations as well: factoring some constant function arguments together. version(Windows) void[] read(in char[] name) { alias TypeTuple!(GENERIC_READ, FILE_SHARE_READ, (SECURITY_ATTRIBUTES*).init, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, HANDLE.init) defaults; auto h = useWfuncs ? CreateFileW(std.utf.toUTF16z(name), defaults) : CreateFileA(toMBSz(name), defaults); ... } The previous code duplicated all those arguments. Andrei
Apr 11 2009
next sibling parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Andrei Alexandrescu wrote:
     alias TypeTuple!(GENERIC_READ,
             FILE_SHARE_READ, (SECURITY_ATTRIBUTES*).init, OPEN_EXISTING,
             FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
             HANDLE.init)
         defaults;

How is that a type-tuple? (As far as I can see, none of those are types...)
Apr 11 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Frits van Bommel wrote:
 Andrei Alexandrescu wrote:
     alias TypeTuple!(GENERIC_READ,
             FILE_SHARE_READ, (SECURITY_ATTRIBUTES*).init, OPEN_EXISTING,
             FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
             HANDLE.init)
         defaults;

How is that a type-tuple? (As far as I can see, none of those are types...)

TypeTuple is a misnomer. A TypeTuple can contain not only types, but also compile-time expressions. Andrei
Apr 11 2009
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Andrei Alexandrescu wrote:
 Frits van Bommel wrote:
 Andrei Alexandrescu wrote:
     alias TypeTuple!(GENERIC_READ,
             FILE_SHARE_READ, (SECURITY_ATTRIBUTES*).init, OPEN_EXISTING,
             FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
             HANDLE.init)
         defaults;

How is that a type-tuple? (As far as I can see, none of those are types...)

TypeTuple is a misnomer. A TypeTuple can contain not only types, but also compile-time expressions.

I know, that's what I was pointing out :). I figure, you've got commit access to Phobos...
Apr 11 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Frits van Bommel wrote:
 Andrei Alexandrescu wrote:
 Frits van Bommel wrote:
 Andrei Alexandrescu wrote:
     alias TypeTuple!(GENERIC_READ,
             FILE_SHARE_READ, (SECURITY_ATTRIBUTES*).init, 
 OPEN_EXISTING,
             FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
             HANDLE.init)
         defaults;

How is that a type-tuple? (As far as I can see, none of those are types...)

TypeTuple is a misnomer. A TypeTuple can contain not only types, but also compile-time expressions.

I know, that's what I was pointing out :). I figure, you've got commit access to Phobos...

I wonder what a good name would be. Andrei
Apr 11 2009
next sibling parent grauzone <none example.net> writes:
Jarrett Billingsley wrote:
 On Sat, Apr 11, 2009 at 7:36 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 I wonder what a good name would be.

How about... umm... oh I don't know. "Tuple"?

That name is already taken. http://www.dsource.org/projects/phobos/browser/trunk/phobos/std/typecons.d#L337
Apr 11 2009
prev sibling next sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2009-04-11 19:36:36 -0400, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 Frits van Bommel wrote:
 Andrei Alexandrescu wrote:
 Frits van Bommel wrote:
 Andrei Alexandrescu wrote:
     alias TypeTuple!(GENERIC_READ,
             FILE_SHARE_READ, (SECURITY_ATTRIBUTES*).init, OPEN_EXISTING,
             FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
             HANDLE.init)
         defaults;

How is that a type-tuple? (As far as I can see, none of those are types...)

TypeTuple is a misnomer. A TypeTuple can contain not only types, but also compile-time expressions.

I know, that's what I was pointing out :). I figure, you've got commit access to Phobos...

I wonder what a good name would be.

Compile time expressions, just like in a static assert and a static if? StaticTuple, obviously. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Apr 11 2009
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2009-04-11 20:33:15 -0400, Michel Fortin <michel.fortin michelf.com> said:

 Compile time expressions, just like in a static assert and a static if? 
 StaticTuple, obviously.

I would add that StaticTuple justifies perfectly the use of "Tuple" as a name for runtime expression tuples (because non-static ifs and asserts take runtime expressions). -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Apr 11 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Michel Fortin wrote:
 On 2009-04-11 20:33:15 -0400, Michel Fortin <michel.fortin michelf.com> 
 said:
 
 Compile time expressions, just like in a static assert and a static 
 if? StaticTuple, obviously.

I would add that StaticTuple justifies perfectly the use of "Tuple" as a name for runtime expression tuples (because non-static ifs and asserts take runtime expressions).

That sounds good to me. If nobody opposes it, I'll make the change. I also made a lot of breaking changes (capitalization) in std.date. The idea is to take the hit once (with the next release) and then have improved overall stability. Andrei
Apr 11 2009
parent bearophile <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:
 That sounds good to me. If nobody opposes it, I'll make the change.

StaticTuple sounds acceptable. (I have used "Tuple" instead of "StaticTuple" and "Record" instead of "Tuple"). Bye, bearophile
Apr 12 2009
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jarrett Billingsley wrote:
 On Sat, Apr 11, 2009 at 7:36 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 I wonder what a good name would be.

How about... umm... oh I don't know. "Tuple"?

Tuple is taken by tuples. Andrei
Apr 11 2009
prev sibling next sibling parent reply Jason House <jason.james.house gmail.com> writes:
Bill Baxter Wrote:

 On Sun, Apr 12, 2009 at 5:50 AM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 Lars Kyllingstad wrote:
 I think isInfinite!() should be called isInfiniteRange!(). The current
 name is, in my opinion, too general.

I'm undecided about this (and similar cases). isInfinite sits inside std.range, so std.range.isInfinite is clear and std.range.isInfiniteRange feels redundant. On the other hand, I don't want to use too common symbols because then the user will be forced to prefix them whenever they clash.

This is one of the big reasons why "static import" by default would have been better than pull-everything-in by default. But since pull-everything-in *is* the default. I agree with Lars. Symbols supplied by modules should look unambiguous even when undecorated by their module name. Or you could use the trick that Tango often uses -- make a static struct with a few members. It's pretty ugly though, if you ask me. Introducing a static struct just to get a namespace to replace the namespace that is already there but gets stripped as the default action upon 'import'. Ick. --bb

There's no need for imported names to be unambiguous. Users can give aliases to imports or import specific members. I hate how Tango puts stuff in structs for no good reason
Apr 11 2009
parent Lutger <lutger.blijdestijn gmail.com> writes:
Jason House wrote:
...
 There's no need for imported names to be unambiguous. Users can give 

in structs for no good reason I agree. It's not that hard to alias / static import. It may just be a matter of preference, but more verbose declarations do not tend to be more readable imho. You have import std.range and the one hand and on the other (the parameter) you are also operating on a range, what more information would one need? If isInfinity would be a member of the range, then even in Java one would not think of writing such constructs: std.range.Range.isInfinityRange()
Apr 12 2009
prev sibling next sibling parent grauzone <none example.net> writes:
Bill Baxter wrote:
 On Sun, Apr 12, 2009 at 5:50 AM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 Lars Kyllingstad wrote:
 I think isInfinite!() should be called isInfiniteRange!(). The current
 name is, in my opinion, too general.

std.range, so std.range.isInfinite is clear and std.range.isInfiniteRange feels redundant. On the other hand, I don't want to use too common symbols because then the user will be forced to prefix them whenever they clash.

This is one of the big reasons why "static import" by default would have been better than pull-everything-in by default. But since pull-everything-in *is* the default. I agree with Lars. Symbols supplied by modules should look unambiguous even when undecorated by their module name. Or you could use the trick that Tango often uses -- make a static struct with a few members. It's pretty ugly though, if you ask me. Introducing a static struct just to get a namespace to replace the namespace that is already there but gets stripped as the default action upon 'import'. Ick.

This could be easily fixed by changing the import statement such, that the module name is used as namespace: import some.mypackage.mymodule; mymodule.somefunctionfrommymodule(); This is a bit different from static imports, that require the full package path, and it's exactly like you use Tango modules.
 --bb

Apr 11 2009
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Bill Baxter:
 But since pull-everything-in *is* the default.  I agree with Lars.
 Symbols supplied by modules should look unambiguous even when
 undecorated by their module name.  Or you could use the trick that
 Tango often uses -- make a static struct with a few members.  It's
 pretty ugly though, if you ask me.  Introducing a static struct just
 to get a namespace to replace the namespace that is already there but
 gets stripped as the default action upon 'import'.  Ick.

I'm waiting still for the design of the D2 module system to be fixed to something more rational than the current one. The following has to import only the module name "foo" in the current namespace: import foo; This is a syntax that imports into the current namespace all the names contained into the "foo" module (but it doesn't import the "foo" name itself): import foo: *; This imports the "bar" and "baz" names into the current namespace (but it doesn't import the "foo" name itself): import foo: bar, baz; This fixes several problems. It also allows me to have a "foo" name inside the "foo" module without troubles (as the current system leads me to). Be well, bearophile
Apr 12 2009
prev sibling next sibling parent Christopher Wright <dhasenan gmail.com> writes:
Bill Baxter wrote:
 On Sun, Apr 12, 2009 at 5:50 AM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 Lars Kyllingstad wrote:
 I think isInfinite!() should be called isInfiniteRange!(). The current
 name is, in my opinion, too general.

std.range, so std.range.isInfinite is clear and std.range.isInfiniteRange feels redundant. On the other hand, I don't want to use too common symbols because then the user will be forced to prefix them whenever they clash.

This is one of the big reasons why "static import" by default would have been better than pull-everything-in by default. But since pull-everything-in *is* the default. I agree with Lars. Symbols supplied by modules should look unambiguous even when undecorated by their module name. Or you could use the trick that Tango often uses -- make a static struct with a few members. It's pretty ugly though, if you ask me. Introducing a static struct just to get a namespace to replace the namespace that is already there but gets stripped as the default action upon 'import'. Ick. --bb

import range=std.range;
Apr 12 2009
prev sibling parent reply Lars Kyllingstad <public kyllingen.NOSPAMnet> writes:
Andrei Alexandrescu wrote:
 Lars Kyllingstad wrote:
 Andrei Alexandrescu wrote:
 Hi everybody,


 I just committed all of Phobos into svn on dsource.org. That is not an
 official release and has known and unknown bugs, limitations, and
 rhinodemons. I expect some ripples before we stabilize, but when we will
 we'll stabilize at a higher potential.

Some corrections/suggestions to std.range, if you are ready for such yet:

 I think isInfinite!() should be called isInfiniteRange!(). The current 
 name is, in my opinion, too general.

I'm undecided about this (and similar cases). isInfinite sits inside std.range, so std.range.isInfinite is clear and std.range.isInfiniteRange feels redundant. On the other hand, I don't want to use too common symbols because then the user will be forced to prefix them whenever they clash.

I'm not too worried about name clashes, I just think it sounds wrong. If R is a range with infinitely many elements, I think it's more correct to say "R is an infinite range" than to say "R is infinite". As an example of what I mean, let the range R be the sequence 1, 1/4, 1/9, ...: alias Sequence!("1/(n*n)", 1) R Then, isInfiniteRange!(R) should obviously yield true. From a mathematical standpoint, I think the result of isInfinite!(R) is less obvious. Yes, the range has infinitely many elements, but none of them are infinite, nor is their sum infinite. -Lars
Apr 12 2009
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2009-04-12 11:09:51 -0400, Lars Kyllingstad 
<public kyllingen.NOSPAMnet> said:

 Andrei Alexandrescu wrote:
 Lars Kyllingstad wrote:
 I think isInfinite!() should be called isInfiniteRange!(). The current 
 name is, in my opinion, too general.

I'm undecided about this (and similar cases). isInfinite sits inside std.range, so std.range.isInfinite is clear and std.range.isInfiniteRange feels redundant. On the other hand, I don't want to use too common symbols because then the user will be forced to prefix them whenever they clash.

I'm not too worried about name clashes, I just think it sounds wrong. If R is a range with infinitely many elements, I think it's more correct to say "R is an infinite range" than to say "R is infinite". As an example of what I mean, let the range R be the sequence 1, 1/4, 1/9, ...: alias Sequence!("1/(n*n)", 1) R Then, isInfiniteRange!(R) should obviously yield true. From a mathematical standpoint, I think the result of isInfinite!(R) is less obvious. Yes, the range has infinitely many elements, but none of them are infinite, nor is their sum infinite.

Perhaps it should be renamed to isUnbounded then. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Apr 12 2009
next sibling parent reply Leandro Lucarella <llucax gmail.com> writes:
Michel Fortin, el 12 de abril a las 12:54 me escribiste:
 On 2009-04-12 11:09:51 -0400, Lars Kyllingstad <public kyllingen.NOSPAMnet>
said:
 
Andrei Alexandrescu wrote:
Lars Kyllingstad wrote:
I think isInfinite!() should be called isInfiniteRange!(). The current name is,
in my opinion, too general.

redundant. On the other hand, I don't want to use too common symbols because then the user will be forced to prefix them whenever they clash.

an infinite range" than to say "R is infinite". As an example of what I mean, let the range R be the sequence 1, 1/4, 1/9, ...: alias Sequence!("1/(n*n)", 1) R Then, isInfiniteRange!(R) should obviously yield true. From a mathematical standpoint, I think the result of isInfinite!(R) is less obvious. Yes, the range has infinitely many elements, but none of them are infinite, nor is their sum infinite.

Perhaps it should be renamed to isUnbounded then.

I was about to write exaclty the same suggestion. I'm glad I read the responses before posting =) -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- If you don't know what direction you should take You don't know where you are
Apr 12 2009
parent reply Leandro Lucarella <llucax gmail.com> writes:
Leandro Lucarella, el 12 de abril a las 15:19 me escribiste:
 Michel Fortin, el 12 de abril a las 12:54 me escribiste:
 On 2009-04-12 11:09:51 -0400, Lars Kyllingstad <public kyllingen.NOSPAMnet>
said:
 
Andrei Alexandrescu wrote:
Lars Kyllingstad wrote:
I think isInfinite!() should be called isInfiniteRange!(). The current name is,
in my opinion, too general.

redundant. On the other hand, I don't want to use too common symbols because then the user will be forced to prefix them whenever they clash.

an infinite range" than to say "R is infinite". As an example of what I mean, let the range R be the sequence 1, 1/4, 1/9, ...: alias Sequence!("1/(n*n)", 1) R Then, isInfiniteRange!(R) should obviously yield true. From a mathematical standpoint, I think the result of isInfinite!(R) is less obvious. Yes, the range has infinitely many elements, but none of them are infinite, nor is their sum infinite.

Perhaps it should be renamed to isUnbounded then.

I was about to write exaclty the same suggestion. I'm glad I read the responses before posting =)

Maybe isBounded, to avoid the double negation when checking for !isUnbounded... -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- PITUFO ENRIQUE ATEMORIZA CATAMARCA, AMPLIAREMOS -- Cr├│nica TV
Apr 12 2009
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2009-04-12 14:24:07 -0400, Leandro Lucarella <llucax gmail.com> said:

 Leandro Lucarella, el 12 de abril a las 15:19 me escribiste:
 Michel Fortin, el 12 de abril a las 12:54 me escribiste:
 On 2009-04-12 11:09:51 -0400, Lars Kyllingstad 
 <public kyllingen.NOSPAMnet> said:
 
 Perhaps it should be renamed to isUnbounded then.

I was about to write exaclty the same suggestion. I'm glad I read the responses before posting =)

Maybe isBounded, to avoid the double negation when checking for !isUnbounded...

Which makes me think of one thing: why "isBounded" instead of plain and simple "bounded"? Ranges don't respond to "isEmpty": they have "empty" instead. I think it is time to establish some kind of standard for naming things, and then follow it. Something a little like Cocoa's Coding Guidelines comes to mind: <http://developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html> -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Apr 12 2009
next sibling parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Michel Fortin wrote:
 On 2009-04-12 14:24:07 -0400, Leandro Lucarella <llucax gmail.com> said:
 
 Leandro Lucarella, el 12 de abril a las 15:19 me escribiste:
 Michel Fortin, el 12 de abril a las 12:54 me escribiste:
 On 2009-04-12 11:09:51 -0400, Lars Kyllingstad
 <public kyllingen.NOSPAMnet> said:

 Perhaps it should be renamed to isUnbounded then.

I was about to write exaclty the same suggestion. I'm glad I read the responses before posting =)

Maybe isBounded, to avoid the double negation when checking for !isUnbounded...

Which makes me think of one thing: why "isBounded" instead of plain and simple "bounded"? Ranges don't respond to "isEmpty": they have "empty" instead. I think it is time to establish some kind of standard for naming things, and then follow it. Something a little like Cocoa's Coding Guidelines comes to mind: <http://developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html>

You mean http://digitalmars.com/d/1.0/dstyle.html ? That said, the "Naming Conventions" section is actually about formatting names, not choosing them. One major advantage Cocoa has over D is that argument names seem to be part of the function's name. For example, this call: sendAction(aSelector, anObject, flag); appears to be written like so in Objective C: [sendAction: aSelector to: anObject forAllCells: flag]; To be honest, there are times I almost wish we could not only name arguments on the caller side, but demand that they're named in the definition. void sendAction(SEL, Object to, extern bool forAllCells); sendAction(aSelector, to: anObject, // optional forAllCells: true); // required -- Daniel
Apr 12 2009
parent Michel Fortin <michel.fortin michelf.com> writes:
On 2009-04-12 21:34:47 -0400, Daniel Keep <daniel.keep.lists gmail.com> said:

 Michel Fortin wrote:
 Which makes me think of one thing: why "isBounded" instead of plain and
 simple "bounded"? Ranges don't respond to "isEmpty": they have "empty"
 instead.
 
 I think it is time to establish some kind of standard for naming things,
 and then follow it. Something a little like Cocoa's Coding Guidelines
 comes to mind:
 
 <http://developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html>


You
 

"Naming Conventions" section is actually about formatting names, not choosing them.

Nice. Indeed, I think there should be a section about choosing proper names in that document.
 One major advantage Cocoa has over D is that argument names seem to be
 part of the function's name.  For example, this call:
 
   sendAction(aSelector, anObject, flag);
 
 appears to be written like so in Objective C:
 
   [sendAction: aSelector to: anObject forAllCells: flag];
 
 To be honest, there are times I almost wish we could not only name
 arguments on the caller side, but demand that they're named in the
 definition.
 
   void sendAction(SEL, Object to, extern bool forAllCells);
 
   sendAction(aSelector,
     to: anObject,         // optional
     forAllCells: true);   // required

It works in Cocoa because it's part of the method name (the actual method name for the above is "sendAction:to:forAllCells:"). Your idea doesn't work well with function overloading and passing function arguments using tuples. In D, the method mangled name includes the argument types to support that, so you can use an enum instead and get mostly the same result: enum ForCells { ALL, SELECTION } setAction(aSelector, anObject, ForCells.ALL); Hum, that'd be a good pattern to add to a programming guideline document. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Apr 12 2009
prev sibling parent reply Rainer Deyke <rainerd eldwood.com> writes:
Michel Fortin wrote:
 Which makes me think of one thing: why "isBounded" instead of plain and
 simple "bounded"? Ranges don't respond to "isEmpty": they have "empty"
 instead.

"bounded(x)" can be read as a predicate ("Is x bounded?"), an assertion ("x is bounded, so treat it as such.") or even a conversion (although I admit that I can think of a meaningful way to convert an unbounded sequence into a bounded sequence). "isBounded(x)" is unambiguous. -- Rainer Deyke - rainerd eldwood.com
Apr 13 2009
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2009-04-13 03:56:11 -0400, Rainer Deyke <rainerd eldwood.com> said:

 Michel Fortin wrote:
 Which makes me think of one thing: why "isBounded" instead of plain and
 simple "bounded"? Ranges don't respond to "isEmpty": they have "empty"
 instead.

"bounded(x)" can be read as a predicate ("Is x bounded?"), an assertion ("x is bounded, so treat it as such.") or even a conversion (although I admit that I can think of a meaningful way to convert an unbounded sequence into a bounded sequence). "isBounded(x)" is unambiguous.

I disagree. How adding the "is" it disambiguate between the predicate and the assertion? "x.isBounded" reads more like "x is bounded" (the assertion) than "is x bounded" (the predicate). * * * Assuming the "is" form is less ambiguous for bounded, the same could be said about "empty". In fact, not putting "is" in front of "emtpy" is even worse since "empty" can also be a verb. Predicate: "Is x empty?"; Assertion: "x is empty"; Verb: "empty x". Anyway, more than advocating for or against the "is" prefix, I mostly want things to be coherent. If you use "is" for bounded, you should use "is" for empty too. That's why I'm suggesting there is a section about choosing names in Phobos' Naming Conventions. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Apr 13 2009
parent Rainer Deyke <rainerd eldwood.com> writes:
Michel Fortin wrote:
 I disagree. How adding the "is" it disambiguate between the predicate
 and the assertion? "x.isBounded" reads more like "x is bounded" (the
 assertion) than "is x bounded" (the predicate).

Method syntax usually leads to incorrect word order. "a.b(c)", should not be read as "a does b to c", but as "Computer, do b to a and c.". It's a command to the computer, not a statement. In that context, "isBounded(x)" reads as "Computer, is x bounded?". I'm also in favor of "asBounded(x)" (treat x as a bounded range) and "toBounded(x)" (convert x to a bounded range, not really applicable for "bounded").
 Anyway, more than advocating for or against the "is" prefix, I mostly
 want things to be coherent. If you use "is" for bounded, you should use
 "is" for empty too. That's why I'm suggesting there is a section about
 choosing names in Phobos' Naming Conventions.

Agreed. -- Rainer Deyke - rainerd eldwood.com
Apr 13 2009
prev sibling parent reply Lars Kyllingstad <public kyllingen.NOSPAMnet> writes:
Michel Fortin wrote:
 On 2009-04-12 11:09:51 -0400, Lars Kyllingstad 
 <public kyllingen.NOSPAMnet> said:
 
 Andrei Alexandrescu wrote:
 Lars Kyllingstad wrote:
 I think isInfinite!() should be called isInfiniteRange!(). The 
 current name is, in my opinion, too general.

I'm undecided about this (and similar cases). isInfinite sits inside std.range, so std.range.isInfinite is clear and std.range.isInfiniteRange feels redundant. On the other hand, I don't want to use too common symbols because then the user will be forced to prefix them whenever they clash.

I'm not too worried about name clashes, I just think it sounds wrong. If R is a range with infinitely many elements, I think it's more correct to say "R is an infinite range" than to say "R is infinite". As an example of what I mean, let the range R be the sequence 1, 1/4, 1/9, ...: alias Sequence!("1/(n*n)", 1) R Then, isInfiniteRange!(R) should obviously yield true. From a mathematical standpoint, I think the result of isInfinite!(R) is less obvious. Yes, the range has infinitely many elements, but none of them are infinite, nor is their sum infinite.

Perhaps it should be renamed to isUnbounded then.

...except that my example, and indeed any range produced by sequence, recurrence, etc. are bounded at one end. Thus the term "infinite range" is more precise, and fits in well with the mathematical terms "infinite series" and "infinite sequence". Just not "infinite" alone. :) -Lars
Apr 13 2009
next sibling parent Michel Fortin <michel.fortin michelf.com> writes:
On 2009-04-13 04:20:32 -0400, Lars Kyllingstad 
<public kyllingen.NOSPAMnet> said:

 ...except that my example, and indeed any range produced by sequence, 
 recurrence, etc. are bounded at one end. Thus the term "infinite range" 
 is more precise, and fits in well with the mathematical terms "infinite 
 series" and "infinite sequence". Just not "infinite" alone. :)

Indeed. And since the thing in the argument is indeed a range, I'd use infinite alone in the function name. That way, if you build something which isn't a range but still represent a sequence, it can have this part of the interface in common. In a language that doesn't support overloading (such as C or Objective-C), I'd be in favor of keeping the "range" suffix to differenciate the function from other functions applying to other kinds of arguments. In D, or C++, which support overloading, I'm in favor of skipping the argument type suffix. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Apr 13 2009
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Lars Kyllingstad wrote:
 Michel Fortin wrote:
 On 2009-04-12 11:09:51 -0400, Lars Kyllingstad 
 <public kyllingen.NOSPAMnet> said:

 Andrei Alexandrescu wrote:
 Lars Kyllingstad wrote:
 I think isInfinite!() should be called isInfiniteRange!(). The 
 current name is, in my opinion, too general.

I'm undecided about this (and similar cases). isInfinite sits inside std.range, so std.range.isInfinite is clear and std.range.isInfiniteRange feels redundant. On the other hand, I don't want to use too common symbols because then the user will be forced to prefix them whenever they clash.

I'm not too worried about name clashes, I just think it sounds wrong. If R is a range with infinitely many elements, I think it's more correct to say "R is an infinite range" than to say "R is infinite". As an example of what I mean, let the range R be the sequence 1, 1/4, 1/9, ...: alias Sequence!("1/(n*n)", 1) R Then, isInfiniteRange!(R) should obviously yield true. From a mathematical standpoint, I think the result of isInfinite!(R) is less obvious. Yes, the range has infinitely many elements, but none of them are infinite, nor is their sum infinite.

Perhaps it should be renamed to isUnbounded then.

...except that my example, and indeed any range produced by sequence, recurrence, etc. are bounded at one end. Thus the term "infinite range" is more precise, and fits in well with the mathematical terms "infinite series" and "infinite sequence". Just not "infinite" alone. :) -Lars

Finally! I was waiting for someone to make this point. "Bounded" would be closer to "having values within a finite interval". Andrei
Apr 13 2009
parent Don <nospam nospam.com> writes:
Andrei Alexandrescu wrote:
 Lars Kyllingstad wrote:
 Michel Fortin wrote:
 On 2009-04-12 11:09:51 -0400, Lars Kyllingstad 
 <public kyllingen.NOSPAMnet> said:

 Andrei Alexandrescu wrote:
 Lars Kyllingstad wrote:
 I think isInfinite!() should be called isInfiniteRange!(). The 
 current name is, in my opinion, too general.

I'm undecided about this (and similar cases). isInfinite sits inside std.range, so std.range.isInfinite is clear and std.range.isInfiniteRange feels redundant. On the other hand, I don't want to use too common symbols because then the user will be forced to prefix them whenever they clash.

I'm not too worried about name clashes, I just think it sounds wrong. If R is a range with infinitely many elements, I think it's more correct to say "R is an infinite range" than to say "R is infinite". As an example of what I mean, let the range R be the sequence 1, 1/4, 1/9, ...: alias Sequence!("1/(n*n)", 1) R Then, isInfiniteRange!(R) should obviously yield true. From a mathematical standpoint, I think the result of isInfinite!(R) is less obvious. Yes, the range has infinitely many elements, but none of them are infinite, nor is their sum infinite.

Perhaps it should be renamed to isUnbounded then.

...except that my example, and indeed any range produced by sequence, recurrence, etc. are bounded at one end. Thus the term "infinite range" is more precise, and fits in well with the mathematical terms "infinite series" and "infinite sequence". Just not "infinite" alone. :) -Lars

Finally! I was waiting for someone to make this point. "Bounded" would be closer to "having values within a finite interval". Andrei

There's a funny thing with floating-point numbers, though. The range [real.max, real.infinity] contains only two elements, one of which is infinity. Is that an infinite range? It would be helpful to distinguish "contains arbitrary many elements"/"length is undefined" from "contains the point at infinity"/"includes the maximum representable element for this type".
Apr 13 2009
prev sibling next sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Sat, Apr 11, 2009 at 7:36 PM, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:
 I wonder what a good name would be.

How about... umm... oh I don't know. "Tuple"?
Apr 11 2009
prev sibling next sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Sun, Apr 12, 2009 at 5:50 AM, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:
 Lars Kyllingstad wrote:
 I think isInfinite!() should be called isInfiniteRange!(). The current
 name is, in my opinion, too general.

I'm undecided about this (and similar cases). isInfinite sits inside std.range, so std.range.isInfinite is clear and std.range.isInfiniteRange feels redundant. On the other hand, I don't want to use too common symbols because then the user will be forced to prefix them whenever they clash.

This is one of the big reasons why "static import" by default would have been better than pull-everything-in by default. But since pull-everything-in *is* the default. I agree with Lars. Symbols supplied by modules should look unambiguous even when undecorated by their module name. Or you could use the trick that Tango often uses -- make a static struct with a few members. It's pretty ugly though, if you ask me. Introducing a static struct just to get a namespace to replace the namespace that is already there but gets stripped as the default action upon 'import'. Ick. --bb
Apr 11 2009
prev sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Sun, Apr 12, 2009 at 11:06 PM, Christopher Wright <dhasenan gmail.com> w=
rote:
 Bill Baxter wrote:
 On Sun, Apr 12, 2009 at 5:50 AM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 Lars Kyllingstad wrote:
 I think isInfinite!() should be called isInfiniteRange!(). The current
 name is, in my opinion, too general.

I'm undecided about this (and similar cases). isInfinite sits inside std.range, so std.range.isInfinite is clear and std.range.isInfiniteRan=



 feels redundant. On the other hand, I don't want to use too common
 symbols
 because then the user will be forced to prefix them whenever they clash=



 This is one of the big reasons why "static import" by default would
 have been better than pull-everything-in by default.

 But since pull-everything-in *is* the default. =A0I agree with Lars.
 Symbols supplied by modules should look unambiguous even when
 undecorated by their module name. =A0Or you could use the trick that
 Tango often uses -- make a static struct with a few members. =A0It's
 pretty ugly though, if you ask me. =A0Introducing a static struct just
 to get a namespace to replace the namespace that is already there but
 gets stripped as the default action upon 'import'. =A0Ick.

 --bb

import range=3Dstd.range;

Not a default. --bb
Apr 12 2009
prev sibling parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Looking at the documentation, I found std.range.isForwardRange.  I had a
look at the implementation, and it basically just checks to make sure
you can do this:

 R r1;
 R r2 = r1;

How do you construct an input range which is not also a forward range? For structs, you can't prevent that second line from working, except by throwing an exception in postblit (which the test won't notice). For classes, you have no control over direct assignment. Here's a practical example: I'm playing with a program that will parse the output of DMD to find out module imports. I want to expose this list of imports as a range. However, this range is NOT resumable since you can't seek a program's captured stdout backwards; copying the file handle certainly isn't going to work... You could probably do it by making sure the range is a struct pointing to a class which can then take its internal file handle and re-assign it to a split buffered stream... but I'm never going to use it like that, so why should I go through all that effort? Aside from making it possible to forbid assignment (blech), it seems like there needs to be a way to flag a range as not supporting resuming. The only reasonable way I can think of off the top of my head would be something like this:
 template isResumableRange(R)
 {
     enum bool isResumableRange = isInputRange!(R)
         && (is(typeof(R.isResumableRange)) && R.isResumableRange)
         && is(typeof(
         {
             R r1;
             R r2 = r1;
         }()));
 }

 unittest
 {
     static assert(!isResumableRange!(int));
     static assert(isResumableRange!(int[]));

     struct A {}
     struct B
     {
         void next();
         bool empty();
         int head();
     }
     struct C
     {
         static enum isResumableRange = true;
         void next();
         bool empty();
         int head();
     }
     struct D
     {
         static enum isResumableRange = false;
         void next();
         bool empty();
         int head();
     }
     static assert(isResumableRange!(A));
     static assert(isResumableRange!(B));
     static assert(isResumableRange!(C));
     static assert(isResumableRange!(D));
 }

I also took the opportunity to rename isForwardRange to isResumableRange since I can't see how the ability to make a "checkpoint" has anything to do with being able to go forward. For example isBidirectionalRange requires isForwardRange, but what does saving checkpoints have to do with being able to go in both directions? -- Daniel
Apr 12 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Daniel Keep wrote:
 Looking at the documentation, I found std.range.isForwardRange.  I had a
 look at the implementation, and it basically just checks to make sure
 you can do this:
 
 R r1;
 R r2 = r1;

How do you construct an input range which is not also a forward range?

In fact you can't. Thank you for opening this discussion, it's very interesting. In the current system, an input range and a forward range cannot be distinguished statically. I wanted to, and initially I thought it's possible, but I had to concede defeat. The problem s that forward ranges also need to be copyable, otherwise using them is a pain. Then I considered defining different symbols for input vs. other ranges, but that only makes things harder. So right now... input range means "one pass, can't save iteration state and backtrack" and forward range means "forward pass, can save iteration state".
 Aside from making it possible to forbid assignment (blech), it seems
 like there needs to be a way to flag a range as not supporting resuming.
  The only reasonable way I can think of off the top of my head would be
 something like this:
 
 template isResumableRange(R)
 {
     enum bool isResumableRange = isInputRange!(R)
         && (is(typeof(R.isResumableRange)) && R.isResumableRange)
         && is(typeof(
         {
             R r1;
             R r2 = r1;
         }()));
 }

 unittest
 {
     static assert(!isResumableRange!(int));
     static assert(isResumableRange!(int[]));

     struct A {}
     struct B
     {
         void next();
         bool empty();
         int head();
     }
     struct C
     {
         static enum isResumableRange = true;
         void next();
         bool empty();
         int head();
     }
     struct D
     {
         static enum isResumableRange = false;
         void next();
         bool empty();
         int head();
     }
     static assert(isResumableRange!(A));
     static assert(isResumableRange!(B));
     static assert(isResumableRange!(C));
     static assert(isResumableRange!(D));
 }

I also took the opportunity to rename isForwardRange to isResumableRange since I can't see how the ability to make a "checkpoint" has anything to do with being able to go forward. For example isBidirectionalRange requires isForwardRange, but what does saving checkpoints have to do with being able to go in both directions?

So essentially we're looking at a symbolic approach - a resumable range would need to advertise that. I've used that for isSorted too, and it works pretty well. The remaining question is one of defaults - are most ranges resumable or not? I.e., should a range advertise explicitly when it's resumable or when it's *not* resumable? I think the safe approach is to go as you say: a range ain't resumable unless it explicitly claims to. So if you forget stuff, the compiler will remind you. I'd love to hear more opinions on the topic. Andrei
Apr 13 2009
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Andrei Alexandrescu wrote:
 Daniel Keep wrote:
 ...

So essentially we're looking at a symbolic approach - a resumable range would need to advertise that. I've used that for isSorted too, and it works pretty well. The remaining question is one of defaults - are most ranges resumable or not? I.e., should a range advertise explicitly when it's resumable or when it's *not* resumable? I think the safe approach is to go as you say: a range ain't resumable unless it explicitly claims to. So if you forget stuff, the compiler will remind you. I'd love to hear more opinions on the topic. Andrei

Actually, I stuffed up the test; I wanted the default to be resumable. :P That'll teach me to not double-check my logic. A quick truth table later, and the correct test is this:
 template isResumableRange(R)
 {
     enum bool isResumableRange = isInputRange!(R)
         && (!is(typeof(R.isResumableRange))
             || (is(typeof(R.isResumableRange)) && R.isResumableRange))
         && is(typeof(
         {
             R r1;
             R r2 = r1;
         }()));
 }

... I think. :P Actually, I've been thinking and I realised that in 95% of cases, you can assume a range is resumable if it has no references. If it has no references, the only way the range can be non-resumable is if the advance member uses the range's state as an argument to some global method. An example might be a Range that statically accesses Stdout instead of taking it as an argument. It's a real shame the range interface doesn't support this:
 struct R
 {
     ...
     pure R advance();
 }

If it did, we could prove a range was resumable if advance was pure and R has no mutable or const references. Honestly, I think the safest option is to *require* resuming to be explicitly stated by the programmer. It'd be nice if we could automatically account for some cases, but I can't think of any you couldn't escape from. Maybe we should default to non-resumable for now, then re-visit the issue when we have an idea of how people are using ranges. -- Daniel
Apr 13 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Daniel Keep wrote:
 Actually, I've been thinking and I realised that in 95% of cases, you
 can assume a range is resumable if it has no references.

Well I'm not so sure. How about a range around an integral file handle or socket?
 If it has no
 references, the only way the range can be non-resumable is if the
 advance member uses the range's state as an argument to some global
 method.  An example might be a Range that statically accesses Stdout
 instead of taking it as an argument.
 
 It's a real shame the range interface doesn't support this:
 
 struct R
 {
     ...
     pure R advance();
 }

If it did, we could prove a range was resumable if advance was pure and R has no mutable or const references.

Hmmmm... well, pure changes "this". We'd need to say that it only changes state owned by "this", but we have no notion of "almost pure".
 Honestly, I think the safest option is to *require* resuming to be
 explicitly stated by the programmer.  It'd be nice if we could
 automatically account for some cases, but I can't think of any you
 couldn't escape from.
 
 Maybe we should default to non-resumable for now, then re-visit the
 issue when we have an idea of how people are using ranges.

I agree. Probably I'll do that, thanks. By the way, Walter and I both changed the names of the members to what everybody seemed to liked best: front, back, popFront, popBack. No more heads and toes. Andrei
Apr 13 2009
next sibling parent reply Benji Smith <dlanguage benjismith.net> writes:
Andrei Alexandrescu wrote:
 Daniel Keep wrote:
 Actually, I've been thinking and I realised that in 95% of cases, you
 can assume a range is resumable if it has no references.

Well I'm not so sure. How about a range around an integral file handle or socket?

If ranges can advertise their resumability, it wouldn't be hard to write a simple template wrapper that provides resumability to an underlying non-resumable range. --benji
Apr 13 2009
parent Michel Fortin <michel.fortin michelf.com> writes:
On 2009-04-13 22:28:33 -0400, Benji Smith <dlanguage benjismith.net> said:

 Andrei Alexandrescu wrote:
 Daniel Keep wrote:
 Actually, I've been thinking and I realised that in 95% of cases, you
 can assume a range is resumable if it has no references.

Well I'm not so sure. How about a range around an integral file handle or socket?

If ranges can advertise their resumability, it wouldn't be hard to write a simple template wrapper that provides resumability to an underlying non-resumable range.

If the language supported making an struct non-copyable, you could use this. Actually, using a class for a non-resumable range would already acheive this (you'd only be copying references). So perhaps you could consider a class used as a range as non-resumable, and use classes for non-resumable ranges. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Apr 14 2009
prev sibling parent Daniel Keep <daniel.keep.lists gmail.com> writes:
Andrei Alexandrescu wrote:
 Daniel Keep wrote:
 Actually, I've been thinking and I realised that in 95% of cases, you
 can assume a range is resumable if it has no references.

Well I'm not so sure. How about a range around an integral file handle or socket?

Most of the time, I'd expect people to be accessing those via the standard library. And that wraps them in objects. :)
 If it has no
 references, the only way the range can be non-resumable is if the
 advance member uses the range's state as an argument to some global
 method.  An example might be a Range that statically accesses Stdout
 instead of taking it as an argument.

 It's a real shame the range interface doesn't support this:

 struct R
 {
     ...
     pure R advance();
 }

If it did, we could prove a range was resumable if advance was pure and R has no mutable or const references.

Hmmmm... well, pure changes "this". We'd need to say that it only changes state owned by "this", but we have no notion of "almost pure".

Hence why I made R a return value. If you have a member function that's pure in every way EXCEPT that it changes "this", you can rewrite it like so:
 R range = getRange();
 range = range.advance;

Ta-da, advance can be pure since the changes are pushed out via the return value. In other words,
 struct R(T)
 {
     pure bool empty();
     pure T head();
     pure R!(T) advance();
 }

is a pure, guaranteed safe-to-resume version of this:
 struct R(T)
 {
     bool empty();
     T head();
     void advance();
 }

The only difference is that instead of writing this:
 for( auto v = r.head; !r.empty; r.advance ) ...

You'd write this:
 for( auto v = r.head; !r.empty; r = r.advance ) ...

 Honestly, I think the safest option is to *require* resuming to be
 explicitly stated by the programmer.  It'd be nice if we could
 automatically account for some cases, but I can't think of any you
 couldn't escape from.

 Maybe we should default to non-resumable for now, then re-visit the
 issue when we have an idea of how people are using ranges.

I agree. Probably I'll do that, thanks. By the way, Walter and I both changed the names of the members to what everybody seemed to liked best: front, back, popFront, popBack. No more heads and toes. Andrei

Cool. I really can't wait to dive into this stuff. There are a few things I've been wanting to write in D2 that I'm holding off until the range stuff is done so I can give it a workout. -- Daniel
Apr 13 2009