View mode: basic / threaded / horizontal-split · Log in · Help
March 05, 2011
Re: Plot2kill 0.2
On 3/5/2011 4:42 PM, Michel Fortin wrote:
> I've always been on the fence about this. I find it useful too, and I
> like the visual effect of optional parenthesis. But returning anything
> that is callable make things ambiguous to the reader and can even bring
> bugs when it comes to generic programming; and ambiguity and bugs are
> things I really don't want to see.
>
>

So?  Make the semantics of @property one-way instead of two-way and make 
it a best practice to always use it in generic code.  @property 
functions **can't** be called with (), but ()s are **optional** for 
stuff not marked @property.
March 05, 2011
Re: Plot2kill 0.2
On 2011-03-05 16:49:30 -0500, dsimcha <dsimcha@yahoo.com> said:

> On 3/5/2011 4:42 PM, Michel Fortin wrote:
>> I've always been on the fence about this. I find it useful too, and I
>> like the visual effect of optional parenthesis. But returning anything
>> that is callable make things ambiguous to the reader and can even bring
>> bugs when it comes to generic programming; and ambiguity and bugs are
>> things I really don't want to see.
> 
> So?  Make the semantics of @property one-way instead of two-way and 
> make it a best practice to always use it in generic code.  @property 
> functions **can't** be called with (), but ()s are **optional** for 
> stuff not marked @property.

There's still a small ambiguity with functions returning callable 
types. For instance, if you have a template defining a property of a 
parametrized type, forgetting to add @property to the getter could 
result in buggy behaviour with a callable type but work fine with 
everything else. Is making parenthesis optional worth making this kind 
of bug easier to slip by, I wonder.

That said, () being optional doesn't help you use setters with 
chaining. You'd have to not label your setters with @property for them 
to work with chaining, unless you want to play with a lot of nested 
parenthesis.

	(((Graph().title = abc).xTitle = def).yTitle = hij);

Wow, that looks almost like Objective-C!

This discussion should probably happen somewhere else than the 
announcement forum though.

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/
March 05, 2011
Re: Plot2kill 0.2
On 3/5/2011 5:51 PM, Michel Fortin wrote:
> There's still a small ambiguity with functions returning callable types.
> For instance, if you have a template defining a property of a
> parametrized type, forgetting to add @property to the getter could
> result in buggy behaviour with a callable type but work fine with
> everything else. Is making parenthesis optional worth making this kind
> of bug easier to slip by, I wonder.

This is an extreme corner case, especially if a one-way semantic 
@property syntax is available to work around it.  The percentage of 
functions that return callables is very small, and of these the 
percentage that would forget @property is probably very small.  I'd 
rather bug-proneness in a ridiculous corner case than breaking tons of 
existing code code and losing a nice feature in the common case.

>
> That said, () being optional doesn't help you use setters with chaining.
> You'd have to not label your setters with @property for them to work
> with chaining, unless you want to play with a lot of nested parenthesis.
>
> (((Graph().title = abc).xTitle = def).yTitle = hij);
>
> Wow, that looks almost like Objective-C!

Right.  The point is that I can do the same thing with either property 
syntax or with chaining.  The choice is up to me as the caller, if the 
API designer is ok with allowing this choice.
March 06, 2011
Re: Plot2kill 0.2
dsimcha:

> I'd rather bug-proneness in a ridiculous corner case than breaking tons of 
> existing code code and losing a nice feature in the common case.

That "existing code" will cause troubles to D2 development. People get attached to wrong/deprecated features.

Bye,
bearophile
March 06, 2011
Re: Plot2kill 0.2
"Robert Jacques" <sandford@jhu.edu> wrote in message 
news:op.vrvz7do126stm6@sandford.myhome.westell.com...
> On Sat, 05 Mar 2011 13:42:32 -0500, bearophile <bearophileHUGS@lycos.com>
> wrote:
>
>> dsimcha:
>>
>>> I've done some major updating of my Plot2kill plotting library lately,
>>
>> I see code that wants named arguments :-)
>>
>> 65     auto sleepinessFig = Figure(sleepinessPlot)
>> 66         .title("Sleepiness Survey")
>> 67         .yLabel("Sleepiness Rating")
>> 68         .xLabel("Activity")
>> 69         .legendLocation(LegendLocation.right)
>> 70         .horizontalGrid(true)
>> 71         .xTickLabels(
>> 72             iota(3),
>> 73             ["In Meeting", "On Phone", "Coding"]
>> 74         );
>>
>> Bye,
>> bearophile
>
> Why? Each of those arguments should be able to be set after creation. So
> given DRY principals, method chaining is the way to go. Besides, Figure
> takes a variable number of plot arguments, which means you couldn't
> support default arguments (at least with the current syntax).

