8 ms·
A point the authors didn't make is that Common Lisp compilers are quite fast compared to e.g. C++ compilers. So even in rare cases where you do need to recompil
by dreamcompiler 3y ago
A point the authors didn't make is that Common Lisp compilers are quite fast compared to e.g. C++ compilers. So even in rare cases where you do need to recompile everything, the cycle time is short.
CCL's compiler is lightning-fast. I can recompile an entire system in CCL almost as fast as I can load the compiled object code. SBCL's compiler is slower (while often generating faster code because it does more work at compile time), but it's still much faster than a typical C++ compiler.
- pjmlp 3y agoThis is the most relevant part that Python misses out from Lisp. There is PyPy, and apparently Mojo will change the world, but still not something to rely on like on Lisps. I guess there is always Julia.
- sva_ 3y agoComparing it to C++ compilers... does Lisp have zero-cost abstractions?
- phoe-krk 3y agoIt does, in form of a sane macro system with the full language available for use at compilation time - something that C++ never had and still doesn't have. No, consteval and constexpr aren't equivalent. No, CPP is not a sane macro system. No, don't even get me started about templates.
- foldr 3y agoPortable CL is missing some key features for making zero cost abstractions such as unboxed arrays of structs.
- phoe-krk 3y agoYes. That's a consequence of language design - unboxed arrays of structs mean no object identity, which means that operators like SETF and EQ no longer have their invariants satisfied when performing assignment to such arrays.
- foldr 3y agoSure, there may be reasons for it, but it means you can’t really build zero cost abstractions. For example, you can’t make a simple 2D vector object with the standard operations defined over it and then store those vectors in flat arrays. This is something that can trivially be done in C++, Rust, etc.
- phoe-krk 3y agoProbably the best workaround for this is going into the foreign memory land - grab some raw memory, define operators over it, manage all that yourself. CFFI works across enough implementations for this to be feasible.
- lukego 3y agoYeah. Common Lisp has quirks and you need to adapt your abstractions to those. Sometimes it's easy, sometimes it's rewarding, sometimes it's just annoying. This week I'm scaling back some abstractions, writing more Fortran-like code on specialized arrays than individual objects, for the sake of zero cost. I appreciate a little bit of a headwind against inventing new abstractions too casually. But it does remind me of programming in C or Forth. That's not everyone's cup of tea.
- foldr 3y agoThis one isn’t a quirk, it’s a fundamental constraint on the kind of code that you can write in CL. C++, Rust, Go (and even Java to some extent, with all the wizardry in Hotspot) all allow you to build a 2D vector abstraction without requiring you to box your vectors. In CL you simply can’t do this. Just look at the kind of bonkers workarounds my comment gave rise to: https://news.ycombinator.com/item?id=35855576 https://news.ycombinator.com/item?id=35855576
- lukego 3y agoI don't really see the problem. If you want to define the bit layout of your objects then you define them using FFI. Support for FFI objects is comprehensive. It is exactly the tool for the job in Common Lisp. Same for LuaJIT. I've spent years happily writing high-level Lua code that's actually operating on objects whose bit layout is explicitly defined using FFI at the C level of abstraction. It doesn't feel much different to objects or dictionaries to me. Sure, it is great that those other languages have native support for inlining storage of structs into various containers, but the lack of such in Common Lisp only makes me write quirky code and doesn't really hold me back.
- ced 3y agoNot sure about Common Lisp, but Julia (which is a Lisp in all ways except surface syntax) definitely does.
- aidenn0 3y agoNot quite to the degree that C++ does, but it's pretty good. There are several places in the standard that specifically allow for making a dynamism/performance tradeoff.