User: Password:
|
|
Subscribe / Log in / New account

Should be: Goodnight, Perl 6.

Should be: Goodnight, Perl 6.

Posted Feb 13, 2013 20:17 UTC (Wed) by efraim (guest, #65977)
In reply to: Should be: Goodnight, Perl 6. by marcH
Parent article: Chromatic: Goodnight, Parrot

It does not prevent Android from being sold in great numbers. It is however annoying as hell to have a freaking dial pad stall for several seconds on a 512 MiB RAM phone. I don't remember such basic functionality annoying me to no end on S40 phones with ~0.5MiB RAM.

Regardless, the greatest problem with GC IMHO is that they don't really collect memory. They collect objects, which reference resources. Those resources are typically much more scarce than memory - think DB connections, file locks. (ouch!) And an application which unpredictably does not free those resources will behave in a buggy way. Worse yet, most of the managed (either .NET or JavaScript) code I've seen is written with an attitude that GC will take care of resource disposal no matter what - and only the expected code execution path has a thought-through way of releasing those resources. If any exception shall occur, all bets are off. So the GC does not really help you. You still need to take care of all those resources - which means lots and lots of catching and rethrowing, not unlike C code which tries not to leak. So you either have an ugly code or exceptionally fragile code. (btw, have a look at the mess which is IDisposable in .NET framework - Microsoft developers had to decide whether to implement IDisposable when they designed each base class and interface in the standard library - based on an idea what those *inheriting* those classes might want to do - guess how many times they got that wrong; I do not blame them for it, seems like GC is simply the wrong idea if you want robust code which uses any external resources)


(Log in to post comments)

Should be: Goodnight, Perl 6.

Posted Feb 13, 2013 20:52 UTC (Wed) by marcH (subscriber, #57642) [Link]

> It is however annoying as hell to have a freaking dial pad stall for several seconds on a 512 MiB RAM phone. I don't remember such basic functionality annoying me to no end on S40 phones with ~0.5MiB RAM.

Agreed but, once again, I never saw any definitive proof that GC was to blame for that. It could just be too many background apps/daemons starting simultaneously when you just wake up the phone to make a call - an entirely different problem.

By the way and for some fun try to google "slow ipad" or "slow iphone".

> So the GC does not really help you. You still need to take care of all those resources

A typical application has an order of magnitude less network connections and files than memory objects, so GC means a LOT less to worry about.

> which means lots and lots of catching and rethrowing, not unlike C code which tries not to leak.

Which language does better and how? Please give some pseudo code example.

Should be: Goodnight, Perl 6.

Posted Feb 14, 2013 0:25 UTC (Thu) by HelloWorld (guest, #56129) [Link]

> Worse yet, most of the managed (either .NET or JavaScript) code I've seen is written with an attitude that GC will take care of resource disposal no matter what - and only the expected code execution path has a thought-through way of releasing those resources.
This is not a problem with garbage collection but with developers who don't know which problems a garbage collector solves and which it doesn't.

> You still need to take care of all those resources - which means lots and lots of catching and rethrowing, not unlike C code which tries not to leak.
Pretty much every language out there offers features to avoid the catch-and-rethrow mess: with statements in Python, using statements in C#, destructors in C++, even Java has try-with-resources nowadays! And let's not mention finally blocks which have been around forever...

> (btw, have a look at the mess which is IDisposable in .NET framework - Microsoft developers had to decide whether to implement IDisposable when they designed each base class and interface in the standard library - based on an idea what those *inheriting* those classes might want to do - guess how many times they got that wrong; I do not blame them for it, seems like GC is simply the wrong idea if you want robust code which uses any external resources
The right way to use IDisposable is through a using statement, not through the GC.

Should be: Goodnight, Perl 6.

Posted Feb 14, 2013 6:46 UTC (Thu) by efraim (guest, #65977) [Link]

>>The right way to use IDisposable is through a using statement, not through the GC.

using statement is only useful under *very* limited circumstances. Far more
often the code allocating the resource is not the top-level process to whom the resource use is limited. Also, often the resource holding object is shared. using provides no method of handling shared ownership of a resource.

So according to what you say, modern GC languages have no way of handling shared resource problem (unlike, uh, C++, which has reference-counted RAII patterns at least)

Another problem is that .NET allows you to reference (not weak references, the real thing) IDisposable objects from non-IDisposable ones. So you may perfectly well be referencing a zombie object which has been disposed of, but not GC'ed.

Should be: Goodnight, Perl 6.

Posted Feb 14, 2013 8:30 UTC (Thu) by alankila (guest, #47141) [Link]

Combine using with a refcount then, so you can reference the same thing in multiple using-statements. Or pool the object. It's not like this is intractable problem.

Altogether these claims sound strange to me. I've never run into it myself. I pass the objects from the scope that has the 'using' downwards to all parties that need it. This makes sense for me because it's usually database connection and I need to commit or rollbak transaction by the end of it.

Should be: Goodnight, Perl 6.

Posted Feb 14, 2013 17:11 UTC (Thu) by HelloWorld (guest, #56129) [Link]

> using statement is only useful under *very* limited circumstances.
> [...]
> So according to what you say, modern GC languages have no way of handling shared resource problem (unlike, uh, C++, which has reference-counted RAII patterns at least)

The using statement is useful under the *exact* same circumstances where a C++ destructor is useful: it's just a way to call a function as soon as a certain local variable goes out of scope.

> her problem is that .NET allows you to reference (not weak references, the real thing) IDisposable objects from non-IDisposable ones. So you may perfectly well be referencing a zombie object which has been disposed of, but not GC'ed.
If you do the same mistake in C++, you'd have a dangling pointer, how is that any better?

Should be: Goodnight, Perl 6.

Posted Feb 14, 2013 17:42 UTC (Thu) by efraim (guest, #65977) [Link]

>> The using statement is useful under the *exact* same circumstances where a C++ destructor is useful: it's just a way to call a function as soon as a certain local variable goes out of scope.

As I've already told you, using cannot be used in certain situations where reference counting can.

>> If you do the same mistake in C++, you'd have a dangling pointer, how is that any better?

You wouldn't, because you'd use a ref-counting pointer such as std::shared_ptr.

Should be: Goodnight, Perl 6.

Posted Feb 14, 2013 20:24 UTC (Thu) by HelloWorld (guest, #56129) [Link]

> As I've already told you, using cannot be used in certain situations where reference counting can.
That's like saying that C++ destructors cannot be used in certain situations where refcounting can: it doesn't make any sense. Refcounting works just as well in C# as it does in C++, you just have to implement the refcounting logic in your Dispose method, similar to how shared_ptr implements its refcounting logic in the destructor. And actually, alankila already pointed this out, so I don't even know why I bother repeating it...

> You wouldn't, because you'd use a ref-counting pointer such as std::shared_ptr.
You would, because if you end up holding a reference to an object with refcount 0, that means you forgot to increase the reference count at some point, and that is perfectly possible with a shared_ptr<T>. You could call .get() on the shared_ptr<T> and store the returned T* somewhere. Or, more subtly, you can write a function that takes a T& and then stores that reference somewhere else. Then you pass *t (where t is a shared_ptr<T>) to that method and you've blown it.

Should be: Goodnight, Perl 6.

Posted Feb 14, 2013 21:01 UTC (Thu) by efraim (guest, #65977) [Link]

>> Refcounting works just as well in C# as it does in C++, you just have to implement the refcounting logic in your Dispose method, similar to how shared_ptr implements its refcounting logic in the destructor. And actually, alankila already pointed this out, so I don't even know why I bother repeating it...

Yes alankina already pointed it out, and it is wrong. Refcounting simply does not work in C#. Because all the helper classes, collections e.t.c, do NOT implement IDispose. That's the point. You cannot implement refcounting when half the standard library is working against you.

>> You would, because if you end up holding a reference to an object with refcount 0, that means you forgot to increase the reference count at some point, and that is perfectly possible with a shared_ptr<T>. You could call .get() on the shared_ptr<T> and store the returned T* somewhere. Or, more subtly, you can write a function that takes a T& and then stores that reference somewhere else. Then you pass *t (where t is a shared_ptr<T>) to that method and you've blown it.

Both would be really stupid things to do and any non-newbie programmer in C++ knows better.

Should be: Goodnight, Perl 6.

Posted Feb 14, 2013 23:49 UTC (Thu) by HelloWorld (guest, #56129) [Link]

Yes alankina already pointed it out, and it is wrong. Refcounting simply does not work in C#. Because all the helper classes, collections e.t.c, do NOT implement IDispose. That's the point. You cannot implement refcounting when half the standard library is working against you.
Well, it's not all that bad. You can write an extension method for IEnumerable that will return an object whose Dispose method disposes of the objects contained within the collection. Then you can write something like
using (myCollection.Disposer()) {
    ...
}
Anyway, C++ still has the advantage that an object will implicitly call its member objects' destructors after running its destructor, and that it'll call the destructors of the already-constructed member objects when an exception is thrown within a constructor. So yeah, point taken, C++ probably does somewhat better in that regard.
Both would be really stupid things to do and any non-newbie programmer in C++ knows better.
I wish! People mess up simple things like that all the time.

Should be: Goodnight, Perl 6.

Posted Feb 14, 2013 23:54 UTC (Thu) by marcH (subscriber, #57642) [Link]

> Both would be really stupid things to do and any non-newbie programmer in C++ knows better.

How many non-newbie C++ programmers have you met for real? Three? Five?

Should be: Goodnight, Perl 6.

Posted Feb 15, 2013 8:26 UTC (Fri) by efraim (guest, #65977) [Link]

Assuming you are asking this in good faith (as opposed to, say, condescension) actually around twenty. Of course in this day and age you don't really have to meet a programmer "for real" to know they exist - just look at the number of people giving competent C++ answers on stackoverflow.com.

Should be: Goodnight, Perl 6.

Posted Feb 15, 2013 20:26 UTC (Fri) by marcH (subscriber, #57642) [Link]

It's hard not to make any harmful mistake in C++, much harder than in other languages. As a consequence good C++ programmers are few and a very large number of C++ programmers in service can be considered as newbies. You cannot dismiss mistakes as being "too stupid to do" in C++ as easily as in other languages.

Should be: Goodnight, Perl 6.

Posted Feb 15, 2013 22:33 UTC (Fri) by efraim (guest, #65977) [Link]

While you are right that there are many gotchas in C++ which can trip newbies, pointers are pretty easy to get right by simple ownership rules:

1. If you get a shared_ptr or unique_ptr you can store it for use later.

2. Otherwise (if you get a raw pointer or a reference) you have to assume that you do not own the resource and can only use it in the method's scope.

3. By calling .get() you are saying you are going to take care of ensuring the object's existence during your use of the pointer - i.e. you get no help all bets are off.

Moreover other languages have much more subtle traps in basic parts of language than C++ does - look at JavaScript and PHPs type-casting rules - while wildly different, both are very counter-intuitive and prone to creating security issues.

Should be: Goodnight, Perl 6.

Posted Feb 16, 2013 1:01 UTC (Sat) by marcH (subscriber, #57642) [Link]

I know nothing about JavaScript besides this funny description I've read some day: a functional language disguised behind curly brackets and some object-orientation not to scare away people afraid of maths :-)

http://javascript.crockford.com/javascript.html

You are probably right about JavaScript dangers. On the other hand, I know enough about PHP not to even consider it as programming language. Otherwise the differences between all other languages become negligible and they all become equally excellent

http://me.veekun.com/blog/2012/04/09/php-a-fractal-of-bad...


Copyright © 2017, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds