12 ms·
Structural 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 t
by bad_user 13y ago
Structural 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(...)".
- Peaker 13y agoEssentially, you're saying that the point is not to use DSL's. The benefits of DSL's are explained everywhere, so I don't think I need to repeat them here... Parser combinators are not what you said they are -- and you won't be able to write the kinds of things you can in Haskell. e.g, to parse 10 comma-followed-by-int: replicateM 10 (parseComma >> parseInt) How would you implement that in Go? Even if you violate DRY and re-implement replicateM in every monadic context I don't think Go will be able to encode anything similar in power to parser combinators. > But I have a nagging feeling that adding logging or exceptions in this context is quite a bit more convoluted To add exceptions, I use an EitherT transformation on my Transaction monad. To do a debug log, you just insert an impure debug log as you would in a non-pure language. To insert an actual production log you would use a Writer that accumulates the logs in order to eventually write them outside the transaction context. Otherwise, aborted transactions will also have the production logs. If you want these semantics, add logging capabilities to the transaction monad. Otherwise, you get nice guarantees about what can't happen.
- aninhumer 13y agoMonads with do-notation also provide a really powerful basis for creating custom DSLs with very varied semantics, which still allow you to use all the standard library functions for working with monads. I suspect various other abstractions could be similarly powerful with appropriate syntax sugar.
- 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