POV-Ray : Newsgroups : povray.off-topic : Coding in the mainstream Server Time
29 Jul 2024 12:19:21 EDT (-0400)
  Coding in the mainstream (Message 1 to 10 of 14)  
Goto Latest 10 Messages Next 4 Messages >>>
From: Invisible
Subject: Coding in the mainstream
Date: 7 Jun 2012 06:06:56
Message: <4fd07d40$1@news.povray.org>
In the film Hudson Hawk [yes, I know], Richard E. Grant can be heard to 
assert that "happiness comes from the fulfilment of /goals/!" Now this 
isn't a film that you should ever take too seriously. But this quote 
does seem to have an air of truth about it.

It's roughly 10 years now since I seriously wrote any Java code. I often 
write psuedocode using Java syntax, but it's a very long time since I 
actually compiled any Java with the serious intention of /running/ it. 
So I just spent the past month or so coding in Java.

The result is Logic Box, as you've all seen. I'm still not completely 
happy with it, but there's definitely a sense of achievement to be 
gained from actually producing a /finished/ program that does something 
[vaguely approaching] useful.

On the one hand, I could have written this program in Haskell in about 
half an hour. Haskell already /has/ sophisticated parsing libraries 
which are trivial to use. The structural inspections are all 1-liners. 
The data transformations are similarly trivial. And, of course, I've 
written this program several in Haskell several times before, so I 
already know the best way to factor it.

On the other hand, the Java program is a ~200KB JAR file which runs 
/everywhere/. A Haskell "hello world" program compiles to 1MB on 
Windows, and runs only on Windows. More to the point, my Java program 
has a GUI. Sure, you can do that in Haskell, but it's a hell of a lot 
more work.

For a start, you need to install GTK (the GTK developers keep moving the 
damned download, and it's hard to figure out exactly which file(s) you 
need), and manually add it to your search path. Oh, and I hope you 
weren't using any /other/ applications that need GTK. Then you need to 
get the Haskell GTK bindings to compile, which is quite a long, 
convoluted dance. Oh, and Glade [the UI painted] no longer seems to be 
part of the standard GTK bundle, so you need to get that separately. It 
also depends on several other GTK packages which aren't really bundled 
for Windows properly, so you have to fiddle with .pkg files to try to 
guess what the correct settings are...

By contrast, once I have NetBeans installed, I can throw a 
non-functional Java GUI together in /seconds/. Adding code to make it do 
something is also fairly trivial. You /do/ have to deal with the extreme 
brain-deadness of the Java APIs. But if you can fight past that, you get 
to have a API application which anybody can run without having to do 
some convoluted dance with installing the entire GTK runtime. (Or, 
alternatively, me figuring out exactly which DLLs are required and 
sending complicated instructions on where to put them.)

So the languages - and more specifically, the ecosystems in which they 
exist - have different strengths and weaknesses. In Haskell, I spend 
most of my time fighting the fact that Windows isn't Linux, and that C 
isn't Haskell. In Java, I spend most of my time fighting the absurd 
APIs, and the general stupidity of the actual programming language.

Java is a very, very, stupid language, by the way. It's a long time 
since I've really done any programming with anything that isn't Haskell. 
I'd forgotten just how much of my time I end up wasting typing "public 
static void Log(BufferedWriter out)" and similar nonsense. But more than 
that, I'd forgotten just how much time is spent trying to find 
workarounds for the stupid limitations of the language, the bugs, the 
glitches, the stuff that doesn't work how it's supposed to, the stuff 
that isn't documented, etc.

Java has generics now. It didn't, back when I used it. One of the things 
I wanted to see is what the syntax is like, and how you use it. I've 
since come to the conclusion that the answer is "you don't". The system 
is just too weak and feeble. Because generics was hacked in as an 
afterthought, it really, really doesn't work properly. You want to 
create an array who's element type is determined at run-time? Oh, I'm 
sorry, that's impossible. The language does not allow it. Have you 
considered using an ArrayList instead?

