FAQ
I came across this discussion and comment on stackoverflow:

http://stackoverflow.com/a/1727737/283851

I decided to use it as an exercise to try out embedded structs and
interfaces.

Here's what I got so far:

https://gist.github.com/mindplay-dk/807179beda57e676b8fb

What I can't figure out is... interfaces can't have methods (?) ... so how
do I write the Withdraw() method in such a way that it can work with either
a BankAccount or an OverdraftAccount?

I'm sure I'm thinking about this all wrong :-)

Tell me how a Go developer would attack this problem?

Thanks!

- Rasmus

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Chris dollin at Dec 3, 2013 at 2:12 pm

    On 3 December 2013 13:51, Rasmus Schultz wrote:

    I came across this discussion and comment on stackoverflow:

    http://stackoverflow.com/a/1727737/283851

    I decided to use it as an exercise to try out embedded structs and
    interfaces.

    Here's what I got so far:

    https://gist.github.com/mindplay-dk/807179beda57e676b8fb

    What I can't figure out is... interfaces can't have methods (?)
    They can't have method /definitions/. But you can write ordinary
    functions that take interface-typed arguments and return
    interface-typed results.

    ... so how do I write the Withdraw() method in such a way that it can work
    with either a BankAccount or an OverdraftAccount?
    You write it once for BankAccount and a second time for OverdraftAccount.
    (Of course these two methods may share code via a third function or
    method.)

    Since we're doing Go I'd feel itchy about making sure concurrency was
    handled correctly. But that's probably outside the scope of the example.

    Chris

    --
    Chris "allusive" Dollin

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Rasmus Schultz at Dec 4, 2013 at 2:17 pm
    Well, I don't like the idea of implementing the same function twice, and I
    discovered I could avoid that, by taking the Withdraw() function out of the
    interface and adding a dead simple internal method, deduct() which doesn't
    perform the balance check.

    I kinda wish there was a way to use a method to do the withdrawal instead
    of a function, but I come from a long background of OO languages, and I
    guess withdrawal is not really something an account does to itself - it's
    something that is done *to *the account, and as such doesn't really belong
    in a method, right? :-)

    I wonder if all of the other methods really should be methods?

    Would you take another look at the updated source and tell me if I'm doing
    better?

    Thanks :-)

    On Tue, Dec 3, 2013 at 9:12 AM, chris dollin wrote:
    On 3 December 2013 13:51, Rasmus Schultz wrote:

    I came across this discussion and comment on stackoverflow:

    http://stackoverflow.com/a/1727737/283851

    I decided to use it as an exercise to try out embedded structs and
    interfaces.

    Here's what I got so far:

    https://gist.github.com/mindplay-dk/807179beda57e676b8fb

    What I can't figure out is... interfaces can't have methods (?)
    They can't have method /definitions/. But you can write ordinary
    functions that take interface-typed arguments and return
    interface-typed results.

    ... so how do I write the Withdraw() method in such a way that it can
    work with either a BankAccount or an OverdraftAccount?
    You write it once for BankAccount and a second time for OverdraftAccount.
    (Of course these two methods may share code via a third function or
    method.)

    Since we're doing Go I'd feel itchy about making sure concurrency was
    handled correctly. But that's probably outside the scope of the example.

    Chris

    --
    Chris "allusive" Dollin
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Egon at Dec 4, 2013 at 3:26 pm
    This should be a bit more realistic situation
    http://play.golang.org/p/JqZFgm-3Cg. I.e. the accounts themselves are more
    of a projection from the bank ledger. (Although this version is also wrong
    from the realism point of view.)

    + egon
    On Wednesday, December 4, 2013 4:17:04 PM UTC+2, Rasmus Schultz wrote:

    Well, I don't like the idea of implementing the same function twice, and I
    discovered I could avoid that, by taking the Withdraw() function out of the
    interface and adding a dead simple internal method, deduct() which doesn't
    perform the balance check.

    I kinda wish there was a way to use a method to do the withdrawal instead
    of a function, but I come from a long background of OO languages, and I
    guess withdrawal is not really something an account does to itself - it's
    something that is done *to *the account, and as such doesn't really
    belong in a method, right? :-)

    I wonder if all of the other methods really should be methods?

    Would you take another look at the updated source and tell me if I'm doing
    better?

    Thanks :-)


    On Tue, Dec 3, 2013 at 9:12 AM, chris dollin <ehog....@googlemail.com<javascript:>
    wrote:
    On 3 December 2013 13:51, Rasmus Schultz <ras...@mindplay.dk<javascript:>
    wrote:
    I came across this discussion and comment on stackoverflow:

    http://stackoverflow.com/a/1727737/283851

    I decided to use it as an exercise to try out embedded structs and
    interfaces.

    Here's what I got so far:

    https://gist.github.com/mindplay-dk/807179beda57e676b8fb

    What I can't figure out is... interfaces can't have methods (?)
    They can't have method /definitions/. But you can write ordinary
    functions that take interface-typed arguments and return
    interface-typed results.

    ... so how do I write the Withdraw() method in such a way that it can
    work with either a BankAccount or an OverdraftAccount?
    You write it once for BankAccount and a second time for OverdraftAccount.
    (Of course these two methods may share code via a third function or
    method.)

    Since we're doing Go I'd feel itchy about making sure concurrency was
    handled correctly. But that's probably outside the scope of the example.

    Chris

    --
    Chris "allusive" Dollin
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Rasmus Schultz at Dec 6, 2013 at 1:14 pm
    Yeah, thanks, but this is an entirely different example that doesn't deal
    with polymorphism - the point of the exercise was to try to work with
    similar types, e.g. BankAccount and OverdraftBankAccount.


    On Wed, Dec 4, 2013 at 10:26 AM, egon wrote:

    This should be a bit more realistic situation
    http://play.golang.org/p/JqZFgm-3Cg. I.e. the accounts themselves are
    more of a projection from the bank ledger. (Although this version is also
    wrong from the realism point of view.)

    + egon
    On Wednesday, December 4, 2013 4:17:04 PM UTC+2, Rasmus Schultz wrote:

    Well, I don't like the idea of implementing the same function twice, and
    I discovered I could avoid that, by taking the Withdraw() function out of
    the interface and adding a dead simple internal method, deduct() which
    doesn't perform the balance check.

    I kinda wish there was a way to use a method to do the withdrawal instead
    of a function, but I come from a long background of OO languages, and I
    guess withdrawal is not really something an account does to itself - it's
    something that is done *to *the account, and as such doesn't really
    belong in a method, right? :-)

    I wonder if all of the other methods really should be methods?

    Would you take another look at the updated source and tell me if I'm
    doing better?

    Thanks :-)


    On Tue, Dec 3, 2013 at 9:12 AM, chris dollin wrote:
    On 3 December 2013 13:51, Rasmus Schultz wrote:

    I came across this discussion and comment on stackoverflow:

    http://stackoverflow.com/a/1727737/283851

    I decided to use it as an exercise to try out embedded structs and
    interfaces.

    Here's what I got so far:

    https://gist.github.com/mindplay-dk/807179beda57e676b8fb

    What I can't figure out is... interfaces can't have methods (?)
    They can't have method /definitions/. But you can write ordinary
    functions that take interface-typed arguments and return
    interface-typed results.

    ... so how do I write the Withdraw() method in such a way that it can
    work with either a BankAccount or an OverdraftAccount?
    You write it once for BankAccount and a second time for OverdraftAccount.
    (Of course these two methods may share code via a third function or
    method.)

    Since we're doing Go I'd feel itchy about making sure concurrency was
    handled correctly. But that's probably outside the scope of the example.

    Chris

    --
    Chris "allusive" Dollin
    --
    You received this message because you are subscribed to a topic in the
    Google Groups "golang-nuts" group.
    To unsubscribe from this topic, visit
    https://groups.google.com/d/topic/golang-nuts/U5wc4F6j18c/unsubscribe.
    To unsubscribe from this group and all its topics, send an email to
    golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Egon at Dec 6, 2013 at 2:21 pm
    (note; I'm being concise and as direct as possible to avoid adding "IMHO"-s
    and "of course there are special situations" everywhere in the text...)

    With such approach quite often you get poor solutions. e.g. you pick
    polymorphism/inheritance and try to figure out what you can do with it;
    eventually you end up with a BankAccount example, and then assume it's an
    appropriate context. I.e. next time you build something similar to
    BankAccount you use polymorphism/inheritance; of course, that may not be
    the best solution. Obviously, I'm oversimplifying and overgeneralizing here.

    The correct way to approach, is to start with the problem and try to find
    the best solution, not the other way around. With enough effort it is
    possible to fit anything to some particular paradigm... but, that brings me
    to one of the reasons I really like Go. When you start to have problems
    with implementing X in a particular way, then it's probably useful to
    reevaluate whether there are better ways of implementing X. I found that,
    if you notice those pain signs then Go will guide you to a better solution
    -- one that is simpler and cleaner.

    As a short answer to your question "Tell me how a Go developer would attack
    this problem?" is that I'd reevaluate the need for such constructs in the
    first place.

    + egon :)
    On Friday, December 6, 2013 3:13:54 PM UTC+2, Rasmus Schultz wrote:

    Yeah, thanks, but this is an entirely different example that doesn't deal
    with polymorphism - the point of the exercise was to try to work with
    similar types, e.g. BankAccount and OverdraftBankAccount.



    On Wed, Dec 4, 2013 at 10:26 AM, egon <egon...@gmail.com <javascript:>>wrote:
    This should be a bit more realistic situation
    http://play.golang.org/p/JqZFgm-3Cg. I.e. the accounts themselves are
    more of a projection from the bank ledger. (Although this version is also
    wrong from the realism point of view.)

    + egon
    On Wednesday, December 4, 2013 4:17:04 PM UTC+2, Rasmus Schultz wrote:

    Well, I don't like the idea of implementing the same function twice, and
    I discovered I could avoid that, by taking the Withdraw() function out of
    the interface and adding a dead simple internal method, deduct() which
    doesn't perform the balance check.

    I kinda wish there was a way to use a method to do the withdrawal
    instead of a function, but I come from a long background of OO languages,
    and I guess withdrawal is not really something an account does to itself -
    it's something that is done *to *the account, and as such doesn't
    really belong in a method, right? :-)

    I wonder if all of the other methods really should be methods?

    Would you take another look at the updated source and tell me if I'm
    doing better?

    Thanks :-)


    On Tue, Dec 3, 2013 at 9:12 AM, chris dollin wrote:
    On 3 December 2013 13:51, Rasmus Schultz wrote:

    I came across this discussion and comment on stackoverflow:

    http://stackoverflow.com/a/1727737/283851

    I decided to use it as an exercise to try out embedded structs and
    interfaces.

    Here's what I got so far:

    https://gist.github.com/mindplay-dk/807179beda57e676b8fb

    What I can't figure out is... interfaces can't have methods (?)
    They can't have method /definitions/. But you can write ordinary
    functions that take interface-typed arguments and return
    interface-typed results.

    ... so how do I write the Withdraw() method in such a way that it
    can work with either a BankAccount or an OverdraftAccount?
    You write it once for BankAccount and a second time for
    OverdraftAccount.
    (Of course these two methods may share code via a third function or
    method.)

    Since we're doing Go I'd feel itchy about making sure concurrency was
    handled correctly. But that's probably outside the scope of the example.

    Chris

    --
    Chris "allusive" Dollin
    --
    You received this message because you are subscribed to a topic in the
    Google Groups "golang-nuts" group.
    To unsubscribe from this topic, visit
    https://groups.google.com/d/topic/golang-nuts/U5wc4F6j18c/unsubscribe.
    To unsubscribe from this group and all its topics, send an email to
    golang-nuts...@googlegroups.com <javascript:>.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Rasmus Schultz at Dec 6, 2013 at 2:37 pm
    I'm not trying to replicate a particular pattern, I'm trying to learn the
    mechanics of the language.

    Just consider the example in the abstract - there are two types of
    accounts, a few common activities such as deposit and withdraw, and one
    type of account has an overdraft allowance.

    If those are the requirements, you can't simply make up different
    requirements that fit the language better ;-)

    I'm not trying to replicate the solution, the patterns, or the mechanics of
    Java or some other language - I'm simply trying to learn how the same
    requirements can be met with Go code.


    On Fri, Dec 6, 2013 at 9:21 AM, egon wrote:

    (note; I'm being concise and as direct as possible to avoid adding
    "IMHO"-s and "of course there are special situations" everywhere in the
    text...)

    With such approach quite often you get poor solutions. e.g. you pick
    polymorphism/inheritance and try to figure out what you can do with it;
    eventually you end up with a BankAccount example, and then assume it's an
    appropriate context. I.e. next time you build something similar to
    BankAccount you use polymorphism/inheritance; of course, that may not be
    the best solution. Obviously, I'm oversimplifying and overgeneralizing here.

    The correct way to approach, is to start with the problem and try to find
    the best solution, not the other way around. With enough effort it is
    possible to fit anything to some particular paradigm... but, that brings me
    to one of the reasons I really like Go. When you start to have problems
    with implementing X in a particular way, then it's probably useful to
    reevaluate whether there are better ways of implementing X. I found that,
    if you notice those pain signs then Go will guide you to a better solution
    -- one that is simpler and cleaner.

    As a short answer to your question "Tell me how a Go developer would
    attack this problem?" is that I'd reevaluate the need for such constructs
    in the first place.

    + egon :)
    On Friday, December 6, 2013 3:13:54 PM UTC+2, Rasmus Schultz wrote:

    Yeah, thanks, but this is an entirely different example that doesn't deal
    with polymorphism - the point of the exercise was to try to work with
    similar types, e.g. BankAccount and OverdraftBankAccount.


    On Wed, Dec 4, 2013 at 10:26 AM, egon wrote:

    This should be a bit more realistic situation http://play.golang.org/p/
    JqZFgm-3Cg. I.e. the accounts themselves are more of a projection from
    the bank ledger. (Although this version is also wrong from the realism
    point of view.)

    + egon
    On Wednesday, December 4, 2013 4:17:04 PM UTC+2, Rasmus Schultz wrote:

    Well, I don't like the idea of implementing the same function twice,
    and I discovered I could avoid that, by taking the Withdraw() function out
    of the interface and adding a dead simple internal method, deduct() which
    doesn't perform the balance check.

    I kinda wish there was a way to use a method to do the withdrawal
    instead of a function, but I come from a long background of OO languages,
    and I guess withdrawal is not really something an account does to itself -
    it's something that is done *to *the account, and as such doesn't
    really belong in a method, right? :-)

    I wonder if all of the other methods really should be methods?

    Would you take another look at the updated source and tell me if I'm
    doing better?

    Thanks :-)


    On Tue, Dec 3, 2013 at 9:12 AM, chris dollin wrote:
    On 3 December 2013 13:51, Rasmus Schultz wrote:

    I came across this discussion and comment on stackoverflow:

    http://stackoverflow.com/a/1727737/283851

    I decided to use it as an exercise to try out embedded structs and
    interfaces.

    Here's what I got so far:

    https://gist.github.com/mindplay-dk/807179beda57e676b8fb

    What I can't figure out is... interfaces can't have methods (?)
    They can't have method /definitions/. But you can write ordinary
    functions that take interface-typed arguments and return
    interface-typed results.

    ... so how do I write the Withdraw() method in such a way that it
    can work with either a BankAccount or an OverdraftAccount?
    You write it once for BankAccount and a second time for
    OverdraftAccount.
    (Of course these two methods may share code via a third function or
    method.)

    Since we're doing Go I'd feel itchy about making sure concurrency was
    handled correctly. But that's probably outside the scope of the
    example.

    Chris

    --
    Chris "allusive" Dollin
    --
    You received this message because you are subscribed to a topic in the
    Google Groups "golang-nuts" group.
    To unsubscribe from this topic, visit https://groups.google.com/d/
    topic/golang-nuts/U5wc4F6j18c/unsubscribe.
    To unsubscribe from this group and all its topics, send an email to
    golang-nuts...@googlegroups.com.

    For more options, visit https://groups.google.com/groups/opt_out.
    --
    You received this message because you are subscribed to a topic in the
    Google Groups "golang-nuts" group.
    To unsubscribe from this topic, visit
    https://groups.google.com/d/topic/golang-nuts/U5wc4F6j18c/unsubscribe.
    To unsubscribe from this group and all its topics, send an email to
    golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Ian Lance Taylor at Dec 6, 2013 at 2:57 pm

    On Fri, Dec 6, 2013 at 6:37 AM, Rasmus Schultz wrote:
    I'm not trying to replicate a particular pattern, I'm trying to learn the
    mechanics of the language.

    Just consider the example in the abstract - there are two types of accounts,
    a few common activities such as deposit and withdraw, and one type of
    account has an overdraft allowance.

    If those are the requirements, you can't simply make up different
    requirements that fit the language better ;-)

    I'm not trying to replicate the solution, the patterns, or the mechanics of
    Java or some other language - I'm simply trying to learn how the same
    requirements can be met with Go code.
    Based on that abstract description, you write a BankAccount type that
    has an overdraftOK field.

    I'm not sure what your real question is, but perhaps this will help:
    you can write a function that takes an interface value and queries
    whether that value supports a specific method. For example, the fmt
    package checks whether the types it is given support a String method,
    and if so it calls that method rather than doing its own formatting.
    See http://golang.org/doc/effective_go.html#interface_conversions .

    Ian

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Malcolm Greaves at Dec 6, 2013 at 3:00 pm
    I've got two cents to add to this conversation:

    From learning go, I've noticed that I'm doing a lot more decoupling of data
    and action. Even in Java (my daily money-maker language) I've observed that
    my code has this property more and more. In go, this helps a ton because
    the functions that implement actions are decoupled from interfaces. These
    functions *use* interfaces as inputs, but the interfaces themselves
    *usually* really only specify how to access information.

    In your gist that you put up, it seems what you're trying to do is have the
    interfaces hide everything that the bank account does. In go, this will
    lead to code duplication. If you can figure out a way to have functions
    that manipulate any bank account interface to achieve the results you want,
    you might be able to get minimal code.

    PS When I say function I don't mean method. If you come from Java, then the
    distinction is function == static and method == class (e.g. func Hello()
    string { return "hello" } and static public String hello(){ return "hello;
    } )
    On Friday, December 6, 2013 9:37:36 AM UTC-5, Rasmus Schultz wrote:

    I'm not trying to replicate a particular pattern, I'm trying to learn the
    mechanics of the language.

    Just consider the example in the abstract - there are two types of
    accounts, a few common activities such as deposit and withdraw, and one
    type of account has an overdraft allowance.

    If those are the requirements, you can't simply make up different
    requirements that fit the language better ;-)

    I'm not trying to replicate the solution, the patterns, or the mechanics
    of Java or some other language - I'm simply trying to learn how the same
    requirements can be met with Go code.



    On Fri, Dec 6, 2013 at 9:21 AM, egon <egon...@gmail.com <javascript:>>wrote:
    (note; I'm being concise and as direct as possible to avoid adding
    "IMHO"-s and "of course there are special situations" everywhere in the
    text...)

    With such approach quite often you get poor solutions. e.g. you pick
    polymorphism/inheritance and try to figure out what you can do with it;
    eventually you end up with a BankAccount example, and then assume it's an
    appropriate context. I.e. next time you build something similar to
    BankAccount you use polymorphism/inheritance; of course, that may not be
    the best solution. Obviously, I'm oversimplifying and overgeneralizing here.

    The correct way to approach, is to start with the problem and try to find
    the best solution, not the other way around. With enough effort it is
    possible to fit anything to some particular paradigm... but, that brings me
    to one of the reasons I really like Go. When you start to have problems
    with implementing X in a particular way, then it's probably useful to
    reevaluate whether there are better ways of implementing X. I found that,
    if you notice those pain signs then Go will guide you to a better solution
    -- one that is simpler and cleaner.

    As a short answer to your question "Tell me how a Go developer would
    attack this problem?" is that I'd reevaluate the need for such constructs
    in the first place.

    + egon :)
    On Friday, December 6, 2013 3:13:54 PM UTC+2, Rasmus Schultz wrote:

    Yeah, thanks, but this is an entirely different example that doesn't
    deal with polymorphism - the point of the exercise was to try to work with
    similar types, e.g. BankAccount and OverdraftBankAccount.


    On Wed, Dec 4, 2013 at 10:26 AM, egon wrote:

    This should be a bit more realistic situation http://play.golang.org/p/
    JqZFgm-3Cg. I.e. the accounts themselves are more of a projection from
    the bank ledger. (Although this version is also wrong from the realism
    point of view.)

    + egon
    On Wednesday, December 4, 2013 4:17:04 PM UTC+2, Rasmus Schultz wrote:

    Well, I don't like the idea of implementing the same function twice,
    and I discovered I could avoid that, by taking the Withdraw() function out
    of the interface and adding a dead simple internal method, deduct() which
    doesn't perform the balance check.

    I kinda wish there was a way to use a method to do the withdrawal
    instead of a function, but I come from a long background of OO languages,
    and I guess withdrawal is not really something an account does to itself -
    it's something that is done *to *the account, and as such doesn't
    really belong in a method, right? :-)

    I wonder if all of the other methods really should be methods?

    Would you take another look at the updated source and tell me if I'm
    doing better?

    Thanks :-)


    On Tue, Dec 3, 2013 at 9:12 AM, chris dollin wrote:
    On 3 December 2013 13:51, Rasmus Schultz wrote:

    I came across this discussion and comment on stackoverflow:

    http://stackoverflow.com/a/1727737/283851

    I decided to use it as an exercise to try out embedded structs and
    interfaces.

    Here's what I got so far:

    https://gist.github.com/mindplay-dk/807179beda57e676b8fb

    What I can't figure out is... interfaces can't have methods (?)
    They can't have method /definitions/. But you can write ordinary
    functions that take interface-typed arguments and return
    interface-typed results.

    ... so how do I write the Withdraw() method in such a way that it
    can work with either a BankAccount or an OverdraftAccount?
    You write it once for BankAccount and a second time for
    OverdraftAccount.
    (Of course these two methods may share code via a third function or
    method.)

    Since we're doing Go I'd feel itchy about making sure concurrency was
    handled correctly. But that's probably outside the scope of the
    example.

    Chris

    --
    Chris "allusive" Dollin
    --
    You received this message because you are subscribed to a topic in the
    Google Groups "golang-nuts" group.
    To unsubscribe from this topic, visit https://groups.google.com/d/
    topic/golang-nuts/U5wc4F6j18c/unsubscribe.
    To unsubscribe from this group and all its topics, send an email to
    golang-nuts...@googlegroups.com.

    For more options, visit https://groups.google.com/groups/opt_out.
    --
    You received this message because you are subscribed to a topic in the
    Google Groups "golang-nuts" group.
    To unsubscribe from this topic, visit
    https://groups.google.com/d/topic/golang-nuts/U5wc4F6j18c/unsubscribe.
    To unsubscribe from this group and all its topics, send an email to
    golang-nuts...@googlegroups.com <javascript:>.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Ian Davis at Dec 6, 2013 at 3:12 pm
    On Fri, Dec 6, 2013, at 02:37 PM, Rasmus Schultz wrote:

    I'm not trying to replicate a particular pattern, I'm trying to learn
    the mechanics of the language.

    Just consider the example in the abstract - there are two types of
    accounts, a few common activities such as deposit and withdraw, and one
    type of account has an overdraft allowance.

    If those are the requirements, you can't simply make up different
    requirements that fit the language better ;-)

    I'm not trying to replicate the solution, the patterns, or the
    mechanics of Java or some other language - I'm simply trying to learn
    how the same requirements can be met with Go code.





    When working with Go you might find it more useful to think in terms of
    "has-a" rather than "is-a", i.e. composition instead of inheritance.



    In your example, instead of having two types of accounts with different
    behaviours, perhaps you have a single type "bank account" that has
    different behaviours: "deposit" and "overdraft". Some instances of bank
    account have just the deposit behaviour, others also have the overdraft
    behaviour.



    -- ian

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Egon at Dec 6, 2013 at 3:31 pm

    On Friday, December 6, 2013 4:37:36 PM UTC+2, Rasmus Schultz wrote:
    I'm not trying to replicate a particular pattern, I'm trying to learn the
    mechanics of the language.

    Just consider the example in the abstract - there are two types of
    accounts, a few common activities such as deposit and withdraw, and one
    type of account has an overdraft allowance.
    I would still argue that the example is still wrong. :)
    And, I've still yet to find a really good example for inheritance +
    polymorphism.

    If those are the requirements, you can't simply make up different
    requirements that fit the language better ;-)

    I'm not trying to replicate the solution, the patterns, or the mechanics
    of Java or some other language - I'm simply trying to learn how the same
    requirements can be met with Go code.
    Nevertheless... there are three possible versions I would consider for
    implementing that dispatch:

    V1: http://play.golang.org/p/R4jNLGRKAx
    V2: http://play.golang.org/p/AKiSrsOkHg
    V3: http://play.golang.org/p/5dh0LuI-0x

    V1: I like the most, although there is duplicated code... this prevents me
    from coupling things together. V2: get's rid of the duplication by sharing
    a function, maybe in a package of it's own if needed... may come useful if
    the similar code is too long. V3: removes the responsibility of Withdrawing
    from the account... i.e. maybe it can be moved to somewhere else.

    + egon

    On Fri, Dec 6, 2013 at 9:21 AM, egon <egon...@gmail.com <javascript:>>wrote:
    (note; I'm being concise and as direct as possible to avoid adding
    "IMHO"-s and "of course there are special situations" everywhere in the
    text...)

    With such approach quite often you get poor solutions. e.g. you pick
    polymorphism/inheritance and try to figure out what you can do with it;
    eventually you end up with a BankAccount example, and then assume it's an
    appropriate context. I.e. next time you build something similar to
    BankAccount you use polymorphism/inheritance; of course, that may not be
    the best solution. Obviously, I'm oversimplifying and overgeneralizing here.

    The correct way to approach, is to start with the problem and try to find
    the best solution, not the other way around. With enough effort it is
    possible to fit anything to some particular paradigm... but, that brings me
    to one of the reasons I really like Go. When you start to have problems
    with implementing X in a particular way, then it's probably useful to
    reevaluate whether there are better ways of implementing X. I found that,
    if you notice those pain signs then Go will guide you to a better solution
    -- one that is simpler and cleaner.

    As a short answer to your question "Tell me how a Go developer would
    attack this problem?" is that I'd reevaluate the need for such constructs
    in the first place.

    + egon :)
    On Friday, December 6, 2013 3:13:54 PM UTC+2, Rasmus Schultz wrote:

    Yeah, thanks, but this is an entirely different example that doesn't
    deal with polymorphism - the point of the exercise was to try to work with
    similar types, e.g. BankAccount and OverdraftBankAccount.


    On Wed, Dec 4, 2013 at 10:26 AM, egon wrote:

    This should be a bit more realistic situation http://play.golang.org/p/
    JqZFgm-3Cg. I.e. the accounts themselves are more of a projection from
    the bank ledger. (Although this version is also wrong from the realism
    point of view.)

    + egon
    On Wednesday, December 4, 2013 4:17:04 PM UTC+2, Rasmus Schultz wrote:

    Well, I don't like the idea of implementing the same function twice,
    and I discovered I could avoid that, by taking the Withdraw() function out
    of the interface and adding a dead simple internal method, deduct() which
    doesn't perform the balance check.

    I kinda wish there was a way to use a method to do the withdrawal
    instead of a function, but I come from a long background of OO languages,
    and I guess withdrawal is not really something an account does to itself -
    it's something that is done *to *the account, and as such doesn't
    really belong in a method, right? :-)

    I wonder if all of the other methods really should be methods?

    Would you take another look at the updated source and tell me if I'm
    doing better?

    Thanks :-)


    On Tue, Dec 3, 2013 at 9:12 AM, chris dollin wrote:
    On 3 December 2013 13:51, Rasmus Schultz wrote:

    I came across this discussion and comment on stackoverflow:

    http://stackoverflow.com/a/1727737/283851

    I decided to use it as an exercise to try out embedded structs and
    interfaces.

    Here's what I got so far:

    https://gist.github.com/mindplay-dk/807179beda57e676b8fb

    What I can't figure out is... interfaces can't have methods (?)
    They can't have method /definitions/. But you can write ordinary
    functions that take interface-typed arguments and return
    interface-typed results.

    ... so how do I write the Withdraw() method in such a way that it
    can work with either a BankAccount or an OverdraftAccount?
    You write it once for BankAccount and a second time for
    OverdraftAccount.
    (Of course these two methods may share code via a third function or
    method.)

    Since we're doing Go I'd feel itchy about making sure concurrency was
    handled correctly. But that's probably outside the scope of the
    example.

    Chris

    --
    Chris "allusive" Dollin
    --
    You received this message because you are subscribed to a topic in the
    Google Groups "golang-nuts" group.
    To unsubscribe from this topic, visit https://groups.google.com/d/
    topic/golang-nuts/U5wc4F6j18c/unsubscribe.
    To unsubscribe from this group and all its topics, send an email to
    golang-nuts...@googlegroups.com.

    For more options, visit https://groups.google.com/groups/opt_out.
    --
    You received this message because you are subscribed to a topic in the
    Google Groups "golang-nuts" group.
    To unsubscribe from this topic, visit
    https://groups.google.com/d/topic/golang-nuts/U5wc4F6j18c/unsubscribe.
    To unsubscribe from this group and all its topics, send an email to
    golang-nuts...@googlegroups.com <javascript:>.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Rasmus Schultz at Dec 9, 2013 at 6:13 pm
    Thanks Egon, this gave me some useful perspective :-)
    On Friday, December 6, 2013 10:31:39 AM UTC-5, egon wrote:

    On Friday, December 6, 2013 4:37:36 PM UTC+2, Rasmus Schultz wrote:

    I'm not trying to replicate a particular pattern, I'm trying to learn the
    mechanics of the language.

    Just consider the example in the abstract - there are two types of
    accounts, a few common activities such as deposit and withdraw, and one
    type of account has an overdraft allowance.
    I would still argue that the example is still wrong. :)
    And, I've still yet to find a really good example for inheritance +
    polymorphism.

    If those are the requirements, you can't simply make up different
    requirements that fit the language better ;-)

    I'm not trying to replicate the solution, the patterns, or the mechanics
    of Java or some other language - I'm simply trying to learn how the same
    requirements can be met with Go code.
    Nevertheless... there are three possible versions I would consider for
    implementing that dispatch:

    V1: http://play.golang.org/p/R4jNLGRKAx
    V2: http://play.golang.org/p/AKiSrsOkHg
    V3: http://play.golang.org/p/5dh0LuI-0x

    V1: I like the most, although there is duplicated code... this prevents me
    from coupling things together. V2: get's rid of the duplication by sharing
    a function, maybe in a package of it's own if needed... may come useful if
    the similar code is too long. V3: removes the responsibility of Withdrawing
    from the account... i.e. maybe it can be moved to somewhere else.

    + egon

    On Fri, Dec 6, 2013 at 9:21 AM, egon wrote:

    (note; I'm being concise and as direct as possible to avoid adding
    "IMHO"-s and "of course there are special situations" everywhere in the
    text...)

    With such approach quite often you get poor solutions. e.g. you pick
    polymorphism/inheritance and try to figure out what you can do with it;
    eventually you end up with a BankAccount example, and then assume it's an
    appropriate context. I.e. next time you build something similar to
    BankAccount you use polymorphism/inheritance; of course, that may not be
    the best solution. Obviously, I'm oversimplifying and overgeneralizing here.

    The correct way to approach, is to start with the problem and try to
    find the best solution, not the other way around. With enough effort it is
    possible to fit anything to some particular paradigm... but, that brings me
    to one of the reasons I really like Go. When you start to have problems
    with implementing X in a particular way, then it's probably useful to
    reevaluate whether there are better ways of implementing X. I found that,
    if you notice those pain signs then Go will guide you to a better solution
    -- one that is simpler and cleaner.

    As a short answer to your question "Tell me how a Go developer would
    attack this problem?" is that I'd reevaluate the need for such constructs
    in the first place.

    + egon :)
    On Friday, December 6, 2013 3:13:54 PM UTC+2, Rasmus Schultz wrote:

    Yeah, thanks, but this is an entirely different example that doesn't
    deal with polymorphism - the point of the exercise was to try to work with
    similar types, e.g. BankAccount and OverdraftBankAccount.


    On Wed, Dec 4, 2013 at 10:26 AM, egon wrote:

    This should be a bit more realistic situation
    http://play.golang.org/p/JqZFgm-3Cg. I.e. the accounts themselves are
    more of a projection from the bank ledger. (Although this version is also
    wrong from the realism point of view.)

    + egon
    On Wednesday, December 4, 2013 4:17:04 PM UTC+2, Rasmus Schultz wrote:

    Well, I don't like the idea of implementing the same function twice,
    and I discovered I could avoid that, by taking the Withdraw() function out
    of the interface and adding a dead simple internal method, deduct() which
    doesn't perform the balance check.

    I kinda wish there was a way to use a method to do the withdrawal
    instead of a function, but I come from a long background of OO languages,
    and I guess withdrawal is not really something an account does to itself -
    it's something that is done *to *the account, and as such doesn't
    really belong in a method, right? :-)

    I wonder if all of the other methods really should be methods?

    Would you take another look at the updated source and tell me if I'm
    doing better?

    Thanks :-)


    On Tue, Dec 3, 2013 at 9:12 AM, chris dollin <ehog....@googlemail.com
    wrote:
    On 3 December 2013 13:51, Rasmus Schultz wrote:

    I came across this discussion and comment on stackoverflow:

    http://stackoverflow.com/a/1727737/283851

    I decided to use it as an exercise to try out embedded structs and
    interfaces.

    Here's what I got so far:

    https://gist.github.com/mindplay-dk/807179beda57e676b8fb

    What I can't figure out is... interfaces can't have methods (?)
    They can't have method /definitions/. But you can write ordinary
    functions that take interface-typed arguments and return
    interface-typed results.

    ... so how do I write the Withdraw() method in such a way that it
    can work with either a BankAccount or an OverdraftAccount?
    You write it once for BankAccount and a second time for
    OverdraftAccount.
    (Of course these two methods may share code via a third function or
    method.)

    Since we're doing Go I'd feel itchy about making sure concurrency was
    handled correctly. But that's probably outside the scope of the
    example.

    Chris

    --
    Chris "allusive" Dollin
    --
    You received this message because you are subscribed to a topic in the
    Google Groups "golang-nuts" group.
    To unsubscribe from this topic, visit https://groups.google.com/d/
    topic/golang-nuts/U5wc4F6j18c/unsubscribe.
    To unsubscribe from this group and all its topics, send an email to
    golang-nuts...@googlegroups.com.

    For more options, visit https://groups.google.com/groups/opt_out.
    --
    You received this message because you are subscribed to a topic in the
    Google Groups "golang-nuts" group.
    To unsubscribe from this topic, visit
    https://groups.google.com/d/topic/golang-nuts/U5wc4F6j18c/unsubscribe.
    To unsubscribe from this group and all its topics, send an email to
    golang-nuts...@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedDec 3, '13 at 1:51p
activeDec 9, '13 at 6:13p
posts12
users7
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase