Mailing List Archive

1 2 3  View All
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
I wrote:
> > > Trying to maintain that recursive list of unclosed lists in your
> > > brain is fun. It stretches the brain in interesting ways.
> > > [ ... ] But I never found Lisp code very maintainable, [ ... ]

2QdxY4RzWzUUiLuE@potatochowder.com writes:
> "[R]ecursive list of unclosed lists"? Can you (whoever you are) expand
> on that? Yes, if you eschew helper functions and local variables, then
> you can end up with depply nested code, but that's true in any language.

To pick a function that I know is readily available in lots
of languages, let's look at a couple implementations of the
Haversine function (from http://rosettacode.org/wiki/Haversine_formula).
Comments to illustrate language differences are mine.

Here's the Common Lisp version.

(defparameter *earth-radius* 6372.8)
(defparameter *rad-conv* (/ pi 180))
;; Minor complication right off: assignment of variables or constants
;; is completely different depending on whether you're
;; defining something in general, like here, or only for
;; a subsequent clause, like the let* functions later on.

(defun deg->rad (x)
(* x *rad-conv*))
;; Prefix notation for arithmatic is unfamiliar to most people
;; since that's not what we learn in school, so that's a first
;; hurdle for readability.

(defun haversine (x)
(expt (sin (/ x 2)) 2))
;; To grok this function you need to have four levels of
;; parentheses simultaneously open in your head.

(defun dist-rad (lat1 lng1 lat2 lng2)
(let* ((hlat (haversine (- lat2 lat1)))
;; Then there's the let vs. let* issue,
;; no big deal for experienced programmers
;; but not entirely easy to explain to a beginner.
;; On the other hand, Python has its own confusing points on
;; that issue, like when you need to specify "global".
(hlng (haversine (- lng2 lng1)))
(root (sqrt (+ hlat (* (cos lat1) (cos lat2) hlng)))))
;; for that expression you need 7 levels of mental parens open
(* 2 *earth-radius* (asin root))))

(defun dist-deg (lat1 lng1 lat2 lng2)
(dist-rad (deg->rad lat1)
(deg->rad lng1)
(deg->rad lat2)
(deg->rad lng2)))

;; End Lisp example

Seven levels of unclosed lists that you need to keep in your head
in order to read and understand the program at its deepest point.

Here's the same thing in Python:

from math import radians, sin, cos, sqrt, asin

def haversine(lat1, lon1, lat2, lon2):
R = 6372.8 # Earth radius in kilometers

dLat = radians(lat2 - lat1)
dLon = radians(lon2 - lon1)
lat1 = radians(lat1)
lat2 = radians(lat2)

a = sin(dLat / 2)**2 + cos(lat1) * cos(lat2) * sin(dLon / 2)**2
c = 2 * asin(sqrt(a))

return R * c

# end Python example

The equation is still the same equation, but it looks a lot more
like the equation you'd see in a math textbook, or write on a
homework assignment, modulo notational issues like ** instead of
superscripts. The deepest level of parentheses you ever need to
keep in your head is two, but the second level is just a very
simple function call, sqrt(a). The indentation level (the program
structure) never gets beyond one.

On the other hand, your brain does need to keep track of more
intermediate variables (dLat, dLon etc.) Perhaps some people might
find that harder.

And yes, you could write the Lisp to look more like the Python or
vice versa. You're welcome to try that, but I predict you'll find that
even if you use the same number of intermediate variables, Lisp will
always require you to keep that larger mental stack of open parens.

> Because of Lisp's simple syntax, text editors can nearly completely
> relieve the programmer from the tedium of indenting and formatting, and
> even closing parenthesis, which also highlights missing/extra/unbalanced
> parentheses pretty quickly.

I find that emacs mostly does a pretty good job of figuring out
indentation, closing parentheses, highlighting syntax errors and
similar boilerplate in Python. Maybe you need a smarter text editor?

But my comment about levels of parens had nothing to do with editors.
To understand the code, you need to build up that list/tree
structure in your head, because that's what defines the program logic.

Again, my point isn't that Python is a better or simpler language
than Lisp. It's that it stretches the brain in different ways, and that
I would guess (but it's just a guess) that most beginners will find
the Python approach more intuitive and easier to learn, since it
emphasizes things they've done before (simple declarative statements,
equations written out in a familiar way) rather than new and unfamiliar
concepts (prefix notation, deeply nested parentheses, tree structures).

...Akkana
--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
On 2020-08-07 at 17:55:45 +0200,
Marco Sulla <Marco.Sulla.Python@gmail.com> wrote:

> On Fri, 7 Aug 2020 at 17:14, Christian Seberino <cseberino@gmail.com> wrote:

> Commonly, in imperative languages like C, you can write
>
> if (a = b) {...}
>
> This is allowed in C, even if a = b is not an expression ...

In C, a = b *is* an expression. An assignment expression that uses the
assignment operator. See
<https://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B>.

> ... 99% of times you simply wrong and wanted:

> if (a == b)

Where did 99% come from?

> Python separates statements and expressions, so where you expect an
> expression, you can't write a statement.

Yes.

> Maybe Lisp does not separate expressions and statements because it
> supports both functional and imperative programming ...

It's not a matter of separating expressions from statements. Lisp
doesn't have statements. It only has expressions. If you choose to
write imperative code in Lisp, all you're really doing is using the
expressions for their side effects rather than their values.

> PS: Recently there's an exception: if you *really* want an assignment
> when an expression is expected, you can use the "walrus" := operator.
> IMO it renders the code less readable and I'm not sure about it's
> usefulness.

It makes some code more concise. Readability is in the eye of the
beholder.

> @Chris: note that "real" recursion in Python is not possible, since
> there's no support for tail recursion. Maybe something similar can be
> done using async functions.

Python has real recursion. Whether or not there's tail recursion on the
inside is an implementation detail.
--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
On 8/7/20 11:55 AM, Marco Sulla wrote:
> Commonly, in imperative languages like C, you can write
>
> if (a = b) {...}
>
> This is allowed in C, even if a = b is not an expression, but an
> assignment statement. 99% of times you simply wrong and wanted:

But in C (and related languages) it IS an expression, and C doesn't have
an 'assignment statement' but an 'expression statement', which is the
source of the issue. = is just another operator, which happens to modify
the value of its left operand.

Python makes assignment a full top level type of statement, so = can't
be misused in an expression thinking it means an equality test (and then
added recently the := operator, so that for the cases you actually want
to do assignments in the middle of an expression you can).

--
Richard Damon

--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
On 8/7/20 11:46 AM, Chris Angelico wrote:
> My point is that doing Fibonacci recursively is arguably more elegant
> while being materially worse at performance, but there are other
> examples that are fundamentally recursive, are just as elegant (merge
> sort: "fracture the array in half, sort each half, then merge them"),
> and can't be done better iteratively. So IMO Fibonacci is a flawed
> demonstration of what is a very valid point ("recursion can be really
> elegant"), and other examples would serve the purpose better.

I would say that doing the recursive Fibonacci version can be an
important step (near the end) of the recursion unit as a learning
experience on some of the dangers of recursion (like turning an O(N)
problem into O(2**N). It perhaps can lead to discussions on optimization
techniques (like caching results) that can alleviate some of the issues
(at other costs).

--
Richard Damon

--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
On Sat, Aug 8, 2020 at 2:21 AM <2QdxY4RzWzUUiLuE@potatochowder.com> wrote:
>
> On 2020-08-07 at 17:55:45 +0200,
> Marco Sulla <Marco.Sulla.Python@gmail.com> wrote:
> > @Chris: note that "real" recursion in Python is not possible, since
> > there's no support for tail recursion. Maybe something similar can be
> > done using async functions.
>
> Python has real recursion. Whether or not there's tail recursion on the
> inside is an implementation detail.

More specifically: Python has real recursion. Whether or not tail
recursion is optimized away is an implementation detail.

Tail call optimization (there's no reason to restrict it to recursion
alone) is something a Python implementation could choose to do, but
the trouble is that full optimization tends to destroy traceback
information, so it's often not worth doing. And the cases where
partial optimization is of value just aren't compelling enough for
anyone to implement it into CPython, nor any other major
implementation (to my knowledge). The biggest uses for TCO tend to be
the situations where recursion is the wrong solution to the problem.

But recursion? Recursion is definitely possible.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
On Sat, Aug 8, 2020 at 2:44 AM Richard Damon <Richard@damon-family.org> wrote:
>
> On 8/7/20 11:46 AM, Chris Angelico wrote:
> > My point is that doing Fibonacci recursively is arguably more elegant
> > while being materially worse at performance, but there are other
> > examples that are fundamentally recursive, are just as elegant (merge
> > sort: "fracture the array in half, sort each half, then merge them"),
> > and can't be done better iteratively. So IMO Fibonacci is a flawed
> > demonstration of what is a very valid point ("recursion can be really
> > elegant"), and other examples would serve the purpose better.
>
> I would say that doing the recursive Fibonacci version can be an
> important step (near the end) of the recursion unit as a learning
> experience on some of the dangers of recursion (like turning an O(N)
> problem into O(2**N). It perhaps can lead to discussions on optimization
> techniques (like caching results) that can alleviate some of the issues
> (at other costs).

Yes, I'd definitely agree. It's great to have some demonstrations of
the advantages and disadvantages of recursion, and Fibonacci offers
both in one tidy package :)

Here's another really great example: triangle numbers.

def tri(n):
if n < 1: return 0
return n + tri(n - 1)

def tri(n):
tot = n
for i in range(n):
tot += i
return tot

def tri(n):
return functools.reduce(operator.add, range(n + 1))

def tri(n):
return n * (n + 1) // 2

A great demo of different ways to think about the same problem, with a
nice O(1) reference at the end that you can validate them against :)

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
About statement vs expression: maybe you, Richard and
2QdxY4RzWzUUiLuE, are right, maybe not. This is hard to say, since the
official C documentation is not public and you have to pay a small fee
to obtain it.

Anyway, I said "in C, the assignment is a statement that can be used
in expression". You're saying "No, in C the assignment IS an
expression".
I don't see the difference. If the assignment is a statement that can
be used as an expression, Python simply forbids that. If in C the
assignment is an expression, Python on the contrary treats it as a
statement.

The only real difference is that Python not only clearly separated the
concepts of statement and expression, but also _where_ you can use
them, for practical reasons.
--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
On Fri, 7 Aug 2020 at 18:48, Chris Angelico <rosuav@gmail.com> wrote:
> Tail call optimization (there's no reason to restrict it to recursion
> alone) is something a Python implementation could choose to do, but
> the trouble is that full optimization tends to destroy traceback
> information

Indeed this is implemented in asyncio.
--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
Your iterative fib(x) code and comment was quite nice.
--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
> Another point to consider is the ecosystem of your language. If you
> install Python, then you get basic math, I/O, a GUI toolkit, network
> libraries, ... In more "traditional" languages like C or Lisp, you get
> math and I/O, period. For everything else you need to hunt down a
> library. Therefore, solve the task "download the gimp installer from
> github via https" requires 2,3 lines in Python and installing a
> (possibly complex) library for the same task in Lisp or C.
>
> Christian

I like this post so much I printed it. It seems you're saying
Python has lots of syntax forms or "mini-languages" in it and *that* is a big
reason why you can typically find syntax that makes an arbitrary
problem more readable in Python. On the other hand, Lisp tries
to everything with less syntax forms (paradigms) and hence it is less readable.

A Lisp person would probably say that they can create domain specific
languages (DSLs) for whatever they wish. However, many people like
that Python has so many standardized "DSLs" ready to go for you from
the start.

I think this is really significant point why more syntax does necessarily mean less readability.

I would just add that Clojure finally solved the ecosystem problem with
Lisp by giving it access to the Java libraries.

cs

--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
On 8/7/20 12:52 PM, Marco Sulla wrote:
> About statement vs expression: maybe you, Richard and
> 2QdxY4RzWzUUiLuE, are right, maybe not. This is hard to say, since the
> official C documentation is not public and you have to pay a small fee
> to obtain it.
>
> Anyway, I said "in C, the assignment is a statement that can be used
> in expression". You're saying "No, in C the assignment IS an
> expression".
> I don't see the difference. If the assignment is a statement that can
> be used as an expression, Python simply forbids that. If in C the
> assignment is an expression, Python on the contrary treats it as a
> statement.
>
> The only real difference is that Python not only clearly separated the
> concepts of statement and expression, but also _where_ you can use
> them, for practical reasons.

The difference is that the two languages define 'expression' differently.

In Python, the = operation is not part of the general expression syntax,
but is specifically allowed only in specific locations.

In C, the = operator is exactly like all the other operators in how it
is parsed, it just has some restrictions on the type that can be on the
left side, and that it changes that value (but then, so do a few other
operators like ++)

In C, there is NO 'statement' called an assignment statement, because
assignments are just parts of expressions, so the statement type
'expression statement' handles both.

In Python, because assignment is NOT just part of an expression, it
needs a separate statement type to handle assignments, to allow them.


(BTW, while the official C Standards are only available at a price, the
draft standards prepared during the development of the final are all
available for free and the last published draft standard is almost
always virtually identical to the final released standard, so most
people will just use those. People who really need the official versions
can pay the price for it, and for them, that price isn't that high to
them). I keep the free downloads of all the major version of the C and
C++ language available on my computer.

--
Richard Damon

--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
On 2020-08-07 at 10:00:25 -0600,
Akkana Peck <akkana@shallowsky.com> wrote:

> I wrote:
> > > > Trying to maintain that recursive list of unclosed lists in your
> > > > brain is fun. It stretches the brain in interesting ways.
> > > > [ ... ] But I never found Lisp code very maintainable, [ ... ]
>
> 2QdxY4RzWzUUiLuE@potatochowder.com writes:
> > "[R]ecursive list of unclosed lists"? Can you (whoever you are) expand
> > on that? Yes, if you eschew helper functions and local variables, then
> > you can end up with depply nested code, but that's true in any language.
>
> To pick a function that I know is readily available in lots
> of languages, let's look at a couple implementations of the
> Haversine function (from http://rosettacode.org/wiki/Haversine_formula).
> Comments to illustrate language differences are mine.
>
> Here's the Common Lisp version.
>
> (defparameter *earth-radius* 6372.8)
> (defparameter *rad-conv* (/ pi 180))
> ;; Minor complication right off: assignment of variables or constants
> ;; is completely different depending on whether you're
> ;; defining something in general, like here, or only for
> ;; a subsequent clause, like the let* functions later on.
>
> (defun deg->rad (x)
> (* x *rad-conv*))
> ;; Prefix notation for arithmatic is unfamiliar to most people
> ;; since that's not what we learn in school, so that's a first
> ;; hurdle for readability.

My first calculator was RPN, so prefix wasn't really a hurdle. ;-)

> (defun haversine (x)
> (expt (sin (/ x 2)) 2))
> ;; To grok this function you need to have four levels of
> ;; parentheses simultaneously open in your head.
>
> (defun dist-rad (lat1 lng1 lat2 lng2)
> (let* ((hlat (haversine (- lat2 lat1)))
> ;; Then there's the let vs. let* issue,
> ;; no big deal for experienced programmers
> ;; but not entirely easy to explain to a beginner.
> ;; On the other hand, Python has its own confusing points on
> ;; that issue, like when you need to specify "global".
> (hlng (haversine (- lng2 lng1)))
> (root (sqrt (+ hlat (* (cos lat1) (cos lat2) hlng)))))
> ;; for that expression you need 7 levels of mental parens open
> (* 2 *earth-radius* (asin root))))
>
> (defun dist-deg (lat1 lng1 lat2 lng2)
> (dist-rad (deg->rad lat1)
> (deg->rad lng1)
> (deg->rad lat2)
> (deg->rad lng2)))
>
> ;; End Lisp example
>
> Seven levels of unclosed lists that you need to keep in your head
> in order to read and understand the program at its deepest point.

Seven? Oh, there it is, inside the calculation of root in dist-rad.

> Here's the same thing in Python:

It's equivalent. It's not the same. (For example, in Lisp, the
parameters are clearly marked as such by the form defparameter, but in
Python, the parameters and the temporary variables are created with the
same syntax. When I read the Python code, how can I tell that R is a
parameter rather than a temporary variable? But that's not related to
the question of open parentheses. Also, the Lisp example separates the
conversion to radians into a helper function, but the Python version
doesn't.)

> from math import radians, sin, cos, sqrt, asin
>
> def haversine(lat1, lon1, lat2, lon2):
> R = 6372.8 # Earth radius in kilometers
>
> dLat = radians(lat2 - lat1)
> dLon = radians(lon2 - lon1)
> lat1 = radians(lat1)
> lat2 = radians(lat2)
>
> a = sin(dLat / 2)**2 + cos(lat1) * cos(lat2) * sin(dLon / 2)**2
> c = 2 * asin(sqrt(a))
>
> return R * c
>
> # end Python example
>
> The equation is still the same equation, but it looks a lot more
> like the equation you'd see in a math textbook, or write on a
> homework assignment, modulo notational issues like ** instead of
> superscripts. The deepest level of parentheses you ever need to
> keep in your head is two, but the second level is just a very
> simple function call, sqrt(a). The indentation level (the program
> structure) never gets beyond one.
>
> On the other hand, your brain does need to keep track of more
> intermediate variables (dLat, dLon etc.) Perhaps some people might
> find that harder.

On the other other hand, there's no confusing operator precedence rules
in Lisp. We know the basic arithmetic operators from grade school, but
who can remember whether & or and bind more tightly than or and | (sic)?
Instead of memory, some programmers use *parentheses* to *clarify*. ;-)

> And yes, you could write the Lisp to look more like the Python or
> vice versa. You're welcome to try that, but I predict you'll find that
> even if you use the same number of intermediate variables, Lisp will
> always require you to keep that larger mental stack of open parens.

A larger stack of *parentheses*, yes, but I don't think a larger stack.

Python: def f(x):
y = b + m * x
return y

Lisp: (defun f (x)
(let ((y (+ b (* m x))))
y))

A function definition, a temporary variable, the familiar "point slope"
artithmetic, and the result of the calculation/function. Now that I've
seen enough Lisp, the parentheses disappear into the whitespace.

> > Because of Lisp's simple syntax, text editors can nearly completely
> > relieve the programmer from the tedium of indenting and formatting, and
> > even closing parenthesis, which also highlights missing/extra/unbalanced
> > parentheses pretty quickly.
>
> I find that emacs mostly does a pretty good job of figuring out
> indentation, closing parentheses, highlighting syntax errors and
> similar boilerplate in Python. Maybe you need a smarter text editor?

Emacs... emacs... emacs... Oh, yeah! Emacs! I used to edit my own
config.h file, before the great emacs/xemacs schism (and I'm using a
more modern version to compose this email). ;-)

> But my comment about levels of parens had nothing to do with editors.
> To understand the code, you need to build up that list/tree
> structure in your head, because that's what defines the program logic.
>
> Again, my point isn't that Python is a better or simpler language
> than Lisp. It's that it stretches the brain in different ways, and that
> I would guess (but it's just a guess) that most beginners will find
> the Python approach more intuitive and easier to learn, since it
> emphasizes things they've done before (simple declarative statements,
> equations written out in a familiar way) rather than new and unfamiliar
> concepts (prefix notation, deeply nested parentheses, tree structures).

Aha. I think.

In Python, different levels of logical nesting use different physical
representations. Indentation, parentheses, operators (and operator
precedence), keywords, colons. But in Lisp, the only tool you have is
parentheses (humans use whitespace sometimes, but the compiler ignores
it). The differences are likely real, and perhaps moreso to beginners,
but if the nesting is too deep, in either case, refactor, and everyone
has their own definition of "too deep."

For completeness, let's not forget Greenspun's Tenth (which really isn't
about the syntax) and Lisp's loop macro (which *is* entirely all about
the syntax). ;-)
--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
> In Lisp, your hammer is the list.

> In, say, Java, your tool is classes and inheritance.

And yet if Lisp or Java programmers were here they would say their
languages //are// multi-paradigm too. For example, Lisp has the
Common Lisp Object System (CLOS) and Java has the Vector class and so on.

Maybe Python somehow gives more paradigms //better// syntax support
whereas in Lisp and Java they are somewhat "bolted on" and not done
as well?

cs
--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
> It's also probably significantly slower, so you'd likely still want to
> use the iterative version

Generalizing this to the majority of recursive functions/methods, are their
iterative counterparts more efficient? (I say "majority of" because I've
personally encountered one or two recursive functions/methods that were
either very difficult for me to translate to iteration or just not possible
with my skill level at the time)

> It is related to the old saying "If all you have is a hammer, then
> everything looks like a nail".

Using this saying in the context of programming languages is extremely
accurate! Because Python can be object oriented or data oriented, it is a
large toolbox capable of tackling an even larger set of problems quite
simply.

I've never personally used Lisp, but I have used Java a bit. Even just the
strict object-oriented nature of Java was fairly cumbersome. The freedom,
fluidity, and the dynamic nature of Python are the reasons it's my
preferred language.

For just a moment, allow me to abstract this argument to include languages
other than Lisp I'm better versed in. Older languages, like Java and C,
required explicit typing for their variables, explicit output types for
their methods, and semicolons and brackets instead of utilized whitespace.
Please correct me if I'm wrong, but this system was primarily for saving
memory because computers were far less powerful when these languages were
born. Python, being a relatively young language, is free from these
shackles and was built to run on more modern computers where bits and bytes
are not a common constraint.

That said, if I were to ever design a software I planned on sharing, I
would write it in one of the more space-friendly languages.

Thank y'all for the great reading about Lisp vs Python and letting me get
very off-topic.

Best,
Wyatt Biggs
--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
On Fri, 7 Aug 2020 at 19:48, Richard Damon <Richard@damon-family.org> wrote:
> The difference is that the two languages define 'expression' differently. [...]

I don't know if this is interesting or pertinent to the topic.

Christian Seberino just expressed a doubt about how a clear separation
between a statement and an expression is quite desiderable in the
"real" programming world. And I tried to explain it with the
assignment operation, since a ton of programmers feel very frustrated
about reading code of other programmers with assignment in an if
statement. I'm quite sure that they thought, as I thought: "What do
this?"
Worse when their program failed and they discovered that they wrote
`if (a=b)` instead of `if (a==b)`.

I'm just more curious about why Lisp programmers think that it's
better to not make a hard distinction between statements and
expressions.
--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
On 2020-08-07 at 11:02:50 -0700,
Christian Seberino <cseberino@gmail.com> wrote:

> > In Lisp, your hammer is the list.
>
> > In, say, Java, your tool is classes and inheritance.
>
> And yet if Lisp or Java programmers were here they would say their
> languages //are// multi-paradigm too. For example, Lisp has the
> Common Lisp Object System (CLOS) and Java has the Vector class and so on.

Of what is "Java has the Vector class" an example? That the tools in
Java are classes and inheritance?
--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
On 8/7/2020 11:46 AM, Chris Angelico wrote:

> My point is that doing Fibonacci recursively is arguably more elegant
> while being materially worse at performance.

This is a common misconception. Linear iteration and tail recursion are
equivalent. The issue is calculating values once versus multiple times.
Here is the fast recursion equivalent to the fast iteration.

def fib(n, pair=(1,0)):
previous, current = pair
if n:
return fib(n-1, (current, previous + current))
else:
return current

for i in range(10): print(fib(i), end=' ')
# 0 1 1 2 3 5 8 13 21 34

One can also do the slow algorithm, with wasteful duplication,
iteratively with one or two stacks of values instead of the hidden stack
of execution frames. I don't remember the details right now without
checking a text.

--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
On 2020-08-07 at 21:54:35 +0200,
Marco Sulla <Marco.Sulla.Python@gmail.com> wrote:

> On Fri, 7 Aug 2020 at 19:48, Richard Damon <Richard@damon-family.org> wrote:

> Christian Seberino just expressed a doubt about how a clear separation
> between a statement and an expression is quite desiderable in the
> "real" programming world. And I tried to explain it with the
> assignment operation, since a ton of programmers feel very frustrated
> about reading code of other programmers with assignment in an if
> statement. I'm quite sure that they thought, as I thought: "What do
> this?"
> Worse when their program failed and they discovered that they wrote
> `if (a=b)` instead of `if (a==b)`.

Don't conflate the concept with the syntax. The fact that Python now
has "the walrus operator" says that assignment expressions are useful.
The issue with the C version is that the assignment and comparison
operators look too much alike and using the wrong one can cause *silent*
catastrophes (although modern C compilers can and do emit appropriate
warnings or errors, if you ask them nicely).

> I'm just more curious about why Lisp programmers think that it's
> better to not make a hard distinction between statements and
> expressions.

Simplicity of syntax. Very few languages have a simpler syntax than
Lisp (Ook, et al, notwithstanding).
--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
On 2020-08-07 at 13:43:06 -0500,
Wyatt Biggs <wyatt.biggs@gmail.com> wrote:

> > It's also probably significantly slower, so you'd likely still want to
> > use the iterative version
>
> Generalizing this to the majority of recursive functions/methods, are
> their iterative counterparts more efficient? (I say "majority of"
> because I've personally encountered one or two recursive
> functions/methods that were either very difficult for me to translate
> to iteration or just not possible with my skill level at the time)

As usual, it depends. :-)

Often, a recursive algorithn in the *source* code is rewritten/optimized
by a compiler into an iterative algorithm in the *object* code. And
sometimes, iterative code is rewritten into straight line imperative
code (i.e., loop unrolling, constant folding, etc.). At runtime, that
stack of pending items has to be somewhere, and the hardware stack
(where the CPU-level return addresses are stored) can be as good a place
as any, which means that the recursive version *might* be as fast or
faster than the iterative version, under certain circunstances.

> For just a moment, allow me to abstract this argument to include
> languages other than Lisp I'm better versed in. Older languages, like
> Java and C, required explicit typing for their variables, explicit
> output types for their methods, and semicolons and brackets instead of
> utilized whitespace. Please correct me if I'm wrong, but this system
> was primarily for saving memory because computers were far less
> powerful when these languages were born. Python, being a relatively
> young language, is free from these shackles and was built to run on
> more modern computers where bits and bytes are not a common
> constraint.

Lisp is older than both C and Java (by decades), and there's still no
explicit typing for variables. In Lisp, the data has a type, and the
"variables" are just names for it (just like Python, or rather Python is
just like Lisp).

> That said, if I were to ever design a software I planned on sharing, I
> would write it in one of the more space-friendly languages.

Space-friendly?
--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
On Fri, 7 Aug 2020 at 19:41, Christian Seberino <cseberino@gmail.com> wrote:
> I think this is really significant point why more syntax does necessarily mean less readability.

I don't think so. Readability of programming languages was measured
using an objective method, and Python was one of the most readable.

The fact that a grammar is simpler does not mean it's more readable
for human beings. It's surely most simple to optimize for compilers.
For example, RISC instructions in CPUs were simpler than CISC. Even if
Intel tried to defend CISC, modern Intel CPUs have reduced their set
of instructions a lot. Furthermore, the majority of smartphone CPUs
are ARM, that have RISC instructions.
Think also about NAND. You can express the whole boolean logic using
only NAND or NOR. In the beginning, only the Military and NASA
constructed electrical circuits only with NAND or NOR gates. Now there
are electronic circuits made for common people, using only or mainly
NAND gates: they are, for example, pen cards and SSD drives.

But they are not simpler to understand. For example, in math you
*could* think a*b as a+a done b times. But what if a and b are
imaginary numbers?

There are many programmers that just feel Python much more simple to
read and use. Google can tell you a lot about this. Also Rosetta code
can show it to you clearly:
http://www.rosettacode.org/wiki/Rosetta_Code

It seems to me that you want to convince your colleagues that Python
is better than Lisp. I think that:

1. there's not a "best". The "best" depends heavily on what you need.
2. the people you have to convince is only yourselves
3. to convince yourselves, you have to try. "Refuse the temptation to guess" :)
--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
On Fri, 7 Aug 2020 at 22:35, Terry Reedy <tjreedy@udel.edu> wrote:
> This is a common misconception. Linear iteration and tail recursion are
> equivalent. The issue is calculating values once versus multiple times.
> Here is the fast recursion equivalent to the fast iteration.
>
> def fib(n, pair=(1,0)):
> previous, current = pair
> if n:
> return fib(n-1, (current, previous + current))
> else:
> return current
>
> for i in range(10): print(fib(i), end=' ')
> # 0 1 1 2 3 5 8 13 21 34

