A Design Pattern Question for Functional Programers

2012-04-18 Thread Xah Lee
Functional programing is getting the presses in mainstream. I ran
across this dialogue where a imperative coder was trying to get into
functional programing:

  A: What are the design patterns that help structure functional
systems?

  B: Design patterns? Hey everyone, look at the muggle try to get the
wand to work!

from:
〈Code Watch: Functional programming's smugness problem〉 (2012-04-16)
By By Larry O'brien. @ 
http://www.sdtimes.com/content/article.aspx?ArticleID=36534

hi, my dearly beloved C++ java perl python hackers, design pattern
your mom!

further readings:

〈Why Software Suck〉
http://xahlee.org/UnixResource_dir/writ/why_software_suck.html

〈What is a Tech Geeker?〉
http://xahlee.org/UnixResource_dir/writ/tech_geeker.html

〈Book Review: Patterns of Software〉
http://xahlee.org/PageTwo_dir/Personal_dir/bookReviewRichardGabriel.html

〈Are You Intelligent Enough to Understand HTML5?〉
http://xahlee.org/UnixResource_dir/writ/html5_vs_intelligence.html

 Xah
-- 
http://mail.python.org/mailman/listinfo/python-list


observer pattern question #1 (reference to subject)

2008-05-08 Thread Alan Isaac

I have two questions about the observer pattern in Python.

This is question #1.  (I'll put the other is a separate post.)



Here is a standard example of the observer pattern in Python:



http://en.wikipedia.org/wiki/Observer_pattern



Contrast with this rather standard discussion:



http://www.dofactory.com/Patterns/PatternObserver.aspx#_self1



The difference I am focusing on is that in the latter,

the observer (investor) maintains a reference to the

subject (stock).  


(Many questions can be raised of course: see the discussion at

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/131499).



Is anything lost by not maintaining this reference (other 

than error checking ...)?  If I feel the observer needs 

access to the subject, what is wrong with just having the 


subject pass itself as part of the notification?



Thank you,

Alan Isaac


--
http://mail.python.org/mailman/listinfo/python-list


observer pattern question #2 (notification chain)

2008-05-08 Thread Alan Isaac

I have two questions about the observer pattern in Python.

This is question #2.  (I'll put the other is a separate post.)



Consider this standard example of the observer pattern in Python:



URL:http://en.wikipedia.org/wiki/Observer_pattern



Now suppose I have a variant.

(I am not a programmer, so this may be a separate related pattern.)

To make it a little concrete and relate it to the discussion at

URL:http://www.dofactory.com/Patterns/PatternObserver.aspx#_self1,

suppose there are stocks, mutual funds, and investors.

Let us say that funds are observers for stocks,

and investors are observers for funds.

Once a month I want all stocks to notify their observing funds

of their end-of-month price, and *then* all fund to notify their

observing investors of their end-of-month investment value.



I see a couple differences from the standard pattern referenced above,

and one problem.



Differences:



- observer/subject linked hierarchy (funds are both observers and subjects)

- many-many relation (a fund is an observer of many stocks)



I think (?) these differences are inessential, but the 

second does create the following problem: if I do not want 

a fund to notify an its investors until all stocks have 

reported, what is the best way to determine the last report 


in event?



Here is one way: create a ``reportreceived`` dict that maps 

stocks to True or False, and after each stock notification 


change False to True and check ``all(reportreceived.values())``

to determine whether it is ok to notify investors.  When it 


is ok, then notify investors and reset all the

``reportreceived`` values.



This is meant to be a general description so please do not 

focus on the real world aspects, which are only for 


illustration.



Thank you,

Alan Isaac 
--

http://mail.python.org/mailman/listinfo/python-list


Re: observer pattern question #1 (reference to subject)

2008-05-08 Thread Ville M. Vainio
Alan Isaac [EMAIL PROTECTED] writes:


 Is anything lost by not maintaining this reference (other

 than error checking ...)?  If I feel the observer needs

 access to the subject, what is wrong with just having the

 subject pass itself as part of the notification?

It reduces the number of places the observer can be called from,
because now the event source is part of the function signature. If you
omit the event source in the signature, you gain looser coupling -
it's the observer business to create the dependency.

Also, consider the situation where you want all investors to refresh
their idea about stock prices (because of, short network
failure). It's easy to run through a list of them and call update()
for everybody, while it's not so easy to find out what stock the
investor is observing (that's the investors business!) and pass that
object to the investor in the call.

Are these school questions btw? ;-)
--
http://mail.python.org/mailman/listinfo/python-list


Re: observer pattern question #1 (reference to subject)

2008-05-08 Thread Alan Isaac