There's lots of other stupidity too. Java has this retarded system where 
everything is a class, *except* int, long, double and bool. [OK, 
actually there's a few more...] These are primitive types, which 
completely different semantics. For performance reasons.

You know what that means? It means that you /cannot/ use these types 
with generics. Which means that you /cannot/ use them with any of the 
standard container types. Unless you wrap them, to turn them into 
objects, thus negating every single one of the performance benefits 
which lead them to be non-object types in the first place. THE STUPID, 
IT BURNS!! >_<

Interestingly, you /can/ make arrays out of them without boxing. Because 
arrays don't use generics, they use a system equivalent to generics but 
hard-wired into the language from day 1, which thus ACTUALLY WORKS 
PROPERLY. If they had extended this to allow you to use it for your own 
classes, we'd be golden. But that would break backwards compatibility, 
so noooo...

You know what? Eiffel allows you to /choose/, on a class by class basis, 
whether objects of this class should have reference semantics or value 
semantics. C++ allows this in a variable by variable basis. Both of 
these languages manage to treat reference objects and value objects in a 
consistent, uniform way that works properly with generics. But no, not 
Java. :-P

Let me just back up a bit and summarise what I just said: Java sucks. 
Badly. The language is complex, bloated, weak and flabby. It's a problem 
that seemingly *all* mainstream languages share to some degree or 
another. Which is crushingly disappointing, because mainstream languages 
let you actually *do stuff*. Useful stuff. Like have GUIs, or access 
multimedia data, or connect to databases, and so on.

Unfortunately, it seems that only obscure languages like Haskell are 
actually well designed. But such languages suffer from it being 
impossible or at least unreasonably difficult to *do* anything that 
involves talking to the outside world. It's really, really frustrating 
that there isn't a language that does both.



Having said all that, I /was/ eventually able to rewrite Logic Box in 
Java, and it /does/ work. It's the first time I've tried to implement 
Logic Box with interactive stepping. Because, let's face it, from a CLI 
that would just be too horrible to be useful. But from a GUI, it's a 
plausible thing to want to do.

(I did once implement Lambda Box as a CGI script, so that I could have 
an interactive UI without losing my mind. It's a sad day when generating 
HTML and sending it over HTTP is /easier/ than writing a native GUI...)

The actual kernel of Logic Box is not difficult to write. Just tedious. 
Of course, writing a program that solves predicates as much simpler than 
writing a program that shows you what it's actually doing while it does 
it. In true iterative-prototyping style, I tried several different 
approaches.

Initially I had an Expression class with a Unify() method, and a 
Predicate class with a Solve() method. But eventually, I decided on 
having a separate Solver object for each kind of predicate, and having 
expressions and predicates as immutable objects, consequently with far 
fewer methods.

Initially unification used a Unify() method defined in Expression and 
overridden by each type of Expression class. But today it's a huge 
tangle of nested if blocks using the "instanceof" operator instead. A 
retrograde step, perhaps, but it works and it means that all the 
unification logic is in one place instead of fifteen places that need to 
cooperate intimately.

The actual solution process itself is a state machine. Initially each 
Solver contained a set of variables holding the necessary data for every 
possible state, most of which starts out as null or similar invalid 
values. Then, in the Step() method, a complicated tangle of logic 
analyses these variables and attempts to reverse-engineer the current 
state by seeing what variables have and haven't been set.

This isn't a great idea. In particular, every time I add a new variable, 
or change the order of states or something, the state detection code 
tends to break horribly, and I spend forever chasing obscure bugs where 
half the code behaves as if we're in one state, and half in another 
state. The solution, obviously, is to encode the current state 
/explicitly/, rather then trying to "guess" it from implicit information.

The solution cries out for first-class functions, but Java has no such 
thing. Ideally, we'd have a Solver that holds all the data, and a 
pointer to the Step() function. When the Step() function executes, it 
updates the data in the Solver, and then updates the function pointer to 
point to the next Step() function. But we can't do that, because Java 
does not have functions.

Instead, every state that the state machine can be in becomes an entire 
class. A private nested class (because nobody else needs to see it), but 
a class none the sell. Oh, but there's some brokenness with inner 
classes and disambiguating between local variables, inner class fields 
and outer class fields. I wasted a lot of time sorting that one out.

I'm still not 100% happy with the result. I kept the data in the Solver 
object rather than the Step object so that I could implement the GUI 
display code just once. But it turns out that different states ought to 
display differently, which leads to the Step object needing to "talk to" 
the Solver object rather a lot, and the display code becoming very 
complicated. It seems that the correct thing to do is just move 
/everything/ related to a state into the actual State object.

Also, currently you can advance the simulation forwards only. I can't 
tell you the number of times I've clicked the button three times and 
then been like "oh, wait, go back!" But you cannot go back. This is the 
beauty of destructive updates; the old state has been lost, and that's 
that. I think with some work, it should be possible to allow going 
backwards as well as forwards.

I /also/ think the GUI display needs some serious work. There are too 
many redundant steps. The GUI displays so much information by default 
that you get lost in a sea of data and it's difficult to understand 
what's really /happening/. I think the display needs to be more focussed.

(Regarding redundant steps: Consider the predicate "x = 1". This has the 
following steps...

1. LHS == RHS?
2. Bind x.
3. Simplify solution.
4. LHS = RHS?
5. LHS == RHS. Predicate solved!
6. Sending solution...
7. Done.

That's 7 times you need to click the Step button to solve this trivial 
little predicate. Surely we can do better...)



Parsing was fun too. And by "fun" I of course mean "not fun at all". :-P

During testing, it rapidly became clear that writing half a page of Java 
code every time I wanted to test a different aspect of the solver was 
just not good enough. So a parser had to be developed early on.

I imagine that somebody somewhere has probably invented either a parser 
library or a parser generator for Java. But I coded mine by hand. The 
/lexing/ is fairly easy. (Once you get around Java's gigantic APIs to 
the bits you actually want.) The /parsing/, not so much.

Initially I tried to implement parsing in Java the way you'd implement 
parsing in Haskell. DON'T DO THIS! It doesn't work at all! First of all, 
a monadic parser really /requires/ first-class functions. Java can 
sort-of simulate these, but the result is horrifyingly complex and 
inefficient. And Java's generics really, really don't work properly, so 
trying to make the parser's result type a generic parameter is an 
exercise in futility.

I am not well-versed in parser theory. I have no idea what the hell the 
difference is between LL1, LR, LALR, top-down parsing, bottom-up 
parsing, recursive descent, or whatever. I am just a humble computer 
science (*cough* information technology) graduate. :-P

What I do know is that I started out with a system of "levels". Each 
level takes a container of terms, and groups some of them together into 
larger terms. The input to level 1 consists of single tokens. Level 1 
turns anything expression-like into expressions, but leaves all other 
tokens alone. Level 2 therefore receives a mixture of tokens and full 
expressions. (This requires a Java analogue of Haskell's "Either" type.) 
Level 3 tries to group pairs of expressions into equality predicates. 
Level 4 thus receives a mixture of tokens and predicates, with no 
expressions remaining.

The good news is that this frameworks makes it easy to dump the result 
of a given level out onto the screen to check everything is parsing 
right. The bad news is... there's quite a lot of boilerplate code, and 
it's hard to get things like bracketing to work. As soon as you see an 
open bracket, you need to jump to another level in the hierarchy.

The final, /working/ implementation is different. There's a function for 
parsing each construct. Null is returned on EOF, otherwise an exception 
is thrown if the required construct is not present. The functions for 
higher precedence operators call the functions for lower precedence 
operators to parse them. At the very bottom is a function which parses 
an equality /or/ a bracketed predicate of any type.

Again, things get tricky when you get to AND and OR. You can tell 
whether a predicate is bracketed or not by looking at the first token. 
You can statically tell where equality predicates are supposed to be 
situated. Exists always starts with "~". And so on. But for AND and OR, 
you need to "look ahead". For this, I have to buffer tokens, so they can 
be "peeked" multiple times without advancing to the next token.

Eventually I got it to work. (I'm surprised nobody has yet found a way 
to break my parser. I assume nobody has bothered trying...) Only the 
most recent prototype actually includes proper error reporting. All 
earlier versions simply throw an exception and die if anything 
unexpected ever happens. The current parser attempts to indicate /what/ 
actually went wrong. This is a surprisingly non-trivial task!

Later I had to go back and hack in the ability to parse named predicate 
definitions. (Originally only the actual predicate in the input box was 
parsed.) And to load and save predicate libraries from file. In the 
process, I once again had to battle against Java's ridiculous I/O APIs. 
But this, too, now works - more or less. (I really ought to add a way to 
have comments though...)



Building the GUI was a somewhat frustrating exercise. The UI painter 
makes it easy enough to draw what you want. Except that the UI painter 
uses the "Windows" look and feel, while the generated code defaults to 
the "Nimbus" look and feel, and AFAIK there is /no way/ to change this. 
I actually deleted the look and feel code, so now it defaults to "Java". 
This is why Logic Box looks so ugly. (In particular, the tool bar 
doesn't look like a tool bar, and the separators between the buttons are 
invisible.)

It took some doing to figure out how to wire up the buttons to some 
executable code. NetBeans was asking me to select predefined Action 
objects or some mumbo-jumbo like that. (I looked it up; apparently this 
is the Swing API's way of getting around the lack of first-class 
functions. So you can have a button and a menu item that do the same 
thing, and you don't have to code it twice.) It turns out you can just 
double-click the button, and NetBeans generates the stub method for you.

Figuring out how to work a tree was harder. As you'd expect. It seems 
it's impossible to modify an existing tree. So every time you click 
Step, the entire tree is deleted and rebuilt from scratch. (Probably 
explains part of why Logic Box is so slow.) I also don't understand why 
you cannot simply say "here is a tree". Instead, you have to have a 
series of DefaultMutableTreeNode objects, then you need to create a 
DefaultTreeModel object (which you cannot do until /after/ the tree 
nodes are built), and finally you can pass this to the JTree object 
which is the actual GUI component.

You would /think/ that DefaultMutableTreeNode would have an attribute or 
a method or something which would let you select whether it is initially 
expanded or collapsed. You would be wrong. Instead, you have to go to 
the JTree object, pass it the TreePath to the DefaultMutableTreeNode 
that you want to expand or collapse, and call either expandPath() or 
collapsePath(). (No, there isn't an expandPath() method that takes a 
boolean. You have to write an if-statement yourself. Every single time.)

You have to refer to the node you want to expand or collapse by path. 
You cannot simply use a pointer to it. Which means you can only expand 
or collapse the node once the tree is completely built (because until 
then, a path doesn't exist). Which means you have to do /two/ passes 
over the input tree to construct the output tree.

You would /think/ that DefaultMutableTreeNode.getPath() would return a 
TreePath. You would be wrong. It returns a TreeNode[]. So what you 
/actually/ have to do is

   TreePath path = new TreePath(node.getPath());

Isn't that silly?

On top of that, presumably in an effort to be helpful, expandPath() 
expands the selected node /and all parent nodes/. Which means to make 
the expansion state of each node match what the input tree actually 
requested, you have to scan the input tree bottom-up rather than 
top-down. Which is just weird...

I also love how when you create a DefaultMutableTreeNode, you can select 
whether this node can have children or not. You would /think/ this 
dictates whether the graphic shows a folder icon or a file icon. You 
would be wrong. The number of actual children dictates that. The setting 
here just controls whether an exception is thrown when you try to add 
children. >_<

In short, tree-building is a pain. OTOH, it turns out that you can use 
HTML in the node titles. (If the title text begins "<html>".) And by 
"HTML", I mean "some SGML derivative vaguely resembling HTML 2". I 
quickly discovered that it really, really does not work well. For 
example, if you set the background colour of some text, and inside that 
span you set the foreground colour, that /cancels/ the background 
colour! There is no style cascading here; if you want that, you have to 
reimplement it by hand.

If you look at the "about" or "quick reference" pages, you will also see 
that the general rendering quality is really quite low. (At least in 
these panes, you can use real HTML with real CSS!) But hey, what do you 
expect if you try to embed an entire web rendering algorithm into a GUI 
library as an afterthought?



In summary, most of my time was spent wrestling with weaknesses of the 
Java language, and the overly complex APIs you have to use with it. Many 
of the bugs in the actual kernel are due to workarounds I had to do 
because the natural way to encode the solution is impossible. It's been 
a frustrating experience.

Then again, if I posted a Zip file containing a random Windows 
executable and half a dozen DLLs and said "run this!", I doubt anybody 
would. And I'm sure I'd be receiving a lot more reports about how broken 
it is. Written in Java, this stuff actually works.

I'm still not completely happy with the GUI. It works fine for the 
utterly trivial predicates I used during testing. However, trying to 
write, debug and run "real" programs in it, I find it to be inadequate.

- The tree view is too complicated. It needs less stuff displayed by 
default, and probably more highlighting to indicate what part is 
currently running.

- The solvers have too many redundant steps.

- The "solve" and "more" buttons run 1,000 steps, but it turns out 
sometimes that locks the entire GUI up for as much as 30 seconds. There 
ought to be some kind of progress display, the work should be in a 
separate thread to avoid stalling the GUI, and there ought to be an 
abort button. Also, perhaps the process should be limited by wall-time 
rather than number of steps. (Wall-time seems oddly variable.)

- There ought to be a way to put comments in source code files.

- It really irritates me that the load and save requesters default to My 
Documents rather than the current folder. There must be some obscure 
hack to fix that...

Whether I will fix these issues or move on to another project remains to 
be seen. Originally my goal was to write the program in Java (which is 
object-oriented), and then have a go at translating it to C++. (Without 
the GUI, because I have no idea how to do GUI programming in C++, and it 
sounds highly non-trivial.) But actually, it looks like it's going to be 
impossible, because it fundamentally /requires/ abstract classes, which 
are hard in C++. So probably another Java project then...


Post a reply to this message

From: clipka
Subject: Re: Coding in the mainstream
Date: 7 Jun 2012 06:53:19
Message: <4fd0881f$1@news.povray.org>
Am 07.06.2012 12:06, schrieb Invisible:

> Whether I will fix these issues or move on to another project remains to
> be seen. Originally my goal was to write the program in Java (which is
> object-oriented), and then have a go at translating it to C++. (Without
> the GUI, because I have no idea how to do GUI programming in C++, and it
> sounds highly non-trivial.) But actually, it looks like it's going to be
> impossible, because it fundamentally /requires/ abstract classes, which
> are hard in C++. So probably another Java project then...

Abstract classes hard in C++? That's news to me. Last time I checked 
they were quite trivial:

   class C
   {
     public:
       virtual ~C() {}
       virtual void DoSomething() = 0;
   };

There. An abstract class.

   class D: public C
   {
     public:
       virtual ~D() {}
       virtual void DoSomething() { ... }
   };

There. A class implementing the abstract one.

   C* Foo;
   Foo = new D();
   Foo.DoSomething();
   delete Foo;

There. An implementation of an abstract class in action.

Did I miss anything?


If you're using MS Visual Studio (or any other sane contemporary C++ 
IDE), GUI programming is quite easy as well; after all, you have a GUI 
builder included. (Writing a /portable/ GUI in C++ is an entirely 
different matter of course, and the beginners' how-to boils down to one 
and a half words: "Don't.")


Post a reply to this message

From: Invisible
Subject: Re: Coding in the mainstream
Date: 7 Jun 2012 07:34:01
Message: <4fd091a9@news.povray.org>
>> Whether I will fix these issues or move on to another project remains to
>> be seen. Originally my goal was to write the program in Java (which is
>> object-oriented), and then have a go at translating it to C++. (Without
>> the GUI, because I have no idea how to do GUI programming in C++, and it
>> sounds highly non-trivial.) But actually, it looks like it's going to be
>> impossible, because it fundamentally /requires/ abstract classes, which
>> are hard in C++. So probably another Java project then...
>
> Abstract classes hard in C++? That's news to me. Last time I checked
> they were quite trivial

> Did I miss anything?

...or rather, to /use/ run-time polymorphism, you need to do manual 
memory management, and manual memory management is infamously hard.

> If you're using MS Visual Studio (or any other sane contemporary C++
> IDE), GUI programming is quite easy as well; after all, you have a GUI
> builder included.

Yeah, but I'm told programming the Win32 APIs directly is incredibly 
hard. Even if you've got an IDE to generate some of the code for you, I 
rather suspect that without a deep understanding for how it works, 
you'll never be able to fill in the empty bits where your application 
goes...

> (Writing a /portable/ GUI in C++ is an entirely
> different matter of course, and the beginners' how-to boils down to one
> and a half words: "Don't.")

This is true of /most/ programming languages that compile to native 
code, to be fair. ;-)


Post a reply to this message

From: clipka
Subject: Re: Coding in the mainstream
Date: 7 Jun 2012 08:05:53
Message: <4fd09921$1@news.povray.org>
Am 07.06.2012 13:34, schrieb Invisible:
>>> Whether I will fix these issues or move on to another project remains to
>>> be seen. Originally my goal was to write the program in Java (which is
>>> object-oriented), and then have a go at translating it to C++. (Without
>>> the GUI, because I have no idea how to do GUI programming in C++, and it
>>> sounds highly non-trivial.) But actually, it looks like it's going to be
>>> impossible, because it fundamentally /requires/ abstract classes, which
>>> are hard in C++. So probably another Java project then...
>>
>> Abstract classes hard in C++? That's news to me. Last time I checked
>> they were quite trivial
>
>> Did I miss anything?
>
> ...or rather, to /use/ run-time polymorphism, you need to do manual
> memory management, and manual memory management is infamously hard.

... or use Boost's (or C++11's) smart pointers.

