www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - Plot2kill 0.2

reply dsimcha <dsimcha yahoo.com> writes:
I've done some major updating of my Plot2kill plotting library lately, 
such that I thought it was worth posting an announcement and calling it 
version 0.2.  The code is at http://dsource.org/projects/plot2kill/wiki 
.  The documentation unfortunately won't compile due to DMD Bug 5704 
(http://d.puremagic.com/issues/show_bug.cgi?id=5704).

New features/improvements:

Box Plots

Grouped Bar Plots

X and Y tick labels can be rotated

Legends

Better tick label drawing heuristics

Several settings (Labels, legends, zoom, fonts, tick labels and 
settings) exposed in GTK default plot window GUI.

A new sample image is located at: 
http://dsource.org/projects/plot2kill/browser/docs/sp.png   Note that 
some of the plots look a little weird because they're so compacted. 
Rest assured, they look better when you zoom in.

For those who aren't familiar with it, Plot2kill supports both gtkD and 
DFL.  I've put the DFL port in maintenance mode.  It still works, but I 
won't be backporting any of the GUI-specific changes anytime soon.  This 
is mostly because DFL has a few key limitations that would make this 
port second-rate compared to the GTK port no matter what.  The most 
important ones are lack of support for non-Windows OS's and lack of an 
easy way to save in vector formats.  Furthermore, DFL has bit rotted 
such that it doesn't even compile without some modifications on DMD 2.052.
Mar 05 2011
next sibling parent reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
On Sat, 05 Mar 2011 13:09:15 -0500, dsimcha wrote:

 I've done some major updating of my Plot2kill plotting library lately,
 such that I thought it was worth posting an announcement and calling it
 version 0.2.
Cool! :) I'll be sure to try it out.
 [...]
 
 For those who aren't familiar with it, Plot2kill supports both gtkD and
 DFL.  I've put the DFL port in maintenance mode.  It still works, but I
 won't be backporting any of the GUI-specific changes anytime soon.  This
 is mostly because DFL has a few key limitations that would make this
 port second-rate compared to the GTK port no matter what.  The most
 important ones are lack of support for non-Windows OS's and lack of an
 easy way to save in vector formats.  Furthermore, DFL has bit rotted
 such that it doesn't even compile without some modifications on DMD
 2.052.
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
Mar 05 2011
parent reply dsimcha <dsimcha yahoo.com> writes:
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.
Mar 05 2011
parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
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
Mar 06 2011
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
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
Mar 05 2011
parent reply "Robert Jacques" <sandford jhu.edu> writes:
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).
Mar 05 2011
next sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2011-03-05 15:22:15 -0500, "Robert Jacques" <sandford jhu.edu> said:

 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).
The funny thing is what will happen to this code once property is properly implemented? I think this is a cleaner way to write the above, and it'll work with property: auto sleepinessFig = Figure(sleepinessPlot); with (sleepinessFig) { title = "Sleepiness Survey"; yLabel = "Seeliness Rating"; xLabel = "Activity"; legendLocation = LegendLocation.right; horizontalGrid = true; xTickLabels(iota(3), ["In meeting, "On Phone", "Coding]); } -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Mar 05 2011
parent reply dsimcha <dsimcha yahoo.com> writes:
This is why I don't want to see  property fully implemented.  Ever.  I 
love this method chaining stuff and you can pry it out of my cold, dead 
hands.  There was a discussion about this a long time ago when I was 
writing the first version of Plot2kill that gave me the impression that 
 property was to be used for disambiguation only.  (See 
http://www.digitalmars.com/d/archives/digitalmars/D/Overloading_property_vs._non-
roperty_113421.html 
.)

The problem with the with statement idea is that you still need to 
declare the variable.  I often throw up quick anonymous plots with 
anonymous Figure objects, like:

Histogram(someDataSet).toFigure
     .title("A Title")
     .xLabel("Stuff")
     .showAsMain();

I consider the ability to have the same function be called with both 
syntaxes to be a beautiful thing, not a defect.  If  property is ever 
fully implemented, I'll nag for an  optionalproperty tag to bring back 
this **feature**.

On 3/5/2011 3:30 PM, Michel Fortin wrote:
 On 2011-03-05 15:22:15 -0500, "Robert Jacques" <sandford jhu.edu> said:

 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).
