Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Lisp-Flavored Programming Languages (github.com/dundalek)
98 points by goranmoomin on Nov 26, 2019 | hide | past | favorite | 76 comments


A quick look at what Quicklisp has to offer for libraries should quickly convince people that fooling around with anything but Common Lisp would be very energy-consuming.

http://blog.quicklisp.org/


Racket has a package manager and plenty of packages. https://pkgs.racket-lang.org

It's also an actively developed modern language not stuck in the 80s.


Question: how lean does a Racket GUI app run? Any samples I can use? Just did the tutorial and I really loved it!

Only thing that’s difficult for me right now is named parameters because I’ve been using Objective C which is really clear on that front.

If they can be hooked together too...that would be fun :)


A quick look at what the job market has to offer (for those who interested in Lisp) should quickly convince people that learning anything but Clojure would be not only energy-consuming but also impractical.


I know this isn't Reddit, but "nick checks out".

Knowledge and skill useful for finding a job is not all the knowledge that is good.

Clojure was developed by someone called Rich Hickey. Not only were there no Clojure jobs when he started hacking, there was no Clojure. That's a textbook example of an energy-consuming and impractical waste of time.

For almost every piece of technology listed in a job ad that you think is worth knowing, someone had to put in a whole lot of time and energy, not knowing if it will pan out at all, and often that time and energy were uncompensated by anything other than the existence of the thing in the end.


You are right. I was just trying to semi-sarcastically mimic the comment, to address "anything but Common Lisp would be very energy-consuming"


These guys are always looking for good coders. Fancy moving into Lisbon or Porto?

https://www.siscog.pt/en/

https://franz.com/success/customer_apps/scheduling/siscog.lh...


I'm amused by the fact that when you criticize LISP's syntax, defenders always say the syntax doesn't matter and real Lisp programmers don't even see the parenthesis. But then you look at these implementations of Lisp-like variants of existing programming languages and the thing the developers are most enamored with is the repetitive, parenthesis-laden syntax of Lisp, while keeping the majority of the non-Lisp semantics in tact (adding just a few functional conveniences like first class functions).

I'm not even criticizing, most of these are hobby projects and you can code how you like. I just think it's funny how hard Lisp clings onto the parenthesis thing while claiming the parenthesis thing doesn't matter.


The thing that matters is that code is written as s-expressions, which has a simple textual serialization format with lists, symbols, numbers, strings, vectors and a bunch of other data types. Thus any Lisp form is automatically data: not simple strings or complex syntax trees.

This enables a bunch of stuff: code can be relatively easily treated as data. It allows easy code generation, transformations (-> macros), traversal (-> interpreters/compilers) or editing.

The parentheses are just a part of the s-expression textual syntax. The s-expressions then are used by basic operations like READ, MACROEXPAND, PRINT and EVAL. Additionally many of the primitive data functions can be used to manipulate code: first/rest, list, append, reverse, map, ...


Yes exactly you have to separate the abstract idea of s-expressions in memory from their textual syntax (parentheses).

S-expressions in memory are a really really good idea and chronically underused in modern programming languages.

The parentheses are irrelevant to the core ideas of lisp. You can make a lisp using C-like braces and infix notation - what makes a lisp is the representation of the program in memory as a tree and the operations you can perform on that representation.

All the interesting macro expansion in lisp is performed after parsing, unlike in the C preprocessor, so you can write your programs using Egyptian hieroglyphics for all lisp cares.


> Yes exactly you have to separate the abstract idea

That was thought around 1960. Lisp had m-expressions in books. The actual Lisp system used s-expressions. The next few decades were often spend trying to get rid of s-expressions on the surface. Most of these attempts failed. If they succeeded they were something different. Like ML. One can think of the early ML as a kind of typed Lisp with a different syntax.

What Lisp made attractive was the similarity between internal and external representation. The Lisp system was internally manipulating programs as s-expressions - that was easier to understand when the external representation is similar.

> The parentheses are irrelevant to the core ideas of lisp.

S-expressions are an actual core idea of Lisp, while you focus on a minor aspect of s-expressions-> that s-expressions use parentheses to denote cons cells and lists.

Since the Lisp uses a certain data representation internally, it is much easier to use a simple textual format for that data externally too - one which makes the mental transformation easy. Using a complex and unrelated syntax does not make that easier, it makes it actually harder.

> All the interesting macro expansion in lisp is performed after parsing, unlike in the C preprocessor, so you can write your programs using Egyptian hieroglyphics for all lisp cares.

Actually that's not true: that's one of the ideas of Lisp and large programming system have been built around this. A Lisp system will expose its inner working to the programmer. Live and interactive systems are not an exception, they are the default.


But lispers are only a small % of programmers. So parentheses have been a success in the sense that lispers really like them, but have been a failure in the sense that they have prevented lisp's cool semantics from reaching a broader audience.

If you are a JS programmer or God-forbid a C++ programmer, you are already living in a world where the transformation from lexical syntax to AST is dozens or hundreds of pages with weird edge cases (e.g. JS semicolon insertion or C++ most vexing parse). If that can be reduced to 1 or 2 pages it's still a massive improvement from their perspective even if it looks like a downgrade to a hardcore lisper who eats parentheses for breakfast, lunch and dinner.


> sense that lispers really like

Lisp programmers's don't 'like parentheses' - parentheses is not what makes Lisp.

Lisp was designed to do programming with s-expressions (aka nested lists). That's its core original purpose. Lisp even means 'List Processor'. It was then early detected that this can be applied to Lisp itself, for example by interpreting s-expressions as Lisp programs.

'Parentheses' are just a part of the notation. If you take away the feature of s-expressions on the surface and thus also the notation, you are no longer programming on the surface in classic Lisp. You can always use alternative notations, but that will take away the seamless symbolic programming.

> failure in the sense that they have prevented lisp's cool semantics from reaching a broader audience

'parentheses' did not prevent that.

Over decades lots of original Lisp stuff was moved to other languages (garbage collection, image-based programming, functional programming, macros, etc.).

There are lots of languages which are somewhat re-invented or re-designed Lisps: Logo, Dylan, Julia, Ruby, ... One can already use those.

Lisp should drop s-expression-based syntax, so that C++ or JavaScript become different internally? This makes no sense.

> If you are a JS programmer or God-forbid a C++ programmer, you are already living in a world where the transformation from lexical syntax to AST is dozens or hundreds of pages with weird edge cases (e.g. JS semicolon insertion or C++ most vexing parse). If that can be reduced to 1 or 2 pages it's still a massive improvement from their perspective even if it looks like a downgrade to a hardcore lisper who eats parentheses for breakfast, lunch and dinner.

Complain to those. Not to a Lisp programmer.


An analogy for web programmers: Parentheses are HTML; S-expressions in memory are the DOM.


The issue is that code is read more often than it is interpreted, written, or compiled.

All the beautiful aspects of lisp make it decidedly unwieldy in production software. There’s a tendency of projects written in lisps to be unwritten in lisps as they mature.


> The issue is that code is read more often than it is interpreted, written, or compiled.

In a Lisp system, the code is always there and not just in textual forms.

> All the beautiful aspects of lisp make it decidedly unwieldy in production software. There’s a tendency of projects written in lisps to be unwritten in lisps as they mature.

There are two main factors which lead to Lisp software being rewritten:

1) deployment. In the early days it was the lack of resources (memory, speed, ...), but there are other factors like having a robust runtime or the ability to integrate in larger software around it.

2) familiarity. There are not many people available to maintain Lisp software. Not because the syntax is strange, but because the whole language is strange. There are no major other programming languages which work like Lisp, so few people can productively program in it. There are exceptions to it, like the simple Lisp used in AutoCAD and related software. These have millions of installations and the complexity on the Lisp side is not that huge - there it's mostly used as a simple interactive programming language.

What makes Lisp actually difficult for programmers is not the syntax, but the pervasive use of code as data, code transformations, various ways of meta-programming, etc. It's the features it was developed for: computing with symbolic expressions - here even applied to itself.

The language Lisp was built to compute with symbolic expressions, then the idea that a Lisp program is itself a symbolic expression is tempting... this then leads to center programming activities around this idea.


Frequently-used interpreted code is probably interpreted more than it is read. Most of the code in a large codebase is likely compiled more than it is read. One-off code is often written, compiled, and executed once, and read never.

If a piece of code is read more often than it's interpreted, written, and compiled, it's probably example code.


That has more to do with managerial ideas of programmer fungibility than Lisp's readability.


The rewrites tend to involve managerial decisions and not technical (arguably Reddit was one of the few cases where I can point to clear cut technical reasons, the reason being "we wanted to run FreeBSD and threads sucked there"). Sometimes it's internal politics (like JPL's C++ developers giving Lisp as reason for their code segfaulting...).

There's quite a lot of big systems written in Lisp. Unfortunately they rarely ever were opensourced, and we get to have blinders made out of our own limited experiences and common generational knowledge loss in IT.


the racket people seem to disagree because they are moving away from lisp/scheme syntax supposedly to improve what they can do with macros.


> Lisp clings onto the parenthesis thing while claiming the parenthesis thing doesn't matter.

Of course it matters; it just doesn't matter in the sense of not being a problem.

Your argumentation is rooted in drifting across different semantics of the phrase "doesn't matter".


You should look into Racket. Apart from getting some momentum due to the merger with Chez, it has a relatively big academic community backing it up.

And it's very different from other Lisps in the sense it's trying hard to be an ecosystem for language-oriented programming, which is probably taking the idea of macros to a new level.

I've used Common Lisp and Clojure for many years, but Racket looks more and more appealing to me.


> it has a relatively big academic community backing it up

this is actually a problem in my eyes and will prevent it from gaining industrial traction. for example, this keeps the main developers as a revolving door of graduate students writing code and the core maintainers as full professors who have priorities different from industrial users. secondly, the culture of racket is as a research language. they just replaced the runtime (loads of risks for industrial users), and now they are replacing the syntax. this does not create an environment enticing to industrial users. the racket team feels these changes will increase its user base, but i believe if that ever happens, these changes are deferring such an increase well into the future.


The parentheses give you Macros, a completely uniform calling convention, and the "everything's an expression" programming style. These are arguably the things you cannot get from a non-lisp language. Almost everything else varies between lisp implementations.

The lack of syntax matters in the sense that once you don't have any you realise that it just gets in the way. Having lots of parentheses is a small price to pay for powerful tools so that's why "it doesn't matter". Non-lispers generally don't understand how lisp is different from their language of choice and therefore don't understand why the lack of syntax is an advantage.


The syntax of S-expressions is the syntax. It's a form to serialize trees (made out of pairs) and it is described by some grammar.


> The syntax of S-expressions is the syntax.

of s-expressions. Lisp has an additional layer of syntax on top of s-expressions.

For example the DEFINE-CONDITION operator has this syntax:

  define-condition name (parent-type*) ({slot-spec}*) option* => name

  slot-spec::= slot-name | (slot-name slot-option) 

  slot-option::= [[{:reader symbol}* |  
                   {:writer function-name}* |  
                   {:accessor symbol}* |  
                   {:allocation allocation-type} |  
                   {:initarg symbol}* |  
                   {:initform form} |  
                   {:type type-specifier} ]] 

  option::= [[(:default-initargs . initarg-list) |  
              (:documentation string) |  
              (:report report-name) ]] 

  function-name::= {symbol | (setf symbol)} 

  allocation-type::= :instance | :class 

  report-name::= string | symbol | lambda expression 
with even more syntax for things like lambda expressions and type specifiers.


I know :) And that's cool, and that property is the base of my own programming language. I am also trying right now to find some explanation why it's cool based on some fundamental conclusions from theoretic computer science...

I just feel that when someone says that Lisp does not have syntax or that syntax is not important, it's plain wrong...


> I just feel that when someone says that Lisp does not have syntax or that syntax is not important, it's plain wrong...

I completely agree. I just feel that not every programming language needs to have the same approach to syntax. Lisp is different from most languages in its way to have a data syntax in which programs are written. Thus the data syntax is textual (s-expressions) and the program syntax is structural (based on data structures like lists, symbols, numbers, ..).


Let's put it this way:

Every function and macro description in the HyperSpec has a "Syntax:" synopsis right at the top.

Section 2 of the standard is "Syntax".


Like the mainstream political arena, the most accurate explanations don't stick, but the most appealing ones do. The parentheses of Lisp's "function within the tuple" application disappear in the same way that other languages' function-before-the-tuple parenthesis disappear - it's not particularly noteworthy. "Don't even see the parenthesis" is talking past the real objection, which is that the depth of parenthesis in every other language does not matter - ie (expr) is equivalent to ((expr)). Whereas in Lisp they also mean another level of application.