>> If you're using MS Visual Studio (or any other sane contemporary C++
>> IDE), GUI programming is quite easy as well; after all, you have a GUI
>> builder included.
>
> Yeah, but I'm told programming the Win32 APIs directly is incredibly
> hard. Even if you've got an IDE to generate some of the code for you, I
> rather suspect that without a deep understanding for how it works,
> you'll never be able to fill in the empty bits where your application
> goes...

Sane IDEs don't use the Win32 C API for GUI (or for most anything else 
for that matter); instead, they come with a fancy object-oriented 
framework of libraries hiding all the uglies from you. (MFC used to be 
the thing for MS Visual C++; they have something new by now, same thing 
they use for C#.)

>> (Writing a /portable/ GUI in C++ is an entirely
>> different matter of course, and the beginners' how-to boils down to one
>> and a half words: "Don't.")
>
> This is true of /most/ programming languages that compile to native
> code, to be fair. ;-)

True enough.

First time I ever wrote a C program that needed graphical output, I 
actually opted for using a printer rather than the computer display, 
because I already knew some PostScript :-P (Later I employed GhostScript 
of course; but only for test runs, as the "display" quality of the A3 
printer was unparalleled :-))


Post a reply to this message

From: Invisible
Subject: Re: Coding in the mainstream
Date: 7 Jun 2012 08:12:10
Message: <4fd09a9a@news.povray.org>
>> ...or rather, to /use/ run-time polymorphism, you need to do manual
>> memory management, and manual memory management is infamously hard.
>
> ... or use Boost's (or C++11's) smart pointers.

