www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Fluent APIs

reply Russel Winder via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
I am having a crisis of confidence. In two places I have structurally:

    datum.action()
      .map!(=E2=80=A6)

and then the fun starts as I need to actually do a flatMap. In one of
the two places I have to:

    .array
    .joiner;

but in the other place I have to:

    .joiner
    .array;

in order to stop the compiler spewing out a mass of (to me anyway)
incomprehensible messages with types I have no knowledge of. So why
does the fluent API chain break in different ways in the two cases. A
Priori this seems like a breakage of the abstraction.

Full code is at
https://github.com/russel/ApproxGC/blob/master/source/main.d
The comparison is between the functions createGenerationsDeleteList and
createListOfPlaces.

Any help rebuilding my knowledge would be good.

Also error message comprehensible to programmers rather than compiler
writers  might help.

--=20
Russel.
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D
Dr Russel Winder      t: +44 20 7585 2200   voip: sip:russel.winder ekiga.n=
et
41 Buckmaster Road    m: +44 7770 465 077   xmpp: russel winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder
May 20 2017
parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Sunday, 21 May 2017 at 05:18:33 UTC, Russel Winder wrote:
 I am having a crisis of confidence. In two places I have 
 structurally:

     datum.action()
       .map!(…)

 and then the fun starts as I need to actually do a flatMap. In 
 one of the two places I have to:

     .array
     .joiner;

 but in the other place I have to:

     .joiner
     .array;

 in order to stop the compiler spewing out a mass of (to me 
 anyway) incomprehensible messages with types I have no 
 knowledge of. So why does the fluent API chain break in 
 different ways in the two cases. A Priori this seems like a 
 breakage of the abstraction.

 Full code is at
 https://github.com/russel/ApproxGC/blob/master/source/main.d
 The comparison is between the functions 
 createGenerationsDeleteList and
 createListOfPlaces.

 Any help rebuilding my knowledge would be good.

 Also error message comprehensible to programmers rather than 
 compiler writers  might help.
For this kind of errors I find that it helps to break the pipeline into individual stages and reason about the type separately. Function createGenerationsDeleteList returns auto. { groups.byPair() // This gives a range of Tuple!(string, string[]) .map!(func) // this gives a sorted range of string[] .array // this gives a string[][] .joiner; // this gives a range of string[] } all is good. If we swap the array and joiner we get { .map!(func) // this gives a sorted range of string[] .joiner // range of range of string(?) .array; // array of range of string } return type is auto, no problems. Function createListOfPlaces return string[] <------ { path.dirEntries(SpanMode.shallow) // range of DirEntries .map!(p => p.name) // range of strings .map!(p => // range of p.dirEntries("*.deb", SpanMode.depth). // range of dir entires map!(a => a.dirName).uniq) // goes to a range of strings // have a range of range of strings here .joiner // range of string .array // string[] } all is good. swap the array and joiner and we have { // have a range of range of strings here .array // array of range of string .joiner // range of string } range of string is NOT string[], hence you get an error. TL;DR you specified the return type in the second case, changing the order of the operations yields a different type -> type error.
May 20 2017