I've also attached this as a file in case it's hard to read on the NG 
clients:

--------------------------------------------------
// Tested on DMD 2.050
import std.variant;

template Optional(T)
{
   alias Algebraic!(T) Optional;
}

template notSpecified(T)
{
   Optional!T notSpecified;
}

Optional!T specified(T)(T val)
{
   return Optional!T(val);
}

void setIfSpecified(T)(ref T target, Optional!T val)
{
   if(val.hasValue())
       target = val.get!T();
}

struct Plot
{
   string name;
}

struct Fancy
{
   string memberVar1;
   int[]  memberVar2;
   bool   memberVar3;

   // I don't know why I need this or why it seems to need to be called 
manually.
   const int opCmp(ref const Fancy other)
   {
       return
           memberVar1 == other.memberVar1 &&
           memberVar2 == other.memberVar2 &&
           memberVar3 == other.memberVar3;
   }
}

struct Figure
{
   Plot   plot;
   string title;
   bool   horizontalGrid;
   Fancy  fancy;

   this(Plot plot)
   {
       this.plot = plot;
   }

   ref Figure set(
       Optional!string title          = notSpecified!string,
       Optional!bool   horizontalGrid = notSpecified!bool,
       Optional!Fancy  fancy          = notSpecified!Fancy
   )
   {
       setIfSpecified!string(this.title,          title);
       setIfSpecified!bool  (this.horizontalGrid, horizontalGrid);
       setIfSpecified!Fancy (this.fancy,          fancy);
       return this;
   }
}

void main()
{
   // All of the ugly 'specified()' could be eliminated if there
   // were some sort of opImplicitCast

   auto fig = Figure(Plot("My Plot"))
       .set(
           specified("My Title"),
           specified(true),
           specified(Fancy("Foo", [1,2,3], true))
       );

   assert(fig.title == "My Title");
   assert(fig.horizontalGrid == true);
   assert(fig.fancy.opCmp( Fancy("Foo", [1,2,3], true) ));

   fig = fig.set().set().set();
   assert(fig.title == "My Title");
   assert(fig.horizontalGrid == true);
   assert(fig.fancy.opCmp( Fancy("Foo", [1,2,3], true) ));

   fig = fig.set( specified("New title name") );
   assert(fig.title == "New title name");
   assert(fig.horizontalGrid == true);
   assert(fig.fancy.opCmp( Fancy("Foo", [1,2,3], true) ));

   // The above maybe aren't so special as-is, but with named arguments
   // the following could be uncommented and used:
   /+

   fig = fig.set(
       fancy: specified(Fancy("Bar", [7,9,12], false)),
       title: specified("Another Title")
   );
   assert(fig.title == "Bar");
   assert(fig.horizontalGrid == true);
   assert(fig.fancy.opCmp( Fancy("Bar", [7,9,12], false) ));

   +/
}

--------------------------------------------------
March 06, 2011
Re: Plot2kill 0.2
On 2011-03-05 18:42:26 -0500, dsimcha <dsimcha@yahoo.com> said:

> This is an extreme corner case, especially if a one-way semantic 
> @property syntax is available to work around it.  The percentage of 
> functions that return callables is very small, and of these the 
> percentage that would forget @property is probably very small.  I'd 
> rather bug-proneness in a ridiculous corner case than breaking tons of 
> existing code code and losing a nice feature in the common case.

The percentage of functions that return a callable is very small until 
you go to template land. I can easily make a container or a range of 
delegates, and if someone somewhere forgot to make 'front' a property 
in the container, in the container's range or in one of the filter 
range layered on top of it, then writing 'front()' to call the front 
delegate becomes unreliable. Is it a corner case? Yes. Is it ridiculous 
to expect the language to detect rare but hard to find bugs? No. Is it 
worth it in this case? I think so.


>> That said, () being optional doesn't help you use setters with chaining.
>> You'd have to not label your setters with @property for them to work
>> with chaining, unless you want to play with a lot of nested parenthesis.
>> 
>> (((Graph().title = abc).xTitle = def).yTitle = hij);
>> 
>> Wow, that looks almost like Objective-C!
> 
> Right.  The point is that I can do the same thing with either property 
> syntax or with chaining.  The choice is up to me as the caller, if the 
> API designer is ok with allowing this choice.