Wouldn't that mean I'd have to somehow install Boost and tell the IDE 
where the hell to find it?

Compared to that, manual memory management sounds trivial. :-P

>>> If you're using MS Visual Studio (or any other sane contemporary C++
>>> IDE), GUI programming is quite easy as well; after all, you have a GUI
>>> builder included.
>>
>> Yeah, but I'm told programming the Win32 APIs directly is incredibly
>> hard.
>
> Sane IDEs don't use the Win32 C API for GUI (or for most anything else
> for that matter); instead, they come with a fancy object-oriented
> framework of libraries hiding all the uglies from you. (MFC used to be
> the thing for MS Visual C++; they have something new by now, same thing
> they use for C#.)

Interesting. Is /that/ why I keep having to install the "VisualStudio 
C++ runtime" every few weeks?

> First time I ever wrote a C program that needed graphical output, I
> actually opted for using a printer rather than the computer display,
> because I already knew some PostScript :-P (Later I employed GhostScript
> of course; but only for test runs, as the "display" quality of the A3
> printer was unparalleled :-))

Oh, that's old skool! :-D

I'm told back in the days of the old mainframes, /all/ user output was 
through a printer. It literally didn't /have/ a video display /at all/. 
So the PRINT command in BASIC? It used to actually *print* stuff! :-D

Suddenly using HTML and HTTP to present a GUI doesn't seem quite so 
insane after all...


Post a reply to this message

From: Stephen
Subject: Re: Coding in the mainstream
Date: 7 Jun 2012 09:20:28
Message: <4fd0aa9c$1@news.povray.org>
On 07/06/2012 1:12 PM, Invisible wrote:
> I'm told back in the days of the old mainframes, /all/ user output was
> through a printer. It literally didn't /have/ a video display /at all/.
> So the PRINT command in BASIC? It used to actually *print* stuff! :-D

I remember playing "golf" where the graphical display was a printer.

-- 
Regards
     Stephen


Post a reply to this message

From: Warp
Subject: Re: Coding in the mainstream
Date: 7 Jun 2012 09:23:39
Message: <4fd0ab5b@news.povray.org>
Invisible <voi### [at] devnull> wrote:
> >> ...or rather, to /use/ run-time polymorphism, you need to do manual
> >> memory management, and manual memory management is infamously hard.
> >
> > ... or use Boost's (or C++11's) smart pointers.

> Wouldn't that mean I'd have to somehow install Boost and tell the IDE 
> where the hell to find it?

> Compared to that, manual memory management sounds trivial. :-P

  Just use a compiler that support C++11. You can then use std::shared_ptr
to manage the objects. (If the object doesn't need to be shared, only moved
around, then you can use std::unique_ptr instead, which is more efficient.)

  To be fair, though, if your program allocates and deallocates such objects
in large quantities very fast, the Java version will probably be faster than
the C++ version (because memory allocation has been optimized in Java but
not in C++).

  (To be clear: It's not the polymorphism that's slow in C++. It's all the
new's and delete's.)

  Some applications require runtime polymorphism of objects (GUI programming
being the most prominent example), but in many cases compile-time
polymorphism using templates is enough (and significantly more efficient).

-- 
                                                          - Warp


Post a reply to this message

From: clipka
Subject: Re: Coding in the mainstream
Date: 7 Jun 2012 10:04:46
Message: <4fd0b4fe$1@news.povray.org>
Am 07.06.2012 14:12, schrieb Invisible:
>>> ...or rather, to /use/ run-time polymorphism, you need to do manual
>>> memory management, and manual memory management is infamously hard.
>>
>> ... or use Boost's (or C++11's) smart pointers.
>
> Wouldn't that mean I'd have to somehow install Boost and tell the IDE
> where the hell to find it?

As for the smart pointers, actually no - the smart pointers magic is all 
header files, so you just need to copy those to a suitable subdirectory 
of your own project and add that directory to the list of preprocessor 
include directories.

