|
What do you mean specifically by managed extensions? Are you talking about Microsoft managed extensions or are you just referring to a garbage collector?
Concerning the trend towards managed environments, there will always be room for non-managed languages like Heron as they will always outperform managed evnironments when used properly. I think the pendulum could very well switch back to non-managed environments as Heron catches on.
Christopher Diggins
http://www.heron-language.com
|
|
|
|
|
Why did you name the laungage as heron? you are breaking the rule, A,B then C , C++, C#, ???
just kidding..
I'll write a suicide note on a hundred dollar bill - Dire Straits
|
|
|
|
|
look at Ruby, you will love it
mystifier
|
|
|
|
|
Actually, I already have
It is a nice dynamic language, but it does not really compete with C++. I would like to use Ruby i.e. for web development - btw what is the state of mod-ruby?
My programming blahblahblah blog. If you ever find anything useful here, please let me know to remove it.
|
|
|
|
|
Thanks for pointing this out!
I'd be curious to know:
How do you feel this compares to "D", and what, in your opinion, makes it better than "D"? I have always thought "D" was really cool, but this also looks really nice. My only beef would be the lack of function pointers, and it doesn't seem like there's any form of RTTI or reflective capabilities in Heron.
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
SELECT * FROM User WHERE Clue > 0
0 rows returned
Save an Orange - Use the VCF!
|
|
|
|
|
I am not an expert in either of them. However, I dislike the D object model: "cosmic hierarchy" and mandatory GC are enough to turn me off. It seems that Heron is more faithful to C++ semantics than D. On the other hand, I wish it took even more syntax from Pascal.
As for reflection, I noticed it was an important concept in VCF, but having worked with C# in the last two years, I found it almost dangerous: too many times you get a run-time exception where a compiler error would have occured in a more static model.
My programming blahblahblah blog. If you ever find anything useful here, please let me know to remove it.
|
|
|
|
|
Nemanja Trifunovic wrote:
having worked with C# in the last two years, I found it almost dangerous: too many times you get a run-time exception where a compiler error would have occured in a more static model.
Well of course you do! By definition the query for reflection is run time based and (probably?) can't/won't be known at compile time. So you do have to use proper error handling, no doubt.
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
SELECT * FROM User WHERE Clue > 0
0 rows returned
Save an Orange - Use the VCF!
|
|
|
|
|
Yesterday, I installed "full" version of VS 2005 Beta 1. Installation went smoothly, which surprised me a bit, because I heard some horror stories before. Anyway, since VC++ 2005 Beta is not in a state that would allow me to do anything serious with it, I started playing with C#.
First topic: generics, of course. Here is my "generic hello world":
namespace Generics
{
class MyArray<T>
{
public MyArray(int size)
{ data_ = new T[size]; }
public T this[int index]
{
get { return data_[index]; }
set { data_[index] = value; }
}
private T[] data_;
}
class Program
{
static void Main(string[] args)
{
MyArray<string> strArray = new MyArray<string>(10);
strArray[0] = "First";
strArray[1] = "Second";
}
}
}
Couple of things to notice at a first glance:
1. Angle brackets are used for type parameters like in C++, and unlike in D where ordinary brackets are used
2. Generics accept only type parameters - no nontype parameters and generics. I'll need to investigate the consequences of this further.
My programming blahblahblah blog. If you ever find anything useful here, please let me know to remove it.
|
|
|
|
|
I looked again at the code I posted earlier (it does not compile with Beta 1):
System::IO::StreamReader file(L"test.txt");
String^ line = file.ReadLine();
Console::WriteLine(line);
Is this really what I want to do with C++/CLI? I don't think so. In practice, if I want to read a line from a file and write it to the console, I'll do something like this:
ifstream file ("test.txt");
if (file.is_open())
{
string line;
getline(file, line);
cout << line << endl;
}
Why do I need C++/CLI then at all? Well, the world is moving towards .NET and managed environments and I don't want to stay behind. On the other hand, I don't partculary like the .NET object model and BCL, and I want to use "classic" C++ whenever possible.
A solution is to develop my "core logic" code in standard C++, and then to expose it to the .NET world through an interface (or "Facade", if you prefer GoF terminology).
I see three ways to do that. One is to "flatten" my facade classes and expose them as a set of C functions, which can be called through PInvoke. Another would be to make COM wrappers. Finally, I can use Managed C++ or C++/CLI to easily write CLS compliant wrappers for my facade classes. COM wrappers is something I would rather avoid, which leaves me with C vs MC++ dilemma. The "C" approach appeals me because it enables other non - .NET languages to use the libraries. On the other hand, if I care only about .NET, with Managed C++ I can create classes that can be used from .NET languages directly, without PInvoke hassles.
The bottom line is: C++/CLI is about making C++ code available to .NET world, and if it is easy enough to do that, than I don't necesseraly care about deterministic finalization, STL.NET and other cool programming techniques. I'll just use ISO C++ for that.
My programming blahblahblah blog. If you ever find anything useful here, please let me know to remove it.
|
|
|
|
|
Nemanja Trifunovic wrote:
If you ever find anything useful here, please let me know to remove it.
I found something useful! Just wanted to be the first to note it, but don't remove it, at least for others sake - plus I will continue to read it as well.
- Nick Parker My Blog | My Articles
|
|
|
|
|
|
Nemanja Trifunovic wrote:
Damn!
Just make it harder to find next time.
- Nick Parker My Blog | My Articles
|
|
|
|
|
Back to my VC++ 2005 Express Beta 1. Today, I am going to play with generics a little bit.
I started with this:
interface class I { int f(); };
generic <typename T> where T : I
ref class GenericClass {};
So far, so good. Compiles fine. Now, I tried to add a member, like this:
interface class I { int f(); };
generic <typename T> where T : I
ref class GenericClass
{
T^ data_;
};
Ooops:
First.cpp(15) : error C3229: 'T1 ^' : indirections on a generic type parameter are not allowed
compiler using 'T1' to continue parsing
Now, this T1 is confusing, but anyway if I modify my class to look like:
generic >typename T< where T : I
ref class GenericClass
{
T data_;
};
everything looks fine. Then I tried to add a constructor and instantiate the thing:
interface class I { int f(); };
ref class C: public I
{
public:
int f() {return 0;};
};
generic <typename T> where T : I
ref class GenericClass
{
T data_;
public:
GenericClass (T data) : data_(data) {}
};
int main()
{
C^ c = gcnew C;
GenericClass<C^> g = gcnew GenericClass<C^> (c);
}
and the result is:
First.cpp(29) : error C3149: 'GenericClass<T>' : cannot use this type here without a top-level '^'
with
[
T=C ^
]
This is frustrating...
My programming blahblahblah blog. If you ever find anything useful here, please let me know to remove it.
|
|
|
|
|
At one point (end of 2003), the web was full of blogs from some very interesting people, like Herb Sutter, Brandon Bray, etc. However, it seems that most of them gave up blogging soon. Stan Lippman is "the last man standing" in this regard, and I try to keep an eye on his blog.
One thing I found on his blog was the next piece of code (from this article[^]:
char *ch = new char[ len ];
bool result = wcstombs( ch, wch, len ) != -1;
target = ch;
delete ch;
See the last line? It should really be:
delete[] ch;
In fact, why did Stan even use this new[] ...delete[] construct here? Modern C++ offers this alternative:
vector<char> ch(len);
bool result = wcstombs( &ch[0], wch, len ) != -1;
target = &ch[0];
Stan's explanation: it is a bad habit for an old dog who was programming with the language before this was added, and of course in current implementations, its absence is actually both non-fatal and possibly more efficient.
This makes me wonder. If a master like Stan Lippman makes a mistake like this, something is wrong here. Old dog's habits are hard to get rid of. Maybe we really need a new, smaller and cleaner language, after all - a language that would inherit the power of C++ but leave the C heritage behind. The problem is - I don't know such a language - Java and C# are definitely not what I have in mind.
My programming blahblahblah blog. If you ever find anything useful here, please let me know to remove it.
|
|
|
|
|
Still playing with VC++ 2005 Beta 1.
Today I tried to compile the following code:
ref class Widget {};
int _tmain()
{
Widget^ managed = gcnew Widget;
Widget* native = new Widget;
}
Yes, I forgot to type gcnew again, but what I wanted to say is that
according to Nick Hodapp[^], this should compile just fine. Guess what? I got error C2750: 'Widget' : cannot use 'new' on the reference type; use 'gcnew' instead.
Another C++/CLI feature that didn't make into Beta 1? I really feel I'm wasting my time here
My programming blahblahblah blog. If you ever find anything useful here, please let me know to remove it.
|
|
|
|
|
Nemanja Trifunovic wrote:
Another C++/CLI feature that didn't make into Beta 1? I really feel I'm wasting my time here
Then stop wasting your time with it and wait for the next release.
Signature under construction.
|
|
|
|
|
I wrote the next piece of code today:
System::IO::StreamReader^ file = new System::IO::StreamReader(L"test.txt");
String^ line = file->ReadLine();
Console::WriteLine(line);
file->Close();
and got the compiler error error C2750: 'System::IO::StreamReader' : cannot use 'new' on the reference type; use 'gcnew' instead.
Of course, of course... even with old MC++ I would usually type
System::IO::StreamReader __gc* file = __gc new System::IO::StreamReader(S"test.txt");
, but it is still too easy to forget. Anyway, if we correct this typo, we end up with:
System::IO::StreamReader^ file = gcnew System::IO::StreamReader(L"test.txt");
String^ line = file->ReadLine();
Console::WriteLine(line);
file->Close();
It compiles and runs fine. However, I would never put something like this into production code. Why? Because StreamReader::ReadLine() can throw an exception, and if it does we have a resource leak - the file never gets closed. One way to make this code exception safe is to rewrite it like this:
System::IO::StreamReader^ file = nullptr;
try
{
file = gcnew System::IO::StreamReader(L"test.txt");
String^ line = file->ReadLine();
Console::WriteLine(line);
}
finally
{
if (file != nullptr)
file->Close();
}
Now, that is too much work, and many developers are just too lazy to write the finally clause. In fact, I can't really blame them. This is way too tedious way to make your code exception safe.
Tha right way to take care about resource management is a technique called RAII. If you don't know much about RAII, I strongly encourage you to read this article by Jon Hanna[^]. This idiom is so simple and effective that I even consider keyword finally a flaw in a programming language, because it is either a sign that RAII is not supported, or encourages developers not to use it.
The problem is that RAII does not go well with nondeterministic GC envirinments. For instance, it is impossible to implement it in Java or VB.NET 2003. In C#, there is using keyword wich enables some kind of poor man's RAII mechanism, but even that is too much work IMHO, and I know some C# developers who just don't get why they should bother with using . Even more, in the first edition of Professional C#[^] the author recommends avoiding using which is IMHO a crime.
In old MC++, there is no built in support for RAII. However, I wrote a template class[^] that gives developer a possibility to use RAII, although with some performance cost.
One of the big things about C++/CLI is supposed to be the return of deterministic finalization and support for RAII. Having read an interview with Nick Hodapp[^], I expected to be able to modify my code like this:
System::IO::StreamReader file(L"test.txt");
String^ line = file.ReadLine();
Console::WriteLine(line);
but I got error C3149: 'System::IO::StreamReader' : cannot use this type here without a top-level '^'. Huh? How do we use deterministic finalization with C++/CLI? I'll try to investigate this, and get back to you later.
My programming blahblahblah blog. If you ever find anything useful here, please let me know to remove it.
|
|
|
|
|
Ah, I found it here[^].
Hi Stan,
In the VC 2005 Express edition, I cannot seem to create a managed ref class on the heap to take advantage of standard RAII techniques. The compiler seems to think I have to use a ^ to build up my instance. What gives?
# re: Changes in Destructor Semantics in Support of Deterministic Finalization 7/7/2004 12:01 PM stan lippman
yes, i know. it did not make it into the beta release. that's disappointing. but it is in the language, and will be there for you when you next get an opportunity towards it. sorry!
stan
No STL.NET, no RAII. Why did I even download this Beta 1?
My programming blahblahblah blog. If you ever find anything useful here, please let me know to remove it.
|
|
|
|
|
One of the new features of C++/CLI is trivial properties. Basicaly, the code:
class SomeClass
{
public:
property int State;
};
translates to:
class SomeClass
{
public:
property int State
{
int get() const
{ return State_; }
void set(int value)
{ State_ = value; }
}
private:
int State_;
};
Now, to be quite honest with you, I don't like properties. Not because I believe they hurt encapsulation like some people do[^]. No, properties per se don't hurt encapsulation any more than other member functions do. What I don't like about them is the syntax: they are really methods, but you call them as if they were public fields. Maybe it is because I work with linguists a lot these days, but I firmly believe that good functions' names are verbs ( DoSomething() ) and that good variables' names are nouns ( someValue ). In my mind object.SetSomething(value); is much better than object.Something = value; .
As for encapsulation, as I said - properties don't have to hurt it at all. Abstraction, yes - just as much as accessor functions hurt abstraction, but this is another story.
BTW, does anybody know why Java and C# even allow public fields?
|
|
|
|
|
Nemanja Trifunovic wrote:
BTW, does anybody know why Java and C# even allow public fields?
Because 95% of the user base for these languages are lazy. Smalltalk 80 is the only "mainstream" language I know where fields are never public.
--
Ich bin Joachim von Hassel, und ich bin Pilot der Bundeswehr.
Welle: Erdball - F104-G Starfighter
|
|
|
|
|
Heh, I would never expect lazy people to use OO languages. I had some arguments with people who use scripting languages like Perl and Python, and their main objection against C# and Java was that "there is too much unnecesary typing" - tehy meant class declarations and even variable declarations.
Whenever a programmer uses public fields, he really says goodbye to encapsulation - one of the pillars of OO. Why do they bother with declaring classes then?
My programming blahblahblah blog. If you ever find anything useful here, please let me know to remove it.
|
|
|
|
|
Nemanja Trifunovic wrote:
Whenever a programmer uses public fields, he really says goodbye to encapsulation - one of the pillars of OO. Why do they bother with declaring classes then?
They may be old timers. C and structs die hard. I sometimes revert back to the C days, only to discover myself rewriting it as classes.
--
Ich bin Joachim von Hassel, und ich bin Pilot der Bundeswehr.
Welle: Erdball - F104-G Starfighter
|
|
|
|
|
Nemanja Trifunovic wrote:
In my mind object.SetSomething(value); is much better than object.Something = value; .
How about:
object.Something += value;
|
|
|
|
|
|