I think an interesting synthesis is Haskell, where function calls are simply juxtaposition. Parenthesis are just grouping like most languages, but it ends up feeling quite Lispy.


> the depth of parenthesis in every other language does not matter - ie (expr) is equivalent to ((expr)).

You might want to rethink that hurried statement just a tad:

  // C
  for ((i = 0; i < MAX; i++)) {...}
  printf(("hello, %", name));
  #if defined ((__GNUC__))

  # Shell
  var=$((cat /etc/motd))

  # Pascal
  type color_type = ((Red, Green, Blue));


Sure, my phrasing was overly simplistic, applying in spirit to the way languages define general recursive expressions.

But if you want to be technical, most of your examples would not be considered expressions in the given language.

    int j = i = 0; i < MAX; i++; /* ? I think not. */
But sure, many languages also use parenthesis for things besides general expressions. Ultimately this argument is anti-productive nitpicking.


> most of your examples would not be considered expressions in the given language.

So that's a piece of cognitive load that you have to carry to know when the parentheses are on an expression, and do not change the meaning if compounded, versus when they are around something else where they may not be removed or compounded.

In Lisp, everything is an expression, and no there is no willy-nilly removal of nesting or compounding of nesting. That's less to remember.

Even fragments of forms are expressions, according to ANSI CL glossary terminology. If we have (let ((a b)) ...) then a, b, (a b), ((a b)) and let are all expressions. With the exception of b, what they are not is forms: expressions presented for evaluation.

> Ultimately this argument is anti-productive nitpicking.

Who started it?


> Who started it?

WTH? You, by nitpicking a general statement meant to connect two perspectives and maybe allow some synthesis between two starkly divided worlds.

I've had the Lisp kool-aid. I agree it makes for a great time. I can do without the proselytizing blast.


Perhaps you know more of kazinator's history than I do, but that HN account wasn't even created until 2014, so saying kazinator is the one who started this very old argument requires some extra evidence.


I was referring to kazinator's specific argument rooted in languages using parenthesis for things besides expression grouping. I didn't see how that language-lawyering affected my overall point.

FWIW "in Lisp [parenthesis] also mean another level of application" is also technically incorrect (nesting is not always application), but I think it gets the actual point across better than being more abstract.


Parenthesized sexprs are easy to parse (by both machines and humans) and Lisp text editors already have many convenient ways to work with them. There are though some interesting alternatives such as sweet-expressions[1] and wisp[2], but not too many people care about these.

[1] - https://srfi.schemers.org/srfi-110/srfi-110.html

[2] - https://srfi.schemers.org/srfi-119/srfi-119.html


I think the appeal of the syntax for those who get used to it is the regularity, like you said.

The advantage of the regularity isn't its human readability, but its ability to macro, no?

What I'd like to see is better tools for reading and editing such a regular syntax. Probably I should just learn emacs, but I'm thinking someone could make a more intuitive structured editor for LISP syntax. No need to mush around blobs of text when everything is nested lists.


> The advantage of the regularity isn't its human readability, but its ability to macro, no?

This.

You can write macros for less regular languages, but there's always additional friction involved. At some point, it comes down to whether you think LISP is a "programmable programming language."

If you do, macros are a core part of the paradigm, and s-exprs make macros easy to work with.


I already really liked Lisp's syntax before I learned about the macros.

No ambiguity; no brain cycles required to work out what element is a child or sibling of what element. Great editing ergonomics.


I would guess, based on the second and third sentences of the article, that the author agrees that this is the primary motivation:

> If you already love s-expressions then lisp-flavored languages will make it nicer when you need to build on existing platforms. In case the target language does not support advanced features like macros and REPL-driven development, these can often be easily added by using the s-expressions layer.

To the comment about "parenthesis-laden syntax", I find that, if I actually count the characters, my Java code tends to have just as many parens as my Clojure code. I suspect that there's just a tendency, if all you've ever known is algol-style syntax, to hyper-fixate on lparens that appear to the left of the function name. I think maybe the only programmers who get to criticize others for overuse of parenthesis are Forth, ML, and Haskell programmers.


Actually, in my experience detractors tend to fixate on the

    ))))))))))
that ends some lispy code.


Yet are completely fine with things like:

                  }
                })
              ]}
            }])
          }
        }
      }
   }


