|
|
Log in / Subscribe / Register

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Jörg Walter has written a detailed and positive review of the Go programming language. "And as a final note, I have seen a fair amount of criticism of Go on the internet, which I cannot ignore, so here it goes: Most of these people didn't actually look at it. Go is different, even though it still looks kinda-C. It isn't. It's not C++, nor Objective C, and it doesn't try to be! So stop saying 'Who needs Go when we have C++/Objective C?' already. Check out how Go tries to solve the same problems in a radically different way."

to post comments

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 14:04 UTC (Wed) by MisterIO (guest, #36192) [Link] (15 responses)

I like Go, except for a few problems hopefully due to its relatively young age. The biggest one for me is the lack of generics. If/when that problems goea away and they implement good generics support, I'll start using Go.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 15:00 UTC (Wed) by aliguori (guest, #30636) [Link] (12 responses)

I get confused by how Go is positioned. Since it's garbage collected, doesn't interface natively to C libraries, and doesn't allow direct memory manipulation, I have a hard time seeing it as a C replacement.

It seems more like a Python replacement to me. I think the only thing that's very different about Go is that it's compiled vs. JIT'd but that's really just an implementation detail.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 15:59 UTC (Wed) by anatolik (guest, #73797) [Link] (1 responses)

"It seems more like a Python replacement to me"

Go Language aims to user-space applications development market. Examples are: UI desktop applications, network services such as web-applications, different console applications, build/development tools, databases etc... Something that does not require low-level hardware access. As you see it covers some areas where mainstream languages are c/c++/python/java.

Go (most likely) will never be used for operation system/run-time systems development.

So it is incorrect to says that "Go will replace language XXX".

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 10, 2011 9:13 UTC (Fri) by roxtar (guest, #75611) [Link]

"Go (most likely) will never be used for operation system/run-time systems development."
From the Go FAQ Go was born out of frustration with existing languages and environments for systems programming. You might also want to check out the list of things which people have done with Go.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 17:01 UTC (Wed) by phiggins (guest, #5605) [Link] (3 responses)

I am not sure how you define interfacing natively to C libraries, but Go does have cgo: http://golang.org/cmd/cgo/

I have not personally used it much, but it has met all my needs so far. Has cgo come up short for you? I'd like to hear about limitations before I hit them, as I have started using Go only recently. So far, I really like it.

Cgo is basically unusable

Posted Jun 8, 2011 20:34 UTC (Wed) by khim (subscriber, #9252) [Link] (2 responses)

JNI is slow, but Cgo is even slower. Not a practical solution. GccGo can be nice if you really need to interact with other languages.

Cgo is basically unusable

Posted Jun 8, 2011 21:48 UTC (Wed) by phiggins (guest, #5605) [Link] (1 responses)

Hmm. That is concerning. My usage so far has been to use libgit2 with cgo which I found took about one quarter of the time used to run the low-level git plumbing commands with fork and exec. I never compared this with using libgit2 directly from a C program.

The fact that cgo uses dynamic linking when the program would otherwise be linked statically prevented me from using it because I am deploying to a much older system that cannot compile the new libgit2. I was hoping that it would have statically linked libgit2 for me.

This led me to contemplate porting libgit2 to Go, which immediately made me think of the early days of Java where there was a rush to re-implement everything under the sun in Java in the name of purity, portability, and safety. The fact that JNI was a dog didn't help.

If cgo is slower than JNI, I can start to imagine that sooner or later we are going to see things analogous to Java's type 2 vs. type 4 database drivers for Go. I would sure hope for better C integration to make a frenzy for "pure" Go code unnecessary.

I have avoided gccgo because my understanding is that it does not support garbage collection and I've been too lazy to investigate how exactly you are supposed to free memory in a language that assumes a garbage collector is going to run...

Cgo is basically unusable

Posted Jun 8, 2011 22:46 UTC (Wed) by cmccabe (guest, #60281) [Link]

> I have avoided gccgo because my understanding is that it
> does not support garbage collection

I'm pretty sure that gccgo now supports garbage collection. See:

http://old.nabble.com/-gccgo--Turn-on-garbage-collector-t...

I guess this is a common problem for open source projects-- somehow a post saying that "we absolutely, positively don't support feature X" gets pushed to the top of the Google results and lingers there long after feature X has been implemented...

I'm curious what the technical problems are that make cgo difficult to optimize.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 17:26 UTC (Wed) by bradfitz (subscriber, #4378) [Link] (5 responses)

It interfaces to C libraries quite well. I embedded Perl in Go and it was surprisingly painless:

https://github.com/bradfitz/campher/

http://groups.google.com/group/golang-nuts/browse_thread/...

I'm biased, of course, working on the Go team, but that was my first use of cgo and it just all worked.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 21:25 UTC (Wed) by elanthis (guest, #6227) [Link] (4 responses)

The problem comes up when interfacing with C libraries that make heavy use of macros or magic structures.

Interfacing GTK is much more of a pain. Interfacing OpenGL isn't even that easy. Unless some particular popular library is already handled for you (like I believe both of the two I just mentioned are) you're in trouble.

And then there's the ease of linking in C++ code, which is increasingly important. Where's DirectX support? ;)

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 1:56 UTC (Thu) by cmccabe (guest, #60281) [Link] (2 responses)

> The problem comes up when interfacing with C libraries that make heavy use
> of macros or magic structures.

I think it's fair to say that a C library whose interface is mostly macros has made a big mistake. For one thing, it will be impossible to change any of those macros without breaking binary compatibility.

I don't know what a "magic structure" is. If it's just the old void* idiom, then I don't see why it should cause a problem. It certainly doesn't in JNI. Recently I wrote a JNI binding for the Ceph filesystem so that it could be used by Hadoop. So I know that JNI can handle void*.

> And then there's the ease of linking in C++ code, which is
> increasingly important.

I suspect the solution for calling C++ code from Go will end up looking a lot like the solution for calling C++ code from JNI: you write a C wrapper function that makes the call you want.

Anyway, nearly every C++ library provides C APIs.

It would be awesome if C++ just worked with cgo, but it's hard to see how that could happen any time soon. Basically, it's the same reason Python's ctypes doesn't work with C++. It would have to understand templates and vtables.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 18:02 UTC (Thu) by atai (subscriber, #10977) [Link] (1 responses)

wonder if calling to C++ from Java or Go via JNI or similar solutions will be ever as efficient as the C++ template based binding solutions to bind C++ libraries for these scripting languages Lua and Squirrel...

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 20:06 UTC (Thu) by cmccabe (guest, #60281) [Link]

I think if mixing C++ and Go as efficiently as possible is the problem, gccgo is probably the solution. Maybe someone here can correct me if I'm wrong, but it seems like that should outperform any kind of binding since it's just making calls to functions in the same binary.

I'm curious how gccgo handles garbage collection issues in the bindings...

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 10, 2011 8:24 UTC (Fri) by uriel (guest, #20754) [Link]

> Interfacing GTK is much more of a pain. Interfacing OpenGL isn't even that easy. Unless some particular popular library is already handled for you (like I believe both of the two I just mentioned are) you're in trouble.

There are both GTK and OpenGL bindings for Go already, I don't think they have been particularly difficult:

http://go-lang.cat-v.org/library-bindings

> And then there's the ease of linking in C++ code, which is increasingly important. Where's DirectX support? ;)

There is SWIG support for Go that makes it possible to link to C++.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 10, 2011 8:32 UTC (Fri) by uriel (guest, #20754) [Link] (1 responses)

> The biggest one for me is the lack of generics.

Have you written much Go code and actually found this to be such a big problem? Most people I know that have written Go code have found it to be a non-issue for the most part. Would it be nice? Yes, but having Go interfaces 'generics' are not as essential as in other languages, and it is worth getting them right if/when they are added.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 11, 2011 12:58 UTC (Sat) by MisterIO (guest, #36192) [Link]

Like I said, "when..blah blah blah, I'll start using Go", so no, I haven't used it much(though I tried some little example just to see how it would feel). But there are some obvious use cases where generics would be useful(data structures?, common algorithms, ...).

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 15:30 UTC (Wed) by cmorgan (guest, #71980) [Link] (49 responses)

Love the article. As a strong believer in leveraging technology it feels good to know there are other people who would also like to ditch great-for-their-time languages like c/c++ etc and move to time saving modern languages. I suspect there is a fair amount of resistance to garbage collection, VM based languages etc that is based upon ideas of performance concerns that don't exist with today's fast computers or can't be solved by using better algorithms.

I did wish that the author had used C# and could comment on that. Its my favorite language, has lambda functions, natural language operations via linq, good built in collections and string manipulation. Built in serialization. Reflection, garbage collection etc. I suspect it would fall short of what Go has in terms of concurrency but maybe the language is extensible enough to allow for a concurrent framework that fits in well with real-world use.

Chris

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 18:49 UTC (Wed) by butlerm (subscriber, #13312) [Link] (25 responses)

I suspect there is a fair amount of resistance to garbage collection, VM based languages etc that is based upon ideas of performance concerns that don't exist with today's fast computers or can't be solved by using better algorithms.

Real programmers don't throw away performance without a compelling reason to do so. Most kinds of system software slow to a crawl when implemented in a garbage collected language. And when not crawling, they are just erratic, flaky, take a ridiculously large time to start up, waste an incredible amount of memory, and are completely unsuitable for anything requiring a real time response.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 19:17 UTC (Wed) by HelloWorld (guest, #56129) [Link] (12 responses)

What a load of crap. Real-time garbage collectors have existed for a long time, and using a GC is usually as fast or faster than manual memory management (though not as space-efficient, but memory is cheap these days).

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 2:12 UTC (Thu) by butlerm (subscriber, #13312) [Link] (10 responses)

Real-time garbage collectors have existed for a long time, and using a GC is usually as fast or faster than manual memory management

Real time tracing garbage collection is an oxymoron, and there is no tracing garbage collector without hundreds of times more overhead than any well thought out manual management scheme. This is why the Linux kernel doesn't use a tracing garbage collector, and never will. Ever. All tracing garbage collectors require "stop the world" algorithms that are uniquely incompatible with anything remotely resembling hard real time response, especially on SMPs.

The idea that tracing garbage collectors are almost always better than any alternative is just something that tracing gc language only advocates tell themselves to explain the inherent injustice in the fact that tracing gcs are little more than unheard of in production real time systems (like operating system kernels), and result in software that is mocked for inferior performance characteristics almost everywhere else.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 4:31 UTC (Thu) by flewellyn (subscriber, #5047) [Link] (5 responses)

>Real time tracing garbage collection is an oxymoron, and there is no >tracing garbage collector without hundreds of times more overhead than any >well thought out manual management scheme. This is why the Linux kernel >doesn't use a tracing garbage collector, and never will. Ever. All tracing >garbage collectors require "stop the world" algorithms that are uniquely >incompatible with anything remotely resembling hard real time response, >especially on SMPs.

Do you have an actual, y'know, proof of that "hundreds of times more overhead" assertion? It's the sort of statement that cries out "citation needed!" Especially when it's apparent you haven't heard of incremental tracing collectors...

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 16:12 UTC (Thu) by dvandeun (guest, #24273) [Link] (1 responses)

Explicit memory management and garbage collection both have their sweet spots. To construct a case in which garbage collection is not just as good as explicit memory management, but actually better, consider this. When you manage your own memory, for each chunk of memory you use, you spend some time allocating it, and some time deallocating it. When you use a garbage collector, you spend time allocating each chunk once, and then some time to hang on to it each time garbage is collected (mitigated by generational collecting). But you never spend time actually deallocating it: garbage collectors typically trace live data, and just ignore the rest. So if your program allocates lots and lots of very short-lived data, so that most data is never handled by the garbage collector even once, a good garbage collector should be faster.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 17:17 UTC (Thu) by flewellyn (subscriber, #5047) [Link]

Oh, I know. That's the generational hypothesis. Generational GCs make use of it to efficiently clean up the short-lived garbage that most programs allocate most of the time; long-lived data is usually the exception.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 11, 2011 0:18 UTC (Sat) by butlerm (subscriber, #13312) [Link] (2 responses)

To be sure, performance and overhead characteristics "hundreds of times" better requires all sorts of memory layout and allocator customizations of the sort that are common in the Linux kernel. No one is going to get performance like that using a general purpose allocator.

In user space though, the number one advantage of most non-GC oriented languages over GC oriented languages is that most objects can be placed on the stack, meaning zero allocation overhead. Sure this can be done in a GC language using escape analysis, but that is the sort of thing that can either only be done at runtime using some sort of dynamic recompilation, or using static linking and global analysis in a native compiled GC environment.

The problem about most GC oriented languages for is that for simplicities' sake, you just don't have a choice. You are stuck with the provided GC and there isn't any way around it short of (perhaps) keeping a list of already created but unused objects, which more or less defeats the purpose.

Generational GC is great, but it still requires the entire heap to be scanned on a regular basis, which has serious "pause"/latency problems, and which does an excellent job of wiping out your CPUs L1, L2 and L3 caches.

There are "concurrent" GCs out there of course, but the latest one I looked at (VCGC) consumes twice the total CPU overhead of a generational GC to get a lower pause time. Even though it can mutate, mark, and sweep in parallel it still requires a "stop the world" synchronization point (like every other GC).

And in this case, the greatly reduced pauses were on the order of 20ms(!) on a heap containing only 20 or 30 MB of data. The generational GC had pause times in the 500 ms range. Of course this was on a ca. 1998 CPU, so those pause times would be reduced on a modern CPU with a presumably somewhat improved CPU design.

It should be obvious why GC is almost unheard of in systems that need hard real time response or anything like it. If I issue a DNS query, I don't expect the response to be delayed several hundred milliseconds some of the time just because the DNS server dropped into "stop the world" mode. That might be okay for a web app server, but it is certainly rather less than ideal for something like a database server or a directory server, to say nothing of subsystems more low level than that. And you can just forget about it for a production kernel.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 14, 2011 11:49 UTC (Tue) by marcH (subscriber, #57642) [Link]

> If I issue a DNS query, I don't expect the response to be delayed several hundred milliseconds some of the time just because the DNS server dropped into "stop the world" mode.

Real-world DNS performance finally explained: thanks!

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 15, 2011 16:26 UTC (Wed) by cesarb (subscriber, #6266) [Link]

I recall reading somewhere about a robot with its software implemented in a garbage-collected language. Whenever the garbage collector ran, the robot went off course. The solution IIRC was to stop the motors during the garbage collection.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 10, 2011 5:55 UTC (Fri) by jd (guest, #26381) [Link] (2 responses)

Hard real-time merely means that you have a hard guarantee that program X will get Y amount of time on the CPU over interval Z. It says nothing about running fast, merely running absolutely predictably.

Garbage collection doesn't impinge on that, as far as I can tell. If your GC routine exploits unused CPU cycles (after all guarantees have been met) then the the guarantees continue to be met. If the GC needs more than that, then either your upper limit on Y goes down or your interval Z goes up. In either case, the guarantees continue to be met.

High-performance computing is another matter. There, you want to minimize overheads where at all humanly possible. GC is still possible, but you want it kept to a minimum or you want it offloaded. (Since the mapping to the location in RAM is done by the MMU, there's nothing to stop anyone designing an MMU with a complete VM implementation plus GC.)

Highly-performing real-time (ie: where the sum total of Ys for user processes is as close to Z as the scheduling overheads permit) is also a case where you'd really want to offload GC if possible. Problem there is that this kind of real-time is generally where power and complexity considerations are critical. Novel hardware is exactly what you don't want in those situations. Taking a few months out for extra software validation is cheaper than replacing an aircraft lost to over-complex avionics. As Airbus has demonstrated.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 11, 2011 0:35 UTC (Sat) by butlerm (subscriber, #13312) [Link] (1 responses)

Garbage collection doesn't impinge on that, as far as I can tell

Unfortunately, it does, for precisely the same reason that tracing GCs will likely never be used in a production kernel. All tracing GCs (even "concurrent" ones) require a regular synchronization point where the entire heap is scanned to perform a complete collection. Otherwise they leak memory.

Scanning the entire heap takes a non-trivial amount of time, during which all threads have to be stopped. In the case of a kernel, it requires stopping nearly all kernel activity for tens to hundreds of milliseconds, depending on the kernel heap size and the performance of the CPU. Generational GC makes the need for a complete collection much less frequent, but does not eliminate the requirement for it.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 11, 2011 15:57 UTC (Sat) by jd (guest, #26381) [Link]

Well, yes, but if the time taken is fixed, the hard real-time guarantee on the timeslice doesn't change. Real-time doesn't mean CPU time is equal to wall-clock time, only that the relationship is constant. And if you need high performance as well as real-time, as I said, move the virtual memory and garbage collection into hardware.

This doesn't mean I disagree with the essence of your points. GC is indeed slow and does involve some horrible locking. It is also implicit and implicit code is generally a Bad Thing as you can't test it.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 15, 2011 3:21 UTC (Wed) by k8to (guest, #15413) [Link]

Compleley true.

And if you really need better than 10 microsecond response time, this is a real problem. Of course, so are pagetables. Better get rid of those!

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 10:24 UTC (Thu) by etienne (guest, #25256) [Link]

> Real-time garbage collectors have existed for a long time, and using a GC is usually as fast or faster than manual memory management

I am not sure those garbage collectors manage:
- physical/virtual addresses with variable physical page sizes
- memory in lower address spaces (DMA-able or not)
- memory only referenced by PCI devices write-only registers
- memory being only referenced by DMA registers (to be freed at end of transfer)
- cacheable/write-through/uncacheable memory
- unused memory because it is reserved/non-working/in low power mode
- physical memory address to be re-used because they are cache-hot
- non-writeable memory (FLASH) or write-protected memory (code garbage collection)
- ...

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 19:18 UTC (Wed) by cmorgan (guest, #71980) [Link] (7 responses)

Real-time systems *can* have requirements that can limit or prevent the use of garbage collection and other 4th generation language features. I do think of the Knuth quote about premature optimization though:

“We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. A good programmer will not be lulled into complacency by such reasoning, he will be wise to look carefully at the critical code; but only after that code has been identified”[5] - Donald Knuth

Don't think of it as throwing away performance, think of it as saving you several months of development and debugging in exchange for performance you probably don't need anyway.

I've see many embedded systems where someone got the idea that it had to be a real-time system without any actual reason for it. It wasn't controlling a reactor or aircraft or anything safety related. I've also seen a majority of embedded programmers that feel that things like c++ are too bloated etc for relatively powerful embedded chips. Considering that PCs have hundreds of times the processing power and memory of some embedded systems that could run garbage collection, I can't help but think that this is a case of worrying about a performance issue that may not exist.

Chris

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 16:21 UTC (Thu) by dashesy (guest, #74652) [Link] (5 responses)

First, sometimes the performance IS one of the goals (as you mentioned for example in real-time or safety critical applications), bad performance is same as not-working.
Second, I believe complexity is the root of most evil, and for an embedded system (or safety critical application) yes C++ is bloated with all the complexity of multiple-inheritance, operator overloading, ...
Firmware written entirely in C has almost no bugs, while C++ written GUI is so complicated programmers are never out of jobs just cleaning those bugs.
Third, proper management of memory has nothing to do with "small efficiencies", but it means the programmer knows what he is doing, and is looking over the code rather than overlooking the problems.

Garbage in garbage out, garbage collection is a response to the new paradigm of fast-to-market coding style and anyone-can-program apps.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 10, 2011 7:31 UTC (Fri) by jezuch (subscriber, #52988) [Link] (4 responses)

> Third, proper management of memory has nothing to do with "small efficiencies", but it means the programmer knows what he is doing, and is looking over the code rather than overlooking the problems.

I'm a little skeptical about this "knows what he is doing" part...

(If memory management takes >50% of my thinking time about the problem (well, not even the problem... about the solution, really), just to make sure "I know what I am doing", then I won't touch a language with explicit memory management with a 10-foot pole.)

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 11, 2011 0:49 UTC (Sat) by butlerm (subscriber, #13312) [Link] (3 responses)

If you have a lot of programmers with middling skills, and your application can handle the disadvantages, then using tracing GC (and languages that rely on them) is a trade-off well worth making.

There seems, however, to be a real need for system programming languages that are memory safe that do not require the use of a tracing GC (due to latency, cache trashing, and memory usage issues primarily) and which would let you make a variety of memory placement and allocation optimizations without random pointer writes, buffer overflows, and the like.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 16, 2011 21:41 UTC (Thu) by dgm (subscriber, #49227) [Link] (2 responses)

@jezuch
>> I'm a little skeptical about this "knows what he is doing" part...
Then why are you using the code to start with?
If you cannot trust the coder to "know what he is doing", then the problem is with the coder, not the language he's using.
>> If memory management takes >50% of my thinking time about the problem[...]
That says it all. You're clearly "fast to market"-oriented.

@butlerm
> If you have a lot of programmers with middling skills [...]
You're defending the "anybody can program" side here.

In my humble opinion, both arguments can be right sometimes, but often are not.
For important stuff I need to trust the software I'm using, and that means I'm implicitly trusting the programmer. If I cannot do that, then I need a new programmer indeed. For unimportant thinks... maybe if it's cheap I could consider using a crappy program, as long as the price is OK (=> low). Nobody in his right mind would expect great code from a poor programmer.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 17, 2011 7:28 UTC (Fri) by jezuch (subscriber, #52988) [Link] (1 responses)

>>> If memory management takes >50% of my thinking time about the problem[...]

>That says it all. You're clearly "fast to market"-oriented.

Not at all. I just hate to concentrate on the tedious while I could actually be solving the problem. Memory management is not the problem I'm trying to solve. But yeah, if it helps me not to exceed the time budget (as I heard most of the software projects do) then it's a plus.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 17, 2011 10:06 UTC (Fri) by elanthis (guest, #6227) [Link]

I'm both with you and against you on this one. :)

As someone who's been writing code for 19 years, I'm definitely tired of the tedium and miscellaneous silly stuff that low-level coding often entails.

However, I've never found a high-level language that doesn't totally destroy my productivity in any of several really important ways. Operator overloading and user-definable pass-by-value/local types are _essential_ for a vast swath of problems, and not having them instantly kills the usability of a language. Writing simple vector/matrix math in anything other than C++ is basically like slamming your hand in a car door. The high level languages simply lack the tools necessary to build clean, simple, stable, safe APIs for anything that isn't naturally representable as a heap-allocated fat object.

And then there's the lack of type checking for interfaces. Yeah, I don't really care about the types of local variables too much. But I really really really care that my DoFooOnString() method actually gets a string, and not anything else. Because if that method just stores the string in a container for later, the eventual crash that results from trying to call toUpper() on some random other type happens in a place that gives you zero clue about where the actual mistake was made. It's useless.

A final really big item -- and this is one I know most UNIX/Linux coders will scoff at, because I used to scoff at it myself until just a year or two ago -- is IntelliSense-like functionality. Not the crappy "word completion" that some UNIX editors have, but the ability to mouse over a variable in a program and have it pop up a little window naming the type, showing you its properties, its methods, etc. Being able to hit ->/. after a variable and find the method or property you're looking for ("was it requestHeader or getHeader or just header?") saves a little time. When you're digging into a new project, it saves a metric ****-load of time. No having to dig around in 20 header files to figure out things that MSVC/KDeveloper/XCode/etc. can tell you in 0.5 seconds.

I'll believe that C++ is less productive to write code in the day that someone disproves that my codebases have no manual memory management (hey, C++ lets you write smart handles that actually do even more for you than a garbage collected language can in the tricky situations where simply freeing an object isn't enough, and a good app framework will have such things) and can also show me a high-level language that doesn't make it so much more easy and efficient to introduce bugs and invalid-type exceptions while simultaneously making complex math a pain in the butt. :)

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 14, 2011 11:56 UTC (Tue) by marcH (subscriber, #57642) [Link]

> I do think of the Knuth quote about premature optimization

This great quote is not at its best here, because you typically use Garbage Collection, or not. GC is not something you can realistically optimize away later.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 15:59 UTC (Thu) by dashesy (guest, #74652) [Link]

Garbage collection might be useful for a very large project with programmers of different level of skills, that try to build upon patches over patches to make things just work!.
For a properly written applications (kernel for example) you do not need any garbage collection, but I would not mind to use garbage collection during the debugging/testing stage if I have the option to turn it off in the final product.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 18:04 UTC (Thu) by juhah (subscriber, #32930) [Link] (1 responses)

Real programmers know how to choose the right tool for the job. And by choosing tools wisely you don't have to sacrifice much performance either.
See Computer Language Benchmarks Game.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 18:31 UTC (Thu) by danieldk (guest, #27876) [Link]

But they are (very) synthetic benchmarks.

Also, 'stop the world' garbage collection maybe annoying (interactive applications) or a show-stopper (realtime applications).

That said, I think the disadvantages of garbage collections are overstated. For 90% of the applications it is fine, and can give tremendous benefits to the programmer. Then there are also languages where absence of garbage collection would be very unnatural or nearly impossible (e.g. functional languages).

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 10, 2011 7:33 UTC (Fri) by jezuch (subscriber, #52988) [Link]

> Real programmers (...)

http://xkcd.com/378/

IMVHO I think we've had enough of this "real programmers" crazy talk already.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 19:54 UTC (Wed) by welinder (guest, #4699) [Link] (9 responses)

> I suspect there is a fair amount of resistance to garbage collection, VM
> based languages etc that is based upon ideas of performance concerns
> that don't exist with today's fast computers or can't be solved by
> using better algorithms.

/me dons the Devil's Advocate hat.

People who like gc have been telling us that for at least two decades.
Delivered? Not so much. This is despite loads of benchmarks that
show all kinds of nice things.

Benchmarks don't lie, of course. But they are typically conducted in
over-simplified environments, because that is the easiest thing to do.
In particular, they're typically the only running program in the
environment.

But take one of those allegedly well-behaved programs and place it into
your regular workload and more often than not you see life sucked out of
the machine. And it doesn't matter if we're talking java, mono, or
Standard ML: when a gc'd program is running together with other programs,
the machine feels sluggish. Two gc'd programs is just painful.

I suspect that the act of doing gc involves accessing so much memory all
over the place that it kills the cpu caches.

There are exceptions, of course. Emacs is one, but that might have more
to do with the nature of a text editor: lots of waiting between reacting
to keystrokes. And gc that preferentially runs when Emacs is idle.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 20:56 UTC (Wed) by HelloWorld (guest, #56129) [Link] (6 responses)

But take one of those allegedly well-behaved programs and place it into your regular workload and more often than not you see life sucked out of the machine. And it doesn't matter if we're talking java, mono, or Standard ML: when a gc'd program is running together with other programs, the machine feels sluggish. Two gc'd programs is just painful.
Yeah right. Do you have any evidence whatsoever for this assertion, or is this just some particularly dumb trolling attempt?

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 22:07 UTC (Wed) by felixfix (subscriber, #242) [Link] (5 responses)

He's at least polite, which lends his argument more weight than yours. Your answer is also short and more devoid of substance than his.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 1:31 UTC (Thu) by HelloWorld (guest, #56129) [Link] (4 responses)

> Your answer is also short and more devoid of substance than his.
He makes arbitrary assertions that aren't backed up in any way. In my book, this is called trolling. If you have another opinion, tell me, where is the *actual* substance in his comment?

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 10:28 UTC (Thu) by modernjazz (guest, #4185) [Link] (2 responses)

I spend ~90% of my time developing in a nice, modern, garbage-collecting environment specializing in numerical analysis (i.e., well optimized for speed, since that's essential for numerical analysis). When I identify a performance bottleneck, I look at it carefully. Sometimes I can fix the limitation within the GC environment, and I am happy. But often, the problem really is the lack of explicit memory management: there's just no way to say "reuse this bit of memory you allocated last time I called this function."

To be more explicit about why I am quite sure this is true: if I essentially "copy" the GC environment's way of doing things in C/C++, and profile the result, guess what? I find that the result is not that much faster than the GC environment, and that the memory manager is consuming much of the time. But if instead I use the features of C/C++ that allow me to rewrite things in a way that reduces the number of calls to the memory manager, often (now that I've been doing long enough to know where my efforts are likely to be rewarded) I get a very big speedup---on some performance-critical code, I've seen ~10x speedup.

So yes, GC is wonderful and I use it whereever I can to simply my life, but sometimes there is simply no replacement for explicit memory management.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 15:35 UTC (Thu) by stevenj (guest, #421) [Link] (1 responses)

I spend ~90% of my time developing in a nice, modern, garbage-collecting environment specializing in numerical analysis (i.e., well optimized for speed, since that's essential for numerical analysis). When I identify a performance bottleneck, I look at it carefully. Sometimes I can fix the limitation within the GC environment, and I am happy. But often, the problem really is the lack of explicit memory management: there's just no way to say "reuse this bit of memory you allocated last time I called this function."

That sounds like a problem with implicit allocation of temporary memory rather than with GC per se. In an API where the temporary memory is supplied explicitly, you can re-use whatever you want, GC or no GC.

For example, suppose you have a Matlab-like system where "w = x + y + z" adds three vectors. A straightforward implementation of this will allocate a temporary vector t, compute t=x+y, then compute w=t+z, then discard t (which is eventually GCed). But then you can't reuse t for subsequent operations. There are several ways around this, but the simplest, which provides the manual control you wanted, is to instead provide calls where the user needs to explicitly supply temporary memory. i.e. "t = new vector[n]; add(t,x,y); add(w,t,z);". Note that this is perfectly possible even in a GC language, and gives you total control over how you re-use "t".

The basic point is that, in a GC language, you relinquish control over deallocation, but GC does not inherently require you to relinqish control over allocation as well. Blame your library API design instead.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 10, 2011 1:26 UTC (Fri) by modernjazz (guest, #4185) [Link]

Of course you are correct. I guess the real problem is not GC, but any environment which tries to "protect" its users from the "complexities" of functions that are allowed to modify their arguments. I guess I have usually seen the two design choices paired, but you're right that they really are separate issues.

> The basic point is that, in a GC language, you relinquish control over deallocation, but GC does
> not inherently require you to relinqish control over allocation as well. Blame your library API
> design instead.

Thanks for sharing the right way to think about it!

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 14:01 UTC (Thu) by interalia (subscriber, #26615) [Link]

That's not trolling IMO; and besides, he even said he was playing devil's advocate :) Sometimes people just aren't in the mood to cite lots of references or don't have them handy. Sometimes they are indeed just describing their own experiences. You could have responded by civilly asking him where he/she had experienced that, with what kind of programs, OS or hardware. Thanks for your posts elsewhere in this thread though on the relative expressiveness or usefulness of the syntactic sugar.

It used to be that people posted quite widely diverging opinions here on LWN (even without citing references everywhere) but were relaxed and treated it like a friendly discussion down at the pub over a drink or two. May it always be so!

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 16:55 UTC (Thu) by b7j0c (guest, #27559) [Link] (1 responses)

> But take one of those allegedly well-behaved programs and place it into
> your regular workload and more often than not you see life sucked out of
> the machine. And it doesn't matter if we're talking java, mono, or
> Standard ML: when a gc'd program is running together with other programs,
> the machine feels sluggish. Two gc'd programs is just painful.

post your address here and i will send you $200 for a new computer

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 19:46 UTC (Thu) by cmccabe (guest, #60281) [Link]

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 3:54 UTC (Thu) by tetley99 (guest, #75573) [Link] (12 responses)

    it feels good to know there are other people who would also like to ditch great-for-their-time languages like c/c++ etc and move to time saving modern languages

In defence of C++, the language is not set in stone: a considerably improved new version/standard is close to being finalised or has just been finalised.

The C++ committee did acknowledge the limitations of the language, and hence provided a lot of cleanups and new features that address many of the problematic areas.

While some areas still remain unruly (eg. the templates beast has been only somewhat tamed), great strides have been made in many other areas. I encourage everyone to have a look at the new standard (colloquially called C++0x and C++11).

btw, please do not lump in C and C++ via "C/C++". They are two different languages, where one contains a large subset of the other. I suspect a similar notion can be applied to C++98 and C++0x -- again, two different languages.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 15:26 UTC (Thu) by cmorgan (guest, #71980) [Link] (3 responses)

I don't mean to conflate older C or C++ revs with some of the new proposals but I didn't believe that the C++0x stuff was really that big of a step forward.

Its things things like built-in utf8 support, foreach operator, 'var' keyword like C# (helps with the articles example declaring a template type), garbage collection, passing everything by reference that I run into every day that cost a significant amount of time.

I don't think its reasonable or suitable though to retro-fit that kind of functionality onto a language like C++. It's simply too much, not suited to it and at that point why not use Java/C#/python?

Chris

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 15:30 UTC (Thu) by cmorgan (guest, #71980) [Link] (2 responses)

To reply to myself, it does look like the 'auto' operator is a nice addition and equivalent to 'var', although I wonder why they don't simply use 'var' given its history with vb, php, c# etc....

Chris

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 15:57 UTC (Thu) by zeekec (subscriber, #2414) [Link] (1 responses)

Using 'var' would have been painful! Do you realize how much code would have had to been rewritten?

'auto' was already a keyword (that no one uses anymore), so no code could have been using it as an identifier.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 15, 2011 3:29 UTC (Wed) by k8to (guest, #15413) [Link]

I'd say that the multiple redefinitions of existing keywords is one of the larger misfeatures in C++. It totally destroys clarity.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 10, 2011 18:06 UTC (Fri) by cmccabe (guest, #60281) [Link] (7 responses)

I wonder if they will add usable reflection support to the next version of C++. If you have RTTI enabled, you are already paying the cost of storing the dynamic data type in every class with a vtable. So why not have a nice interface that would let you iterate over the fields in your class?

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 11, 2011 8:42 UTC (Sat) by ikm (guest, #493) [Link] (1 responses)

What I really miss in GCC is some command-line switch to prevent the RTTI names from being emitted (only the names, i.e. string literals, but not the typeinfo structs themselves). I really don't like the fact that my class names are being leaked into the compiled binary - especially considering they are typically never used there at all.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 12, 2011 22:53 UTC (Sun) by cmccabe (guest, #60281) [Link]

I guess it really depends on whether those names are part of the ABI or not. You'd have to troll through the gcc source-- in particular, the part that handles exception catch blocks and dynamic_cast-- to find out exactly how gcc is using those names, if at all.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 21, 2011 22:56 UTC (Tue) by MattV (guest, #70341) [Link] (4 responses)

An interesting looking option here (that I have never tried, sorry) is XRTTI:

http://www.ischo.com/xrtti/

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 22, 2011 7:28 UTC (Wed) by elanthis (guest, #6227) [Link] (3 responses)

Interesting, but not really ideal. Preprocessors are notoriously hard to integrate into certain build systems, and many (most?) C++ users are not using autohell or scons or such, but rather various IDE-specific build systems and their numerous limitations.

Also, a reflection system that isn't extensible at runtime has serious problems. Yes, my framework needs to know what properties and methods a class has. It also needs a ton of other metadata, like serialization attributes (which properties should or should not be serializable), inter-dependencies for components in a composited object system, etc.

If I have to build those separately anyway then there's not necessarily a huge draw to building half of it into the language or half of it into some external tool. I need _flexibility_ rather than built-in paradigms, which is what makes C++ so superior to every last other language in common usage today for large-scale complex projects like the ones I work on. For whatever parts of C++ that get "fixed" by the numerous replacements that have sprung up there is always some major necessary strength of C++ that is lost.

The failings of C++ are less about it lacking things like a full reflection system and more that it's lacking a few low-level tools to make building a reflection system in a library possible, hence requiring pre-processors like xrtti. Add those few low-level features and build a default general-case reflection system in the STL for those who can deal with general-case performance is what C++ needs. This largely what the C++ committee focuses on, thankfully. Thinks like r-value references aren't features you're expected to use in every day code, but they can make implementing certain framework/platform/library features significantly easier or just allow them to be significantly more efficient.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 22, 2011 23:15 UTC (Wed) by MrWim (subscriber, #47432) [Link] (2 responses)

I agree. It would be great to be able to iterate over all public members of a struct/class in template code (e.g. at compile time) to produce, say, a DBus binding from a class interface or a generic "swap" that works for all types with no private data members.

It would also be nice to be able to be able to do compile time string manipulation (like in D) so you could implement string hashing for matching strings at run time with a switch statement.

It would also be nice to have some more powerful constructs for type traits so you can tell if swap is nothrow or move can be implemented with memcpy or if memset has the same effect as default constructing a class (like in go). These kind of tools would allow much easier template hoisting for reducing the bloat that often accompanies template heavy code

C++11 goes some way in this direction, and I hope they go further. If only the syntax, speed and error messages weren't so awful

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 23, 2011 2:27 UTC (Thu) by elanthis (guest, #6227) [Link]

> It would also be nice to be able to be able to do compile time string manipulation (like in D) so you could implement string hashing for matching strings at run time with a switch statement.

Actually, you can do this in C++0x now, using a constexpr recursive function to calculate the hash. I implemented a simple FNV-1a test case for this in about 5 lines, works on GCC 4.6 with -std=c++0x.

I also actually just have a custom StringLiteral class with a constexpr constructor that precalcs the hash, so my StringPool doesn't need to ever rehash the strings. For ref-counted systems (which I usually avoid, but some systems they make sense for) I also have the constexpr StringLiteral constructor convert to a ref-counted String with a copy and a ref count of 0, which signals to never increment/decrement the count. (I don't delete when the count hits 0, I delete when the count is 1 and a decrement operation is called, and I don't increment when the count is 0, so 0 becomes a "don't ref-count me" value.)

> It would also be nice to have some more powerful constructs for type traits so you can tell if swap is nothrow or move can be implemented with memcpy or if memset has the same effect as default constructing a class (like in go)

Also in C++0x, which I'm using in my STL container replacements (and which the STL will use too, of course). Unfortunately, GCC 4.6 is missing a couple of the new type traits I need to make it perfect, but I believe they're already in 4.7.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 24, 2011 7:29 UTC (Fri) by jezuch (subscriber, #52988) [Link]

> It would be great to be able to iterate over all public members of a struct/class in template code (e.g. at compile time)

Comments like this remind me of Greenspun's Tenth Rule, except that we're talking about a language, not a program.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 16:26 UTC (Wed) by martinfick (subscriber, #4455) [Link] (14 responses)

I am all for more expressive syntaxes, especially in the more verbose languages. So, I couldn't help but think more about his ternary operator comments:

Expression Syntax Many people shun it, but the ?: ternary operator is a good idea, if used correctly. Python does foo if bar else baz, which is a little more verbose but still okay. JS and Perl, however, rock with their boolean operators AND and OR not just evaluating to true and false, but to the actual value that was considered true. Imagine the assignment value = cmdline_option || "default". That requires a decent boolean interpretation of all data types, however.

One similar but more limited idea might be to create a simpler ternary operator for null checks for languages like java. I can't tell you how many times I have to write:

    Object a = b == null ? c : b;
I would be much happier if instead, I could only just write something like:
    Object a = b ? c;

And how about eliminating the need to check for many nulls by trapping null pointer exceptions easily with a ternary like operator? Instead of:
    String a = "bar"; if (foo != null && foo.get() != null) a = foo.get().get();
wouldn't it be cool if you could just write:
    String a = foo.get().get() : "bar";

Then, if we used both ideas together we might have:
    String a = "bar"; if (foo != null && foo.get() != null && foo.get().get() != null) a = foo.get().get();
rewritten as:
    String a = foo.get().get() : "bar" ? "bar";
Now, how about combining the two ideas to make what people really want to do easy and just be able to write something like:
    String a = foo.get().get() :? "bar";
that would assign a the value "bar" in case of a null anywhere in foo, foo.get() or foo.get().get()!

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 16:54 UTC (Wed) by cesarb (subscriber, #6266) [Link]

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 17:24 UTC (Wed) by tseaver (guest, #1544) [Link] (3 responses)

> Python does foo if bar else baz, which is a little more verbose but still
> okay. JS and Perl, however, rock with their boolean operators AND and OR
> not just evaluating to true and false, but to the actual value that was
> considered true

Python's 'and' and 'or' operators already do what you seem to want:

>>> x = {}
>>> y = {'not': 'empty'}
>>> z = ['also', 'not', 'empty']
>>> x and y
{}
>>> y and x
{}
>>> x or y
{'not': 'empty'}
>>> y or x
{'not': 'empty'}
>>> y and z
['also', 'not', 'empty']
>>> z and y
{'not': 'empty'}

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 23:53 UTC (Wed) by baldridgeec (guest, #55283) [Link] (2 responses)

>>> y and z
['also', 'not', 'empty']
>>> z and y
{'not': 'empty'}

I like the logic until these last two. The union of the two should either be independent of catalogue type (array vs. dictionary) and thus "y and z" return only {'not': 'empty'} (or ['not', 'empty']) OR it should be dependent on type and return {}. The way it's implemented, the "AND" operation's answer is non-commutative, which makes it much less useful, as now the order of arguments can result in subtle bugs if this feature is used.

So it does a full evaluation and returns the final evaluated TRUE value from the set if they are all true. Not sure when you would want to use that functionality (as opposed to just testing "empty || !empty") without adding enough comments to the block that it would take fewer bytes to rewrite the test anyway.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 0:03 UTC (Thu) by baldridgeec (guest, #55283) [Link] (1 responses)

Sorry, I had my comment written then edited it and reformatted a bunch, and I think that I made it somewhat less clear in the end.

If a test like that were to return any values other than true/false -- especially returning a collection of some sort -- I would expect naively that for the examples you posted the AND operator would give the union of the two collections. I dislike situations where subtle bugs can be introduced by basic operators like that. If you reread my previous comment with this in mind, it may make more sense. :)

(I've programmed a fair amount in Python, but never knew about the return values from comparing two collections - I only use such cases as explicit tests for empty/undef, so the return value is irrelevant.)

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 1:02 UTC (Thu) by chad.netzer (subscriber, #4257) [Link]

> The way it's implemented, the "AND" operation's answer is non-commutative

But shortcutting logical expressions *cannot* be commutative, since the evaluation of the right side is conditional on the value of the left. This is true for many languages other than Python, and is desirable. Programmers simply have to be aware of shortcutting, and not expect logical operators to act like union or intersection operators.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 17:27 UTC (Wed) by tialaramex (subscriber, #21167) [Link]

I think the operator you want is the one sometimes called 'Elvis' because the obvious symbol for the operator is ?: which looks a bit like Elvis if you squint (and assuming you have the right photo of Elvis in mind).

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 20:14 UTC (Wed) by Karellen (subscriber, #67644) [Link] (1 responses)

Imagine the assignment value = cmdline_option || "default".
I can't tell you how many times I have to write:
    Object a = b == null ? c : b;
I would be much happier if instead, I could only just write something like:
    Object a = b ? c;
Why is that better than:
    Object a = b || c;
You've saved one whole letter of typing. So?
    String a = foo.get().get() :? "bar";
Maybe a bit too much syntactic sugar? With javascript-like bools, although it is a bit longer, you could do:
    String a = (foo && foo.get() && foo.get().get()) || "bar";
Alternatively, in a language where all statements are also expressions, you might be able to do something like:
    String a = (try { foo.get().get(); } catch { "bar"; });
without need a new unique operator.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 21:59 UTC (Wed) by martinfick (subscriber, #4455) [Link]

> Why is that better than:
> Object a = b || c;

Likely because that is currently invalid in java, and if I understand it correctly, for it to ever make it into java would require being able to interpret references as a boolean value. In other words, b ('null' or 'not null') would have to be evaluated as true or false, java cannot do that. You cannot do if (b) in java unless b is a boolean.

So, I have nothing against your proposal, but it simply seems completely opposed to java's philosophy. Perhaps I am naive, but I think that it would actually be easier to add a new operator to the language than to propose evaluating references as booleans.

> Alternatively, in a language where all statements are also expressions, you might be able to do something like:
> String a = (try { foo.get().get(); } catch { "bar"; });

I don't believe that is equivalent. This would only catch the NPEs and would not handle the simple case when foo.get().get() == null since it would not cause an exception.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 20:41 UTC (Wed) by HelloWorld (guest, #56129) [Link] (5 responses)

One similar but more limited idea might be to create a simpler ternary operator for null checks for languages like java. I can't tell you how many times I have to write: Object a = b == null ? c : b; I would be much happier if instead, I could only just write something like: Object a = b ? c;
It's trivial to write a utility method for this kind of stuff, so I don't see the need for adding an operator to the language to do this.
And how about eliminating the need to check for many nulls by trapping null pointer exceptions easily with a ternary like operator? Instead of: String a = "bar"; if (foo != null && foo.get() != null) a = foo.get().get(); wouldn't it be cool if you could just write: String a = foo.get().get() : "bar";
If null checks like these are a significant burden in your daily work, you may be overusing null. Often it's possible to use the null object pattern (see wikipedia). It's also worth noting that the Haskell language solved this problem a long time ago with monads. In Haskell, you'd write fromMaybe "bar" (foo >>= get >>= get) to do this.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 21:46 UTC (Wed) by martinfick (subscriber, #4455) [Link] (4 responses)

> It's trivial to write a utility method for this kind of stuff, so I don't see the need for adding an operator to the language to do this.

It's trivial to implement the ternary operator with an if. The difference is that one is expressive, and the other isn't, it is verbose.

I wish that your solution were a decent one, but a utility method in java would have to be a static somewhere in some class (if you want it to be usable everywhere, which you would.) So calling that utility method would likely require prefixing a package name and a class, or adding an import, and then calling the method. In the end, repeating the object being compared to null is simpler. Even using an if would likely be less verbose than calling this proposed utility method! :(

> If null checks like these are a significant burden in your daily work, you may be overusing null... It's also worth noting that the Haskell language solved this problem a long time ago with monads.

Or perhaps I simply have a lower tolerance for things that could be easier. And if there is a solution for this in Haskell (although that solution seems way more verbose than my suggestion) then likely I am not alone.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 22:40 UTC (Wed) by HelloWorld (guest, #56129) [Link] (3 responses)

It's trivial to implement the ternary operator with an if. The difference is that one is expressive, and the other isn't, it is verbose.
The essential difference isn't verbosity but the fact that ?: evaluates lazily while method arguments can't be evaluated lazily (in Java, that is). So I was actually wrong before when I said that this can be implemented in a helper method.
Or perhaps I simply have a lower tolerance for things that could be easier. And if there is a solution for this in Haskell (although that solution seems way more verbose than my suggestion) then likely I am not alone.
Actually, the Haskell solution is a just by-product of monads, and calling it "way more verbose" is a stretch, as it's only about 50% longer. Adding new operators to the language to make things easier that rarely happen in well-written programs is a bad idea in my book.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 23:00 UTC (Wed) by martinfick (subscriber, #4455) [Link] (2 responses)

and calling it "way more verbose" is a stretch, as it's only about 50% longer.

Sure, if you look at these 2 strings, it is only about 50%:
    foo.get().get() : "bar"
    fromMaybe "bar" (foo >>= get >>= get)
But if you look at the essential operator difference:
    :
    fromMaybe()
it's a 1100% percent difference! :)

Not to mention that one is symbolic and the other is wordy. Verbose doesn't seem like a stretch to me.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 1:48 UTC (Thu) by HelloWorld (guest, #56129) [Link]

Oh well, if you think this really matters, you should probably go and play with Perl 6.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 1:57 UTC (Thu) by paoleary (subscriber, #66381) [Link]

Of course we can define infix operators in Haskell, so it's possible to define (?:) = fromMaybe; then you can use the "bar" ?: (foo >>= get >>= get):
    Prelude Data.Maybe> let (?:) = fromMaybe
    Prelude Data.Maybe> "bar" ?: Just "foo"
    "foo"
    Prelude Data.Maybe> "bar" ?: Nothing
    "bar"

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 19:47 UTC (Wed) by ikm (guest, #493) [Link] (1 responses)

All C-like languages except one suck? What a weenie. He would want a language to support making a local on-the-stack variable long-lived by taking a pointer to it, and also thinks there's reflection in C++. Come on, one bit from the article says it all:

> You didn't really think I would forget Java in my rant about C-oid languages, did you? Now, Java is almost the solution.

And yes, then he goes on to also include JavaScript. It seems that his definition of a C-like language there is any sort of language whose syntax loosely resembles C. Would you assume like me that a C-like language is one as low-level as C itself? Nope. If it has curly braces, it's C-like. No wonder they all suck.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 8, 2011 20:04 UTC (Wed) by cmccabe (guest, #60281) [Link]

> [He] also thinks there's reflection in C++

He just said that C++ has RTTI ("runtime type information"), which is true.

He probably could have been more explicit about how limited RTTI is compared to real reflection support like that of Java or Go, but I don't think that was his goal.

> And yes, then he goes on to also include JavaScript.

Yeah, I don't know why he included Javascript.

I think in general, he was trying to cover the languages that most people consider Go's "competitors." We could probably argue forever about exactly which languages those are, but I think Java and C++ belong there as a minimum.

P.S. Golang is cool, I'm glad to see more people pick up on it!

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 0:26 UTC (Thu) by leandro (guest, #1460) [Link] (1 responses)

Why are C-like languages relevant?

With D, Lisp and ðe such around…

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 10, 2011 5:39 UTC (Fri) by jd (guest, #26381) [Link]

Well, since D is a C-like language, I guess you've answered your question.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 0:49 UTC (Thu) by thedevil (guest, #32913) [Link] (24 responses)

There are more than a few things to like about Go, but this is a total showstopper (which I wasn't aware of until now):

# Indent with tabs (which lets the user twiddle his editor settings to get his comfortable amount of horizontal white space)

Yeah, right. Means every time I get code from *anyone* else I'll have to reformat it. Have we not been there?

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 1:48 UTC (Thu) by HelloWorld (guest, #56129) [Link] (15 responses)

> Yeah, right. Means every time I get code from *anyone* else I'll have to reformat it.
Um, no you don't. Why do you think that?

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 4:02 UTC (Thu) by thedevil (guest, #32913) [Link] (4 responses)

Because nobody can ever keep to using *only* tabs and no spaces, and when the two are mixed the code becomes unreadable with a different tab size setting.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 10:52 UTC (Thu) by HelloWorld (guest, #56129) [Link]

> Because nobody can ever keep to using *only* tabs
Actually, it worked pretty well in one place where I used to work.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 10, 2011 5:19 UTC (Fri) by nicooo (guest, #69134) [Link] (2 responses)

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 10, 2011 23:08 UTC (Fri) by nybble41 (subscriber, #55106) [Link] (1 responses)

From the description, I don't think that would help. It always uses tabs at the beginning of the line, up to the first non-space character, which means you'll still have problems with lines like:

+...int x = long_variable_name_1 +
+...+...+...long_variable_name_2 +
+...+...+...long_variable_name_3;

becoming

+.......int x = long_variable_name_1 +
+.......+.......+.......long_variable_name_2 +
+.......+.......+.......long_variable_name_3;

What is wanted is more like:

+...int x = long_variable_name_1 +
+...        long_variable_name_2 +
+...        long_variable_name_3;

with tabs up to the statement indentation level and spaces afterward.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 11, 2011 5:53 UTC (Sat) by nicooo (guest, #69134) [Link]

It works fine here.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 4:05 UTC (Thu) by jzbiciak (guest, #5246) [Link] (9 responses)

Well, if everyone must use tabs and must not use spaces, then it lessens part of the problem, since all code at a particular level of indentation will line up, regardless of whether [TAB] is 2 characters or 200.

The fun starts to happen when you use [TAB]s to line up pieces of code at some point other than the very start of the line. Now the number of characters in each [TAB] becomes significant. For example, suppose I wanted to format my code like so:

    line1 = blah + blah + blah +
            blah + blah + blah

If I have tabs set to 4 characters, then I'd enter the following: (using ^___ to indicate each tab)

^___line1 = blah + blah + blah +
^___^___^___blah + blah + blah

Now I send the file to you. You have your tabs set to 8 characters, not 4. Here's how the file comes up:

^_______line1 = blah + blah + blah +
^_______^_______^_______blah + blah + blah

You grumble at the askew line, go delete a [TAB], giving:

^_______line1 = blah + blah + blah +
^_______^_______blah + blah + blah

I open the file and then see my beautifully formatted code turned into:

^___line1 = blah + blah + blah +
^___^___blah + blah + blah

I think you can see why [TAB] characters aren't a magic bullet that allows different programmers to set tab stops however they please on the same source and still get visually pleasing results across the board. I haven't even gotten to the fun that'd happen when someone tries to make a table in a comment with tabs to go between the columns....

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 10:31 UTC (Thu) by cortana (subscriber, #24596) [Link]

A solution would be to forbid space characters at the start of a line. This is what I try to do when not working on code that has some other indentation requirement (like the annoying use of a tab character to 'compress' 8 space characters).

Your code would then be indented as:

void foo (void) {
␉line1 = blah + blah + blah +
␉        blah + blah
}

I can set my tab width to 4, and Linus can keep it at 8.

Use tab for nesting leves, spaces for column adjustments

Posted Jun 9, 2011 11:03 UTC (Thu) by gioele (subscriber, #61675) [Link]

I use tabs and I align code such that in your example

    line1 = blah + blah + blah +
            blah + blah + blah

with the following convention:

  1. use tabs for nesting levels;
  2. use spaces after the tabs to adjust the code split on multiple lines so that it is aligned with an important feature of the first line.

Examples(*... means "tab" and _ means "space").

With 4-spaces tab you get:


*...line1 = blah + blah + blah +
*...________blah + blah + blah

and


*...line1 = call_me(arg1, arg2, arg3
*...________________arg4, arg5)

8-spaces tabs?


*.......line1 = blah + blah + blah +
*.......________blah + blah + blah

2-spaces tabs?


*.line1 = blah + blah + blah +
*.________blah + blah + blah

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 12, 2011 18:35 UTC (Sun) by wahern (subscriber, #37304) [Link] (6 responses)

Use tabs to indent, spaces to align. It's a simple and foolproof rule.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 12, 2011 18:57 UTC (Sun) by jzbiciak (guest, #5246) [Link] (5 responses)

Great, if all your team members have the self-discipline to maintain it, or if you mandate an editor + config that can detect and enforce it, but at that point you may as well adopt a single team-wide indentation level.

That also says that tabs are only good for leading whitespace up to the current indentation level, and never anywhere else.

I've seen far too much tab-scrambled code (usually code that's crossed multiple team boundaries) to ever thing that hard tabs can be made to work properly. Maybe it's because I work in an engineering shop, where software is usually incidental to the product, not the primary output of the team.

In the specific case of Go, though, it appears that many of these issues are moot. It appears reading through the Go site that 'gofmt' can output tabs or spaces. Furthermore, it appears that Go's architects would have you run your code through 'gofmt' at every available opportunity, to keep the "programmatically mandated format for all Go programs" enforced. After all, they say, "Go is a new language and gofmt's style is as good as any other." Not sure I agree...

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 13, 2011 3:39 UTC (Mon) by wahern (subscriber, #37304) [Link] (4 responses)

The thing about "tabs to indent and spaces to align" is not only is it the best rule, it's also the least bad. Spaces to indent are impossible to work with for tab people and people without reformatting editors like vim or emacs. But tabs for indentation are easy for everyone because almost every editor, even dumber one like pico or joe, can easily set tab width. Tabs for aligning suck for everyone.

Curly brace style is less annoying because all styles are similarly easy to use when hacking on other people's code, no matter your editor. Except, perhaps, for GNU bracing, which is headache inducing.

There's really no arguing with this rule. It just works. Even the excuse, "but others don't use it", doesn't fly well. I'm a convert. I was all tabs for years, but I had to submit to reason when pressed. (Submitting to reason doesn't mean I immediately switched styles; that was a longer process.)

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 13, 2011 4:00 UTC (Mon) by jzbiciak (guest, #5246) [Link]

Well.. no arguing until someone's nicely formatted 80-column code with 4-character tabs gets word-wrapped and trashed by someone else's "helpful" editor with 80 columns and 8-character tabs....

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 13, 2011 16:07 UTC (Mon) by bronson (subscriber, #4806) [Link]

Unarguable? Hardly! If you force your team to put the invisible characters precisely where you want for aesthetic reasons, you're going to develop quite the reputation. I can see code reviews turning into another discussion on the difference between indentation and aligning.

On small projects, sure, go ahead. But in the real world, a world with big teams, Java-based editors and ridiculous deadlines, I don't think your idea will fly.

Just curious: are you pro- or anti- syntactically significant whitespace?

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 13, 2011 22:17 UTC (Mon) by Wol (subscriber, #4433) [Link]

Well, on one system I used, it was actually MUCH better. It used neither spaces nor tabs :-)

Okay, the system needed to know whether a file was text or binary, but spaces in text files were represented by ascii "DC1" x where x was the number of spaces as a byte.

Nice and simple. Most of my code was stored with each line on disk starting "DC1 6" for 6 spaces. No guesses as to which language it was :-)

Then when you open the file, you'll see exactly the same spacing as me :-)

Cheers,
Wol

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 13, 2011 22:19 UTC (Mon) by Wol (subscriber, #4433) [Link]

"It just works". Don't think so :-(

What happens when you're using one of those intelligent editors with auto-corrupt, that change spaces into tabs for you automatically?

Cheers,
Wol

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 9, 2011 12:06 UTC (Thu) by obi (guest, #5784) [Link]

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 10, 2011 7:02 UTC (Fri) by Comet (guest, #11646) [Link]

Go uses gofmt as the canonical layout tool; the devs went further than merely suggesting a canonical style, they wrote a tool to do the canonicalisation, and later wrote new tools which took advantage of this.

It's reasonable to have SCM pre-submits which confirm that Go code is gofmt compliant and reject the code if it is not, or just run gofmt as a tranform for you.

So any errant spaces will be fixed as part of the canonicalisation which has been deliberately entrenched as part of the Go culture.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 10, 2011 8:29 UTC (Fri) by uriel (guest, #20754) [Link] (5 responses)

> Yeah, right. Means every time I get code from *anyone* else I'll have to reformat it. Have we not been there?

Go has gofmt, which is one of the reasons why in Go you will *never* have to do this.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 10, 2011 17:54 UTC (Fri) by phiggins (guest, #5605) [Link] (4 responses)

This is one of the biggest advantages I've seen to Go. Just the size of this thread indicates the huge problem caused by various people using different styles. It's total police-state programming to define and enforce a single style that everyone must use...but you end up having to do this or else you end up with people reformatting code to their liking, leading to cluttered history and difficult code merges.

Without gofmt, you need to define a style guide and enforce it rigorously to avoid these problems. Saying "just use gofmt" resolve the argument, frees you from having to define the style guide, and brings consistency to every project written in the language. Java had a standard style guide, but I've run into many shops where a team decided to use their own without any justification other than personally liking it better.

The only open question in my mind is whether a single tool will really be able to handle the formatting needs of all programs. I'm not sure if this has ever been tried before, but it is worth a try!

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 10, 2011 18:02 UTC (Fri) by cmccabe (guest, #60281) [Link] (2 responses)

To be fair to the other languages, you can format C/C++ with GNU Indent, and there is a "Sun standard style" for Java as well. Ruby has a 2-space indent convention, whereas Python has a 4-space one.

Maybe the only difference with Go is that the formatter is bundled alongside the compiler, so you don't have to install a separate package. It's another small, practical touch that makes the language more usable.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 10, 2011 19:14 UTC (Fri) by phiggins (guest, #5605) [Link] (1 responses)

True--Go does not require use of gofmt. Perhaps adoption of it will be low in the end.

Go does have some other features that enforce a certain style even if you don't use gofmt. I am thinking in particular of the automatic semicolon insertion rules. This means you have to put curly braces on the same line as a conditional or loop, and that multi-line array or struct initializers require trailing commas, even on the last element. For example, this is the required style:

a := []int{
0,
1,
}

Leaving off the comma after the 1 is not valid.

I think what Go offers that GNU Indent does not is full backing and support from the people who designed and implemented the language. Their desire is to try and make gofmt work for all programs. I'm on the fence about how well that might work out after the number of programs written in Go gets sufficiently large.

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 11, 2011 4:42 UTC (Sat) by uriel (guest, #20754) [Link]

> True--Go does not require use of gofmt. Perhaps adoption of it will be low in the end.

So far adoption has been pretty much universal.

> Their desire is to try and make gofmt work for all programs. I'm on the fence about how well that might work out after the number of programs written in Go gets sufficiently large.

What programs would gofmt not work for?

Walter: The Go Programming Language, or: Why all C-like languages except one suck

Posted Jun 10, 2011 23:32 UTC (Fri) by jwakely (guest, #60262) [Link]

Style is substance


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