And if you use VS 2010 (or later), it's even as simple as activating the 
C++11 (aka "C++0x") features. The C++11 smart pointers are actually 
identical to the boost smart pointers, except that they live in a 
different namespace.


The only caveat not explicitly warned about in the smart pointers 
documentation is that the smart pointer assignment operator ("=") is 
implemented as a swap operation, so to create another smart pointer 
referencing the same object you need to explicitly make use of the smart 
pointers' copy constructor:

   typedef shared_ptr<FooType> FooPtr; // really helps

   FooPtr A(new FooType());
   FooPtr B;
   B = FooPtr(A); // NOT just "B = A;"

or just

   FooPtr B(A);


shared_ptr is complemented with weak_ptr.


>> Sane IDEs don't use the Win32 C API for GUI (or for most anything else
>> for that matter); instead, they come with a fancy object-oriented
>> framework of libraries hiding all the uglies from you. (MFC used to be
>> the thing for MS Visual C++; they have something new by now, same thing
>> they use for C#.)
>
> Interesting. Is /that/ why I keep having to install the "VisualStudio
> C++ runtime" every few weeks?

Not really. That's just the /general/ habit of dynamically-linked 
software. Usually the VS C++ Runtime should simply discover that the VS 
C++ Runtime is already installed though.


> I'm told back in the days of the old mainframes, /all/ user output was
> through a printer. It literally didn't /have/ a video display /at all/.
> So the PRINT command in BASIC? It used to actually *print* stuff! :-D

Yup. Heard that, too. Haven't ever seen any proof with my own eyes 
though, so it must be urban legend :-P


Post a reply to this message

From: Warp
Subject: Re: Coding in the mainstream
Date: 7 Jun 2012 10:35:52
Message: <4fd0bc48@news.povray.org>
clipka <ano### [at] anonymousorg> wrote:
> The only caveat not explicitly warned about in the smart pointers 
> documentation is that the smart pointer assignment operator ("=") is 
> implemented as a swap operation, so to create another smart pointer 
> referencing the same object you need to explicitly make use of the smart 
> pointers' copy constructor:

That makes no sense. It would break basically everything if it were like
that.

You are confusing it with how operator= of some versions of shared_ptr might
be implemented, in that it internally swaps its contents with a temporary
that has been initialized with the parameter (this is done to avoid problems
that would happen when assigning to itself). Externally there's no swapping
behavior (and there can't be).

-- 
                                                          - Warp


Post a reply to this message

From: Invisible
Subject: Re: Coding in the mainstream
Date: 7 Jun 2012 11:35:25
Message: <4fd0ca3d$1@news.povray.org>
>> I'm told back in the days of the old mainframes, /all/ user output was
>> through a printer. It literally didn't /have/ a video display /at all/.
>> So the PRINT command in BASIC? It used to actually *print* stuff! :-D
>
> Yup. Heard that, too. Haven't ever seen any proof with my own eyes
> though, so it must be urban legend :-P

I've personally operated a green-screen terminal where there's a 
2-second delay between pressing a key and seeing the character on the 
screen because it's a dumb terminal connected over a modem link to a 
mainframe somewhere. After keying in several /very/ cryptic commands, 
the line printer next to be sprang into life. And let me tell you, those 
things are LOUD! I was using it to print benefits cheques for the local 
county council, in around about 1997 or so. I doubt that their 
infrastructure has been modernised since then...


Post a reply to this message

Goto Latest 10 Messages Next 4 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.