Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.misc > #1486

should we Go now?

From Ivan Shmakov <oneingray@gmail.com>
Newsgroups comp.lang.misc, comp.lang.c, comp.lang.perl.misc
Subject should we Go now?
Followup-To comp.lang.misc
Date 2013-02-24 10:47 +0000
Organization Aioe.org NNTP Server
Message-ID <87hal29eeb.fsf@violet.siamics.net> (permalink)

Cross-posted to 3 groups.

Followups directed to: comp.lang.misc

Show all headers | View raw


	[Cross-posting also to news:comp.lang.perl.misc and
	news:comp.lang.c, as Go seem to be positioned as a successor to
	both the "system programming languages" (C) and the "Web
	programming languages," of which Perl is one I'm familiar with.
	Setting Followup-To: news:comp.lang.misc only, though.]


    Introduction

	Becoming interested in this relatively new "Go" programming
	language [1] (now that I've found that its libraries' collection
	may even outshine CPAN, depending on the task at hand; I'm yet
	to check the quality of the code, though), I've decided to check
	its FAQ [2], and some of the related documents.  There, I've
	found a few design choices described which I'd like to comment
	on.  Certainly, there may be some misunderstanding on my part,
	hopefully to be resolved in the discussion.

	TIA.

[1] https://en.wikipedia.org/wiki/Go_(programming_language)
[2] http://golang.org/doc/faq


    An unusual control flow feature

	For me, one of the most notable features of Go seems to be its
	"defer" statement.  To quote [3]:

 > A defer statement pushes a function call onto a list.  The list of
 > saved calls is executed after the surrounding function returns.
 > Defer is commonly used to simplify functions that perform various
 > clean-up actions.

	And the code example follows:

 > func CopyFile(dstName, srcName string) (written int64, err error) {

 >     src, err := os.Open(srcName)
 >     if err != nil {
 >         return
 >     }
 >     defer src.Close()

 >     dst, err := os.Create(dstName)
 >     if err != nil {
 >         return
 >     }
 >     defer dst.Close()

	Certainly, this feature could simplify such clean-ups in the
	code; the only other way for such simplification I know of is to
	introduce additional functions all along the way.

	Somehow, "defer" looks quite Perl-ish to me!  (Such nice control
	features are characteristic of the Scheme programming language,
	too, but there "defer" would be too "imperative" to implement.)
	I wonder if there's a clever way to bring "defer" to, say, Perl?

[3] http://golang.org/doc/articles/defer_panic_recover.html


    Exceptions and assertions

	The stance of the language designers on exceptions does (for the
	most part) match my experience with them: which is little.  To
	quote the FAQ [2]:

 > Why does Go not have exceptions?

 > We believe that coupling exceptions to a control structure, as in the
 > try-catch-finally idiom, results in convoluted code.  It also tends
 > to encourage programmers to label too many ordinary errors, such as
 > failing to open a file, as exceptional.

	And then [3]:

 > The convention in the Go libraries is that even when a package uses
 > panic internally, its external API still presents explicit error
 > return values.

	Also per my experience with CPAN packages, exceptions are rarely
	used there, with most of the code I've seen returning "undef"
	instead (which is known in Go as "nil", AIUI.)

	The assertions go next:

 > Why does Go not have assertions?

 > Go doesn't provide assertions.  They are undeniably convenient, but
 > our experience has been that programmers use them as a crutch to
 > avoid thinking about proper error handling and reporting.  Proper
 > error handling means that servers continue operation after non-fatal
 > errors instead of crashing.

	Which is contrary to my experience, which says that for a
	prototype (which may or may not become a "real" project later),
	it's far better to have an "assert ()"-, or "or die"-ridden,
	code, than to waste time thinking about "proper" error
	reporting.  The latter may even be impossible at a given stage
	of development, "thanks" to the relative unfamiliarity of the
	coder with the new libraries, protocols, file formats, etc.

	Unfortunately, C-style assertions in Go would likely require a
	separate syntactic construct.  Perhaps a simple panic () may fit
	the majority of cases, however.


    Expressions and statements

	Being familiar with the languages of the Lisp family (mostly
	Scheme and Emacs Lisp), I don't believe in the necessity of firm
	separation of the "statement" and "expression" contexts.  C and
	Perl are rather close to Lisp in this respect, given that, for
	instance, the assignment operator forms an "expression" in both
	(while in other languages it may be a "statement" instead.)

	At least one modern C implementation (GCC) goes a bit further
	and allows statements almost anywhere in expressions.  Also,
	both C and Perl provide three conditional operators for use
	within expressions: binary &&, ||, and the ternary ? :.  (Perl
	provides a few more, but it isn't all that relevant here.)

	Unfortunately, Go seem to take a step back there.  Consider [2]:

 > Does Go have the ?: operator?

 > There is no ternary form in Go.  You may use the following to achieve
 > the same result:

 > if expr {
 >     n = trueVal
 > } else {
 >     n = falseVal
 > }

	In my opinion, this latter form is more error-prone, just as the
	"a = a + b" form is more error-prone than "a += b", -- thanks to
	the duplication of the identifier.

	Also, with several choices being handled, this can easily expand
	the code quite a bit.  Consider, e. g.:

   a = (foo_p   ? foo
        : bar_p ? bar
        : baz_p ? baz
        : qux);

	which has to be transformed to, say:

   switch {
     case foo_p:
       a = foo;
     case bar_p:
       a = bar;
     case baz_p:
       a = baz;
     case true:
       a = qux;
   }

	There's one more notable difference in having two particular
	operators form statements, and not expressions.

 > Why are ++ and -- statements and not expressions?  And why postfix,
 > not prefix?

 > Without pointer arithmetic, the convenience value of pre- and postfix
 > increment operators drops.  By removing them from the expression
 > hierarchy altogether, expression syntax is simplified and the messy
 > issues around order of evaluation of ++ and -- (consider f(i++) and
 > p[i] = q[++i]) are eliminated as well.  The simplification is
 > significant.

	I have some doubt regarding whether this decision is justified
	or not.  For instance, even though the pointer arithmetic is
	gone (the inconveniece of which is partly remedied by an easier
	to use "slicing" feature), wouldn't it still be convenient to
	write, say, a[i++] = b[j++]?  Go doesn't allow for that.


    The matters of style

	One more notable decision made for Go is that it allows for a
	newline to end a statement (unless it leads to an error), thus
	eliminating most of the semicolons one'd find in a similar C
	code, and is (AIUI) similar to the AWK approach.  The price to
	pay for that is that there can't be a newline before the
	function definition's opening brace:

func () foo() {
  // ...
}

	... Frankly, I don't seem to recall for a major programming
	language designer /not/ to advocate for a particular coding
	style.  (And so for the major users.)

	The all-time low record in this respect is probably set by the
	Python language, which goes as far as to hardwire a particular
	coding style into the language syntax itself (which made Python
	a no-go for me.)  Go seem to take a gentler approach here [2]:

 > Since Go code is meant to be formatted automatically by gofmt, some
 > style must be chosen.  That style may differ from what you've used in
 > C or Java, but Go is a new language and gofmt's style is as good as
 > any other.  More important -- much more important -- the advantages of a
 > single, programmatically mandated format for all Go programs greatly
 > outweigh any perceived disadvantages of the particular style.

	Instantly, I began to think if there could be a person brave
	enough to fork gofmt (or write a similar tool anew) to provide
	for a set of parameters to adjust comparable to that of
	GNU Indent [4]!

	A particular point is that there's an old typographic convention
	of spacing the parenthesis from the outside (as in "a (b) c"),
	which Go seem to forgo at times, and which I'd like to get back.

[4] http://www.gnu.org/software/indent/manual/

-- 
FSF associate member #7257	np. The Clairvoyant -- Iron Maiden

Back to comp.lang.misc | Previous | NextNext in thread | Find similar


Thread

should we Go now? Ivan Shmakov <oneingray@gmail.com> - 2013-02-24 10:47 +0000
  Re: should we Go now? Ben Morrow <ben@morrow.me.uk> - 2013-02-24 13:40 +0000
  Re: should we Go now? Rainer Weikusat <rweikusat@mssgmbh.com> - 2013-02-24 16:37 +0000
    Re: should we Go now? Ivan Shmakov <oneingray@gmail.com> - 2013-02-24 17:02 +0000
      Re: should we Go now? Rainer Weikusat <rweikusat@mssgmbh.com> - 2013-02-24 19:38 +0000
        Re: should we Go now? Nils M Holm <news2009@t3x.org> - 2013-02-25 07:23 +0000
          Re: should we Go now? Rainer Weikusat <rweikusat@mssgmbh.com> - 2013-02-25 17:30 +0000
      Re: should we Go now? Ben Morrow <ben@morrow.me.uk> - 2013-02-24 21:42 +0000
        Re: should we Go now? Rainer Weikusat <rweikusat@mssgmbh.com> - 2013-02-24 22:26 +0000
        Re: should we Go now? Rainer Weikusat <rweikusat@mssgmbh.com> - 2013-02-25 01:04 +0000
        Re: should we Go now? Ivan Shmakov <oneingray@gmail.com> - 2013-02-25 13:32 +0000
          Re: should we Go now? Ben Morrow <ben@morrow.me.uk> - 2013-02-25 15:28 +0000
            Re: should we Go now? Rainer Weikusat <rweikusat@mssgmbh.com> - 2013-02-25 17:54 +0000
      Re: should we Go now? "BartC" <bc@freeuk.com> - 2013-02-25 01:29 +0000
        Re: should we Go now? Ivan Shmakov <oneingray@gmail.com> - 2013-02-25 13:12 +0000
  Re: should we Go now? Ivan Shmakov <oneingray@gmail.com> - 2013-02-24 17:04 +0000
  Re: should we Go now? Bjoern Hoehrmann <bjoern@hoehrmann.de> - 2013-02-24 18:24 +0100
  Re: should we Go now? Keith Thompson <kst-u@mib.org> - 2013-02-25 17:01 -0800

csiph-web