By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
429,022 Members | 856 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 429,022 IT Pros & Developers. It's quick & easy.

Python syntax in Lisp and Scheme

P: n/a
I think everyone who used Python will agree that its syntax is
the best thing going for it. It is very readable and easy
for everyone to learn. But, Python does not a have very good
macro capabilities, unfortunately. I'd like to know if it may
be possible to add a powerful macro system to Python, while
keeping its amazing syntax, and if it could be possible to
add Pythonistic syntax to Lisp or Scheme, while keeping all
of the functionality and convenience. If the answer is yes,
would many Python programmers switch to Lisp or Scheme if
they were offered identation-based syntax?
Jul 18 '05
Share this Question
Share on Google+
699 Replies


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


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 indiscriminately 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

Jul 18 '05 #651

P: n/a
Raffael Cavallaro <ra**************@junk.mail.me.not.mac.com> once said:
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.


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
"processFileAndPrint" and "processFileAndSave"? Or perhaps we should
use the name as it's known in the user interface, and name them
"doItWithTheDashPeeOption" and "doItWithoutTheDashPeeOption"?

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 lo****@acm.org : I am a parsing fool!
** Reduce - Reuse - Recycle ** : (Where's my medication? ;) )
Jul 18 '05 #652

P: n/a
|>And you DO NOT NEED lambdas for HOFs!

bo**@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:

http://en2.wikipedia.org/wiki/Y_combinator

|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:
def ValFactory(x): ... def say_val(x=x): return 'My value is %s' % x
... return say_val
... funlist = map(ValFactory, range(5))


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 _/_/_/
_/_/ ~~~~~~~~~~~~~~~~~~~~[me***@gnosis.cx]~~~~~~~~~~~~~~~~~~~~~ _/_/
_/_/ The opinions expressed here must be those of my employer... _/_/
_/_/_/_/_/_/_/_/_/_/ Surely you don't think that *I* believe them! _/_/
Jul 18 '05 #653

P: n/a
In article <87************@thalassa.informatimago.com>,
Pascal Bourguignon <sp**@thalassa.informatimago.com> wrote:
Pascal Costanza <co******@web.de> writes:
Hartmann Schaffer wrote:
> In article <bm***********@f1node01.rhrz.uni-bonn.de>,
> Pascal Costanza <co******@web.de> writes:
>
>> ...
>> I think that's the essential point here. The advantage of the

names car and cdr is that they _don't_ mean anything specific.
>
>
>
> gdee, you should read early lisp history ;-). car and cdr ha[d|ve] a
> very specific meaning

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.


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...


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.
Jul 18 '05 #654

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

iD8DBQA/j21GLth4/7/QhDoRAh2nAKCcXh235hUbrwrewoawxQjwOz2vkACfc1s/
5tL3QKMbDoykwZFu3usfesE=
=4tah
-----END PGP SIGNATURE-----
Jul 18 '05 #655

P: n/a
In article <bm**********@news-int.gatech.edu>,
gt*****@prism.gatech.edu (Brian McNamara!) wrote:
[snip]
\fn -> do info <- processFile fn
printInfo info
and
\fn -> do info <- processFile fn
saveInfo info (fn++".sav")
[snip]
What ought I call them? Perhaps
"processFileAndPrint" and "processFileAndSave"?


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:

ProcessFileAndPrint
Even more so in lisp:

process-file-and-print
Jul 18 '05 #656

P: n/a
In article <87***********@strelka.synthcode.com>,
Alex Shinn <fo**@synthcode.com> wrote:
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).


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
Jul 18 '05 #657

P: n/a
In article <87***********@strelka.synthcode.com>,
Alex Shinn <fo**@synthcode.com> wrote:
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).


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
Jul 18 '05 #658

P: n/a
In article <87***********@strelka.synthcode.com>,
Alex Shinn <fo**@synthcode.com> wrote:
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).


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
Jul 18 '05 #659

P: n/a
At Fri, 17 Oct 2003 05:45:29 GMT, Raffael Cavallaro wrote:

In article <87***********@strelka.synthcode.com>,
Alex Shinn <fo**@synthcode.com> wrote:
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).


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.


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

Jul 18 '05 #660

P: n/a
"Greg Ewing (using news.cis.dfn.de)" <g2********@sneakemail.com> wrote in message news:<bm************@ID-169208.news.uni-berlin.de>...

[snip]

From that point of view, "car" and "cdr" are as good
as anything!


Better in one sense, I think. With "first" and "rest", you can't
have fun making bumper stickers that say "My other car is a cdr."

Avi Blackmore
Jul 18 '05 #661

P: n/a
On Thu, 16 Oct 2003 23:10:52 -0400, me***@gnosis.cx (David Mertz) wrote:
|>And you DO NOT NEED lambdas for HOFs!

bo**@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 You snipped the line following the preceding:
(unless you create some specialized syntax for a recursive call)

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:

http://en2.wikipedia.org/wiki/Y_combinator I'd call that a specialized syntax, to serve my purposes ;-)