At the very least that is more readable due to the indents and the extra syntax. Depending on what language you're using, those different common groups of tokens do communicate context, whereas a dozen right-parens on a single line really don't.


For me personally the regularity is definitely a plus. Especially combined with an editor like paredit or smartparens it becomes very easy to move entire sections of code around.


I suppose that's a good point. Lisp programmers seem to enjoy macros quite a bit, and so I guess those things do work well together.


It's not about syntax. It's about code being data and vice versa.

> Syntax, interestingly, complects meaning and order often in a very unidirectional way. Professor Sussman made the great point about data versus syntax, and it's super true. I don't care how many you really love the syntax of your favorite language. It's inferior to data in every way.

Rich Hickey


The python ones, Hy and Pixie, look pretty cool. Two very different takes on what it means to "use python" for a lisp.

Pixie uses the RPython toolchain and is totally its own language, with its own VM and JIT.

Hy appears to be python with lisp syntax.

Both sound fascinating.


Hy is indeed very cool, but other than a different syntax it is still at the end of the day, identical to python.

Pixie does look very cool, but the project on github seems dead?


Yeah, I thought so too. I've been teaching myself Lisp as a side project, working through online tutorials and, more productively, Paul Graham's "ANSI Common Lisp", using SBCL and CLISP in a terminal window. OK, cool, try another Lisp, leverage my Python knowledge.

Took a look at the github of Pixie: "pre-alpha" and no docs whatever. Not for the student.

Hy is cleanly packaged, installed with pip3, has complete(ish) docs[1], great. So I installed it and started it, it puts up a REPL prompt, and I paste in one of the functions I've worked out:

    (defun hello ()
      (write-line "this is the prompt:")
      (let ( (name (read-line)) )
         (format t "Hello, ~A.~%" name)
         )
     )
Error message: "empty expressions are not allowed at top level"

Sorry? Exactly that usage, an empty expression when a function takes no argument, is used on (I just checked) page 20 of Graham. But ok, I try it without, "(defun hello" etc.

Error message: "NameError: name 'defun' is not defined"

You what? defun is introduced on page 14, and defined in the "Language Reference" Appendix of Graham. OK, wait, what does Hy use, if not defun? Search their tutorial chapter: "Define named functions with defn".

OK, this is a deal-breaker for somebody trying to learn (ahem) COMMON Lisp. Why would you do that, just arbitrarily change the probably third or fourth name a student learns after car, cdr and setv? And more importantly, if you have taken it on yourself to dick around with (ahem) Common Lisp at this basic point, what else have you changed that will break the examples in my textbook or online tutorial?

    pip3 uninstall hy
[1] https://docs.hylang.org/en/master/index.html


Hy isn't a Common Lisp implementation, and it isn't trying to be one, so I think this criticism is a little misplaced.


> Hy is cleanly packaged, installed with pip3, has complete(ish) docs

But is not, and does not claim to be, an implementation of Common Lisp, so judging it harshly for being inconsistent with—and a poor tool for learning—Common Lisp makes as much sense as complaining C++ is a poor tool for learning Algol 68.


Why you think Hy has anything to do with Common Lisp is beyond me.


What about Dylan and other Lisps with Algol based syntax (M-expressions)?