Alan Isaac [EMAIL PROTECTED] writes:


Is anything lost by not maintaining this reference (other 


than error checking ...)?  If I feel the observer needs 


access to the subject, what is wrong with just having the 


subject pass itself as part of the notification? 






Ville M. Vainio wrote:

It reduces the number of places the observer can be called 


from, because now the event source is part of the function 


signature. If you omit the event source in the signature, 


you gain looser coupling - it's the observer business to 


create the dependency. 




As I said, I'm not a programmer, and perhaps as a result, 

I have questions about both of your points.  I'll stick with 


the stock example, since it is concrete.



Note that the observor/listener in the example at

URL:http://en.wikipedia.org/wiki/Observer_pattern

does not create a reference to the subject.

So in this context I take you to be saying something like 

the following: OK, here's the pattern, now your listener 

wants to know the event source, do not ask something new the 

subject to respond to that need.  That is unnecessary 

coupling.  Instead, just rewrite your listener to maintain 


a reference to the subject.



Do I have that right?



It seems to me that this response begs the question.

That is, an appropriate reply seems to be: here is a related 

pattern, call it observer2.  In the observer2 pattern, the 


subject has a getState method and always passes itself when

it notifies the observer. Now: in what sense does this 


require closer coupling?





Also, consider the situation where you want all investors 


to refresh their idea about stock prices (because of, 


short network failure). It's easy to run through a list of 


them and call update() for everybody, while it's not so 


easy to find out what stock the investor is observing 


(that's the investors business!) and pass that object to 


the investor in the call. 




I seem to be missing your point here.

Let's keep using the stock/investor example.

When the network comes up, each stock should notifies 


everyone in its list of listeners.  It either passes itself

or does not.  In either case, the investor took care of hir 


side of the business by registering as a listener.

If the stock does not notify all its registered investors, 


it is breaking its contract.  So, what is the problem?



Or to put it a different way, your suggestion that the 

investors should have to *pull* this information from the 

stocks seems out of step with the observer pattern, where 

the stocks should be pushing this information to the 


investor.



Again, talk of stocks and investors is just a convenient 

short hand for discussing the observer pattern.  I do not 


care about stocks/investors more than other applications.




Are these school questions btw?




No, sorry.  But I still appreciate the feedback.



Cheers,

Alan Isaac


--
http://mail.python.org/mailman/listinfo/python-list


Re: observer pattern question #1 (reference to subject)

2008-05-08 Thread Ville M. Vainio
Alan Isaac [EMAIL PROTECTED] writes:

 the following: OK, here's the pattern, now your listener
 wants to know the event source, do not ask something new the
 subject to respond to that need.  That is unnecessary
 coupling.  Instead, just rewrite your listener to maintain
 a reference to the subject.

 Do I have that right?

Not really. It has to be determined case-by-case. Note that I'm not
arguing *for* not passing subject on notification, just trying to
elaborate on situations that might want to choose that route.

 It seems to me that this response begs the question.
 That is, an appropriate reply seems to be: here is a related
 pattern, call it observer2.  In the observer2 pattern, the
 subject has a getState method and always passes itself when
 it notifies the observer. Now: in what sense does this
 require closer coupling?

It creates stronger connection between the subject and observer,
thereby reducing the amount different of places that can call the
observer (I don't mean different stock, but altogether different
places - say, a central stock controller that can broadcast the change
in several stocks at the time by stock id, once per second).

This is not really a feature of the observer pattern, both approaches
are somewhat valid observer patterns, depending on problem domain. If
you think it makes sense in the first place to have ONE reference to
the subject in observer, it's probably a workable approach - but in
case of stocks, you are probably monitoring several stock objects, so
the stock should probably pass itself to the observer (so that you
don't need to check all stocks every time something changes!).

Of course this stock thing is a bad example for this case, because you
have several stocks per investor. It's analogous to a typical UI
scenario where you have several widgets forwarding events to one big 
observer - and they *do* provide the event source and event type.

 Or to put it a different way, your suggestion that the
 investors should have to *pull* this information from the
 stocks seems out of step with the observer pattern, where
 the stocks should be pushing this information to the
 investor.

It's not necessarily the observer that has the interesting
information. It's quite typical to have general catch-all
notifications than report observers that something has
chanced somewhere, so you should refresh your data. 

All in all, though, the right solution should be obvious from the
problem at hand.
--
http://mail.python.org/mailman/listinfo/python-list


Re: observer pattern question #1 (reference to subject)

2008-05-08 Thread Alan Isaac

Ville M. Vainio wrote:

in case of stocks, you are probably monitoring several 


stock objects, so the stock should probably pass itself to 



the observer




OK.  This is related to my question #2 (in a separate 


thread), where I'd also appreciate your comments.





analogous to a typical UI scenario where you have several 


widgets forwarding events to one big observer - and they 


*do* provide the event source and event type. 




That is a helpful comparison.





All in all, though, the right solution should be obvious 


from the problem at hand. 




For CS types, maybe.  The rest of us are just trying to get 


things done without as much background and context.



Thanks,

Alan


--
http://mail.python.org/mailman/listinfo/python-list


Re: observer pattern question #1 (reference to subject)

2008-05-08 Thread castironpi
On May 8, 4:57 pm, Alan Isaac [EMAIL PROTECTED] wrote:
 Ville M. Vainio wrote:
  in case of stocks, you are probably monitoring several
  stock objects, so the stock should probably pass itself to
  the observer

 OK.  This is related to my question #2 (in a separate

 thread), where I'd also appreciate your comments.

  analogous to a typical UI scenario where you have several
  widgets forwarding events to one big observer - and they
  *do* provide the event source and event type.

 That is a helpful comparison.

  All in all, though, the right solution should be obvious
  from the problem at hand.

 For CS types, maybe.  The rest of us are just trying to get

 things done without as much background and context.

 Thanks,

 Alan