Allowing optional '()' and allowing optional '=' are two different 
things. But contrary to optional '()' I don't see much of a problem 
with '=' as there's no ambiguity possible. It just looks a little 
strange to have a @property attribute and not restrict the property 
assignment syntax to it.

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/
March 06, 2011
Re: Plot2kill 0.2
"Michel Fortin" <michel.fortin@michelf.com> wrote in message 
news:ikum9a$2agj$1@digitalmars.com...
> On 2011-03-05 18:42:26 -0500, dsimcha <dsimcha@yahoo.com> said:
>
>> This is an extreme corner case, especially if a one-way semantic 
>> @property syntax is available to work around it.  The percentage of 
>> functions that return callables is very small, and of these the 
>> percentage that would forget @property is probably very small.  I'd 
>> rather bug-proneness in a ridiculous corner case than breaking tons of 
>> existing code code and losing a nice feature in the common case.
>
> The percentage of functions that return a callable is very small until you 
> go to template land. I can easily make a container or a range of 
> delegates, and if someone somewhere forgot to make 'front' a property in 
> the container, in the container's range or in one of the filter range 
> layered on top of it, then writing 'front()' to call the front delegate 
> becomes unreliable. Is it a corner case? Yes. Is it ridiculous to expect 
> the language to detect rare but hard to find bugs? No. Is it worth it in 
> this case? I think so.
>

Along those lines, I'll point out that the idea of a range of delegates is 
not a stretch at all: it could make a lot of sense for a GUI API, for 
instance. The .NET windowing API handles callbacks as collections of 
delegates and I always thought that worked fairly well (and seems 
functionally equivalent to Qt's system of signals and slots, AIUI).
March 06, 2011
Re: Plot2kill 0.2
"Nick Sabalausky" <a@a.a> wrote in message 
news:ikuome$2edr$1@digitalmars.com...
> "Michel Fortin" <michel.fortin@michelf.com> wrote in message 
> news:ikum9a$2agj$1@digitalmars.com...
>> On 2011-03-05 18:42:26 -0500, dsimcha <dsimcha@yahoo.com> said:
>>
>>> This is an extreme corner case, especially if a one-way semantic 
>>> @property syntax is available to work around it.  The percentage of 
>>> functions that return callables is very small, and of these the 
>>> percentage that would forget @property is probably very small.  I'd 
>>> rather bug-proneness in a ridiculous corner case than breaking tons of 
>>> existing code code and losing a nice feature in the common case.
>>
>> The percentage of functions that return a callable is very small until 
>> you go to template land. I can easily make a container or a range of 
>> delegates, and if someone somewhere forgot to make 'front' a property in 
>> the container, in the container's range or in one of the filter range 
>> layered on top of it, then writing 'front()' to call the front delegate 
>> becomes unreliable. Is it a corner case? Yes. Is it ridiculous to expect 
>> the language to detect rare but hard to find bugs? No. Is it worth it in 
>> this case? I think so.
>>
>
> Along those lines, I'll point out that the idea of a range of delegates is 
> not a stretch at all: it could make a lot of sense for a GUI API, for 
> instance. The .NET windowing API handles callbacks as collections of 
> delegates and I always thought that worked fairly well (and seems 
> functionally equivalent to Qt's system of signals and slots, AIUI).
>

s/callbacks/events/   (Although I guess it works either way.)
March 06, 2011
Re: Plot2kill 0.2
The GUI lib DFL uses callbacks as well IIRC. Probably not a range of
them though. I do know that in Qt you can have a signal attached to
multiple slots.
March 06, 2011
Re: Plot2kill 0.2
On Sat, 05 Mar 2011 13:31:22 -0500, dsimcha wrote:

> On 3/5/2011 1:27 PM, Lars T. Kyllingstad wrote:
>> Does this mean that it can save to vector formats now, or just that you
>> intend to add that functionality?  EPS would be awesome, because it's
>> pretty much the only thing you can use directly with LaTeX.  (Yes,
>> pdfLaTeX accepts many other formats, but many scientific journals still
>> require you to provide EPS figures.)
>>
>> Of course, one can usually convert losslessly between the various
>> vector formats, but it would be most convenient if Plot2kill could save
>> directly to EPS, PDF and SVG.
>>
>> -Lars
> 
> ?????  Plot2kill (the GTK version) has been able to save to EPS, SVG,
> PDF, PNG, JPEG and BMP since I switched the GTK port to use the Cairo
> backend last July.  (The DFL port can only do BMP and PNG.)  If this is
> a killer feature for you, I apologize for not publicizing it more back
> then.  I've been eating my own dogfood since then.  All of the graphs in
> my Ph.D. proposal and a publication manuscript I'm working on are
> Plot2Kill rendered and saved in vector formats.

Oh, I didn't know that.  That's very cool!  I can't remember seeing an 
announcement of this feature from you, nor did I expect the feature to be 
there, so I guess I just didn't look that closely for it. :)

-Lars
1 2 3 4 5
Top | Discussion index | About this forum | D home