Wrong const. He's talking about the gcc function attribute extension, which most of the time is too strict, so recommending its general use isn't a great idea.
C++ const has no effect on optimization, since it can be casted away.
And being aware of aliasing issues is a good idea in general; nothing the compiler does can fix this in the general case (e.g. if computeWidth() is located in an external shared library it's basically impossible for the compiler to determine that it can't modify m_cachedWidth)
"And being aware of aliasing issues is a good idea in general; nothing the compiler does can fix this in the general case (e.g. if computeWidth() is located in an external shared library it's basically impossible for the compiler to determine that it can't modify m_cachedWidth)"
This is of course, false, it would be more accurate to say "in most open source compilers, ....".
Doing compile/dynamic link/ analyze based points-to analysis is at least 15 years old (papers published), and likely much older.
There is nothing that fundamentally stops the compiler from knowing things about external shared libs. At some point, the binary is being linked against those libs. You can store the necessary info in those libs, and then use it at link time
(This is in fact, one of the premises of LLVM and having a good, cheap, complete on-disk representation).
In any case, in this example,
1. you don't need the function attribute, just the normal C++ function modifier (It's too early to remember if that is the right C++ terminology) would do, since m_cachedWidth is clearly a member.
Link time for shared libraries is run-time, so unless you're advocating everything be JITed the compiler still cannot know in the general case whether an external function modifies random memory.
1. I'm relatively sure that const member functions are still allowed to write into pointers that could potentially lead back to the object.
2. No way to know that just from the source. No way to know it's a member function either - if it isn't then 1. is irrelevant.
C/C++ const has no effect on optimization, unless it's on a global/static object and the compiler can see the original declaration.
I'm not going to look it up in the C++ spec, but in C it's only undefined behavior if the original object was const, and it would make sense for C++ to be the same.
But if you have a const reference to a non-const object, it's legal to use a const_cast to remove the const part. This is the more likely scenario, since most objects aren't const.
This is bullcrap. When someone has a rifle pointed at you, you don't care what the statistics are. You know your life is in danger and much, much more so than if someone had a knife or "blunt object". How is it supposed to make me feel safe that anyone can have a rifle? I'll just trust in their goodwill and hope they won't kill me with it if I piss them off?
What? How is this not a disgrace? This article means that practically anyone anywhere in the US can have an AK-47 with no licensing. How is that supposed to make me feel safe? What if I sneak into my GF's house and her dad tries me right then and there, and decides that the punishment for fucking his daughter is death. Oh, and what do you know? He has an AK-47 for it so all my hopes of running away are dashed. People shouldn't have the power to kill other people so easily - not unless they're the police or army.
"People shouldn't have the power to kill other people so easily - not unless they're the police or army."
And why should some some 18yo kid in the army have that right but not a middle aged adult? Because some other army guy yelled at him for a few weeks and gave him a uniform?
You mention a father could go crazy and kill you for sneaking in to screw his daughter, but what if you were a rapist sneaking in to rape his daughter? Might be nice to have way to defend your home in that situation. That being said, I don't believe that assault rifles should be legal though.
Not to nitpick, but "assault rifle" is a technical term for a select-fire (fully automatic) weapon that fires an underpowered rifle caliber, and any select-fire weapon is quite illegal for individuals to own in the US.
"Assault weapon" is a made up term used to try to discriminate these civilian rifles on the basis of the cosmetic features that make them seem frightening to non-gun-owners. When we talk about a semi-automatic civilian "AK-47" like this, it's really just called a rifle.
What, aside from the obvious reason? Someone in the military follows orders and serves the nation while someone with a gun will probably do whatever he/she feels with it and nothing actually useful. How is that?
More generally, at least some of us have taken note of the lessons learned from around a quarter billion disarmed people being killed by their own governments in the 20th century (and rather obviously most of that was done by the Only Ones you enshrine, the police and military with I suppose some paramilitaries in the middle).
Good luck convincing us to willingly give up another inch on this issue.
Heh, so out of the millions of policemen and militants in the world, that protect the billions out there, you found a handful that have gone bad. Sure, let's let anyone kill anyone then! Moral reasoning!
Heh, I'm < 25 yrs old and a coder at a top software company with a six figure salary. And I've only been coding for a couple of years. I give you advice, kid.
You do realize that your point there is exactly the same that most gun-control opponents make? If we are to accept your point, you need to accept theirs.
What do you work on, out of curiosity? Maybe it's something you're actually qualified to give me advice on--I'm always up for learning. :)
You should know that, unless you have a 24/7 guard watch (and maybe not even then), if someone truly wants to kill you, there's nothing stopping them.
I mean, courts will try them afterwards, but that's no consolation to your corpse.
Yes I am aware that the parents example would probably fall under "crimes of passion". The man would still want him dead for more than long enough to make it reality.
Wow! Why have any protection against getting killed at all?! Let's just let everyone murder everyone else at will and then we'll try them afterwards! After all we can't stop them if we wanted to. Great logic!
I'm not talking about what should and shouldn't be here.
I worded my last post incorrectly it seems. Let me be clearer.
When you get people angry enough, they try to kill you. This is usually the wrong thing for them to do. But people do it anyway. Police and courts have nothing to do with it. People are still very much able to kill you without a gun, and they have a decent chance of succeeding.
If you continually do things that result in people trying to kill you, the chance of you becoming a homicide statistic rapidly approaches one. If you want to dispute this, you can argue with the 506 homicides in Japan in 2009. (Where weapons are virtually nonexistent.)
In other words, please don't get yourself killed under the mistaken notion that men without guns are somehow incapable of it.
Constructing an argument that leans on the courts and police to protect you is entirely specious.
Contrary to the mantra that is often plastered on the side of every patrol car, the police have no duty whatsoever to protect you. And likewise, the courts or police cannot nor will not protect you from threat even if that threat is imminent and certain[1]. The only duty of our justice system is to investigate and apprehend criminals, not to protect your person or property[2][3].
1. Warren v. District of Columbia, 444 A.2d 1 (D.C. Ct. of Ap., 1981)
2. DeShaney v. Winnebago Cnty. Dep’t of Soc. Servs., 489 U.S. 189 (1989)
3. Leidy v. Borough of Glenolden, et al., 277 F. Supp. 2d 547, 561 (E.D. Pa. 2003)
What if your girlfriend's dad decided to run you down in his car--again, running away is dashed. Hopefully she can find a mate who has more spine and isn't cowed so easily by the thought of other humans with possession of means of force.
Seriously, you can either live your life afraid of every damn thing, or accept that while there are dangerous devices out there the odds of ending up on the wrong side of one can be mitigated--unless, you know, you go looking for trouble.
I'd like to see your brave Kratos face with an AK-47 in your face.
Every point you make is wrong:
I'd have a decent chance of getting away from a car, I wouldn't from an AK-47. A car has other legitimate uses. Guns outside of the police and hunting, don't imo.
I wouldn't say being afraid of firearms counts me as having no spine and afraid of "anything". I just think you're kinda full of crap and would cry the most if you actually had a gun in your face.
I wouldn't say guns are just a means of force. A good punch, a knife is. A gun is just an automatic KO for me. So yes, I don't think the average person should be able to have a gun - something that serves no means other than give him the ability to kill people at will.
You ever shot at something outside of a video game? Especially with an old semi-auto assault rifle? While it's running away from you? It's hardly a decided matter--try skeet shooting sometime.
Are you afraid of cars? Of lathes or mills? One misstep with those and you're going to lose a digit, more likely than not.
Weapons are tools, and you can't go through life being afraid of tools. You respect them, you treat them carefully, but you shouldn't be afraid of them.
Why is the idea of someone else being able to kill people at will so distressing to you? It shouldn't be an issue, right, if you haven't put yourself in a position to deserve it--after all, that's the position you're wishing on those who would go against the military or police.
I'm not sure what these questions have to do with anything, but no, no, and no.
Again every point adds nothing to the debate:
Guns are tools for killing. I'm pretty afraid of that, and I think so are lots/the majority of other people, so that settles that.
Because there is the police and courts for trials. I don't want to be tried by some dude with shit judgement and there - my life is over.
You really are hopeless case. The whole world laughs at the stupidity of US gun control laws and it's just agonizing debating with someone on the other side. You know, the Boston bomber shouldn't have done that. He should've just assembled one of these and killed a couple hundred in the crowd, and you should be there.
The difference between a military assault rifle and a normal gun is the selective fire which allows automatic fire and semi-automatic. In the military, the type of firing that does almost all the killing is semi-automatic, just like a consumer gun. There's really nothing special about an AK-47.
What awful advice. I prefer someone to ask me "Can I help you?" If I need help I'll tell him, if I don't right now I'll tell him. Cornering me like that with a two choice question would just provoke me to rudely answering "I'll let you know when I need help".
Any plans to add templates/a form of generic programming? Does the community care about that? How have people been working around that?
And congrats!
EDIT: Yes I know what the faq says [1]. I was wondering if someone working on that can shed light on how the development of a satisfactory proposal has been going. Also, what's exactly wrong with template instantion like in C++ from the perspective of Go devs?
It gets brought up continually on the mailing list.
The Go authors have repeatedly stated that they will not be implementing generics.
They don't seem to miss them, I don't miss them, and indeed most people who write much Go don't seem to miss them. The people who continually whine about generics seem to be the type who say, "Oh boy, I'd sure LOVE to write a bunch of kickass code in Go, but I just couldn't do ANYTHING without generics! Why don't you put them in, then I'll try the tutorial"
It's not something we feel the need to work around, we just sit down and write concise programs that do the job, in fewer lines than C++.
Edit: as others have mentioned, it seems the authors would be willing to put them in if they find a way to do it without crapping up the language. If they do, I'll try writing Go code with generics, but they have a bad taste for me after dealing with code containing GenericType.cpp, GenericType.hpp, AbstractType.cpp, AbstractType.hpp, AbstractGenericType.cpp, and AbstractGenericType.hpp all in one place.
>The Go authors have repeatedly stated that they will not be implementing generics.
No, they have repeatedly made ho-hum excuses about how they can't think of any proper way of implementing them, and that they will do them if they find a "clean way".
>They don't seem to miss them, I don't miss them, and indeed most people who write much Go don't seem to miss them. The people who continually whine about generics seem to be the type who say, "Oh boy, I'd sure LOVE to write a bunch of kickass code in Go, but I just couldn't do ANYTHING without generics!"
Well, isn't this dismissal of them a kind of "confirmation bias"?
Sure, they people who don't care about generics can churn out tons of code without them. Like people have been churning out tons of code in C or pre-generics Java anyway. And, sure, they might not even miss them.
Plus, some of the core Go members have been using languages without generic for decades and even created some. So, being used to working like that, it makes sense for them not to miss them.
That doesn't mean the people who DO want them are wrong in wanting them in -- or that because guys writing C for several decades doesn't find a need for generics in Go, means that there really isn't one.
Russ Cox wrote down in 2009 what's the dilemma about generics: http://research.swtch.com/generic
I think this is a very valuable article to understand why the Go team hesitates to implement generics in some suboptimal form.
It also highlights Go's weak spot ... it's too low level, while not being low level enough for manual memory management.
The JVM engineers have been free to do whatever they want in terms of optimizations at runtime, like code inlining or escape analysis. They may even add trace compilation or whatever they feel like it's necessary. The JVM's GC is precise and generational. The CMS garbage collection rarely blocks the whole process and you've got options for GCs that are totally non-blocking. In fact, the JVM's GC is so efficient that allocating and deallocating short-lived objects is almost as efficient as doing that on the stack.
Russ Cox speaks about the boxing that Java does, but Java makes boxing almost a non-issue. Personally I've learned to appreciate the JVM and what it can do in the context of servers receiving tens of thousands of requests per second.
And here in lies the problem - Go is too low level to achieve the same level of optimizations that Java is able of. But on the other hand it's totally dependent on a per-process GC and personally I don't think we'll ever see a precise, generational GC for it precisely because Go is too low level. The Rust engineers at the very least redefined the problem by making individual threads in a process have their own heap and their own garbage collector.
Go on the other hand feels like a hack on multiple accounts. And to me it's not a beautiful hack either, plus once a language achieves inertia, you cannot change its fundamentals without redefining the language to be something else entirely. If Go will indeed get popular, it will join a long line of languages that people hate, because they have to maintain code-bases written in it, with no easy way out.
Its authors say they don't want Go to be like C++. In many ways, it already is.
> The JVM engineers have been free to do whatever they want in terms of optimizations at runtime, like code inlining or escape analysis.
Both of these optimizations are present in this release of Go. Granted, there is no doubt more inlining opportunities exist, and better escape analysis is possible, but I think you'd want to chose different optimizations to highlight your point.
What specifically makes you think that there'll never be a precise, generational GC for Go? What about Go makes it too low-level for such an implementation. Unless I'm missing some key issue, I definitely think its possible...
> Go on the other hand feels like a hack on multiple accounts.
Again, what specifically about the language gives you this impression?
> If Go will indeed get popular, it will join a long line of languages that people hate, because they have to maintain code-bases written in it, with no easy way out.
Forget about evidence, you're making claims with absolutely no reasoning behind them. What is different about Go as opposed to say Python, or Erlang, or Node, or C++ in this situation? A code-base written in any of these languages needs maintenance... I don't see how Go is any different in this situation.
One of the 3 original designers of Go is Robert Griesemer, who worked on the Java HotSpot compiler, so I think it's safe to say that the Go team is quite aware of what the JVM can and cannot do.
If that argument is used to defend against arguments of bad design decisions, in spite of years of research by many other well renowned computer scientists that went ignored, then yes.
This is a bad attitude, imo. The Go standard library wouldn't be possible without generics [1]. It's just that the functionality exposed to the standard library isn't exposed otherwise.
If it's a feature needed for the standard library, then it's safe to say the devs will need it to. The devs aren't (shouldn't) be consistently writing programs that are more trivial than the standard library.
I could easily write a custom Append func in my own application because I would know the Slice types I'm trying to operate on. Writing a language feature is different than writing an application, and it has nothing to do with how trivial something is.
Honestly, Append() as a concept is about as trivial as it gets..
Yeah, that was supposed to be singular: because I would know the Slice type I'm trying to operate on. Appreciate the clarification. I'll leave the typo there for context.
> Writing a language feature is different than writing an application
True enough. But libraries can easily tend toward either of those extremes. And any obstacles to library development will eventually become obstacles to application development.
You could also say that ANSI C has fenced off generics (array of T). Just as with Go's append and co, that's part of the language, not it's standard library.
The thing is, you can do that with interface{} and you don't even need type switching. It's awkward, but considering that the rarity with which interface{} is necessary (at least in my experience), much less interface{} with type switching, I really don't see a big gain in generics. I agree with jff, it seems most people who complain about the lack of generics are those who haven't written much code without generics.
You lose a lot of type safety via interface{}. I'm currently writing a server that makes heavy use of []interface{} and I hate it. For many, most, maybe even all, code pathes in the app I could 100% static-type if Go allowed for something akin to Haskell's generies. Basically I bundle around a type `APIVal` (an alias for []interface{}), but everywhere I either take as an argument or return an APIVal, I can tell you exactly what type the underlying slice items "really" have, but I can't assert that at compile time, and it kinda bugs me.
>>The Go authors have repeatedly stated that they will not be implementing generics.
Not so http://golang.org/doc/faq#generics; "This remains an open issue." In the discussions I have read, if an implementation of generics is proposed that doesn't sacrifice performance and it truly generic, they are open to it.
What I have seen said is that implementing generics was not on the table for 1.1 or maybe even 1.x
>In the discussions I have read, if an implementation of generics is proposed that doesn't sacrifice performance and it truly generic, they are open to it.
Sounds like weasel speak for "take a hike and leave us alone".
Or maybe professor speak for freshmen Johnny who thinks he as an answer to the the Halting problem...
But in all seriousness they are interested in implementing generics, just not in a hurry to do it. It doesn't seem unreasonable to me to label it a low priority feature compared to other things they have added to Go. Java got along just fine before generics (which are arguably poor) and C still gets along fine without them. The Go authors are saying, lets add Generics when we are all happy about the solution and feel we are going to get it "right".
>>Any plans to add templates/a form of generic programming?
The Go team is open to generics as soon as there is a proposal they feel fits right without performance penalties.
Read: http://golang.org/doc/faq#generics
>>Does the community care about that?
Yes, but most people in the Go community are OK waiting for the "right" solution.
>>How have people been working around that?
Generics are nice and convenient, but you can write anything/everything without generics. Just look at everything written in C. And C doesn't have interfaces like Go.
I haven't looked at go beyond doing the tutorial, so what follows isn't a learned opinion. The interface system in Go covers most of what you would do with generics, if you use interfaces your code is generic. The only friction over a generics implementation is the way you wire up types to interfaces.
The other place you really feel the lack of generics is in the collections. They are built around the empty interface so that they can hold any type. Then you have to cast back to what you want. Exactly like Java pre generics. ugh.
I urge you to take this criticism more seriously. With your library a programmer is changing the semantics of class nesting in the language, all by pre-pending a very missable and ambiguous @case to the class. I'm no expert but I think this is pretty bad in any language, and especially one that says "explicit is better than implicit"
We do take it seriously; it's a hard tradeoff between Novelty and Utility. Given that the whole point of macros is to change the semantics of the Python language, this (valid) criticism applies not just to case classes but macros in general. If you go haywire with macros, all hell breaks loose.
We think that with some discipline, it is possible to come up with macro transformations which are both useful and understandable by a programmer. This means setting clearly defined semantics for the transformations, which is difficult but doable.
If you think macros are kinda crazy (well, they are!) you should look at the implementation of such pythonic constructs like `namedtuple`, the `ast` module and the new Enum library coming out!
I'd argue that "fields as a string with spaces inside, or maybe a list of strings" is changing language semantics quite a bit.
We're used to namedtuples doing it like this now, but if namedtuples didn't exist, "fields as a list of strings with spaces inside, or maybe a list of strings" would definitely not make it past code review and probably get me yelled at by my future colleagues.
Yes, it could be bad, but at the same time the "@case" isn't the only indicator that this class is special. A case class definition can be very visually distinct compared to a normal class.
One thing case classes let you do is implement functionality externally to a class using pattern-matching functions. When you do this, your case class definition will consist of nothing but empty class definitions:
@case
class List:
class Nil(): pass
class Cons(x, xs): pass
In any case, Python's enums will use fully qualified names, so we may change our current system for compatibility and consistency.
I think that's true, but it's also sad. I've looked at D and it's criticism seems reasonable to me: it actually seems to have more features than C++.
I really hope Go catches on more and fixes some of the (imho) bad things about it (like lack of generic programming). And then C++ won't be the only option anymore.
Go is nice but it's a replacement for Java or Python not for C++. I'm working on an in-memory analytics engine, something that has only become affordable in recent years because memory prices have fallen so much.
In-memory computing is a very important trend and garbage collected languages just don't work. You can't have the system stall for seconds or even tens of seconds unless it's purely a batch workload.
I have to admit that I haven't really researched what can be done in Go to keep in-memory data off-heap so the garbage collector doesn't see it. I have done that research for Java and it's unworkable. It's either slow or extremely unproductive to work with or both.
Garbage collection pauses are a huge concern with larger heap sizes. Depending on the application it may be OK to make a user wait for a second or two, but not for 30 seconds. Multitasking doesn't cause that kind of lag usually.
It's even more problematic for some types of trading systems or stream processing of sensor data, etc.
All the trends are working against garbage collection right now. Memory sizes are growing and we're moving away from batch processing for many workloads.
Most definitely - on a modern multitasking operating system your "all types of pauses" is generally only synchronous IO issues to disk or network - as long as you've got spare CPU available to your process/threads and you're sensible with your memory allocation.
> garbage collected languages just don't work. You can't have the system stall for seconds or even tens of seconds unless it's purely a batch workload.
What about languages like Erlang and Rust where each actor/object/process has its own heap, GCed individually?
> In-memory computing is a very important trend and garbage collected languages just don't work. You can't have the system stall for seconds or even tens of seconds unless it's purely a batch workload.
As someone who had tried to work with available GCs in Java, GP is spot on; it doesn't matter that algorithms exist - production JVMs still pause (or at least did 2 years ago when I looked into it)
Can you point me to a reasonably mature and efficient implementation of such an algorithm for Go or Java? I only know the Azul one which costs thousands of dollars per server per year.
Irrelevant for what? This was a debate about whether or not Go can replace C++, remember? So the fact that there is no such implementation for Go has to be relevant.
It is also very relevant for me that there is no Java implementation of a pauseless garbage collector that is even remotely viable for my business model or the business model of 99% of all startups out there.
If all you want to say is that it is possible to solve this problem for garbage collected languages, then we can agree. Unfortunately there is no viable solution available right now.
> Irrelevant for what? This was a debate about whether or not Go can replace C++, remember? So the fact that there is no such implementation for Go has to be relevant.
Well, surely with so many top notch brains Google can come up with a way to improve Go's runtime if they care about the issue.
> It is also very relevant for me that there is no Java implementation of a pauseless garbage collector that is even remotely viable for my business model or the business model of 99% of all startups out there.
Do you mean viable, as free of charge?
> If all you want to say is that it is possible to solve this problem for garbage collected languages, then we can agree. Unfortunately there is no viable solution available right now.
No, but it would have to be a fraction not a multiple of my per server profit margin. Azul's target market is clearly hedge funds and the like. They don't even quote a price on their website.
To be not only viable but also beneficial, the Azul license plus the additional DRAM cost of Java itself would have to be less than it costs me to use C++ instead of Java.
That's exactly how I feel, I guess. D seems to have a lot more features (import, public import, and static import?) and I'm no expert but I feel some aren't all that necessary/add enough value. Go has fewer than C++, which I think is really good, except for some few ones that I wish were there. Only generic programming/templates off the top of my head actually.
See I don't know about that. Maybe exceptions was one of the features that was good to be left out. I think maybe the comma ok idiom forces the programmer to more actively check for errors and recover from them, and there is no need to do things like RIIA. Maybe also the code is clearer to read, because you can see "if not ok then do_this()" and know that this is error checking/recovery code, instead of looking up the call stack to see where the exception that was thrown in one place is being handled.
I haven't looked at D in a while, but I recall it having two competing standard libraries.
I'm pinning all my hopes and dreams on Rust, but as a frequent (ab)user of Boost.Coroutine and gevent I certainly wouldn't mind if Go gained a bit more traction.
There isn't anything nondeterministic about garbage collection systems; it is just that it is hard to predict how much time they will take for a call.
However, the same can be said about classical C style memory management. An alloc can be almost immediate or take lots of time because it has to request a fresh memory block from the OS. Similarly, a free can or cannot take time to coalesce blocks.
Yes, the differences are much smaller there, certainly historically, but garbage collectors have improved, and I am not sure that C-style allocators can stay predictable in long-running programs. Let's say you have a terabyte of RAM, and want to run a multi-threaded server in it 'forever'. Chances are that your garbage-collected system will be more stable and use less memory because it can compact memory. A C style allocator would need quite a few heuristics (or maybe, even contain some machine learning code that builds a model of memory allocation patterns) to prevent memory fragmentation. Such features would make their timing less predictable.
Because of that, I think we may at some time see an OS with built-in garbage-collection become mainstream.
If it interrupts your running code, it only can happen at moments when you allocate memory, just like with malloc. You cannot predict when malloc calls brk(), either.
Also, most OS-es are non-deterministic, anyways. You cannot predict whether your code lives in cache/main memory, or on disk. In some systems, your data even might have to be brought in by a tape robot without your code being aware of it. As soon as a garbage collector manages to get its interruptions to be about equal to delays caused by caching and virtual memory, I doubt many people will care.
With Gargage collection, there are ni deallocations.
Also, garbage collection does not "harvest for memory locations that need to be freed and frees them.". Garbage collection does not collect garbage, it collects used space.
Just followed that thread again, and I think we're on the same side :)
I mean, when I say that I prefer deterministic memory management, that includes an automatic reference counting - smart pointers - which are now part of C++11.
On that thread, under my "deterministic", you assumed only "manual" as it seems.
After using zsh for a while I moved back to bash. The main reason is that I want to learn bash well, because I might be writing shell scripts in the future and I don't want to use zsh specific features in my scripts so I don't want to get used to them.
Well I think there are if statements, loop conditions, and wildcard expansion that works in zsh but not in bash. So you could get used to something working in zsh, then you write an sh script with that thing, and then it doesn't work, and you have no idea why.
Example, I _think_ / (recursive globbing) works by default in zsh but not in bash. If you have / in a bash script without setting the right options then your script won't work and you will have no idea why until you've wasted a lot of time debugging.
I'm trying to do windows development and I'm learning that if you don't try to force it into a unix-lixe env, it works fine.
I installed chocolatey [1] a package manager. With that I install python, git, and vim and I'm up and running. My vimrc and gitconfigs almost worked copied straight out of linux. I use cmd. My advice is not to use cygwin and the other stuff like it...
I don't agree with this advice at all. That you are stuck with cmd is really all that needs to be said.
On the other hand, Cygwin's gotten to the point where it, plus mintty, are actually pretty good--Cygwin used to be a real pain to work with (I mean, bad) but it's improved by leaps and bounds over the last few years. You can get a bash or zsh shell that work remarkably closely to OS X or Linux and just about every tool you're likely to run into will work as you expect. Contrast this to direct Windows ports of your software, which are frequently compromised to work in the fairly deranged environment of the Windows shell.