Earlier quoted context omitted.
I do it in C code instinctively; it's very useful for instrumentation, debugging, and resource management in straight C to have a single return point. When I get too far to the right, that's a signal that it's time to further decompose my functions; that signal is also useful, which is another thing that keeps me doing it. But that style doesn't make much sense in Golang. It makes even less sense in Ruby and Python,…
do you know of any languages that have a sort of inverted switch statement to clean up a list of if statements like this? something like: invswitch err !=nil { case 'err := binary.Write(w, binary.LittleEndian, int32(len(g.Name)))': return err case _, err = w.Write([]byte(g.Name)): return err case err = binary.Write(w, binary.LittleEndian, g.Age): return err default: return binary.Write(w, binary.LittleEndian, g.FurCo…
Twelve Go Best Practices
131–140 of 153 posts
Re: Twelve Go Best Practices
#132Earlier quoted context omitted.
do you know of any languages that have a sort of inverted switch statement to clean up a list of if statements like this? something like: invswitch err !=nil { case 'err := binary.Write(w, binary.LittleEndian, int32(len(g.Name)))': return err case _, err = w.Write([]byte(g.Name)): return err case err = binary.Write(w, binary.LittleEndian, g.Age): return err default: return binary.Write(w, binary.LittleEndian, g.FurCo…
Yes, CPS is essentially that and available in any modern language, or can be emuated by setcontext(2)/getcontext(2). However, it can become a mess very quickly. Another option is monadic style, which will pass error checking along. I believe it will work well for this example, and can be implemented in Go, most likely (I don't know Go, bur it seems so). Of course, the real problem with this code is that it is not dec…
Re: Twelve Go Best Practices
#133Earlier quoted context omitted.
I would prefer to see something like (probably not legal Go, but would work in C, if err is of type bool): err = Write(int32(len(g.Name))) err |= Write([]byte(g.Name)) err |= Write(g.Age) err |= Write(g.FurColor) return err; If err is of type int with 0 == noError, this will require some new syntax if you want to return the correct error code (which you should want to do). I would suggest introducing x ||= y x = x ||…
> An alternative could be to have a language construct that takes a sequence of lambda's, executes them in sequence until the first one that fails (if any) and returns the index and the result code of the failing lambda. You could write a function in Go as it is that takes a sequence of lambdas and does that, so why would you need a language construct?
You'd want generics if you wanted the chain to return a result though (or if you wanted intermediate steps to thread results through).
Re: Twelve Go Best Practices
#134Earlier quoted context omitted.
> Go occupies an interesting space. In my mind, I see it as competing simultaneously with C and Python. I suppose that the developers didn't see a place for an Optional type within that realm. I would assume that everything that hasn't been implemented in Go 1.1 is not implemented because the devleopers of Go "didn't see a place for" it. Now, either not seeing it as more important than the theings that did make it in…
You make a valid point, but for something as fundamental as nullability, I think that's baked into the core language spec. It's possible that we could see an Option type in the future, but the fact that it's not an integral part of the language now means it would be unreliable and defeats the purpose of eliminating NPEs.
Re: Twelve Go Best Practices
#135Earlier quoted context omitted.
Also, you can use the arrow keys to go back and forth through the slides.
Yes all those options work. But why remove a common method of navigation? In addition, the format makes it impossible to search for text within the presentation.
Re: Twelve Go Best Practices
#136Earlier quoted context omitted.
You make a valid point, but for something as fundamental as nullability, I think that's baked into the core language spec. It's possible that we could see an Option type in the future, but the fact that it's not an integral part of the language now means it would be unreliable and defeats the purpose of eliminating NPEs.
> You make a valid point, but for something as fundamental as nullability, I think that's baked into the core language spec. Well, its certainly out for 1.x; I wouldn't presume to assume how much or little flexibility there will be for 2.x if/when it happens. > It's possible that we could see an Option type in the future, but the fact that it's not an integral part of the language now means it would be unreliable and…
Re: Twelve Go Best Practices
#137Earlier quoted context omitted.
I would prefer to see something like (probably not legal Go, but would work in C, if err is of type bool): err = Write(int32(len(g.Name))) err |= Write([]byte(g.Name)) err |= Write(g.Age) err |= Write(g.FurColor) return err; If err is of type int with 0 == noError, this will require some new syntax if you want to return the correct error code (which you should want to do). I would suggest introducing x ||= y x = x ||…
You can panic inside Write() and recover at the top of the DumpBinary() function. This has been demonstrated by Rob Pike and Andrew Gerrand in a talk at Google IO. As long as you don't leak panics outside of your package, it's OK to use them for non-local error returns.
Re: Twelve Go Best Practices
#138The type cast as part of the switch is really cool, I hadn't seen that before. switch v := v.(type) { case string: w.Write(int32(len(v))) w.Write([]byte(v)) default: w.err = binary.Write(w.w, binary.LittleEndian, v) } Great way to alter control flow based on the type, without a ton of ugly casts cluttering things up.
This is why I love pattern matching in languages that support it - typing is just one of the things on which they can switch. As the Scala website puts it (paraphrasing), "Pattern matching is switch on steroids!" Here is how you would return all leaf values in a binary tree in Scala: case class Node case class Fork(left: Node, right: Node) extends Node case class Leaf(value: Int) extends Node def getValues(node: Node…
@tailrec
def getValuesFromNode(node: Node, accValues: List.empty[Int], nodeList: List.empty[Node]): List[Int] = node match {
case Fork(left, right) => getValuesFromList(accValues, nodeList ++ List(left, right))
case Leaf(value) => getValuesFromList(accValues ++ List(value), nodeList)
}
@tailrec
def getValuesFromList(accValues: List.empty[Int], nodeList: List.empty[Node]): List[Int] = nodeList match {
case x :: xs => getValuesFromNode(x, accValues, xs)
case _ => accValues
}Re: Twelve Go Best Practices
#139if err == nil { _, err := w.Write([]byte(g.Name)) if err == nil { err := binary.Write(w, binary.LittleEndian, g.Age) if err == nil { return binary.Write(w, binary.LittleEndian, g.FurColor) } return err } return err } Why does anyone have to tell people not to do this? How does it enter anyone's mind as a thing to do in the first place? I've been known to go too far to minimize nesting. I get twitchy at the second lev…
Quite a few people write deeply nested code for some reason unless you tell them not to. Maybe it depends on how your brain works. There is surprising variance within the human population. I find deeply nested code ugly and unreadable, others nest eight levels deep and love it. Some people even claim they find parentheses soup (LISP-like syntax) readable. Personally, I cannot comprehend that.
I find that anything more verbose (EDIT: I'm having difficulty thinking of the right word for what I mean here - hopefully you understand anyway) is useful while you're writing the code, but actually increases the difficulty and length of time to understand what's going on when you come back to it.
Symbolic representations of relationships - including parentheses among many others - just make more instant sense to me. To the extent that a characterisation of the Lisp family as "parenthesis soup" just does not make sense to me -- it implies an arbitrary jumble of symbols, while for me, as none of the parentheses could possibly be moved, they're in a perfect and immovable pattern.
I'll admit, though, that without [ and ] I would sometimes be more than a little lost.
I think I might enjoy an APL-like language if I ever had time to learn it...
Re: Twelve Go Best Practices
#140if err == nil { _, err := w.Write([]byte(g.Name)) if err == nil { err := binary.Write(w, binary.LittleEndian, g.Age) if err == nil { return binary.Write(w, binary.LittleEndian, g.FurColor) } return err } return err } Why does anyone have to tell people not to do this? How does it enter anyone's mind as a thing to do in the first place? I've been known to go too far to minimize nesting. I get twitchy at the second lev…
Quite a few people write deeply nested code for some reason unless you tell them not to. Maybe it depends on how your brain works. There is surprising variance within the human population. I find deeply nested code ugly and unreadable, others nest eight levels deep and love it. Some people even claim they find parentheses soup (LISP-like syntax) readable. Personally, I cannot comprehend that.
Lisp is read like python, you read indentation, ignore the parenthesis.