8 ms·
It’s interesting that they chose to use Common Lisp for their entire quantum stack. Maybe it hit the sweet spot between expressiveness and performance? Choosing
by mruts 8y ago
It’s interesting that they chose to use Common Lisp for their entire quantum stack. Maybe it hit the sweet spot between expressiveness and performance? Choosing a Lisp makes sense, but I’m not sure I would choose CL. The macro system is primitive and the whole language stinks of a compromised design. Also, at this point, the language feels old and somewhat archaic.
If performance isn’t a dealbreaker, Racket would be sensible choice. Though personally, I think OCaml would be great for this sort of project. Native code, syntax extensions with ppx, a bulletproof type system, and a highly optimized compiler that produces blazing fast code.
- reikonomusha 8y agoCommon Lisp isn’t a very pretty language and isn’t the pinnacle of academic language design, but it’s rock solid, is ANSI standardized, is very highly performing, has great IDE support, has multiple companies offering commercial support, and has many open source implementations. The ugliness, in my opinion, comes from the odd character of the language, and not its fundamental design. It’s not perfect, but it’s surprisingly orthogonal. There is the odd pitfall, and some semantics that aren't standard (but are de facto standard), and in the end you get a combination of a lot of great features, paradigms, and functionalities that are difficult to find elsewhere. (The macro system is plain, but surprisingly effective!) Without even getting into the benefits of Lisp for language & compiler development, these are wonderful aspects for a company.
- 4thaccount 8y agoI think a lot of the choices that went into common lisp were done for practicality's sake although there is some archaic elements due to design by committee and trying to put something together to unite the many different lisp implementations at the time. There's a lot to like about Racket, but Common Lisp is really fast, practical, and is portable to many different implementations like SBCL, AllegroCL, LispWorks...etc that are similar, but have different characteristics (one compiles faster, one has better performance, the commercial ones have GUI libraries...etc). Given a choice, I would personally choose Common Lisp over Racket pretty much any day (not that Racket isn't nice btw). Performance is one reason, but the Chez Scheme migration should help out Racket a bit. OCaml is neat too, but not really directly comparable to Common Lisp. Both are solid languages, but I wouldn't put them in the same category. If I was writing a compiler I would choose OCaml...crazy macros and code generation everywhere...lisp :) I'd like to see someone who really uses Common Lisp regularly like LispM comment though.
- peatmoss 8y agoI wonder if the Chez Scheme port, we’ll see Racket ported to more places. A lot of moving to Chez has been writing more of Racket in Racket rather than C. While the Chez and Racket are probably more similar, I have to wonder if we’ll see Racket ported to SBCL or elsewhere. I like Racket for the cleanliness and good design, but I do covet SBCL’s performance and CL’s ubiquity.
- lispm 8y ago> archaic elements due to design by committee The 'archaic' elements are due to backwarts compatibility with Lisp. You get that raw core of Lisp from the 60s: s-expressions, cons cells, LAMBDA, LIST, CONS, CAR, CDR, APPEND, COND, EVAL, PRINT, PROG, READ, macros, dynamic binding, ... all these (and more) are still in Common Lisp. Common Lisp is an improved Lisp dialect, not a fully new language. A goal was to relatively easily port some existing software which was written in the years from 1958-1984 to Common Lisp. CL appeared in a documented form in 1984 with CLtL. Thus some code that ran in Common Lisp was a port of code written starting in the 60s, like Macsyma. People did not want to throw away hundred thousands lines of code and they wanted to use the newer language, because it was available, slightly better than the old one and was supported on more machine types. This language was mostly developed by five people: Scott Fahlman, Guy Steele, David Moon, Daniel Weinreb, and Richard P. Gabriel. > and trying to put something together to unite the many different lisp implementations at the time Common Lisp is specifically a successor to Maclisp, mostly based on Lisp Machine Lisp (another Maclisp successor), by simplifying/generalizing LML. It's even not directly compatible with LML. It's much less compatible with other Lisp dialects of the time: Interlisp, Scheme, IBM's Lisp, Standard Lisp, or even Scheme or Logo. After the initial design of Common Lisp was done, an effort was started to standardize the language: improve it and add a bunch of important features like error handling and object-oriented programming. Error handling was then based on the Symbolics 'New Error System' and the object-system CLOS was a new design based on Flavors and LOOPs - two earlier Lisp extensions. The most committee like design was actually CLOS. But even that was driven by only six people, lots of community support and a portable reference implementation (PCL). Arguably, CLOS is one of the greater designs in the Lisp language space. The third part then are implementation extensions, which got especially important, when the standards effort went out of steam/funding/interest...: concurrency, unicode support, foreign-function interfaces, standard libs, ... The design advantage Common Lisp has over Scheme is that it started as a larger integrated language. This makes features know of each other and the language is designed to use and support them. Scheme has often this feeling of a very small core language, even a too small core language, and a lot of stuff bolted on top. The result is that 'practical' implementations (practical here means implementations which are used to write software and not so much as a teaching language/implementations) often reach the size of Common Lisp and one of its implementations AND all of them are diverging in some basic ways (Chez, Chicken, Racket, Guile, ...). Take for example the object system. Since CLOS was added to Common Lisp no one bothered to propose a replacement for it in Common Lisp. Thus every implementation, small and large, is using it. > but the Chez Scheme migration should help out Racket a bit If I would want to use Scheme, I'd use Chez Scheme directly. It's a great implementation of Scheme. In provides what many Common Lisp systems (incl. SBCL) also offer: an optimizing native code AOT compiler. Chez already has what Racket now gets: an improved implementation mostly written in itself.
- neilv 8y agoCommon Lisp seems like a fine choice. Just to add to your Racket comments... Some of the ways one might do this in Racket are also doable the same in most any Scheme variant/descendant of the last couple decades (and more ways, for Scheme implementations that provide `syntax-case`). So you could write it "in Racket" in such a way that you can also try out performance of the same code with various other Schemes (Gambit, Chicken, Bigloo, etc.). Some ways in Racket, however, have no equivalent in any other platform right now. For example, having a `#lang quilc` that uses the Racket module&phase system and syntax objects&transformers to turn the language into Racket code behind the scenes (preserving things like source location, and source IDE support), and let you mix&match with modules implemented in other `#lang`s. An optional addition to this idiomatic syntax transformation-based approach in Racket is that you could could also write the code to make it simultaneously spit out some native/assembler or IR for LLVM, CUDA/OpenCL, C, etc., like a traditional compiler. Perhaps the expand-to-Racket "backend" is initial rapid prototype as you figure out your language's syntax and semantics, and the IR-writing is what you do later. And you can keep both backends, and test the tricky one against the original simple one that's easy to analyze. And your compiler is bootstrappable from a nice language. (The Racket universe also has some hands-on PL people, who you can still talk with directly on the email lists, thanks to Racket still being a relatively small and strong community. Without the temptations of money confusing things. :) And it has some nice related PL tools, like Redex.)
- aidenn0 8y agoThe macro system is primitive in the sense that a hammer is primitive: old but still a good choice for putting a nail in something. I don't want to get into a scheme/lisp flamewar (there are enough of those already), but I think the expressiveness of the two is sufficiently close to make other choices dominate[1]. As far as OCaml, despite what appears to be mutual love between the ML and lisp communities, the world can be divided into people who like typed languages and people who like untyped languages, so I imagine that has an effect. Ultimately there's a lot that goes into making decisions into what language to use; I think the Mill guys are insane for implementing their assembler in the C++ templating language (as in a valid assembly file is sugared into a C++ program that outputs the binary), but it works for them, so shrug. 1: OTOH Scheme is small enough that various implementations are doing intereseting things with expressiveness (racket has several, the language modules coming to mind first; Gerbil with process migration, &c.). Common Lisp is probably just too big to make a new implementation just to experiment with a single feature (though see CLASP for a counterexample)
- smotti 8y agoVideo of the main implementer Robert Smith: https://www.youtube.com/watch?v=f9vRcSAneiw https://www.youtube.com/watch?v=f9vRcSAneiw Where he also mentions why Common Lisp.
- armitron 8y agoSBCL (which Rigetti has chosen for qvm and quilc) is better than OCaml in pretty much every aspect of importance for these projects. Performance (compiler macros, intrinsics, runtime assembler, ease of code generation, parallelism), interactivity (no contest, OCaml isn't even close), speed of development and exploring the solution space via DSLs. Compared to SBCL, OCaml feels slow, clunky and academic.
- reikonomusha 8y agoAs a heavy user of both languages (though I’m partial to Standard ML compared to OCaml), I strongly agree with this sentiment.
- mruts 8y agoOCaml’s syntax feels a little (well actually a lot) clunky and illthoughtout. Reason ML fixes a lot of these problems and is a great language all around. I’m a hardcore static typing guy (though I started with Common Lisp, which is why I really appreciate static typing), so maybe I’m biased though. I’ve programmed professionally in both CL and Racket (though it was a research institution so maybe “professionally” isn’t the right word), and in both languages always felt this sense of unease when hitting the “run” button. Half the time the program would error out with something that even the most basic type checker would catch (you called car on a non-list type, oh no!). When programming in OCaml, or Haskell, or Scala, I feel like I have a guardian angel watching my back. Being able to move many runtime errors into compile time errors is such a great thing, I’m not sure why some people prefer dynamic typing. Certainly, the number of correct program with static typing is a subset of programs with dynamic typing (which can be keenly felt with Typed Racket) but even with this restriction, I still think static typing is a massive win. Admittedly though, with a big enough working memory, it shouldn’t make a big difference. Personally though, I love myself some auto-completes and underlined red squiggles!
- armitron 8y agoI don't know how you programmed CL, since there is no "Run" button like in DrRacket (which simply evaluates everything and discards previous state) but if you did the equivalent of that, you were doing it wrong. The way one should program Common Lisp, is through an environment like SLIME which lets you write code interactively and iteratively. DrRacket is very far away from that. In CL/SLIME, you usually evaluate everything you type in, immediately after you do so. Since you program inside a live environment, you can see this as continuously adding to a live process and molding it to your mental model. You build your program up from zero and all state is kept as you do so. There is no reload/wipe-previous-state/run cycle. This way of engineering, when done over a short feedback loop, is supremely powerful. I can't stress this enough. Since you can evaluate expressions inside your editor, without any context switches [unlike Python, Ocaml, Haskell where there is a separate interpreter and one does not build his program up from scratch from inside the interpreter], evaluating things becomes second nature. So you do it all the time. Not to mention that the entire language is geared around this sort of development. The object system (CLOS) allows you to redefine pretty much everything at runtime. The debugger allows you to do the same. Errors (conditions) can have associated restarts that you can select interactively. You have inspectors that let you dig into the state of your process as it runs. The short of errors you are describing are easy to catch and after becoming proficient working in this way, simply do not happen. The main issue that a lot of dabblers in Lisp run into is that they are not exposed to the Lisp Machine development paradigm and thus do not know how CL is different and how to take advantage of all that it offers. If DrRacket -> Run was how I had to write Lisp code, I'd be quickly moving on to something else myself. Thankfully I can use SBCL / SLIME and recapture some (most?) of the magic of the Lisp Machines.
- z3phyr 8y ago> The macro system is primitive Is there a better macro system in any other lisp? I am curious. I find Common Lisp macro system to be magical.
- mruts 8y agoI find scheme’s hygienic macro system or racket’s insanely powerful macro system to be more advanced and easier to use correctly. None of the gensym and hygiene problems you have with CL.
- lispm 8y ago> None of the gensym and hygiene problems you have with CL. Doesn't matter much. Practically Common Lisp's macros are great to use.
- mruts 8y agoAre they better than scheme? I’m skeptical. PS: I know you probably know more and CL and Lisp Machines than anyone else on HN. But do you think CL macros are better than Scheme macros? If so, I would be genuinely interested in why (I know you have more experience with Lisp than I could ever have, do I think your opinion would be valuable to this discussion)
- lispm 8y agoWhat does 'better' even mean? For what? Which of the dozen of Scheme macro systems? Macros are a tool and over the past decades literally zillions of procedural macros have been written in Common Lisp. Somehow people managed to do that. Without 'hygienic' macros. Without rule-based macros. Scheme has seen a lot of research in that area and that's great. Common Lisp is more concerned with core language stability. Having a single macro system, which might have an older but careful design, still has some advantage: basically all code in Common Lisp uses the same macro system and all tools need to support only one macro system. Most of the time it gets the job done. It's like asking whether a carbon bicycle frame is better than a steel one. Depends. If one is travelling, the steel one is possibly more robust and easier to repair. It might not include the latest research in lightweight materials, though.