6 ms·
Go has interfaces that you implement just by having the methods, without declaring that you're implementing the interface (e.g. "implements" in Java). This kind
by isbadawi 13y ago
Go has interfaces that you implement just by having the methods, without declaring that you're implementing the interface (e.g. "implements" in Java). This kind of feels like duck typing in python. For example, in python lots of APIs work with file-like objects, e.g. anything with a read method -- you can do the same sort of thing in Go.
- aeden 13y agoAlmost, except that you still do have to be conscious of argument and return types. The one thing that still catches me (and I'm a relative newbie in Go, so that's probably why) is attempting to return nil when the return type won't allow it, such as the case when the return type is a string. It feels weird, but at least the compiler catches it so I can fix it and move on.
- bad_user 13y agoStructural typing is nothing like duck typing. People saying that don't know what they are talking about. Yes, both features allow one to escape the manifest typing present in languages like Java. But duck typing is so much more, as duck typing allows you to make shit up at runtime (e.g. come up with new interfaces based on the data you have). By definition a static type system will reject pieces of computation that are correct when described in a dynamic type system. Also Go's static type system isn't even a good static type system, as it makes it next to impossible to work with monads or Haskell's Maybe. And serving as proof that Go's type system is weak, consider how these are non-issues in Haskell or Scala or dynamic languages such as Ruby or Clojure (yes, Clojure developers are know to use monads when it makes sense to do so). Go's type system is a rather poor implementation of features that were properly implemented in other languages, such as Ocaml or Haskell. It's a shame really that such an awful implementation gained so much popularity on account of Google, but on the other hand I view it as a fad that will pass like all the rest.
- pacala 13y agoI'll bite. What are useful uses of monads, other than implementing exceptions, async, state and IO? Granted, it's aestethically pleasing to have a really tiny core on which to layer more sugar, but sometimes using the language as-is suffices. The mother of all monads is Cont (http://blog.sigfpe.com/2008/12/mother-of-all-monads.html http://blog.sigfpe.com/2008/12/mother-of-all-monads.html), but that belongs in the bowels of the compiler.
- Peaker 13y agoContinuations are useful monads too (for implementing coroutines or control features like Python's "with", etc). As are parsers, uniqueness, randomness, non-determinism, readers, writers, regions, resource management, local-state threads (ST monad), probability distributions, software transactional memory, .... Another nice thing is composing various monads to build a custom one for the purpose you need. For example: StateT S1 (EitherT Err (State S2)) a Will be a stateful computation that always has yields a new S2 value, even in exceptions (preserving any modifications up to the exception) but only yields an S1 in the case of success. This is just one of infinite possible compositions of monad transformers. If you hard-code a certain ambient monad into your language, you won't be able to use monads as a DSL for the use case you have at a certain time. For example, in the application I'm developing now, I use a "Transaction" monad that guarantees that my key/value store transactions cannot do any IO or anything other than read keys and write keys. As a bonus, that means I don't even need transactionality from the underlying data store -- I can "revert" or "commit" by implementing the Transaction monad as a state tracker of all the changes on top of a hidden IO layer that exclusively allows reading keys. This also means I can implement useful transactional primitives such as "forkScratch" which allows me to fork the transactional state, run an action in that forked state, discard its transactional side effects, and keep its result. I use this to "try out" a transaction, see if it would work (in my context, type-check the new state and discard it) without actually having any effect. tl;dr: There isn't a finite set of useful monads you can bake into the language. There are infinite compositions of useful monads.
- pacala 13y agoThe point is to not (re)invent little languages all the time, but to use the actual language. For coroutines, see https://sites.google.com/site/gopatterns/concurrency/coroutines https://sites.google.com/site/gopatterns/concurrency/corouti.... The parser combinator is also interesting. A parser combinator is merely a function that takes an input pointer and produces a list of matches. One can implement this in Go (or any programming language I know of) without agonizing over the syntax used to chain combinators. Essentially, the type machinery necessary to implement and use monads is a tradeoff. One can implement the code in pretty much any language one wants. The only point in contention is how many invariants are enforced by the type system vs. how much type system wrestling one has to deal with. I lack the empirical evidence that, for example, "monad that guarantees that my key/value store transactions cannot do any IO" is any better than a comment "// Transactions never do IO. To perform perform IO use package TIOBridge.". But I have a nagging feeling that adding logging or exceptions in this context is quite a bit more convoluted than "import log; log.info(...)" or "panic(...)".
- redbad 13y ago> Structural typing is nothing like duck typing. People > saying that don't know what they are talking about. Structural typing is at least facially similar to duck typing. People contesting that are being pedants.
- masklinn 13y agoStructural typing is facially similar to duck typing when anonymous types (interfaces and structures) are allowed, as in OCaml. I don't believe either exists in Go.
- burntsushi 13y agoThey are absolutely allowed. [1] You can have anonymous structs in a similar fashion. [1] - http://play.golang.org/p/tHYLcdbPSS http://play.golang.org/p/tHYLcdbPSS
- Teckla 13y agoGo has interfaces that you implement just by having the methods, without declaring that you're implementing the interface (e.g. "implements" in Java). How well does that work with tooling? For example, in Java, I frequently ask my tools, "Give me a list of classes that implement this interface," and I expect a fast and -- most important -- 100% accurate answer. My instinct is that Go's approach makes it tooling-unfriendly (a good chance of false positives, especially in large systems), but perhaps I'm missing something.
- redbad 13y ago> in Java, I frequently ask my tools, "Give me a list of > classes that implement this interface," You don't generally ask this question when working in Go, because you don't really construct your "type" system in these terms.