|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. That's what I meant by the first line in
"""
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?
| >>> 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 The above spelling works fine, being verbatim cut/paste). Just not if you want
to replace the comment as it invites you to imagine. I guess the hypothetical
version is what you were referring to by 'that way.'
available spellings are not bad looking IMO. E.g., with no lambda: I pre-agreed, following my example with:
"""
(Not that a bound method (aka callable object if bound method is __call__) might
not be as good or better in many cases, ...
"""
>>> def ValFactory(x): ... def say_val(x=x): return 'My value is %s' % x
... return say_val
... >>> funlist = map(ValFactory, range(5))
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.
The relevant phrase from the post you are replying to was
"... where the def names would at best be ignored side effects." (Although
you are forced to use the temp bindings to return the function).
If you want, you can even 'del' the name 'ValFactory' after the list is
created.

Sure. Interesting you chose to use the default-value hack rather than
a closure ;-). What I had in mind when I pre-agreed was something like
class SayVal(object): ... def __init__(self, v): self.v=v
... def __call__(self): return 'My value is %s' % self.v
... funlist = map(SayVal, range(5))
for f in funlist: print f()

...
My value is 0
My value is 1
My value is 2
My value is 3
My value is 4

Regards,
Bengt Richter
Jul 18 '05 #662

P: n/a


David Mertz wrote:

...

|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:

http://en2.wikipedia.org/wiki/Y_combinator


please bear with me on something which i have evidently misunderstood.
what are the symbols 'h' and 'x' in the referenced exposition on the "y
combinator" if they are not names?
is the essential distinction, that one does not "need" free "names"?

?
Jul 18 '05 #663

P: n/a
In article <3f******@news.sentex.net>,
hs@heaven.nirvananet (Hartmann Schaffer) wrote:
map is an abstraction that
specifies that you want to apply a certain operation to each element
of a collection, with adding the offset being the desired operation.


Sorry to reply so late - I didn't see this post.

In the context in which the offsets are added, it isn't necessary to
know that the offsets are added using map, as opposed, for example, to
an interative construct, such as loop. Since we don't need to know _how_
the adding of offsets is done at every location in the source where we
might want to add an offset to the elements of a list or vector, we
should _name_ this bit of functionality. This is an even bigger win
should we ever decide to switch from map to loop, or do, or dolist, etc.
Then we write a single change, not one for every time we use this bit of
functionality.
Jul 18 '05 #664

P: n/a
Hartmann Schaffer wrote:
In article <bm***********@f1node01.rhrz.uni-bonn.de>,
Pascal Costanza <co******@web.de> writes:
...
I think that's the essential point here. The advantage of the names car
and cdr is that they _don't_ mean anything specific.

gdee, you should read early lisp history ;-). car and cdr ha[d|ve] a
very specific meaning


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.
Pascal

Jul 18 '05 #665

P: n/a
Marcin 'Qrczak' Kowalczyk wrote:
Because these hard-coded syntaxes are prettier than the extensible Lisp
syntax full of parentheses.


Obviously, you haven't tried to actually program in Lisp. Getting used
to the syntax is a matter of one or two weeks at most of actual coding,
provided you use a decent editor that supports parenthesis highlighting
and automatic indentation.

Despising Lisp because of its syntax is like thinking that Japanese is a
too complicated language because it doesn't use latin characters.
Mind you, I had more or less exactly the same objections to Lisp's
syntax about one and a half year ago. Now, I don't see any language out
there that nearly provides the same level of usability than Lisp,
exactly because of its regular syntax "full of parentheses". It's far
prettier and easier to read than languages whose syntaxes are based on
some unreflected, purely aesthetical choices.
Pascal

Jul 18 '05 #666

P: n/a
In article <87***********@strelka.synthcode.com>,
Alex Shinn <fo**@synthcode.com> wrote:
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.

I have no problem with a HOF, as long as the HOF corresponds to
something in the language of the problem domain. But it doesn't here. I
think it is telling that your example is taken from the problem domain
of computer science (memoization of functions), not that of the domain.

It's exactly equivalent to

(memoize run)


If we were writing a program that simulated people running and swimming,
it's very doubtful that "quickly" would mean "memoize." "Quickly" would
mean, "with-increased-framerate," or something similar. (Note that
with-increased-framerate would almost certainly be a macro).

In domains outside of functional programming and mathematics, the
concepts of the problem domain don't usually map to applicable HOFs.
People fall in love with HOFs because they are great tools for lower
level implementation. But I don't think they usually map well to the
concepts of problem domains other than mathematics and computer science.
Named functions and macros let us capture the power of HOFs inside a
vocabulary _and_ syntax that matches the problem domain.
Jul 18 '05 #667

P: n/a
me***@gnosis.cx (David Mertz) writes:
|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).


Actually you do need a name. The Y combinator is just a way to give a name to
the anonymous function, where the name is a parameter name. It is only with
that name that the recursive invocation is done.

--
Cheers, The Rhythm is around me,
The Rhythm has control.
Ray Blaak The Rhythm is inside me,
rA******@STRIPCAPStelus.net The Rhythm has my soul.
Jul 18 '05 #668

P: n/a
Jan Rychter wrote:
I've recently tried to teach someone programming. I thought "Python has
an easy syntax, let's try that". Well, guess what -- she had a really
hard time. Inconsistency was a real problem, as was the confusion
between "statements" and "expressions". When you start programming in
Python, you get really confused -- does this call have side effects or
not? You can't tell by looking at the call.
Strange. A beginner shouldn't have a problem with the distinction between
statements and expressions, and shouldn't know about side effects at all, since
this is a notion introduced by functional languages. Does this beginner, by
any chance, come from a functional programming language, or maybe a strong
mathemathical background?
Also, the syntax was confusing. Yes, indenting the statements is
easy. But the dot notation is all but obvious, especially with its
inconsistent application in Python.
How is it inconsistent? It's used to access an object's attributes.
And where did those square brackets
suddenly come from and when do I use them?
They're syntactic sugar indicating a "data lookup" of some sorts, hence their
application with dicts and lists.
Mind you, this is from a beginner's point of view. Most of you look at
the language syntax from the point of view of a person knowing at least
one (or more) programming languages and having the basic programming
concepts drilled in. It's very different for someone who does not have
that background.
It's possible I guess, different beginners have different ideas, expectations
and experiences, but usually the opposite is true... beginners find Python easy
to use.
An experiment has shown that Scheme was *much* easier to grasp. In
Scheme, you can clearly see where side-effects occur and there are less
syntax rules to follow.


Again, this raises my suspicions that the beginners that were tested have a
mathemathical background. Heck, beginners used Basic for ages... I haven't
heard anyone complain about statements vs expressions, or side effects. They
usually don't even know the distinction.

Cheers,

--
Hans (ha**@zephyrfalcon.org)
http://zephyrfalcon.org/

Jul 18 '05 #669

P: n/a
|m****@gnosis.cx (David Mertz) writes:
|> |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).

Ray Blaak <rA******@STRIPCAPStelus.net> wrote previously:
|Actually you do need a name. The Y combinator is just a way to give a name to
|the anonymous function, where the name is a parameter name. It is only with
|that name that the recursive invocation is done.

Well, OK. This is true. But the context was basically whether you
could write whole programs as big lambda abstractions--e.g. Lisp minus
'defun' and 'set', or Python minus 'def'.

"Normal" recursive programs let the programmer know the name of the
function she is writing, and use that name for the recursion call. You
could use the Y combinator even if pixies would come it at random and
change the bound name 'h' to something else, throughout your code; the
name itself is never -used- beyond the lambda.

Yours, David...

--
---[ to our friends at TLAs (spread the word) ]--------------------------
Echelon North Korea Nazi cracking spy smuggle Columbia fissionable Stego
White Water strategic Clinton Delta Force militia TEMPEST Libya Mossad
---[ Postmodern Enterprises <me***@gnosis.cx> ]--------------------------
Jul 18 '05 #670

P: n/a
bo**@oz.net (Bengt Richter) wrote previously:
|>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:
|> http://en2.wikipedia.org/wiki/Y_combinator
|I'd call that a specialized syntax, to serve my purposes ;-)

Well... it's specialized. But it's not a syntax, just a somewhat odd
HOF. But I would definitely agree that I don't want all my recursion to
be based on anonymous functions.

|>This particular convenience is VERY small.
|That's what I meant by the first line in

Yeah, but I put the 'very' in caps :-).

|the hypothetical version is what you were referring to by 'that way.'

Yeah, sorry about my pronoun. I meant "can't spell the full suite..."

|> >>> def ValFactory(x):
|> ... def say_val(x=x): return 'My value is %s' % x
|> ... return say_val
|Sure. Interesting you chose to use the default-value hack rather than
|a closure ;-). What I had in mind when I pre-agreed was something like
| >>> class SayVal(object):
| ... def __init__(self, v): self.v=v
| ... def __call__(self): return 'My value is %s' % self.v

Well... the "default value hack" *IS* a closure.

I know I'm in the minority here, but it feels like more of a hack to me
to make class instances whose (main) purpose is to "act like functions"
(i.e. have custom '.__call__()' methods). In my mind, when I want a
bunch of related callables, the natural approach is writing a function
factory, not a class.

But either way, Bengt's is another perfectly good spelling for a
collection of callables that allow full suites. Not being Dutch, I
can't say which one is the "one obvious way."

Yours, David...

--
---[ to our friends at TLAs (spread the word) ]--------------------------
Echelon North Korea Nazi cracking spy smuggle Columbia fissionable Stego
White Water strategic Clinton Delta Force militia TEMPEST Libya Mossad
---[ Postmodern Enterprises <me***@gnosis.cx> ]--------------------------
Jul 18 '05 #671

P: n/a
In article <ma*************************************@python.or g>, David Mertz wrote:

I know I'm in the minority here, but it feels like more of a hack to me
to make class instances whose (main) purpose is to "act like functions"
(i.e. have custom '.__call__()' methods). In my mind, when I want a
bunch of related callables, the natural approach is writing a function
factory, not a class.


In most cases, I would completely agree with you. Though they are often
interchangeable (closures and callable objects), there is a subtle semantic
difference to me. Is it a stateful function or a callable object? What does
it feel like? I usually go with my intuition.

--
..:[ dave benjamin (ramenboy) -:- www.ramenfest.com -:- www.3dex.com ]:.
: d r i n k i n g l i f e o u t o f t h e c o n t a i n e r :
Jul 18 '05 #672

P: n/a

"Luke Gorrie" <lu**@bluetail.com> wrote in message
news:lh************@dodo.bluetail.com...
ke********@ii.uib.no writes:
Anonymous functions *can* be more clear than any name. Either because
they are short and simple, because it is hard to come up with a good
name, and/or becuase they are ambigous.

Say I want to attach an index to elements of a list. I could write

integers = [1..]
attach_index ls = zip integers ls

or just

attach_index ls = zip [1..] ls


If we're arguing to eliminate names that don't say very much, then

attach_index = zip [1..]


I think dynamic scoping within blocks really trims down on duplication and
make the code easier to read. For example:

employees sort: [ | a b | a date < b date ]

A lot of typing for a simple concept:

employees sort: [ < data ]

I'm not against too much typing to be clear, but rather too much typping
that makes the concept unclear.

-- Mike
Whether you want to give an explicit name to the list of integers is
not given. If the indexed list is local, it is better to use the
definition directly; I don't want to look up the definition of
integers (perhaps in a different module) to check whether it is [1..]
or [0..].


And for the exact same reason you might like to just write "zip [1..]"
instead of using a separate "attach_index" function.

Cheers,
Luke

Jul 18 '05 #673

P: n/a
Pascal Costanza <co******@web.de> writes:
Hartmann Schaffer wrote:
In article <bm***********@f1node01.rhrz.uni-bonn.de>,
Pascal Costanza <co******@web.de> writes:
...
I think that's the essential point here. The advantage of the names
car and cdr is that they _don't_ mean anything specific.

gdee, you should read early lisp history ;-). car and cdr ha[d|ve] a
very specific meaning


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.


For that matter, even the very first LISP _programmer_ did not refer
to that meaning either.

Only the _implementer_ of the first LISP did.

--
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
Lying for having sex or lying for making war? Trust US presidents :-(
Jul 18 '05 #674

P: n/a
Ray Blaak wrote:
Actually you do need a name. The Y combinator is just a way to give a
name to the anonymous function, where the name is a parameter name.
It is only with that name that the recursive invocation is done.


This is technically not true. See
http://www.eleves.ens.fr:8080/home/m...a/#lambda_elim.
--
Rainer Deyke - ra*****@eldwood.com - http://eldwood.com
Jul 18 '05 #675

P: n/a
Pascal Costanza <co******@web.de> wrote in message news:<bm**********@f1node01.rhrz.uni-bonn.de>...
David Eppstein wrote:
In article <bm**********@newsreader2.netcologne.de>,
Pascal Costanza <co******@web.de> wrote:

It's probably just because the Common Lisp community is still relatively
small at the moment. But this situation has already started to improve a
lot.

It's only been out, what, twenty years? And another twenty before that
for other lisps... How much time do you think you need?


AFAIK, Lisp was very popular in the 70's and 80's, but not so in the
90's. At the moment, Common Lisp is attracting a new generation of
programmers.


I was a Lisp fan back when Common Lisp came out. We went from a
stunningly simple language that could be described in a small booklet
to one that couldn't be adequately described in a 300-page tome. It
was about that time that Lisp dropped off the radar.

Now I have a language called Python, which like the original Lisp can
be described simply but has extraordinary power. And _it_ is what is
attracting a new generation of programmers.
Jul 18 '05 #676

P: n/a
Raffael Cavallaro <ra**************@junk.mail.me.not.mac.com> wrote in article <ra************************************@netnews.at tbi.com> in comp.lang.functional:
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.


In what sense are "lambda" and "apply" not names?

--
Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig
"Who needs drugs when we have sex and chocolate?" -- Cory Kerens
Jul 18 '05 #677

P: n/a
A. Lloyd Flanagan wrote:
I was a Lisp fan back when Common Lisp came out. We went from a
stunningly simple language that could be described in a small booklet
to one that couldn't be adequately described in a 300-page tome. It
was about that time that Lisp dropped off the radar.

Now I have a language called Python, which like the original Lisp can
be described simply but has extraordinary power. And _it_ is what is
attracting a new generation of programmers.


Common Lisp still has a small core, and most of the stuff of the indeed
large spec would rather be considered standard libraries in more
conventional languages.

Yes, it would probably have been better if Common Lisp designers would
have made this distinction clearer, for example by defining language
layers. That's maybe the only real mistake they have made. [1]
Pascal

[1] Somewhere in this thread someone accused "us" Lispers that we don't
admit that Lisp has "bad" features. The reason why wo don't admit
anything here is not because it doesn't have bad features, but because
the flexibility of Lisp always allows us to code around these
misdesigns. And we don't have to wait for some language designer to
release version x.y of the language to fix a feature of the language.

The fact that Common Lisp is large is indeed the only mistake that we
can't "code around".

Jul 18 '05 #678

P: n/a
In article <t7************@proper.ptq.dyndns.org>,
Ken Shan <ke*@digitas.harvard.edu> wrote:
In what sense are "lambda" and "apply" not names?


Not names from the problem domain, unless the problem domain is
functional programming.
Jul 18 '05 #679

P: n/a
Raffael Cavallaro <ra**************@junk.mail.me.not.mac.com> wrote in article <ra************************************@netnews.at tbi.com> in comp.lang.functional:
In article <t7************@proper.ptq.dyndns.org>,
Ken Shan <ke*@digitas.harvard.edu> wrote:
In what sense are "lambda" and "apply" not names?

Not names from the problem domain, unless the problem domain is
functional programming.


But in the style of programming that you advocate, as I understand
it, one does not need to give a name to function application from the
problem domain before using it.

--
Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig
"Who needs drugs when we have sex and chocolate?" -- Cory Kerens
Jul 18 '05 #680

P: n/a
> Obviously, you haven't tried to actually program in Lisp. Getting used
to the syntax is a matter of one or two weeks at most of actual coding,
provided you use a decent editor that supports parenthesis highlighting
and automatic indentation.

I'd have to concur with this one. Parenthesized-prefix syntax is rather
pretty. What I like is the flexibility in code layout. Ex:

(defun foo (x)
...long function definition here...)

and

int foo(int x)
{
...long function definition here...
}

Are equally natural in their respective syntaxes. However, if you have a
short, simple function:

(defun foo (x) (+ x 2))

is still perfectly natural, while:

int foo(int x) { return x + 2; }

looks a little weird. Most people would write the above similarly to the
first example, which makes it much longer. Block-structured languages in
general tend to suffer from this problem.
Jul 18 '05 #681

P: n/a
On Tue, 14 Oct 2003 22:09:44 GMT, Raffael Cavallaro
<ra**************@junk.mail.me.not.mac.com> wrote:
In article <bm**********@terabinaries.xmission.com>,
Thant Tessman <th***@acm.org> wrote:
A programmer accustomed to the functional style finds the need in non-FP
languages to name every function analogously awkward.
No one is talking about need, but about clarity of exposition.

.... It just makes code less readable to use _anonymous_ functions.


No. It doesn't.

david rush
--
(\x.(x x) \x.(x x)) -> (s i i (s i i))
-- aki helin (on comp.lang.scheme)
Jul 18 '05 #682

P: n/a
Ken Shan <ke*@digitas.harvard.edu> wrote in message news:<bm**********@news.fas.harvard.edu>...
But in the style of programming that you advocate, as I understand
it, one does not need to give a name to function application from the
problem domain before using it.


No, one doesn't, as long as that function application is the one place
where the implementation of that bit of functionality needs to be
expressed.

However, if one is using that bit of functionality elsewhere, then it
only constitutes information overload to re-express the implementation
of that functionality yet again in that location. In such a case, that
function application should be named in the one place it is necessary
to express its implementation, and the named version used elsewhere.

Again, it comes down to uniqueness and necessity of exposition. If it
is only going to be expressed once, and there is no loss of clarity,
then use an anonymous function. In this sense anonymous functions are
no different than using the built-ins or primitives of the language.
If this is the place where this bit of functionality needs to be
defined, then, by all means, use anonymous functions to express that
implementation if it is easier.

But if that is not the one and only place where that bit of
functionality is used, then name it. If that is not the one and only
place where that functionality needs to be defined, then don't repeat
the implementation in a half dozen places. Implement it once, name it,
and use the name elsewhere.
Jul 18 '05 #683

P: n/a
Raffael Cavallaro <ra**************@junk.mail.me.not.mac.com> wrote in message news:<ra************************************@netne ws.attbi.com>...

In the context in which the offsets are added, it isn't necessary to
know that the offsets are added using map, as opposed, for example, to
an interative construct, such as loop.


Sorry for the typo - that should be "iterative" of course.
Jul 18 '05 #684

P: n/a
Raffael Cavallaro <ra*****@mediaone.net> wrote in article <ae**************************@posting.google.com > in comp.lang.functional:
Ken Shan <ke*@digitas.harvard.edu> wrote in message news:<bm**********@news.fas.harvard.edu>...
But in the style of programming that you advocate, as I understand
it, one does not need to give a name to function application from the
problem domain before using it.

No, one doesn't, as long as that function application is the one place
where the implementation of that bit of functionality needs to be
expressed.


The implementation of function application is definitely something
that doesn't need to be expressed in the vast majority of programs.
Moreover, function application is used in many places, far from just
one place. So according to you, I need to find a name for function
application, and not just any name -- it needs to be a name from the
problem domain. But what is a name for function application from the
cash register problem domain?

--
Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig
"Who needs drugs when we have sex and chocolate?" -- Cory Kerens
Jul 18 '05 #685

P: n/a
At Fri, 17 Oct 2003 12:28:14 GMT, Raffael Cavallaro wrote:

I have no problem with a HOF, as long as the HOF corresponds to
something in the language of the problem domain. But it doesn't here. I
think it is telling that your example is taken from the problem domain
of computer science (memoization of functions), not that of the domain.
Actually, my problem domain more often than not *is* computer science,
but you could also stick strictly to human language or whatever suits
your fancy.
If we were writing a program that simulated people running and swimming,
it's very doubtful that "quickly" would mean "memoize." "Quickly" would
mean, "with-increased-framerate," or something similar.
I don't see how a framerate is less computer-specific than memoization.
If you want to stay close to the original human language then it would
simply mean the act of running faster than usual.
(Note that with-increased-framerate would almost certainly be a
macro).
Not necessarily. In Scheme with- forms are almost never macros, and are
almost always passed anonymous functions as arguments.
In domains outside of functional programming and mathematics, the
concepts of the problem domain don't usually map to applicable HOFs.
People fall in love with HOFs because they are great tools for lower
level implementation. But I don't think they usually map well to the
concepts of problem domains other than mathematics and computer science.
Named functions and macros let us capture the power of HOFs inside a
vocabulary _and_ syntax that matches the problem domain.


You're switching to macros and HOFs when we were talking about anonymous
functions. If you are seriously arguing against the use of HOFs in
general then I think you have a lot to learn. Learn a Lisp (Scheme is
nice and clean) or one of the more functional languages like Haskell.
If you brought macros into the discussion with the idea that any direct
application of an anonymous function should be hidden with a macro then
I question whether your goal is really to achieve more legible code or
is just some irrational bias against anonymous functions?

If you want to program in logic as close to the problem domain as
possible, try a logic programming language like Prolog or CLIPS. You
may be disappointed because even in these languages you have to refer to
low-level details at times. Also you will find that an extremely useful
feature is not only anonymous functions but anonymous facts and rules.
If you want to wait until you can program explicitly in the
highest-level human language then I think you may be even more
disappointed. Firstly because as already mentioned human language makes
heavy use of anonymous functions and unnamed concepts in general. When
possible we combine existing ideas and use their compound forms directly
in speech without giving them a new name. Secondly because human
language is not well suited to exact specifications, which is why when
we try to nail down rules as specifically as possible we end up with
language like legalese.

If you want to tell computers what to do in natural human language,
trusting them to learn what you mean when you're ambiguous (through a
process of correcting them when they guess wrong) then that is an
admirable dream. But it's not programming.

--
Alex

Jul 18 '05 #686

P: n/a
Ken Shan <ke*@digitas.harvard.edu> wrote in message news:<bm**********@news.fas.harvard.edu>...
So according to you, I need to find a name for function
application, and not just any name -- it needs to be a name from the
problem domain.


From the problem domain _at_that_level_. If, at that level, we're
dealing with array bounds checking (assuming, for the moment that
we're using a language that doesn't have that built in), then function
names like check-index, report-invalid-index-error, etc. are names
from the problem domain at that level.

The problem I see with the use of the typical anonymous functional
style is twofold:

1. The same functional idiom is repeated, but not abstracted (i.e.,
not named). This leads to unnecessary "programmer inlining," that is,
writing out the implementation everywhere it is used, rather than
naming it once, and using the name everywhere else.

2. The anonymous functional idioms map well to domains such as
arithmetic, mathematics, and functional programming itself. These same
idioms don't map so well to other domains. The more abstract the
program becomes (that is, the closer it moves to the problem domain,
and the farther it moves from the low level arithmetic and functional
abstractions) the less the anonymous functional idioms will correspond
to the existing concepts and vocabulary of the problem domain.
Jul 18 '05 #687

P: n/a
On 16 Oct 2003 16:37:01 +0200, rumours say that Pascal Bourguignon
<sp**@thalassa.informatimago.com> might have written:
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.


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...


Perhaps on 680x0 they would be ca0 and cd0, or ca0r and cd0r. AFAIK car
stands for contents of address register and cdr for contents of contents
of data register. So, picking register 0 out of 8 (7 if you exclude a7
/ sp) address registers and register 0 out of 8 data registers is just a
choice on this hypothetical subject.

However, I have a suspicion that the "correct" names would be ca0r and
c(a0)r ...
--
TZOTZIOY, I speak England very best,
Ils sont fous ces Redmontains! --Harddix
Jul 18 '05 #688

P: n/a
I've just about decided to killfile this whole thread, but I can't
let this one go by. Two unsubstantiated assertions do not make a bad
programming practice, no matter how hard you try.

On 19 Oct 2003 19:22:04 -0700, Raffael Cavallaro <ra*****@mediaone.net>
wrote:
The problem I see with the use of the typical anonymous functional
style is twofold:
How much programming have *you* done with anonymous functions? Or is this
complaint based on your esthetic reactions to a series of contrived
examples in usenet posts?
1. The same functional idiom is repeated, but not abstracted (i.e.,
not named). This leads to unnecessary "programmer inlining," that is,
writing out the implementation everywhere it is used, rather than
naming it once, and using the name everywhere else.
Not by this heavy user of anonymous functions. In fact one of the main
uses I have for anonymous functions is to *avoid* code duplication by
parameterizing over entire categories of functions.

Cut & Paste programming is bad practice in any language. IME, functional
programmers do it *less* often than those from other communities.
2. The anonymous functional idioms map well to domains such as
arithmetic, mathematics, and functional programming itself. These same
idioms don't map so well to other domains. The more abstract the
program becomes (that is, the closer it moves to the problem domain,
and the farther it moves from the low level arithmetic and functional
abstractions) the less the anonymous functional idioms will correspond
to the existing concepts and vocabulary of the problem domain.


Again, I disagree heartily. I use HO&AFs to enable greater levels of
abstraction since they allow me to abstract *outer* components of
functions while I pass in the site-specific portions. Control-structure-
like
functions are only a fairly trivial example of this kind of thing, but
I have in a mail-processing application 2 functions IF-FROM-LINE (used in
mbox file processing) and RFC822-COLLAPSE-HEADER (used in RFC822 header
processing) which both implement algorithms which are parameterized
by functions. This is vaguely similiar in spirit to the visitor pattern
from OO land, but much more flexible. Both of these functions are used
in multiple contexts where the anonymous functions contextualize the
operations performed under specific conditions in their implemented
algorithms. These operations have (so far) been strictly one-off animals.
In the event that I ever feel a need to re-use one of them I will simply
lift the anonymous function from its original source location, give it
a top-level name et voila - instant reuse.

david rush
--
(\x.(x x) \x.(x x)) -> (s i i (s i i))
-- aki helin (on comp.lang.scheme)
Jul 18 '05 #689

P: n/a
In article <op**************@news.nscp.aoltw.net>,
David Rush <dr***@aol.net> wrote:
I have in a mail-processing application 2 functions IF-FROM-LINE (used in
mbox file processing) and RFC822-COLLAPSE-HEADER (used in RFC822 header
processing) which both implement algorithms which are parameterized
by functions. This is vaguely similiar in spirit to the visitor pattern
from OO land, but much more flexible. Both of these functions are used
in multiple contexts where the anonymous functions contextualize the
operations performed under specific conditions in their implemented
algorithms. These operations have (so far) been strictly one-off animals.
I think you are in violent agreement with me.

I wrote:
The problem I see with the use of
the typical anonymous functional ^^^^^^^^^ style is twofold:

1. If-from-line is a _named_ function, not an anonymous function. My
only objection was to _anonymous_ functions replacing named
abstractions, not to functional programming itself.
In the event that I ever feel a need to re-use one of them I will simply
lift the anonymous function from its original source location, give it
a top-level name et voila - instant reuse.


2. Which is precisely what I suggested in all of my previous posts.
I.e., if the anonymous function is used more than once, name it, and use
the name.
Jul 18 '05 #690

P: n/a
Christos "TZOTZIOY" Georgiou <tz**@sil-tec.gr> wrote:
+---------------
| AFAIK car stands for contents of address register and
| cdr for contents of contents of data register.
+---------------

From the IBM 704 CPU instruction format:
CAR == "Contents of Address [part of] Register".
CDR == "Contents of Decrement [part of] Register".
See <URL:http://www.catb.org/~esr/jargon/html/C/cdr.html>.

Note that the PDP-10 AOBJP/AOBJN/BLKI/BLKO/PUSH/PUSHJ/POP/POPJ
instructions used a similar format, but with the "decrement" part
being a negative count in the upper half of the word (which was
*incremented* in parallel with the address in the lower half
[or in the case of POP & POPJ only, decremented in parallel with
the address]).
-Rob

-----
Rob Warnock <rp**@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607

Jul 18 '05 #691

P: n/a
rp**@rpw3.org (Rob Warnock) wrote:
Note that the PDP-10 AOBJP/AOBJN/BLKI/BLKO/PUSH/PUSHJ/POP/POPJ
instructions used a similar format.


I havn't thought about that stuff for many years. Now you've made my
brain hurt again.
Jul 18 '05 #692

P: n/a
In article <1j********************************@4ax.com>,
Michele Dondi <bi******@tiscalinet.it> wrote:
It's certainly true that mathematicians do not _write_
proofs in formal languages. But all the proofs that I'm
aware of _could_ be formalized quite easily. Are you
aware of any counterexamples to this? Things that
mathematicians accept as correct proofs which are
not clearly formalizable in, say, ZFC?


I am not claiming that it is a counterexample, but I've always met
with some difficulties imagining how the usual proof of Euler's
theorem about the number of corners, sides and faces of a polihedron
(correct terminology, BTW?) could be formalized. Also, however that
could be done, I feel an unsatisfactory feeling about how complex it
would be if compared to the conceptual simplicity of the proof itself.


Which one do you think is the usual proof?
http://www.ics.uci.edu/~eppstein/junkyard/euler/

Anyway, this exact example was the basis for a whole book about what is
involved in going from informal proof idea to formal proof:
http://www.ics.uci.edu/~eppstein/jun.../refs.html#Lak

--
David Eppstein http://www.ics.uci.edu/~eppstein/
Univ. of California, Irvine, School of Information & Computer Science
Jul 18 '05 #693

P: n/a
On Tue, 21 Oct 2003 01:52:07 -0500, rumours say that rp**@rpw3.org (Rob
Warnock) might have written:
+---------------
| AFAIK car stands for contents of address register and
| cdr for contents of contents of data register.
+---------------

From the IBM 704 CPU instruction format:
CAR == "Contents of Address [part of] Register".
CDR == "Contents of Decrement [part of] Register".
See <URL:http://www.catb.org/~esr/jargon/html/C/cdr.html>.


Thanks for correcting me :)
--
TZOTZIOY, I speak England very best,
Ils sont fous ces Redmontains! --Harddix
Jul 18 '05 #694

P: n/a
Raffael Cavallaro <ra*****@mediaone.net> wrote in article <ae**************************@posting.google.com > in comp.lang.functional:
Ken Shan <ke*@digitas.harvard.edu> wrote in message news:<bm**********@news.fas.harvard.edu>...
So according to you, I need to find a name for function
application, and not just any name -- it needs to be a name from the
problem domain.

From the problem domain _at_that_level_. If, at that level, we're
dealing with array bounds checking (assuming, for the moment that
we're using a language that doesn't have that built in), then function
names like check-index, report-invalid-index-error, etc. are names
from the problem domain at that level.


I'm not sure if I understand your notion of problem-domain levels. For
instance, in a preceding example

amount_due = sum(item_prices) * (1 + tax_rate)

is the problem domain possibly "functions and their arguments", or is
the problem domain possibly "customer billing"? If the former, would
you rewrite the above expression with names in the problem domain, as in

amount_due = apply(*, apply(sum, item_prices), apply(+, 1, tax_rate)

or

amount_due = apply(apply, *,
apply(apply, sum, item_prices),
apply(apply, +, 1, tax_rate))

or

amount_due = apply(apply, apply, *,
apply(apply, apply, sum, item_prices),
apply(apply, apply, +, 1, tax_rate))

(when do I stop?)? If the latter, how would you recommend that I
(re)write the code... certainly, since the use of function application
is so pervasive in the above code, a human-readable name in the problem
domain is in order?

--
Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig
"Who needs drugs when we have sex and chocolate?" -- Cory Kerens
Jul 18 '05 #695

P: n/a
Jacek Generowicz wrote:
Yes, you use flet (or labels) if you want a local function definition,
and defun if you want a global one. Lisp caters for both
possibilities. Does Python ?


If you mean the ability to have a nested function definition
that actually defines a top-level function, then yes, it
does...

Python 2.2 (#1, Jul 11 2002, 14:19:37)
[GCC 3.0.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
def f(): .... global g
.... def g():
.... print "Urk!"
.... g() Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'g' is not defined f()
g() Urk!


Although I'm having a hard time imagining why you'd
actually *want* to do such a thing!

--
Greg Ewing, Computer Science Dept,
University of Canterbury,
Christchurch, New Zealand
http://www.cosc.canterbury.ac.nz/~greg

Jul 18 '05 #696

P: n/a
On Tue, 21 Oct 2003 20:33:23 -0700, David Eppstein
<ep******@ics.uci.edu> wrote:
I am not claiming that it is a counterexample, but I've always met
with some difficulties imagining how the usual proof of Euler's
theorem about the number of corners, sides and faces of a polihedron
(correct terminology, BTW?) could be formalized. Also, however that
could be done, I feel an unsatisfactory feeling about how complex it
would be if compared to the conceptual simplicity of the proof itself.
Which one do you think is the usual proof?
http://www.ics.uci.edu/~eppstein/junkyard/euler/


Uhmmm, let me see... 13! (no, not the factorial of 13)
Anyway, this exact example was the basis for a whole book about what is
involved in going from informal proof idea to formal proof:
http://www.ics.uci.edu/~eppstein/jun.../refs.html#Lak
D'Oh! Unfortunate choice of mine...
Michele
-- Comments should say _why_ something is being done.

Oh? My comments always say what _really_ should have happened. :)
- Tore Aursand on comp.lang.perl.misc
Jul 18 '05 #697

P: n/a
In article <52************@proper.ptq.dyndns.org>,
Ken Shan <ke*@digitas.harvard.edu> wrote:
I'm not sure if I understand your notion of problem-domain levels. For
instance, in a preceding example

amount_due = sum(item_prices) * (1 + tax_rate)

is the problem domain possibly "functions and their arguments", or is
the problem domain possibly "customer billing"?
How about simple arithmetic, which is built into most computer languages.

However, if you do this often enough in your code (i.e., compute a
total, then add the tax), you migh want to have a named function, say
"total-with-tax," instead of just reimplimenting it every time you use
it. It's simply a matter of how much of what you're doing is specific to
the larger problem, how much is just arithmetic, using built-ins, and,
probably most importantly, how often you'll be repeting yourself in
exactly the same way.

[snip] (when do I stop?)?


When you reach the built-ins of the language, of course. No need to
define a method called "add" in a language that has + as a built in
function (unless you're going to overload addition to do something that
the built-in function doesn't do yet.)

But the very telling larger picture issue is that there is such a
reluctance to name bits of code that are going to be used more than once.
Jul 18 '05 #698

P: n/a
In comp.lang.scheme Andrew Dalke <ad****@mindspring.com> wrote:
Pascal Costanza:
I don't know how this could be done with 1st, rst or hd, tl respectively.
Okay, I gave alternatives of "." and ">" instead of "car" and "cdr"
"." for "here" and ">" for "the rest; over there". These are equally
composable. . == car
> == cdr

cadr == >.
caddr == >>.
cddr == >>


One can also go like:

1st == car
rst == cdr
1rst == cadr
1rrst == caddr
rrst == cddr

The benefit being, it's less messy to quote these in Usenet :-)
Jul 18 '05 #699

P: n/a
In article <87***********@strelka.synthcode.com>,
Alex Shinn <fo**@synthcode.com> wrote:
If you are seriously arguing against the use of HOFs in
general then I think you have a lot to learn.


No, I'm not arguing against HOFs in general. I'm arguing against the
repeated use of the _same_ anonymous function throughout code. These
should clearly be named funtions instead.

But I've apparently touched a nerve, because so many FPers seem to
equate eschewing repetition of the same anonymous functional idoim in
numerous places throughout ones code, with an attack on HOF use itself.
Jul 18 '05 #700

699 Replies

This discussion thread is closed

Replies have been disabled for this discussion.