3 ms·
Common Lisp, which I would consider the most modern, has convenience features which most other languages (even other Lisps) lack. CLOS, macro expansion, and, of
by tmtvl 1y ago
Common Lisp, which I would consider the most modern, has convenience features which most other languages (even other Lisps) lack. CLOS, macro expansion, and, of course, the condition system.
- terminalbraid 1y agoWhich lisps lack a macro expansion system?
- tmtvl 1y agoR7RS (small, at least) doesn't seem to have macro-expand. R6RS also doesn't appear to have it.
- kryptiskt 1y agoR6RS has syntax-case macros which is superior to Common Lisp macros in every respect, they're both hygienic and can be used to implement a sloppy macro system if one so wishes.
- tmtvl 1y agoI think we're talking past each other. I mean something like: (macroexpand '(when-let (foo (frob bar)) (jib foo))) ;; (let ((foo (frob bar))) ;; (when foo ;; (jib foo)))
- ashton314 1y ago`syntax-rules` is very good and you can do a whole lot with them. However, you are limited to template -> pattern transformations, and there are plenty of macros that you cannot write this way. (E.g. anything requiring a predicate on the source syntax that you can't express in the template language, etc.) For that, you need the full power of procedural macros. Racket improves on Scheme: its macros are fully hygienic whilst not being limited to template -> pattern transforms. See https://docs.racket-lang.org/guide/macro-transformers.html https://docs.racket-lang.org/guide/macro-transformers.html EDIT: syntax-case -> syntax-rules; R6RS specifies the latter—I believe the former is a Racket construct equivalent in power to `syntax-rules`.
- Straw 1y agoI think the parent meant that R6RS has `syntax-rules`, which has enough power to implement CL `defmacro` as well as `syntax-case`.
- ashton314 1y agoMy mistake: R6RS has `syntax-rules`, not `syntax-case` as far as I can tell. However, `syntax-rules` and `syntax-case` are equivalent in power. [1] It does not have the same power as `defmacro`: you cannot define general procedural macros with `syntax-rules`, as you are limited to the pattern-matching language to compute over and construct syntax objects. [1]: https://docs.racket-lang.org/reference/stx-patterns.html#%28form._%28%28lib._racket%2Fprivate%2Fstxcase-scheme..rkt%29._syntax-rules%29%29 https://docs.racket-lang.org/reference/stx-patterns.html#%28...
- shawn_w 1y agoI think you got your wires crossed. R5 and R7 only have `syntax-rules` macros. R6 has both (`syntax-rule` can be trivially defined as a `syntax-case` macro). R6 having `syntax-case` macros is one of the more controversial things about it; a surprising number of implementers don't care for them.
- ashton314 1y agoI found the relevant documentation and you are absolutely correct and I was mistaken. Thank you for setting me straight. https://www.scheme.com/tspl4/syntax.html#./syntax:h3 https://www.scheme.com/tspl4/syntax.html#./syntax:h3
- terminalbraid 1y agoSo the modern scheme specs. (I'd argue putting small in there is unfair considering its intent and the actual implementations of r6rs do offer expansion, e.g. chez, guile, racket)
- soegaard 1y agoThe name `macro-expand` is from Common Lisp. Scheme R5RS, R6RS and R7RS all have macro systems. In R5RS has a pattern/template based system (syntax-rules). In R6RS the system has both patterns, templates and procedural macros. The most modern system is Racket though. See `syntax-parse`.
- ashton314 1y ago+1 for `syntax-parse`—it's thoroughly the most powerful (and yet somehow also the most ergonomic) way to write macros in any language thus far. Wait, r6rs has proc macros? Where is that in the spec? I've only seen the `syntax-rules` bit.
- soegaard 1y ago/u/ashton314 Look for `define-syntax`. https://www.r6rs.org/final/html/r6rs/r6rs-Z-H-14.html#node_idx_358 https://www.r6rs.org/final/html/r6rs/r6rs-Z-H-14.html#node_i... https://www.r6rs.org/final/html/r6rs/r6rs-Z-H-13.html https://www.r6rs.org/final/html/r6rs/r6rs-Z-H-13.html
- setopt 1y agoDo you consider Common Lisp more "modern" than say Scheme or Racket? As far as I know, the CL spec hasn’t been updated for 30+ years, and most of its design is far older.
- tmtvl 1y agoDon't know much about Racket, but CL has type dispatch: (defmethod join ((a String) (b String)) (concatenate 'String a b)) ;; example: (join "abc" "def") => "abcdef" (defmethod join ((a Integer) (b Integer)) (parse-integer (format nil "~D~D" a b))) ;; example: (join 123 456) => 123456 And rudimentary support for ADTs: (deftype Low-Score () '(Integer 0 20)) (deftype Normal-Score () '(Integer 21 79)) (deftype High-Score () '(Integer 80 100)) (deftype Score () '(or Low-Score Normal-Score High-Score)) (But note that deftypes aren't allowed to recurse.) CL also has first-class support for debugging with things like describe, step, and trace built-in. EDIT: Yeah, the CL spec dates from 1994 and a bunch of things which we would expect nowadays (networking, POSIX,...) are provided by external libraries rather than being part of the spec, but in various ways CL is way ahead of its time.
- pjmlp 1y agoAnd yet we're still catching up on having features from Allegro Common Lisp and LispWorks more widespread across mainstream languages, where Java and .NET ecosystems are the closests in terms of IDE capabilities, graphical debugging, runtime introspection, JIT and AOT on the same package,..... Which goes to show how many lessons the industry failed to learn on those 30+ years.
- spauldo 1y agoI wouldn't consider a "moderness" comparison between CL and Scheme to be useful. They're too different in intent and capabilities. CL has a more-or-less frozen standard, in the sense that it's unlikely to have an update. Scheme gets updated standards, but they seem to focus on refining Scheme rather than adding "modern" features. Both are very extensible and people do add modern features as implementation extras or libraries. I can't comment about Racket. As an outsider, it appears to be a playground for hardcore CS types to experiment with different programming language features, which suggests it's the most "modern." That's just the impression I get, though - feel free to correct me on that.