The funny thing is what will happen to this code once property is properly implemented? I think this is a cleaner way to write the above, and it'll work with property: auto sleepinessFig = Figure(sleepinessPlot); with (sleepinessFig) { title = "Sleepiness Survey"; yLabel = "Seeliness Rating"; xLabel = "Activity"; legendLocation = LegendLocation.right; horizontalGrid = true; xTickLabels(iota(3), ["In meeting, "On Phone", "Coding]); }
Mar 05 2011
next sibling parent dsimcha <dsimcha yahoo.com> writes:
BTW, my proposal for the  property debacle is the following:

1.  Getter  property functions **must** be called without ()s and the 
compiler may use this to disambiguate things like function 
pointer/delegate returns, etc.  Functions not marked  property **may** 
be called without ()s and in all respects the status quo is preserved 
(whatever that is--I don't know or care what it is in the weird corner 
cases) w.r.t. non- property functions.

2.  Setter  property functions **must** be called with a.property = b 
and the compiler may use this to disambiguate corner cases.  Again, the 
status quo is preserved for functions not marked as such.
Mar 05 2011
prev sibling next sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2011-03-05 16:30:06 -0500, dsimcha <dsimcha yahoo.com> said:

 The problem with the with statement idea is that you still need to 
 declare the variable.  I often throw up quick anonymous plots with 
 anonymous Figure objects, like:
 
 Histogram(someDataSet).toFigure
      .title("A Title")
      .xLabel("Stuff")
      .showAsMain();
But does 'with' really need a variable name? Wouldn't that work? with (Histogram(someDataSet).toFigure()) { title = "A Title"; xLabel = "Stuff"; showAsMain(); } I'd even say it's more readable this way since you're now using '=' to set your properties.
 I consider the ability to have the same function be called with both 
 syntaxes to be a beautiful thing, not a defect.  If  property is ever 
 fully implemented, I'll nag for an  optionalproperty tag to bring back 
 this **feature**.
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. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Mar 05 2011
parent reply dsimcha <dsimcha yahoo.com> writes:
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.
Mar 05 2011
parent reply Michel Fortin <michel.fortin michelf.com> writes:
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/
Mar 05 2011
parent reply dsimcha <dsimcha yahoo.com> writes:
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.
Mar 05 2011
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
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
Mar 05 2011
prev sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
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/
Mar 05 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"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).
Mar 05 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"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.)
Mar 05 2011
parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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.
Mar 05 2011
prev sibling next sibling parent reply Kagamin <spam here.lot> writes:
dsimcha Wrote:

 This is why I don't want to see  property fully implemented.  Ever.  I 
 love this method chaining stuff and you can pry it out of my cold, dead 
 hands.  There was a discussion about this a long time ago when I was 
 writing the first version of Plot2kill that gave me the impression that 
  property was to be used for disambiguation only.  (See 
 http://www.digitalmars.com/d/archives/digitalmars/D/Overloading_property_vs._non-
roperty_113421.html 
 .)
 
 The problem with the with statement idea is that you still need to 
 declare the variable.  I often throw up quick anonymous plots with 
 anonymous Figure objects, like:
 
 Histogram(someDataSet).toFigure
      .title("A Title")
      .xLabel("Stuff")
      .showAsMain();
http://msdn.microsoft.com/en-us/library/bb384062.aspx
Mar 10 2011
parent reply dsimcha <dsimcha yahoo.com> writes:
On 3/10/2011 10:03 AM, Kagamin wrote:
 dsimcha Wrote:

 This is why I don't want to see  property fully implemented.  Ever.  I
 love this method chaining stuff and you can pry it out of my cold, dead
 hands.  There was a discussion about this a long time ago when I was
 writing the first version of Plot2kill that gave me the impression that
  property was to be used for disambiguation only.  (See
 http://www.digitalmars.com/d/archives/digitalmars/D/Overloading_property_vs._non-property_113421.html
 .)

 The problem with the with statement idea is that you still need to
 declare the variable.  I often throw up quick anonymous plots with
 anonymous Figure objects, like:

 Histogram(someDataSet).toFigure
       .title("A Title")
       .xLabel("Stuff")
       .showAsMain();
