I discovered a new Python library "you must not miss" from a youtuber. At first sight, everything looks awesome. Reading icecream's README sparks a lot of joy.
"Python is ingesting all cool Lisp features"
ic() is like print(), but better:
- It prints both expressions/variable names and their values.
that is, printing ic(foo(123))
gives us
ic| foo(123): 456
which is both the expression we wanted to print, and the result.
=> it's like a logging library, like Lisp's log4cl
, and that's cool.
It's 60% faster to type.
OK, minor point and not relevant for a lisper, but cool.
Data structures are pretty printed.
OK, like log:info
or the Lisp printer in general, and that's cool.
Output is syntax highlighted.
I didn't see that in Lisp land, so Python is more powerful than lisp or what?!
It optionally includes program context: filename, line number, and parent function.
OK, that's like a logging library, but that's nice.
and:
ic() returns its argument(s), so ic() can easily be inserted into pre-existing code.
so foo(ic(bar))
prints the result of bar
and returns it so it can be used in foo
.
That's just like Lisp's print
and that's cool for Python.
Add the walrus operator and Python looks more and more like Lisp, isn't it?
Installation and global use
They say:
To make ic() available in every file without needing to be imported in every file, you can install() it. For example, in a root A.py:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from icecream import install
install()
install() adds ic() to the builtins module, which is shared amongst all files imported by the interpreter. Similarly, ic() can later be uninstall()ed, too.
This is not common and requires a bit of ceremony, but it is cool, and the result looks like Common Lisp: given we loaded a library in our image, we can use it wherever we want.
"IceCream in Other Languages"
At the end is a list of languages that support the icecream print style: Go, Rust, PHP, C++, Node.js, Ruby, Java, ClojureScript… and, of course, no Common Lisp. So "Common Lisp isn't a popular language and certainly not something you'll want to use if it doesn't have such popular libraries", right? I asked myself this many times when looking at other libraries, when evaluating CL.
Cherry on the cake, icecream is available for Python 2.7 and onwards.
Until now, everything's great
Unfortunately, details matter. We can't judge until we tried. There's a list of open issues.
My favourite one, it doesn't work in Python's REPL, nor in a packaged application (but that isn't Python's strength):
ic| Error: Failed to access the underlying source code for analysis. Was ic() invoked in a REPL (e.g. from the command line), a frozen application (e.g. packaged with PyInstaller), or did the underlying source code change during execution?
Releases can break, including when it isn't the maintainers' fault (python 2.7 builds are broken).
The first call can take "a significant amount of time" to complete in game environments and "especially in debug mode".
The default colors annoy or handicap people.
It doesn't work well with Python's debugger: you can step over ic
calls with n
, but continuing with c
might fail.
Some issues are unanswered.
Of course, none of that has ever been an issue with print
and log
in CL.
Final words
This is a good illustration of Python VS Common Lisp. Python looks
nice, Python is trendy, Python is easy to use… until it isn't, and it
can fail pretty quickly.
Of course Common Lisp has shortcomings, but my personal main
difficulty with it was getting started and finding my way. Since
then, I don't stumble on silly limitations, breakages, etc. I feel
like everything I add to my toolbet is rock solid and future-proof.
That was an invitation to read big claims more carefully and to
evaluate the Lisp world with a different eye.
My bigger Python VS Common Lisp comparison is here: https://lisp-journey.gitlab.io/pythonvslisp/
WDYT, am I fair here?
Top comments (1)
Looks pretty cool. Thanks for sharing!