If your write an object system on top of your performant hobby Scheme implementation, you'll likely find that the performance of its method dispatch is about as slow as it is in Python. Probably even slower.
Purely procedural Python code isn't as slow as object-oriented Python code.
The Python ecosystem has certainly received a lot of developer resources and attention the past couple of decades. Shall we compare the performance of CLOS on SBCL, which again has seen comparatively little developer resources, to Python's performance in dealing with objects? I'd take that performance wager.
I'm thinking CLOS has more dynamism than Python - they're both dynamically typed, they're both doing a lookup then dispatch, but then CLOS adds dynamism on top of that, it's also looking in the metadata thingy (i'm not a lisp developer, do they call it the hash? I'm meaning the key value store on every "atom" - i'm so out of my depth here, is atom the right word?) plus if i remember right the way CLOS works you use multiple dispatch not just single dispatch like python.
I like python (especially things like comprehensions), but to say it's more dynamic than common lisp is a little insane.
If I recall correctly, method calls in CLOS are also not syntactically distinguished from regular calls either (like they are in x.f() languages), so there is no motivation to write a method unless you actually want the dynamic dispatch methods provide. Methods are fairly rare compared to regular functions.
Unless you declare them "notinline".
http://www.lispworks.com/documentation/HyperSpec/Body/d_inli...
> so there is no motivation to write a method unless you actually want the dynamic dispatch methods provide.
Methods have some different functionality in CL than in most languages. For example, you can have the methods from the entire inheritance hierarchy (well, the classes that have had that method specialized for them) all be called as, essentially a pipeline of methods.
https://lispcookbook.github.io/cl-cookbook/clos.html#method-...
But this is a discussion about dynamism of the object system, and most of that is defined before runtime. How about changing an object's class at runtime? https://www.cliki.net/site/HyperSpec/Body/stagenfun_change-c...
a become: b
Now all references of a and b across the complete image are changed, invalidating all assumptions done at every call site sending messages to each of them.Two parts to your argument:
- Writing a Scheme implementation quickly: Google "Write a Scheme in 48 hours" and "Scheme from scratch." 48 hours to a functioning Scheme implementation seems to be a feat replicated in multiple programming languages.
- Performance: I haven't benchmarked every hobby scheme, but given the proliferation of Scheme implementations that, despite limited developer resources, beat (pure) Python with it's massive pool of developers (CPython, PyPy), I still don't buy the idea that optimizing Scheme is a harder task than optimizing Python. Again, I'd strongly suggest that optimizing Scheme is a much easier task than optimizing Python simply by virtue of how often the feat has been accomplished.
Fair enough, you're right. But if we're only talking about incomplete Scheme implementations it's not a very interesting claim. As I pointed out in another comment, even I could write a fast Scheme implementation in 48 hours if I kept my scope very limited. That doesn't say much about Scheme performance overall or how it relates to Python.
"An Incremental Approach to Compiler Construction"
You simply can't say these things about Python (and I generally like Python!). It's truer for PyPy, but PyPy is pretty big and complex itself. Take a look at the source for the scheme or scheme-derived language of your choice sometime. I can't claim to be an expert in any of what's going on in there, but I think you'll be surprised how far down those parens go.
The claim I was responding to asserted that lisps and smalltalks can only be fast because of complex JIT compiling. That is trueish in practice for Smalltalk and certainly modern Javascript... but it simply isn't true for every lisp. Certainly JIT-ed lisps can be extremely fast, but it's not the only path to a performant lisp. In these benchmarks you'll see a diversity of approaches even among the top performers: https://ecraven.github.io/r7rs-benchmarks/
Given how many performant implementations of Scheme there are, I just don't think you can claim it's because of complex implementations by well-resourced groups. To me, I think the logical conclusion is that Scheme (and other lisps for the most part) are intrinsically pretty optimizable compared to Python. If we look at Common Lisp, there are also multiple performant implementations, some approximately competitive with Java which has had enormous resources poured into making it performant.
I think people who haven't implemented a language underestimate how slow CPython is. And overestimate how hard it is to build a compiler for a dynamic language.
I think every professional developer or CS student can and should build a compiler for a dynamic language!
Even I, very much a non-computer scientist, could write a fast Scheme quickly if I could keep myself to a very small subset, so that’s not interesting to me.
Compared with current state of affairs in CPython, even with basic code generation algorithms, the machine code would be fast enough.
Introducing to compilers means also writing one in the process, unless it is a lousy degree.