http://msdn.microsoft.com/en-us/library/bb384062.aspx
They work about as well as a with() statement and not as well as method chaining. The problem is that the toFigure call returns a different type. The idiomatic way to use Plot2kill is to create a Plot, set all the Plot properties you need, call toFigure, then set all the Figure properties you need. (Plot and Figure are distinct because you can have more than one Plot on a Figure, though you often don't.) Example: Histogram(someDataSet, 10) .barColor(getColor(255, 0, 0)) .histType(HistType.Probability) .toFigure .title("A Histogram") .showAsMain();
Mar 10 2011
parent reply Kagamin <spam here.lot> writes:
dsimcha Wrote:

 They work about as well as a with() statement and not as well as method 
 chaining.  The problem is that the toFigure call returns a different 
 type.  The idiomatic way to use Plot2kill is to create a Plot, set all 
 the Plot properties you need, call toFigure, then set all the Figure 
 properties you need.  (Plot and Figure are distinct because you can have 
 more than one Plot on a Figure, though you often don't.)  Example:
 
 Histogram(someDataSet, 10)
      .barColor(getColor(255, 0, 0))
      .histType(HistType.Probability)
      .toFigure
      .title("A Histogram")
      .showAsMain();
new Figure { title="A Histogram", new Histogram { barColor=getColor(255, 0, 0), histType=HistType.Probability } } not sure, what showAsMain means.
Mar 10 2011
parent Kagamin <spam here.lot> writes:
forgot about dataset

 Histogram(someDataSet, 10)
      .barColor(getColor(255, 0, 0))
      .histType(HistType.Probability)
      .toFigure
      .title("A Histogram")
      .showAsMain();
new Figure { title="A Histogram", new Histogram(someDataSet, 10) { barColor=getColor(255, 0, 0), histType=HistType.Probability } }
Mar 10 2011
prev sibling parent reply Kagamin <spam here.lot> writes:
dsimcha Wrote:

 The problem with the with statement idea is that you still need to 
 declare the variable.  I often throw up quick anonymous plots with 
 anonymous Figure objects, like:
 
 Histogram(someDataSet).toFigure
      .title("A Title")
      .xLabel("Stuff")
      .showAsMain();
It's also easier to debug code if you store objects in variables. What if histogram is created with a bug, how would you diagnose it? If you have the histogram stored in a variable, you can put a breakpoint after the assignment and inspect the histogram, but your example doesn't provide a variable to inspect.
Mar 10 2011
next sibling parent reply David Nadlinger <see klickverbot.at> writes:
On 3/11/11 8:49 AM, Kagamin wrote:
 It's also easier to debug code if you store objects in variables. What if
histogram is created with a bug, how would you diagnose it? If you have the
histogram stored in a variable, you can put a breakpoint after the assignment
and inspect the histogram, but your example doesn't provide a variable to
inspect.
Just put a break point at the beginning of the line and step through it? David
Mar 11 2011
parent reply Kagamin <spam here.lot> writes:
David Nadlinger Wrote:

 On 3/11/11 8:49 AM, Kagamin wrote:
 It's also easier to debug code if you store objects in variables. What if
histogram is created with a bug, how would you diagnose it? If you have the
histogram stored in a variable, you can put a breakpoint after the assignment
and inspect the histogram, but your example doesn't provide a variable to
inspect.
Just put a break point at the beginning of the line and step through it?
Those are library methods. You probably won't have sources for them, but you can still access its properties or inspect private members if you have appropriate symbols for them. It also can be quite tedious to step through those chained methods, because the chain can be long. May be m$ debugger sucks, but it's nontrivial to step through methods called in single statement: it tends to step through the whole statement, though you can step-in and step-out.
Mar 11 2011
parent reply Kagamin <spam here.lot> writes:
 Just put a break point at the beginning of the line and step through it?
May be m$ debugger sucks, but it's nontrivial to step through methods called in single statement: it tends to step through the whole statement, though you can step-in and step-out.
You will also step into functions called for arguments like getColor() in the example.
Mar 11 2011
parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Kagamin (spam here.lot)'s article
 Just put a break point at the beginning of the line and step through it?
May be m$ debugger sucks, but it's nontrivial to step through methods called
in single statement: it tends to step through the whole statement, though you can step-in and step-out.
 You will also step into functions called for arguments like getColor() in the
example. Ok, I'll admit I don't know much about this stuff. I debug mostly with asserts and print statements. I very seldom use a debugger.
Mar 11 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"dsimcha" <dsimcha yahoo.com> wrote in message 
news:ildvns$2epk$1 digitalmars.com...
 == Quote from Kagamin (spam here.lot)'s article
 Just put a break point at the beginning of the line and step through 
 it?
May be m$ debugger sucks, but it's nontrivial to step through methods called
in single statement: it tends to step through the whole statement, though you can step-in and step-out.
 You will also step into functions called for arguments like getColor() in 
 the
example. Ok, I'll admit I don't know much about this stuff. I debug mostly with asserts and print statements. I very seldom use a debugger.
Same here. I got used to "printf-debugging" when dealing with a bunch of platforms that lacked debuggers. Plus it makes it a lot easier to look backwards in time (just scroll up instead of restarting and re-stepping through). Unfortunately that makes debugging CTFE a royal pain in the ass since CTFE has absolutely zero way to send anything to stdout - or any other IO for that matter. And you can't work around it by appending to a log to then display at runtime because CTFE deliberately disallows any global mutable state *even* when order-of-evaluation doesn't matter for what you're trying to do.
Mar 11 2011
next sibling parent reply Simon <s.d.hammett gmail.com> writes:
On 11/03/2011 21:33, Nick Sabalausky wrote:
 "dsimcha"<dsimcha yahoo.com>  wrote in message

 Unfortunately that makes debugging CTFE a royal pain in the ass since CTFE
 has absolutely zero way to send anything to stdout - or any other IO for
 that matter. And you can't work around it by appending to a log to then
 display at runtime because CTFE deliberately disallows any global mutable
 state *even* when order-of-evaluation doesn't matter for what you're trying
 to do.
huh? just use: pragma(msg, CTFE_string); piss of piss. -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Mar 11 2011
next sibling parent reply David Nadlinger <see klickverbot.at> writes:
On 3/11/11 11:36 PM, Simon wrote:
 On 11/03/2011 21:33, Nick Sabalausky wrote:
 Unfortunately that makes debugging CTFE a royal pain in the ass since
 CTFE
 has absolutely zero way to send anything to stdout - […]
[…] just use: pragma(msg, CTFE_string);
No, this doesn't quite cut it for debugging CTFE functions: While you can obviously use pragma(msg, …) to write the *result* of a function invoked via CTFE to standard output, this doesn't help you if you want to debug the stuff going on *in* that function itself, for example to track down one of the numerous CTFE bugs. David P.S.: As a last resort to get something printed during CTFE evaluation, it is possible to use »assert(false, message)« – DMD prints the (correctly evaluated) message as part of the compiler error message. Obviously, this screws up compilation though.
Mar 11 2011
parent reply Simon <s.d.hammett gmail.com> writes:
On 11/03/2011 22:52, David Nadlinger wrote:
 On 3/11/11 11:36 PM, Simon wrote:
 On 11/03/2011 21:33, Nick Sabalausky wrote:
 Unfortunately that makes debugging CTFE a royal pain in the ass since
 CTFE
 has absolutely zero way to send anything to stdout - […]
[…] just use: pragma(msg, CTFE_string);
No, this doesn't quite cut it for debugging CTFE functions: While you can obviously use pragma(msg, …) to write the *result* of a function invoked via CTFE to standard output, this doesn't help you if you want to debug the stuff going on *in* that function itself, for example to track down one of the numerous CTFE bugs. David P.S.: As a last resort to get something printed during CTFE evaluation, it is possible to use »assert(false, message)« – DMD prints the (correctly evaluated) message as part of the compiler error message. Obviously, this screws up compilation though.
Never had a problem myself; and I've used some really hairy string mixins to create runtime & CTFE functions. Worse case, when composing functions is to print out the result and copy into a file and then debug as normal. It's neither elegant or convenient, but it works. -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Mar 11 2011
next sibling parent David Nadlinger <see klickverbot.at> writes:
On 3/12/11 12:41 AM, Simon wrote:
 No, this doesn't quite cut it for debugging CTFE functions: While you
 can obviously use pragma(msg, …) to write the *result* of a function
 invoked via CTFE to standard output, this doesn't help you if you want
 to debug the stuff going on *in* that function itself, for example to
 track down one of the numerous CTFE bugs.
 […]
Never had a problem myself; and I've used some really hairy string mixins to create runtime & CTFE functions. Worse case, when composing functions is to print out the result and copy into a file and then debug as normal. It's neither elegant or convenient, but it works.
But not for the case mentioned above – first, because there is often no sane way to »print out the result«, and second, because if there are CTFE bugs involved, running the code at runtime (I guess that's what you meant with »debug as normal«) obviously doesn't help you in any way. And yes, I had (or rather have) this problem myself, with not even that crazy code… David
Mar 11 2011
prev sibling parent "Nick Sabalausky" <a a.a> writes:
"Simon" <s.d.hammett gmail.com> wrote in message 
news:ilec50$cj0$1 digitalmars.com...
 On 11/03/2011 22:52, David Nadlinger wrote:
 On 3/11/11 11:36 PM, Simon wrote:
 On 11/03/2011 21:33, Nick Sabalausky wrote:
 Unfortunately that makes debugging CTFE a royal pain in the ass since
 CTFE
 has absolutely zero way to send anything to stdout - [.]
[.] just use: pragma(msg, CTFE_string);
No, this doesn't quite cut it for debugging CTFE functions: While you can obviously use pragma(msg, .) to write the *result* of a function invoked via CTFE to standard output, this doesn't help you if you want to debug the stuff going on *in* that function itself, for example to track down one of the numerous CTFE bugs. David P.S.: As a last resort to get something printed during CTFE evaluation, it is possible to use »assert(false, message)« - DMD prints the (correctly evaluated) message as part of the compiler error message. Obviously, this screws up compilation though.
Never had a problem myself; and I've used some really hairy string mixins to create runtime & CTFE functions. Worse case, when composing functions is to print out the result and copy into a file and then debug as normal. It's neither elegant or convenient, but it works.
Yes. Like I said, it's a pain in the ass. I never said it wasn't possible.
Mar 11 2011
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Simon" <s.d.hammett gmail.com> wrote in message 
news:ile8be$4as$1 digitalmars.com...
 On 11/03/2011 21:33, Nick Sabalausky wrote:
 "dsimcha"<dsimcha yahoo.com>  wrote in message

 Unfortunately that makes debugging CTFE a royal pain in the ass since 
 CTFE
 has absolutely zero way to send anything to stdout - or any other IO for
 that matter. And you can't work around it by appending to a log to then
 display at runtime because CTFE deliberately disallows any global mutable
 state *even* when order-of-evaluation doesn't matter for what you're 
 trying
 to do.
huh? just use: pragma(msg, CTFE_string); piss of piss.
s/piss/shit/ void foo(string str) { pragma(msg, str); } enum x = foo("fubared"); Try it. Big fail.
Mar 11 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"Nick Sabalausky" <a a.a> wrote in message 
news:ilf11q$1l6l$1 digitalmars.com...
 "Simon" <s.d.hammett gmail.com> wrote in message 
 news:ile8be$4as$1 digitalmars.com...
 On 11/03/2011 21:33, Nick Sabalausky wrote:
 "dsimcha"<dsimcha yahoo.com>  wrote in message

 Unfortunately that makes debugging CTFE a royal pain in the ass since 
 CTFE
 has absolutely zero way to send anything to stdout - or any other IO for
 that matter. And you can't work around it by appending to a log to then
 display at runtime because CTFE deliberately disallows any global 
 mutable
 state *even* when order-of-evaluation doesn't matter for what you're 
 trying
 to do.
huh? just use: pragma(msg, CTFE_string); piss of piss.
s/piss/shit/ void foo(string str) { pragma(msg, str); } enum x = foo("fubared"); Try it. Big fail.
Erm, I meant: int foo(string str) { pragma(msg, str); return 0; } enum x = foo("fubared");
Mar 11 2011
parent Simon <s.d.hammett gmail.com> writes:
On 12/03/2011 05:48, Nick Sabalausky wrote:
 "Nick Sabalausky"<a a.a>  wrote in message

 Erm, I meant:

 int foo(string str)
 {
      pragma(msg, str);
      return 0;
 }
 enum x = foo("fubared");
lol, not come across that before. guess I just write my code a different way from you. -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Mar 12 2011
prev sibling parent reply Kagamin <spam here.lot> writes:
Nick Sabalausky Wrote:

 Same here. I got used to "printf-debugging" when dealing with a bunch of 
 platforms that lacked debuggers. Plus it makes it a lot easier to look 
 backwards in time (just scroll up instead of restarting and re-stepping 
 through).
One man wrote a debug logger for .net, that instruments IL code and logs all operations at runtime and later you can browse the log with a visual debugger interface and easily go back and forth in time. He also claimed that the log wasn't very big.
Mar 16 2011
next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
 dsimcha:

I can't compile your demotest from plot2kill, using gtkD and D2:
..\lib\plot2kill.lib(gtkwrapper)
 Error 42: Symbol Undefined _D5cairo12ImageSurface12ImageSurface7__ClassZ
..\lib\plot2kill.lib(gtkwrapper)
 Error 42: Symbol Undefined
_D5cairo12ImageSurface12ImageSurface6createFE4gtkc10cairotypes14cairo_format_tiiZC5cairo12ImageSurface12ImageSurface
..\lib\plot2kill.lib(gtkwrapper)
 Error 42: Symbol Undefined _D5cairo12ImageSurface12__ModuleInfoZ
..\lib\plot2kill.lib(gtkwrapper)
 Error 42: Symbol Undefined _D4gtkc3all12__ModuleInfoZ
--- errorlevel 4

I've built gtkD via the \gtkD\src\build\gtkD.bat script, which uses
Bud. The GtkD.lib file does have a bunch of cairo symbols in it.

For demotest I'm building with:
dmd -version=gtk -version=test -I..\ ..\lib\plot2kill.lib
D:\dev\lib\D\gtkD\src\build\GtkD.lib ..\lib\dstats.lib
-ID:\dev\lib\D\gtkD\src -ID:\dev\lib\D\dstats demotest.d

Includes are fine but some symbols are missing. I've tried gtkD v1.4.1
and from svn. :/

How did you build gtkD exactly?
Apr 03 2011
parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Andrej Mitrovic (andrej.mitrovich gmail.com)'s article
  dsimcha:
 I can't compile your demotest from plot2kill, using gtkD and D2:
 ..\lib\plot2kill.lib(gtkwrapper)
  Error 42: Symbol Undefined _D5cairo12ImageSurface12ImageSurface7__ClassZ
 ..\lib\plot2kill.lib(gtkwrapper)
  Error 42: Symbol Undefined
_D5cairo12ImageSurface12ImageSurface6createFE4gtkc10cairotypes14cairo_format_tiiZC5cairo12ImageSurface12ImageSurface
 ..\lib\plot2kill.lib(gtkwrapper)
  Error 42: Symbol Undefined _D5cairo12ImageSurface12__ModuleInfoZ
 ..\lib\plot2kill.lib(gtkwrapper)
  Error 42: Symbol Undefined _D4gtkc3all12__ModuleInfoZ
 --- errorlevel 4
 I've built gtkD via the \gtkD\src\build\gtkD.bat script, which uses
 Bud. The GtkD.lib file does have a bunch of cairo symbols in it.
 For demotest I'm building with:
 dmd -version=gtk -version=test -I..\ ..\lib\plot2kill.lib
 D:\dev\lib\D\gtkD\src\build\GtkD.lib ..\lib\dstats.lib
 -ID:\dev\lib\D\gtkD\src -ID:\dev\lib\D\dstats demotest.d
 Includes are fine but some symbols are missing. I've tried gtkD v1.4.1
 and from svn. :/
 How did you build gtkD exactly?
I didn't even know there was a gtkD.bat. I used dsss. To use DSSS, though, you have to mess with the configuration files (I don't remember exactly which one) in your DSSS directory to enable D_Version2. For some reason this isn't enabled by default when building with DSSS even when using a D2 compiler. Eventually Plot2kill needs better documentation, but I've temporarily given up on that until the DDoc bug report I filed that prevents the DDoc from compiling at all is fixed.
Apr 04 2011
parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Ok thanks for letting me know.
Apr 04 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Also I'm on XP32.
Apr 03 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Sorry, I think these are gtkD-specific issues, not plot2kill. I've had
another problem building a cairo example project from gtkD, which I've
reported.
Apr 03 2011
prev sibling parent dsimcha <dsimcha yahoo.com> writes:
On 3/11/2011 2:49 AM, Kagamin wrote:
 dsimcha Wrote:

 The problem with the with statement idea is that you still need to
 declare the variable.  I often throw up quick anonymous plots with
 anonymous Figure objects, like:

 Histogram(someDataSet).toFigure
       .title("A Title")
       .xLabel("Stuff")
       .showAsMain();
It's also easier to debug code if you store objects in variables. What if histogram is created with a bug, how would you diagnose it? If you have the histogram stored in a variable, you can put a breakpoint after the assignment and inspect the histogram, but your example doesn't provide a variable to inspect.
Well, then give it a name if you ever end up needing to. In general I hate this as an argument against terse but readable code because you can always make things into named variables very easily if you ever need to set a breakpoint there. Usually I use as few named variables as I can without hurting readability when I program, both to save typing and because I find it hard to think of good names for intermediate variables, so I end up naming them something horrible.
Mar 11 2011
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Robert Jacques:

 Why?
Because that syntax works, but it's a little brutal.
 Each of those arguments should be able to be set after creation.
Then call again a method of Figure that takes arguments for changes after creation: auto sleepinessFig = Figure(args...); sleepinessFig.modify(args...);
 Besides, Figure  
 takes a variable number of plot arguments, which means you couldn't  
 support default arguments (at least with the current syntax).
I see. Something to try to design for D3. Bye, bearophile
Mar 05 2011
prev sibling parent "Nick Sabalausky" <a a.a> writes:
"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) )); +/ } -------------------------------------------------- begin 666 plotStuff2.d M+R\ 5&5S=&5D(&]N($1-1" R+C U, T*:6UP;W)T('-T9"YV87)I86YT.PT* M('-P96-I9FEE9"A4*2A4('9A;"D-"GL-" ER971U<FX 3W!T:6]N86PA5"AV M;65M8F5R5F%R,3L-" EI;G1;72 ;65M8F5R5F%R,CL-" EB;V]L(" ;65M M8F5R5F%R,SL-" D-" DO+R!)(&1O;B=T(&MN;W< =VAY($D ;F5E9"!T:&ES M(&]R('=H>2!I="!S965M<R!T;R!N965D('1O(&)E(&-A;&QE9"!M86YU86QL M<C$ )B8-" D)"6UE;6)E<E9A<C( /3T ;W1H97(N;65M8F5R5F%R,B F) T* M"0D);65M8F5R5F%R,R ]/2!O=&AE<BYM96UB97)687(S.PT*"7T-"GT-" T* M<W1R=6-T($9I9W5R90T*>PT*"5!L;W0 ("!P;&]T.PT*"7-T<FEN9R!T:71L M"0T*"71H:7,H4&QO="!P;&]T*0T*"7L-" D)=&AI<RYP;&]T(#T <&QO=#L- M;F%L(6)O;VP ("!H;W)I>F]N=&%L1W)I9" ](&YO=%-P96-I9FEE9"%B;V]L M+ T*"0E/<'1I;VYA;"%&86YC>2 9F%N8WD (" (" (" /2!N;W13<&5C M=&AI<RYT:71L92P (" (" (" =&ET;&4I.PT*"0ES971)9E-P96-I9FEE M9"%B;V]L(" H=&AI<RYH;W)I>F]N=&%L1W)I9"P :&]R:7IO;G1A;$=R:60I M.PT*"0ES971)9E-P96-I9FEE9"%&86YC>2 H=&AI<RYF86YC>2P (" (" M86EN*"D-"GL-" DO+R!!;&P ;V8 =&AE('5G;'D )W-P96-I9FEE9" I)R!C M<G0 ;V8 ;W!);7!L:6-I=$-A<W0-" D-" EA=71O(&9I9R ]($9I9W5R92A0 M9FEG+G1I=&QE(#T](")->2!4:71L92(I.PT*"6%S<V5R="AF:6<N:&]R:7IO M9RYS970H*2YS970H*2YS970H*3L-" EA<W-E<G0H9FEG+G1I=&QE(#T](")- M>2!4:71L92(I.PT*"6%S<V5R="AF:6<N:&]R:7IO;G1A;$=R:60 /3T =')U M9" B3F5W('1I=&QE(&YA;64B*2 I.PT*"6%S<V5R="AF:6<N=&ET;&4 /3T M9" ]/2!T<G5E*3L-" EA<W-E<G0H9FEG+F9A;F-Y+F]P0VUP*"!&86YC>2 B M>6)E(&%R96XG="!S;R!S<&5C:6%L(&%S+6ES+"!B=70 =VET:"!N86UE9"!A M<F=U;65N=',-" DO+R!T:&4 9F]L;&]W:6YG(&-O=6QD(&)E('5N8V]M;65N M<W-E<G0H9FEG+G1I=&QE(#T](")"87(B*3L-" EA<W-E<G0H9FEG+FAO<FEZ M;VYT86Q'<FED(#T !" `` ` end
Mar 05 2011