My local vernacular calls them carfulls of people, which analogy to
the body of collective man, extends pretty far.

It's not the gas pedal we hate!  I'm schedule more coasting on shore.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Pattern question

2005-07-09 Thread cantabile
Scott David Daniels a écrit :
 cantabile wrote:
 
 bruno modulix a écrit :

 You may want to have a look at the Factory pattern...
 ... demo of class Factory ...
 
 
 Taking advantage of Python's dynamic nature, you could simply:
 # similarly outrageously oversimplified dummy example
 class Gui(object):
def __init__(self, installer):
self.installer = installer
 
 class PosixGui(Gui):
 pass
 
 class Win32Gui(Gui):
 pass
 
 if os.name == 'posix':
 makeGui = PosixGui
 elif os.name == 'win32':
 makeGui = Win32Gui
 else:
 raise os %s not supported % os.name
 
 
 class Installer(object):
 def __init__(self, guiFactory):
 self.gui = guiFactory(self)
 
 def main():
 inst = Installer(makeGui)
 return inst.gui.main()
 
 --Scott David Daniels
 [EMAIL PROTECTED]

Thank you too for this tip. :)
Coming from C++ (mainly), I'm not used to this dynamic way of doing
things. That's usefull.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pattern question

2005-07-08 Thread bruno modulix
cantabile wrote:
 Hi,
 
 I'm trying to write a small installer for a server. But this program
 should be able to run in the future under heterogenous environments and
 os (at least linux/windows). I mean, the install will be done either in
 text mode or curses or gtk or tk, either in debian or windows 2000 and
 so on...
 
 The idea, at the moment, is as follows :
 
 class Server:
 def __init__(self, params = None):
 self.params = params
 def __getattr__(self, attr):
 return self.params.get(attr, None)
 
 class Installer:
  def __init__(self, gui = None):
 self.gui =  gui
 self.srv = None
 
 def update(self, dict):
 self.srv = Server(dict)
 
 class Gui:
 def __init__(self, installer = None):
 self.installer = installer
 def main():
 ## Some stuff here calling doIt() when the
 ## user is done with filling various fields
 
 def doIt(self):
 dict = {param1:qwerty, param2:uiop}
 self.installer.update(dict)
 
 def main():
 inst = Installer()
 gui =  Gui(inst)
 inst.gui = gui
 inst.gui.main()
 
 ## Here will be the actual install method
 ## ...
 
 ## An example of accessing srv values:
 print inst.srv.param1, inst.srv.param2
 
 But, considering this code, I find the 3 first lines of my main() a bit
 heavy. I have to inform inst that it has a 'gui', and Gui that it has an
 'installer'. I was trying to implement something looking like (very
 roughly) to the Observer pattern (so that the Gui would be totally
 independant from the actual install process).
  I guess there is something wrong in my approach. Is there a better
 pattern than this one for that kind of stuff ?
 
 Tanks for your help.

You may want to have a look at the Factory pattern...

# outrageously oversimplified dummy exemple
class Gui(object):
   def __init__(self, installer):
 self.installer = installer

class PosixGui(Gui):
   pass

class Win32Gui(Gui):
   pass

class GuiFactory(object):
   def getGui(self, installer):
  if os.name == 'posix':
 return PosixGui(installer)
  elif os.name == 'win32':
  return Win32Gui(installer)
  else:
  raise os %s not supported % os.name

class Installer(object):
   def __init__(self, guiFactory):
  self.gui = guiFactory.getGui(self)