It seems to me a sort of not persistent caching. If you do:

fib(very_large_number)

without calculating any previous Fibonacci number before, it will be
very slow and you could have a stack overflow.

A language with tail call optimization will execute it faster and with
less memory. Otherwise why asyncio de-facto implemented tail
optimization?

PS: it seems there's a module that implement tail call:
https://github.com/baruchel/tco
--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
On Sat, Aug 8, 2020 at 6:34 AM Terry Reedy <tjreedy@udel.edu> wrote:
>
> On 8/7/2020 11:46 AM, Chris Angelico wrote:
>
> > My point is that doing Fibonacci recursively is arguably more elegant
> > while being materially worse at performance.
>
> This is a common misconception. Linear iteration and tail recursion are
> equivalent. The issue is calculating values once versus multiple times.
> Here is the fast recursion equivalent to the fast iteration.
>
> def fib(n, pair=(1,0)):
> previous, current = pair
> if n:
> return fib(n-1, (current, previous + current))
> else:
> return current
>
> for i in range(10): print(fib(i), end=' ')
> # 0 1 1 2 3 5 8 13 21 34
>
> One can also do the slow algorithm, with wasteful duplication,
> iteratively with one or two stacks of values instead of the hidden stack
> of execution frames. I don't remember the details right now without
> checking a text.

I'm aware you can do recursion iteratively and iteration recursively,
but why WOULD you ever do this? The version you've shown here isn't
any more elegant than the purely iterative version, and all it's doing
is implementing a for loop using recursive calls. (Also, it has one
thing that rankles with me, and that's a function signature that is
intentionally different for the recursive calls as for the main call.
You should *never* pass the 'pair' parameter on the initial call, and
it will *always* be passed on the recursive calls.) The idiomatic
recursive version is not tail recursive. Same with the idiomatic
recursive merge sort, which does forking recursion and then tail-calls
the merge operation. (Or you can implement the merge inline, but
whenever I'm explaining it, I prefer to write merge() as a separate
function.)

Knowing how to translate recursion into iteration and vice versa is a
useful skill (picture this: you're trying to build some actual coded
logic into an alias expansion system, where the only conditional you
have is "execute this file" with text substitution in the file name,
and the only looping you have is to re-execute the same file), but
it's not the way to show off the beauty of recursion.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
On 8/7/20 4:08 PM, Terry Reedy wrote:
> On 8/7/2020 11:46 AM, Chris Angelico wrote:
>
>> My point is that doing Fibonacci recursively is arguably more elegant
>> while being materially worse at performance.
>
> This is a common misconception.  Linear iteration and tail recursion
> are equivalent.  The issue is calculating values once versus multiple
> times.  Here is the fast recursion equivalent to the fast iteration.
>
> def fib(n, pair=(1,0)):
>    previous, current = pair
>    if n:
>       return fib(n-1, (current, previous + current))
>    else:
>       return current
>
> for i in range(10): print(fib(i), end=' ')
> # 0 1 1 2 3 5 8 13 21 34
>
> One can also do the slow algorithm, with wasteful duplication,
> iteratively with one or two stacks of values instead of the hidden
> stack of execution frames.  I don't remember the details right now
> without checking a text.
>
But your example breaks the 'problem' in the recursion that Fibonacci,
when expressed 'naturally', the current value is based on two different
earlier values. You have morphed the definition, using basically the
iterative solution, so that the recursive call to fir(0, ...) doesn't
actually calculate the fib(0) value, but fib(n).

Yes, this shows that you can convert an iterative solution into a
recursive solution with a bit of hand waving, but you still end up with
a program based on the iterative algorithm, not the possibly natural
recursive one.

--
Richard Damon

--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
On Sat, Aug 08, 2020 at 01:46:28AM +1000, Chris Angelico wrote:
> On Sat, Aug 8, 2020 at 1:38 AM Python <python@bladeshadow.org> wrote:
> TBH most people won't get the recursive version right the first time
> either.

So FWIW, I/my team don't find this to be true. I was originally going
to mention this in my previous post but decided to leave it out
for brevity (and in part because I assumed anyone familiar with the
problem already expected it was so).

In fact my team frequently uses Fibonacci as an interview question.
We've been doing so for at least a decade, so we do have a
not-insubstantial sample size. We find that candidates can much more
easily implement the recursive version correctly, and do so on the
first try roughly 70-80% of the time. Nearly all candidates choose to
implement the recursive version for that reason. Those that don't are
pretty familiar with the problem, and choose the iterative version so
they can "show off" their knowledge of the performance benefits. They
typically also implement the recursive version immediately after,
because it's pretty trivial to do it in most programming languages,
and because they assume the point of the question is to ascertain
whether they grok recursion. Which is partly true, but only
partly--we use it because it is a short problem that can be quickly
implemented, and demonstrates a few different interesting concepts,
one of which is recursion.

When we do use it, we always follow up with "Can you implement this
iteratively?" (assuming they didn't already). A small percentage
insist that it is impossible. Most who try (again, roughly 70-80%)
fail on the first try. Figuring out how to correctly prime the state
is pretty much invariably the sticking point.

These are not students, they are experienced programmers. This may
explain why they usually can easily implement the recursive version,
but it does not really address why most of them have trouble with the
iterative version. :)

--
https://mail.python.org/mailman/listinfo/python-list
Re: How explain why Python is easier/nicer than Lisp which has a simpler grammar/syntax? [ In reply to ]
On 8/7/2020 11:55 AM, Marco Sulla wrote:

> @Chris: note that "real" recursion in Python is not possible,

This is backwards. Python only does real recursion when one writes
recursive calls.

> since there's no support for tail recursion.

I am pretty sure that what you mean by 'support' is to turn tail
recursive syntax into iteration, making it fake recursion.


--
Terry Jan Reedy

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

1 2 3  View All