Python syntax in Lisp and Scheme

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Alan Gauld

    Re: Express What, not How.

    On Thu, 16 Oct 2003 19:06:00 GMT, Raffael Cavallaro
    <raffaelcavalla ro@junk.mail.me .not.mac.com> wrote:[color=blue]
    > is to write clear code. The reason we see 300 line function bodies is
    > that many programmers resist expressing the solution in the language of
    > the problem domain, preferring instead to write in an idiom that they
    > already understand, the programming language.[/color]

    Do you have any objective evidence to suggest that this is true?
    What proprtion exactly is due to this? The reason I ask is that
    most of the long functions I have seen have been products of the
    algorithm being implemented. If an algorithm takes 300 lines to
    express it should be expressed as 300 lines. I have *never* seen
    a long function that is the result of a programmer avoiding using
    user vocabulary!

    Equally I see no evidence whatsoever to suggest that users
    express requirements in short chunks - usually the opposite, we
    get presented with long complex prose describing a convoluted
    business process and the programmer has to split that into its
    natural chunks during analysis!

    If anyone has done any research to connect long functions with
    ignoring of user language I'm unaware of it and would be most
    interested in seeing it.
    [color=blue]
    > The higher level abstractions of a complex piece of software will, of
    > necessity, be concepts in the problem domain.[/color]

    Not necessarily(*), but I would agree that usually they are, but
    at the lower levels the solution space may bear no resemblance to
    the problem domain at all!

    (*) For example where the solution architecture is based on a
    mathematical technique which would be impractical in a manual
    business process but is entirely practical using computing power.
    As a somewhat dated example - the processes used in computer
    crytography for example being entirely different to those used in
    manual cryptrography. There will be some concepts in common
    but many will be entirely novel.
    [color=blue]
    > interactions _in_the_languag e_of_the_proble m_domain_. These problem
    > domain names are the appropriate units of the language that the software
    > should be written in. Named functions and macros are the appropriate
    > labels for the programmer's software definitions of the concepts of the
    > problem domain, not anonymous functions.[/color]

    In the general case I agree completely but a blanket statement
    that it is always true is absurd. There are many cases when a
    programmer is dealing with issues that simply don't arise in the
    human scenario. Anonymous functions are often used in
    scenarios where a name is meaningless. Even in business processes
    it is not unusual to find processes with names like JDI(Just Do
    It) or DWN (Do Whatever's Necessary) to deal with extraordinary
    scenarios. (Although ironically these are rarely the ones which
    require anonymous funtions in code!)
    [color=blue]
    > At some low level of abstraction, when building the functionality of the
    > ...
    > implementation. These implementations will, where appropriate, use
    > anonymous functions.[/color]

    Ah, we do agree at this level. So your point only applies to
    "high level" functions. The issue then becomes one of deciding at
    what point the solution and problem domains separate.
    [color=blue]
    > However, once we get above this lower level of abstraction, we will be
    > dealing with concepts from the problem domain, which _have_names_.[/color]

    Usually, but not always. Or often highly generic names which are
    best implemented using higher order programming techniques
    involving anonymous names.
    [color=blue]
    > This stands in direct opposition to those who think that software should
    > seek to _avoid_ names whenever possible. I, on the other hand find this
    > simple equation is true:
    >
    > Names = Clarity[/color]

    Again, in general I agree. But if the name is f and it is only
    used for as long as it takes to convey a single use function into
    the argument list of another function then I find the naming to
    be of little or no value.
    [color=blue]
    > Some posters here have replied that this is just "obvious," and true
    > independent of the issue of anonymous functions. But the two issues are
    > _of_necessity_ related, because you cannot have both names and anonymity.[/color]

    I'm not sure I agree there. It happens in the real world all the
    time. (Consider Internet Chat Rooms! Many users there desire
    anonymity while using a name which may not be their identity.
    Indeed they achieve anonynimty through their false identity!)
    [color=blue]
    > prolixity, or names = exra work. But disdaining this work of finding
    > appropriate, descriptive, names from the problem domain, is a recipe for
    > obfuscated code.[/color]

    I agree that good names are a good thing and time should be spent
    considering appropriate ones but...
    [color=blue]
    > Worse, it is a recipe for failed software projects.[/color]

    Bad naming is rarely if ever the reason for failed projects. It
    may contribute by slowing down testing or integration and thus
    causing estimate failure (the most comon reason for failed
    projects) but naming alone is not enough to cause a failure IMHO.
    [color=blue]
    > failure to find good names from the problem domain indicates a failure
    > to properly understand the problem domain in its own terms. Failure to
    > understand the problem domain in its own terms means that the program's
    > design is almost certainly fatally flawed.[/color]

    Insofar as the problem domain is reflected in the solution space
    I agree. Certainly a programmer who does not understand the
    vocabulary of his end user is unlikely to create good solutions.

    Naming is important where a name aids understanding. If a name is
    just there as a marker it serves no purpose. I agree that this
    rarely happens at a high level in the design but I think it
    happens at a higher level that you suggest. Not often, but often
    enough to prevent blanket assertions being made.

    Alan G.

    Author of the Learn to Program website

    Comment

    • Kaz Kylheku

      Re: Python syntax in Lisp and Scheme

      Alexander Schmolck <a.schmolck@gmx .net> wrote in message news:<yfszng1fe wt.fsf@black132 .ex.ac.uk>...[color=blue]
      > Did it occur to you that people maybe use python not so much because they are
      > retards but because it's vastly more effective than CL at the tasks they
      > currently need to perform?[/color]

      People use Python most likely for these reasons:

      - they read some articles about it in popular press
      - it is relatively new
      - it came with their Linux distribution

      The second point is important. When something is new, there is a
      ready-made explanation for not being popular. When the pointy haired
      boss asks why isn't the whole world using Python for everything, you
      just have to say ``It's too new, so only the smart, hip people who
      have their ears to the ground are using it, but just wait a few
      years.''

      It's easy to add a positive adornment to the explanation which gives
      rise to an expectation of success, and which in turn creates a
      psychological pressure to adopt or else be left behind!

      Soon, the language starts being mentioned on job advertisements as a
      desireable skill, and the pressure starts to snowball. At this point,
      hordes of immature programmers are paniced into learning it, just so
      they can put it on their resumes and be able to say something about it
      in interviews.

      But these programmers resent being pressured into learning! They
      resent the new programming language, even if they contribute to its
      body of popularity.

      This is why in ten, fifteen, maybe twenty years, when the popularity
      bubble of that language has long burst, there will be hordes of
      detractors who will have ready-made seemingly technical explanations
      why that language is no longer popular.

      Comment

      • Raffael Cavallaro

        Re: Express What, not How.

        In article <egfzhtx9tu.fsf @vipe.ii.uib.no >, ketil+news@ii.u ib.no wrote:
        [color=blue]
        > So, do you agree or not that anonymous functions can improve clarity
        > in some cases?[/color]

        Of course. However, those cases tend to be low level abstractions
        precisely because were talking about _anonymous_ functions, not
        functional abstractions in general. Their anonymity itself prevents them
        from improving the clarity of high level abstractions.

        In other words, the higher the level of abstraction, the more we are
        talking in the language of the problem domain. The language of the
        problem domain has a vocabulary with _names_ for entities and their
        interactions. Anonymous functions, by definition _have_no_names_ , so
        they can't possibly be isomorphic with the language of the problem
        domain. If an anonymous function _does_ accomplish something identical
        to a named entity or interaction in the problem domain, then you should
        give your anonymous function _that_name_ from the problem domain. Now,
        of course, it is a named function or macro, not an anonymous function
        anymore.

        The language of the problem domain, and anonymous functions, are,
        _of_necessity_, mutually exclusive, because the domain experts use
        _names_, not anonymous functions, when they talk about their domain of
        expertise.

        Comment

        • Raffael Cavallaro

          Re: Express What, not How.

          In article <3f8f0bca.42545 0585@news.bluey onder.co.uk>,
          alan.gauld@btin ternet.com (Alan Gauld) wrote:
          [color=blue]
          > In the general case I agree completely but a blanket statement
          > that it is always true is absurd. There are many cases when a
          > programmer is dealing with issues that simply don't arise in the
          > human scenario. Anonymous functions are often used in
          > scenarios where a name is meaningless.[/color]

          And in those cases, anonymous functions are perfectly appropriate.

          However, when dealing with the existing abstractions of the problem
          domain, named functions and macros are superior. I contend that a great
          deal more code should be dealing with the existing abstractions of the
          problem domain than is currently the norm. (Part of this is premature
          optimization - Programmers are reluctant to break code into smaller
          named units for fear that the additional code and function calls will be
          more computationally costly.) Remember that mathematics, string
          manipulation, network protocols, etc., are all well understood problem
          domains with _preexisting_na med_abstraction s_. These named abstractions
          are what we should be thinking and programming in, not the primitives of
          whatever language we happen to be using, nor even in anonymous
          functional abstractions.

          In addition, even if the programmer finds some novel way, only possible
          in a machine implementation, to express a solution, our ability to think
          clearly about that process is greatly aided by giving it a _name_. E.g.,
          it is much easier to think about different sorting methods (bubble sort,
          quicksort, etc.) by refering to them by name, than it is to have to look
          at an implementation of them every time we wish to refer to them.

          Naming is a fundamental step in building abstraction. Anonymous
          functions, keep us trapped at the level of abstraction at which they are
          defined. If we wish to reuse them, we must reiterate them, because we
          can't simply refer to them by name. Why not simply name them, and use
          the names? This is, after all, how people have been communicating
          abstractions since the dawn of spoken language.

          Comment

          • Bengt Richter

            Re: Python syntax in Lisp and Scheme

            On Thu, 16 Oct 2003 05:01:44 -0400, mertz@gnosis.cx (David Mertz) wrote:
            [color=blue]
            >|> But the underlying issue was the spurious claim that lambda forms
            >|> were somehow required for HOFs, which is totally bogus. Python
            >|> could get by with only 'def', Lisp with only 'defun', and Haskell
            >|> only '=' and 'where'... and all of them would be just as capable at
            >|> using combinatorial and other HOFs.
            >
            >Jacek Generowicz <jacek.generowi cz@cern.ch> wrote previously:
            >|Yes, but arguments such as these are the first step down the slippery
            >|slope to Turing Equivalence. For just about any feature in just about
            >|any language, you could argue that the langugage could get by without
            >|it ... and taking this to its logical conclusion, you end up with
            >|assembler.
            >
            >There is no such slope. OF COURSE everything is *computable* in every
            >language. That's obvious and trivial. Well, so are lots of things, but
            >it's not the point I've made.
            >
            >What I am talking about is HIGHER ORDER FUNCTIONS. I.e. things
            >(abstraction s) that don't exist in assembly language or in Turing
            >machines. You don't need that abstraction to do any computation, but
            >obviously, HOFs have a certain utility and beauty.
            >
            >And you DO NOT NEED lambdas for HOFs! Categorically so--it's not that
            >you can use only a subset of HOFs if you only have def/defun/=. A
            >language that doesn't have lambda, but treats functions as first class,
            >can express EVERY HOF that one that adds lambda can.[/color]

            ISTM there could be ways that you need BOTH named and un-named functions.
            I.e., a function NEEDS a name in order to call itself recursively
            (unless you create some specialized syntax for a recursive call).

            OTOH, if you evaluate a def in a namespace where you don't know what
            all the names are, you have a collision risk when you choose a name.
            An un-named function eliminates that risk.

            I.e., even if the function-definition part is identical in syntax and
            capability, ISTM the name-binding side effect could be an issue.
            Practically, it is probably rare that you can't use a named function,
            but really def is a convenience construct that does name binding after
            doing (what would be) a full-fledged lambda thing IMO.

            Why should the following kind of thing be arbitrarily restricted?
            (currently for two reasons -- a name is useless here and def
            is a statement, not allowed in this contex):
            [color=blue][color=green][color=darkred]
            >>> funlist = [[/color][/color][/color]
            ... (lambda value:
            ... lambda:'My value is %s'%value
            ... # imagine freedom to have full suites here
            ... )(y) for y in range(5)
            ... ][color=blue][color=green][color=darkred]
            >>> for fun in funlist: print fun()[/color][/color][/color]
            ...
            My value is 0
            My value is 1
            My value is 2
            My value is 3
            My value is 4

            (Not that a bound method (aka callable object if bound method is __call__) might
            not be as good or better in many cases, but that might lead to asking whether
            you NEED to be able to define functions outside of classes ;-)

            ISTM there are uses for lists (and dicts for that matter) of functions
            where the def names would at best be ignored side effects. E.g., perhaps
            key or macro-key-sequence bindings for an editor, or event bindings for a GUI, etc.
            [color=blue]
            >
            >This point is quite neutral as to whether lambda forms are otherwise
            >worthwhile. It's just a basic fact that a bunch of posters oddly want
            >to deny.
            >[/color]
            ISTM you are focusing on the defined function to the exclusion of
            the name-binding-as-side-effect, and saying you don't need lambdas
            because def's can generate the same functions, but ISTM that's not the whole story ;-)

            Regards,
            Bengt Richter

            Comment

            • Alex Shinn

              Re: Express What, not How.

              At Fri, 17 Oct 2003 00:54:53 GMT, Raffael Cavallaro wrote:
              [color=blue]
              > Naming is a fundamental step in building abstraction. [...] This is,
              > after all, how people have been communicating abstractions since the
              > dawn of spoken language.[/color]

              Language may have begun with proper names, but these are by definition
              *not* abstract. Abstraction comes from being able to combine different
              linguistic elements to build more complex ideas without needing to give
              them names. We use adjectives and adverbs to modify existing words
              without needing to come up with new words, and build further with noun
              clauses and prepositions. So you can both "run quickly" and "swim
              quickly," which is analogous to a higher order function (quickly)
              working on two existing functions (run and swim). You could give
              specific names to either of these but indiscriminatel y naming puts a
              burden on the memory. In this case, the further modified function "run
              quickly over a short distance" is a common enough concept that it does
              get its own name "sprint," but there is no equivalent for when those two
              modifiers are applied to "swim." It may be fun to suggest that "swint"
              be used, but I don't think anyone would argue that would make the
              language more clear, quite the contrary it would make the spoken
              language unwieldy.

              Naming is of course important, but we'd have a very difficult time
              communicating if we had to name everything we wanted to talk about. You
              need to choose a good balance of what deserves a name.

              And don't name the farm animals, it only makes it harder when you eat
              them :)

              --
              Alex

              Comment

              • Brian McNamara!

                Re: Express What, not How.

                Raffael Cavallaro <raffaelcavalla ro@junk.mail.me .not.mac.com> once said:[color=blue]
                >In other words, the higher the level of abstraction, the more we are
                >talking in the language of the problem domain. The language of the
                >problem domain has a vocabulary with _names_ for entities and their
                >interactions . Anonymous functions, by definition _have_no_names_ , so
                >they can't possibly be isomorphic with the language of the problem
                >domain. If an anonymous function _does_ accomplish something identical
                >to a named entity or interaction in the problem domain, then you should
                >give your anonymous function _that_name_ from the problem domain. Now,
                >of course, it is a named function or macro, not an anonymous function
                >anymore.[/color]

                I still disagree. Below is an example where I still think it's best to
                use anonymous functions, despite the fact that both (1) it's at a high
                level of abstraction and (2) it maps exactly to the problem domain.

                Here's the example. You've got some command-line application that
                processes some binary files. The details aren't important. You can
                run the program like this:

                % prog foo bar baz
                # processes data files foo, bar, and baz, and then
                # saves binary results in foo.sav, bar.sav, and baz.sav

                or like this

                % prog -p foo
                # processes data files (in this case, just "foo")
                # and prints human-readable results to the screen

                Hopefully you get the basic idea for the application.


                Now, I can imagine the program being structured something like this.
                (I'm using Haskell, which is the FPL I know best, but it's not my native
                tongue, so apologies if I screw up minor details.)

                processFile :: String -> IO Info
                -- process data file named by string, return Info data structure

                printInfo :: Info -> IO ()
                -- print Info in human-readable form to stdout

                saveInfo :: Info -> String -> IO ()
                -- save Info (in binary) to file named by String

                Now, somewhere in or near the main() function (that is, at the very
                highest level of abstraction for this program), I can imagine seeing
                code like this:

                -- assume these vars:
                fileList :: [String] -- names of files to process
                wantPrint :: Bool -- whether user specified '-p' option
                ...
                let forEachFilename op = mapM op fileList
                in if wantPrint
                then forEachFilename \fn -> do info <- processFile fn
                printInfo info
                else forEachFilename \fn -> do info <- processFile fn
                saveInfo info (fn++".sav")

                Note the two anonymous functions:

                \fn -> do info <- processFile fn
                printInfo info
                and
                \fn -> do info <- processFile fn
                saveInfo info (fn++".sav")

                Note that they map exactly to ideas from the problem domain (actually,
                to the very user interface of this program). Now, you want me to make
                these separate named functions? What ought I call them? Perhaps
                "processFileAnd Print" and "processFileAnd Save"? Or perhaps we should
                use the name as it's known in the user interface, and name them
                "doItWithTheDas hPeeOption" and "doItWithoutThe DashPeeOption"?

                I think that such a strategy would be silly, especially if there is
                more than one command-line option, each of which slightly alters the
                program's overall behavior. I think that the anonymous functions do a
                good job of succinctly specifying the behavior for each option.


                I have enjoyed this discussion because it's forced me to think about
                what rules I apply when making coding choices (such as whether-or-not to
                use an anonymous function). I've found it's surprisingly difficult to
                come up with succinct, precise, hard-and-fast rules which capture how I
                choose to write code. You have an advantage here: even if we disagree
                about what the "best" style is, you can at least describe the rules for
                your style, whereas I cannot easily do the same for mine.

                --
                Brian M. McNamara lorgon@acm.org : I am a parsing fool!
                ** Reduce - Reuse - Recycle ** : (Where's my medication? ;) )

                Comment

                • David Mertz

                  Re: Python syntax in Lisp and Scheme

                  |>And you DO NOT NEED lambdas for HOFs!

                  bokr@oz.net (Bengt Richter) wrote previously:
                  |there could be ways that you need BOTH named and un-named functions.

                  Nope, you do not NEED both. It can be convenient or expressive to have
                  both, but it is certainly not necessary for HOFs or any other
                  computational purpose. And I have yet to see an example where a
                  hypothetical loss of unnamed functions would *significantly* worsen
                  expressiveness.

                  |a function NEEDS a name in order to call itself recursively

                  Nope. That's the point of the Y combinator; you don't need a name to do
                  this (just first class anonymous functions). See, for example:



                  |OTOH, if you evaluate a def in a namespace where you don't know what
                  |all the names are, you have a collision risk when you choose a name.
                  |An un-named function eliminates that risk.

                  Sure, that can occassionally be useful in eliminating the small risk.
                  But so can 'grep'. There are always more names out there to use. This
                  particular convenience is VERY small.

                  |Why should the following kind of thing be arbitrarily restricted?
                  | >>> funlist = [
                  | ... (lambda value:
                  | ... lambda:'My value is %s'%value
                  | ... # imagine freedom to have full suites here
                  | ... )(y) for y in range(5)
                  | ... ]
                  | >>> for fun in funlist: print fun()

                  Obviously, you cannot spell 'funlist' quite that way in Python. But the
                  available spellings are not bad looking IMO. E.g., with no lambda:
                  [color=blue][color=green][color=darkred]
                  >>> def ValFactory(x):[/color][/color][/color]
                  ... def say_val(x=x): return 'My value is %s' % x
                  ... return say_val
                  ...[color=blue][color=green][color=darkred]
                  >>> funlist = map(ValFactory, range(5))[/color][/color][/color]

                  I'm not sure the point here. My spelling happens to be Python's (or at
                  least one option in Python)... and it works fine without any lambdas.
                  If you want, you can even 'del' the name 'ValFactory' after the list is
                  created.

                  Yours, David...

                  --
                  _/_/_/ THIS MESSAGE WAS BROUGHT TO YOU BY: Postmodern Enterprises _/_/_/
                  _/_/ ~~~~~~~~~~~~~~~ ~~~~~[mertz@gnosis.cx]~~~~~~~~~~~~~~~ ~~~~~~ _/_/
                  _/_/ The opinions expressed here must be those of my employer... _/_/
                  _/_/_/_/_/_/_/_/_/_/ Surely you don't think that *I* believe them! _/_/


                  Comment

                  • John M. Gamble

                    Re: Car and cdr (Re: Python syntax in Lisp and Scheme)

                    In article <87k775jlki.fsf @thalassa.infor matimago.com>,
                    Pascal Bourguignon <spam@thalassa. informatimago.c om> wrote:[color=blue]
                    >Pascal Costanza <costanza@web.d e> writes:
                    >[color=green]
                    >> Hartmann Schaffer wrote:
                    >>[color=darkred]
                    >> > In article <bmgh32$1a32$1@ f1node01.rhrz.u ni-bonn.de>,
                    >> > Pascal Costanza <costanza@web.d e> writes:
                    >> >
                    >> >> ...
                    >> >> I think that's the essential point here. The advantage of the[/color]
                    >> names car and cdr is that they _don't_ mean anything specific.[color=darkred]
                    >> >
                    >> >
                    >> >
                    >> > gdee, you should read early lisp history ;-). car and cdr ha[d|ve] a
                    >> > very specific meaning[/color]
                    >>
                    >>
                    >> Yes, but noone (noone at all) refers to that meaning anymore. It's a
                    >> historical accident that doesn't really matter anymore when developing
                    >> code.[/color]
                    >
                    >Indeed. Had the first lisp been programmed on a 680x0, we would have
                    >d0 and d1 instead of car and cdr, or worse, had it been done on 8086,
                    >we would have ax and bx...
                    >[/color]

                    I think you mean "cd0 and cd1" and "cax and cbx". The Cs in car
                    and cdr mean "contents". For that matter, the Rs mean register,
                    so i suppose it would go "cd0r", "cd1r", etc.

                    --
                    -john

                    February 28 1997: Last day libraries could order catalogue cards
                    from the Library of Congress.

                    Comment

                    • Jan Rychter

                      Re: Python syntax in Lisp and Scheme

                      -----BEGIN PGP SIGNATURE-----
                      Version: GnuPG v1.2.2 (GNU/Linux)

                      iD8DBQA/j21GLth4/7/QhDoRAh2nAKCcXh 235hUbrwrewoawx QjwOz2vkACfc1s/
                      5tL3QKMbDoykwZF u3usfesE=
                      =4tah
                      -----END PGP SIGNATURE-----

                      Comment

                      • Raffael Cavallaro

                        Re: Express What, not How.

                        In article <bmnl9e$e8g$1@n ews-int.gatech.edu> ,
                        gt5163b@prism.g atech.edu (Brian McNamara!) wrote:


                        [snip][color=blue]
                        > \fn -> do info <- processFile fn
                        > printInfo info
                        > and
                        > \fn -> do info <- processFile fn
                        > saveInfo info (fn++".sav")[/color]

                        [snip]
                        [color=blue]
                        > What ought I call them? Perhaps
                        > "processFileAnd Print" and "processFileAnd Save"?[/color]

                        Yup. Next question. Only someone who hasn't taken a break from coding
                        for a long time could think that:

                        \fn -> do info <- processFile fn
                        printInfo info

                        is clearer or easier to understand than:

                        ProcessFileAndP rint


                        Even more so in lisp:

                        process-file-and-print

                        Comment

                        • Raffael Cavallaro

                          Re: Express What, not How.

                          In article <87ekxciphd.wl@ strelka.synthco de.com>,
                          Alex Shinn <foof@synthcode .com> wrote:
                          [color=blue]
                          > We use adjectives and adverbs to modify existing words
                          > without needing to come up with new words, and build further with noun
                          > clauses and prepositions. So you can both "run quickly" and "swim
                          > quickly," which is analogous to a higher order function (quickly)
                          > working on two existing functions (run and swim).[/color]

                          I think you miss the point - "quickly" is itself a _name_ for an
                          abstract modifier. If this is the analog of a higher order function, it
                          is a _named_ higher order function, not an anonymous one.

                          We don't say "he ran (large distance covered/unit time)" or "he swam
                          (large distance covered/unit time)." Instead, we give this abstraction,
                          (large distance covered/unit time) a name, "quickly."

                          I am most definitely _not_ arguing against the use of higher order
                          functions when appropriate. When dealing with concepts of the problem
                          domain though, those higher order functions should probably have
                          _names_. And when it is not possible to cast these HOFs in a _syntax_
                          that fits the usage of the problem domain, these named HOFs will
                          naturally find their way into macros ;^)

                          One could conceive of a loose ranking of modes of expression and levels
                          of abstraction. From lowest (least abstract) to highest:

                          language primitives
                          anonymous functions
                          named functions and higher order anonymous functions
                          (a tie here because naming is inherently more abstract
                          than anonymity, and HOFs are of course more abstract
                          than ordinary functions)
                          named higher order functions
                          macros

                          Comment

                          • Raffael Cavallaro

                            Re: Express What, not How.

                            In article <87ekxciphd.wl@ strelka.synthco de.com>,
                            Alex Shinn <foof@synthcode .com> wrote:
                            [color=blue]
                            > We use adjectives and adverbs to modify existing words
                            > without needing to come up with new words, and build further with noun
                            > clauses and prepositions. So you can both "run quickly" and "swim
                            > quickly," which is analogous to a higher order function (quickly)
                            > working on two existing functions (run and swim).[/color]

                            I think you miss the point - "quickly" is itself a _name_ for an
                            abstract modifier. If this is the analog of a higher order function, it
                            is a _named_ higher order function, not an anonymous one.

                            We don't say "he ran (large distance covered/unit time)" or "he swam
                            (large distance covered/unit time)." Instead, we give this abstraction,
                            (large distance covered/unit time) a name, "quickly."

                            I am most definitely _not_ arguing against the use of higher order
                            functions when appropriate. When dealing with concepts of the problem
                            domain though, those higher order functions should probably have
                            _names_. And when it is not possible to cast these HOFs in a _syntax_
                            that fits the usage of the problem domain, these named HOFs will
                            naturally find their way into macros ;^)

                            One could conceive of a loose ranking of modes of expression and levels
                            of abstraction. From lowest (least abstract) to highest:

                            language primitives
                            anonymous functions
                            named functions and higher order anonymous functions
                            (a tie here because naming is inherently more abstract
                            than anonymity, and HOFs are of course more abstract
                            than ordinary functions)
                            named higher order functions
                            macros

                            Comment

                            • Raffael Cavallaro

                              Re: Express What, not How.

                              In article <87ekxciphd.wl@ strelka.synthco de.com>,
                              Alex Shinn <foof@synthcode .com> wrote:
                              [color=blue]
                              > We use adjectives and adverbs to modify existing words
                              > without needing to come up with new words, and build further with noun
                              > clauses and prepositions. So you can both "run quickly" and "swim
                              > quickly," which is analogous to a higher order function (quickly)
                              > working on two existing functions (run and swim).[/color]

                              I think you miss the point - "quickly" is itself a _name_ for an
                              abstract modifier. If this is the analog of a higher order function, it
                              is a _named_ higher order function, not an anonymous one.

                              We don't say "he ran (large distance covered/unit time)" or "he swam
                              (large distance covered/unit time)." Instead, we give this abstraction,
                              (large distance covered/unit time) a name, "quickly."

                              I am most definitely _not_ arguing against the use of higher order
                              functions when appropriate. When dealing with concepts of the problem
                              domain though, those higher order functions should probably have
                              _names_. And when it is not possible to cast these HOFs in a _syntax_
                              that fits the usage of the problem domain, these named HOFs will
                              naturally find their way into macros ;^)

                              One could conceive of a loose ranking of modes of expression and levels
                              of abstraction. From lowest (least abstract) to highest:

                              language primitives
                              anonymous functions
                              named functions and higher order anonymous functions
                              (a tie here because naming is inherently more abstract
                              than anonymity, and HOFs are of course more abstract
                              than ordinary functions)
                              named higher order functions
                              macros

                              Comment

                              • Alex Shinn

                                Re: Express What, not How.

                                At Fri, 17 Oct 2003 05:45:29 GMT, Raffael Cavallaro wrote:[color=blue]
                                >
                                > In article <87ekxciphd.wl@ strelka.synthco de.com>,
                                > Alex Shinn <foof@synthcode .com> wrote:
                                >[color=green]
                                > > We use adjectives and adverbs to modify existing words
                                > > without needing to come up with new words, and build further with noun
                                > > clauses and prepositions. So you can both "run quickly" and "swim
                                > > quickly," which is analogous to a higher order function (quickly)
                                > > working on two existing functions (run and swim).[/color]
                                >
                                > I think you miss the point - "quickly" is itself a _name_ for an
                                > abstract modifier. If this is the analog of a higher order function, it
                                > is a _named_ higher order function, not an anonymous one.[/color]

                                I was making the analogy that verbs are functions (any functions).
                                "run" is thus a function of one argument (the person running).
                                "quickly" is as we both say an HOF which acts on run. My point is the
                                result of applying the HOF gives us "run quickly" which is itself a
                                function, and an anonymous one at that because "run quickly" is not a
                                name but a visible application of an HOF. It's exactly equivalent to

                                (memoize run)

                                whereas the named version would require you to define externally

                                (define run-memoized (memoize run))

                                a technique which quickly begins to clutter your language with names
                                like "swint."

                                --
                                Alex

                                Comment

                                Working...