def main():
   inst = Installer(GuiFactory())
   return inst.gui.main()

NB 1:
You may want to hide away the gui stuff:

class Installer(object):
  def __init__(self):
self.gui = GuiFactory().getGui(self)

  def main(self):
return self.gui.main()

def main():
  return Installer().main()


NB 2 :
if it has to run in text mode, you should consider renaming gui to
ui, since a CLI is not really a 'graphical' ui !-)

NB 3 :
I made the GuiFactory a class, but it could also be a simple function.

NB 4 :
there are of course other solutions to the problem, which may or  not be
more appropriate...


HTH
-- 
bruno desthuilliers
python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in '[EMAIL PROTECTED]'.split('@')])
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pattern question

2005-07-08 Thread cantabile
bruno modulix a écrit :

 You may want to have a look at the Factory pattern...
 
 # outrageously oversimplified dummy exemple
 class Gui(object):
def __init__(self, installer):
  self.installer = installer
 
 class PosixGui(Gui):
pass
 
 class Win32Gui(Gui):
pass
 
 class GuiFactory(object):
def getGui(self, installer):
   if os.name == 'posix':
  return PosixGui(installer)
   elif os.name == 'win32':
   return Win32Gui(installer)
   else:
   raise os %s not supported % os.name
 
 class Installer(object):
def __init__(self, guiFactory):
   self.gui = guiFactory.getGui(self)
 
 def main():
inst = Installer(GuiFactory())
return inst.gui.main()
 
 NB 1:
 You may want to hide away the gui stuff:
 
 class Installer(object):
   def __init__(self):
 self.gui = GuiFactory().getGui(self)
 
   def main(self):
 return self.gui.main()
 
 def main():
   return Installer().main()
 

Thanks for this, Bruno. It is much more elegant and adaptable than my
first attempt.
 
 NB 2 :
 if it has to run in text mode, you should consider renaming gui to
 ui, since a CLI is not really a 'graphical' ui !-)

You're right :))

 NB 3 :
 I made the GuiFactory a class, but it could also be a simple function.

 NB 4 :
 there are of course other solutions to the problem, which may or  not be
 more appropriate...
 

Thanks a lot for these detailed explanations.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pattern question

2005-07-08 Thread Scott David Daniels
cantabile wrote:
 bruno modulix a écrit :
You may want to have a look at the Factory pattern...
 ... demo of class Factory ...

Taking advantage of Python's dynamic nature, you could simply:
 # similarly outrageously oversimplified dummy example
 class Gui(object):
def __init__(self, installer):
self.installer = installer

 class PosixGui(Gui):
 pass

 class Win32Gui(Gui):
 pass

 if os.name == 'posix':
 makeGui = PosixGui
 elif os.name == 'win32':
 makeGui = Win32Gui
 else:
 raise os %s not supported % os.name


 class Installer(object):
 def __init__(self, guiFactory):
 self.gui = guiFactory(self)

 def main():
 inst = Installer(makeGui)
 return inst.gui.main()

--Scott David Daniels
[EMAIL PROTECTED]
-- 
http://mail.python.org/mailman/listinfo/python-list


Pattern question

2005-07-07 Thread cantabile
Hi,

I'm trying to write a small installer for a server. But this program
should be able to run in the future under heterogenous environments and
os (at least linux/windows). I mean, the install will be done either in
text mode or curses or gtk or tk, either in debian or windows 2000 and
so on...

The idea, at the moment, is as follows :

class Server:
def __init__(self, params = None):
self.params = params
def __getattr__(self, attr):
return self.params.get(attr, None)

class Installer:
 def __init__(self, gui = None):
self.gui =  gui
self.srv = None

def update(self, dict):
self.srv = Server(dict)

class Gui:
def __init__(self, installer = None):
self.installer = installer
def main():
## Some stuff here calling doIt() when the
## user is done with filling various fields

def doIt(self):
dict = {param1:qwerty, param2:uiop}
self.installer.update(dict)

def main():
inst = Installer()
gui =  Gui(inst)
inst.gui = gui
inst.gui.main()

## Here will be the actual install method
## ...

## An example of accessing srv values:
print inst.srv.param1, inst.srv.param2

But, considering this code, I find the 3 first lines of my main() a bit
heavy. I have to inform inst that it has a 'gui', and Gui that it has an
'installer'. I was trying to implement something looking like (very
roughly) to the Observer pattern (so that the Gui would be totally
independant from the actual install process).
 I guess there is something wrong in my approach. Is there a better
pattern than this one for that kind of stuff ?

Tanks for your help.
-- 
http://mail.python.org/mailman/listinfo/python-list