The evolution of a Scheme programmer (2020)
erkin.party
erkin.party
Surely there is a lazier implementation than a define and 2x lambdas to use a library function. Although I did get a chuckle about not feeling a need to add brackets to the Scheme example.
prod(1:63)
For bigger numbers, factorial(n) = 1:n .|> BigInt |> prodhttps://people.eecs.berkeley.edu/~fateman/papers/factorial.p...
Also: It's more fun to use the name `fact` in benchmarks...
B&W ()
B&W and optional bold ()
B&W and optional bold/larger ()
Full color rainbow parentheses.
B&W ()
One or two of the Lisp editors I use also support rainbow parentheses, but after an initial phase of experimentation, I have disabled that feature.
Lisp is by far my favorite language but if I had to write it with a "dumb" text editor it would quickly stop being my favorite. Most editors are smart these days, and this is why it's hard to explain to newbies that the parens don't get in your way: When you build lisp code your editor manages the parens for you and they become essentially invisible. So color solves a problem that doesn't exist (for me).
Rainbow colors are extremely distracting and overloading to me.
Scheme as a language and from a clean/simplicity point of view has always appealed to me, but I have mostly used Common Lisp because I have so much legacy code.
let factorial n = [1..n] |> List.reduce (*)
> There should be one-- and preferably only one --obvious way to do it.
> Although that way may not be obvious at first unless you're Dutch.
def factorial(n):
result = 1
for i in range(2, n + 1):
result *= i
return result
The recursive version would be fine as well, but I would say it's less idiomatic in Python, and less efficient.def factorial(n):
if n == 0 or n == 1:
return 1
else:
return n * factorial(n - 1)
Beyond that, I cannot think of any obvious way to do this (without getting unreasonably convoluted).In my opinion, it's great that there are such few options to express this operation, and that both cases are eminently readable.
There are lots of ways to do this in Python. That's not only fine, it's inevitable.
Here's a burnt-out PhD level one using highly pythonic paradigms:
def fac(n):
return eval("*".join(str(1+a) for a in range(n))Of course there are more ways, but I would definitely qualify this as "unreasonably convoluted".
Again I ask, considered by who? This is the kind of language that wikipedians would call "weasel words". Of course you shouldn't misuse eval or goto, and it's fine to have a rule of thumb to discourage it.
What's not fine, and strikes me as no better than superstition, is to make vague "everybody knows"-type statements that convey almost no information. If it's bad you should be able to say (or provide reference to) specifically how it's bad and what convinced you this was the case.
And yes, I deliberately wrote a perverse function because it was funny, but if you did a real fold instead of my fake one with strings then it wouldn't be so perverse. And wasn't it more pythonic to use a generator?
Not embracing Perl's tmtowtdi is fine, but until you solve the halting problem some people will write "x+x" and some will write "2*x" and some will write "x<<2" and those can't sensibly be unified.
Your idiomatic Python version uses three variables, two of which mutate. I'm a simple man - go easy on me please! The `n + 1` took me a while to figure out too.
This is exactly why I asked the question!
from math import prod # from Python 3.8 onwards
def factorial(n):
return prod(range(n+1)) return prod(1,range(n+1))Edit: prod(range(1, n+1)) does work