home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / comp / lang / pop / 44 < prev    next >
Encoding:
Internet Message Format  |  1992-11-17  |  4.3 KB

  1. From: sfk@otter.hpl.hp.com (Steve Knight)
  2. Date: Tue, 17 Nov 1992 17:52:42 GMT
  3. Subject: Re: A little Pop history
  4. Message-ID: <116670010@otter.hpl.hp.com>
  5. Organization: Hewlett-Packard Laboratories, Bristol, UK.
  6. Path: sparky!uunet!charon.amdahl.com!pacbell.com!sgiblab!sdd.hp.com!hpscit.sc.hp.com!scd.hp.com!hpscdm!hplextra!otter.hpl.hp.com!otter!sfk
  7. Newsgroups: comp.lang.pop
  8. References: <Bxpqvt.Lq@deshaw.com>
  9. Lines: 93
  10.  
  11. In comp.lang.pop, bh@anarres.CS.Berkeley.EDU (Brian Harvey) writes:
  12. > Of course, these examples are entirely equivalent to what could be done
  13. > in Lisp.  I think you should post examples using some of the more unusual
  14. > POP features, such as pattern matching.
  15.  
  16. Pop is very closely related to the Lisp family of languages, so it should
  17. come as no surprise that many programs look similiar.  The main reasons
  18. for choosing to write in Pop rather than Lisp are aesthetic ones, in 
  19. my view.  For example, the lack of distinction between the empty list
  20. (nil) and the false value (false) in almost all Lisps is, to the eyes of
  21. many Poppers like myself, clunky and ugly.  But in practical programming
  22. such differences are not a big deal.
  23.  
  24. The key difference between Lisp and Pop's semantics (putting the 
  25. important issue of syntax aside for one moment) is the open stack.
  26. After all, the Pop pattern-matcher is a nice idea, incorrectly
  27. implemented, but trivial to duplicate in extensible languages such as
  28. Lisp or Prolog.  Having the open stack at the heart of all programming
  29. idioms gives the language family its distinctive character.
  30.  
  31. One idiom will illustrate my point nicely.  The task is (say) to
  32. add all the numbers in a list.  One of the built-in routines is
  33. called "applist" which takes a list and a procedure as arguments.
  34. It then applies the procedure to each element of the list in turn.
  35. We can add all the numbers in the list as follows:
  36.  
  37.     applist( 0, LIST, nonop + )    ;;; nonop disables infix-ness of +
  38.  
  39. Oh?  Did I say applist takes 2 arguments?  Well, I did but don't forget
  40. that Pop uses an open stack, so there's no notion of argument checking.
  41. All the arguments go on the stack and come off again.  This example works
  42. because the iteration starts with 0 on the stack, then element 1 gets 
  43. pushed, then the top two items get added and replaced by the single result,
  44. and so on and so on.  At the end of the iteration, all that remains on
  45. top of the stack is the answer.
  46.  
  47. Of course, the equivalent functional programming idiom (e.g. in Lisp)
  48. would be to define a slightly different higher-order operator to 
  49. "applist" which might be called "fold".
  50.  
  51. define fold( sofar, list, op ); 
  52.     if null( list ) then
  53.         sofar
  54.     else
  55.         fold( op( sofar, hd( list ) ), tl( list ), op )
  56.     endif
  57. enddefine;
  58.  
  59. That's always true.  You can always do it in Lisp (or whatever) but
  60. you just do it differently.  Here's another nice use of the open stack.
  61. Suppose we want to flatten a tree (represented as a list of lists) 
  62. into (say) a list.  What's the idiomatic way of writing that?  The answer
  63. is to use the stack as a temporary collection zone.
  64.  
  65. define flatten_to_stack( tree ); 
  66.     if islist( tree ) then
  67.         applist( tree, flatten_to_stack )
  68.     else
  69.         tree
  70.     endif
  71. enddefine;
  72.  
  73. define flatten( tree );
  74.     [% flatten_to_stack( tree ) %]
  75. enddefine;
  76.  
  77. The virtue of writing flatten this way is that, for example, it might
  78. turn out that we didn't want a list but we wanted a vector (1D array).
  79. Well that was easy ...
  80.  
  81. define flatten( tree );
  82.     {% flatten_to_stack( tree ) %}
  83. enddefine;
  84.  
  85. Changed my mind.  I wanted to convert the vector into a string.  Fine ...
  86.  
  87. define flatten( tree );
  88.     consstring(#| flatten_to_stack( tree ) |#)
  89. enddefine;
  90.  
  91. Note the use of count brackets "#|" and "|#" in the above example.  These
  92. simply count the difference in the length of stack before and after the
  93. expression between them.  This makes sense when you know that consstring
  94. expects a count of the number of characters on the stack as its "topmost"
  95. argument.
  96.         
  97. This is probably far too long a post already but I could go on about the
  98. open stack for another couple of hours.  It is the most wonderful thing 
  99. about Pop and defines the language family.  It is never the case that 
  100. it makes you able to do things that can't be done in Lisp-like
  101. languages but it does make you want to say them rather differently!
  102.  
  103. Steve
  104.