I have designed a programming language that borrows an important part of its architecture from Lisp(s) (maybe mostly Scheme, but also Kernel: http://klisp.org). However, I have always opposed to the concrete syntax of S-expressions (being mostly unable to be productive with it).

My arguments are not on the familiarity side (with the infix notation), but on the psychological one:

1. S-expressions are not the most simple, natural, or uniform surface form (as they claim); they do have syntactic sugar (quote, even lists themselves!, etc.), so why not to add some more sugar (but sufficiently abstract of course)?

2. Humans' brain has limited "stack" space (especially when closing parentheses); infix forms may "cascade" and do not consume the stack (equally machine on human, due to possibility of "tail recursion")

3. Lack of diverse "visual clues" for humans (note how most natural languages have 40-60 phonemes, and none less than 15)

4. S-expressions and homoiconicity are related but orthogonal features (so the homoiconicity argument is often not valid)

Having that said, when I finally managed to write a working 50+-lines program in Scheme, with "proper" indentation, I was just proud of it, and I said, "Wow, it looks cool!". But I am still on the side of the above rational arguments! My point is that as my experiment demonstrates, it is probably too easy to get on an emotional side of computer-human interaction once you accomplished something a bit challenging (like speaking in classic S-expressions)?


For me S-expressions feel like the most natural way to program because they compose naturally with zero ambiguity. Infix notation might be slightly clearer for simple expressions but it doesn't compose: As soon as you try to compose infix notation you have to add parens, depend on unstated precedence rules, or both. Lisp's philosophy is to just use parens everywhere, make everything composable, and have no precedence rules.

That said, I would hate to write Lisp code with Notepad. Fortunately nobody does this. In conjunction with a paren-matching, auto-indenting programmer's editor (which is roughly all of them these days), S-expressions are easy. A good editor is vital not just for writing Lisp programs but also for reading them.

I will not claim parentheses are mandatory. I find Haskell just as simple, unambiguous, and composable without (many) parens but that's only because it has automatic currying, and that takes a bit of practice to wrap one's head around.


IMHO, if you need an editor with paren-matching and auto-indenting (and maybe even syntax highlighting) just to make working with your language tolerable, that's a possible design flaw in the language.

I know it's heresy in a Lisp thread to claim that it's possible for a language to have too little syntax, but I can write Javascript, C and C++ just fine in Notepad or Sublime Text if I want.


My one counter argument for 1 and 2 is that with infix, I'm forever trying to remember precedence rules and in my own code, just end up wrapping everything in parentheses anyway, to be sure. In lisp, the ordering is always explicit.

For 3, that's one reason why I like Clojure's syntax: it has just enough extra syntax to break up the code and provide visual cues, at least for me.

Re 4, sure, you can even enable macros without homoiconicity, but with s-expressions, I find it to be mentally much simpler because I can just write a template and fill in the gaps and its natural since my code is in that form already. Overall, though, in all but a few cases, I think macros should be avoided in favour of pure data structures and functions, when possible.


You're right. Lisp syntax makes the totally wrong tradeoff of being slightly easier to parse for the machine, and much harder for the human. An eloquent name for it is that Lisp fails the squint test https://www.teamten.com/lawrence/writings/the_language_squin...


I have to say applying the squint test to language design seems immensely confused to me.


The syntactic structure of both "code" snippets seems equally clear (or maybe "uncertain in the same ways") to me, though my understanding might be a bit off if the author has biased the comparison by following generally accepted use of whitespace with one language and not the other.

This looks like another instance of slapping a pseudo-scientific veneer on top of conclusions driven more by untrained gut feeling in order to pretend one's subjective impressions are firmly grounded in objective reality. It's like the phrenology of programming languages.


I love s expressions, i can now manipulate my code semantically thanks to paredit & co. Learning vim is the first step to being able to properly manipulate code. Paredit is the next and last step ;)


Toccata seems very interesting! I like the clojure-like syntax and the gradual typing aspect of it.


C/C++ should really be separated. There are very few lisps with good C++ interop, and so they are an interesting category on their own.


I already see a trend building behind functional programming and LISP. Oh brother, right after I started reading SICP.


LISP is a functional programming language.


For some definition of "functional" that was appropriate when LISP was discovered, and of course any claim about LISP tends to be met with, "which one?"

LISP really deserves to be "grandfathered in" as the original functional programming language, but if it were discovered today, we'd likely call it a multi-paradigm language that supports functions as first-class entities.

And as a "programmable programming language," we can use LISP to implement many other paradigms, including what we now consider "functional" programming.


Lisp's development was skewed by the high cost of memory. Early on, scope was dynamic, lists were mutable and often spliced in-place, linear searches were typical (hash tables were almost unheard of), and there were very few first-class types because a pointer only had so many tag bits available.


Things evolved in the 70s. Hash tables were added over time, with some alternatives were using some tree like search. Usually the first thing was to make the symbol table not a list -> making the symbol table a hash table was reportedly done in 1971 by Jon L White. Tag bits then also were not a part of the pointers (with only very few exceptions), but a part of the data object (numbers, strings, arrays, symbols, ..).


To be fair lisps are multi-paradigm languages, especially Common Lisp.


And even Scheme.


The OP probably meant that.


> julia --lisp


AutoLISP for AutoCAD products :)


Cool list I made a pull request .


Where "flavor" means "subset of". But good on them.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: