[HN Gopher] "Stop Designing Languages. Write Libraries Instead" ...
       ___________________________________________________________________
        
       "Stop Designing Languages. Write Libraries Instead" (2016)
        
       Author : teleforce
       Score  : 213 points
       Date   : 2026-01-07 12:29 UTC (10 hours ago)
        
 (HTM) web link (lbstanza.org)
 (TXT) w3m dump (lbstanza.org)
        
       | whazor wrote:
       | With a Domain Specific Language (DSL), you parse code and build
       | an abstract syntax tree. But you can also build a Python library
       | where you construct the same tree. With the benefit that LLMs are
       | already better trained on Python code. If you need a
       | deterministic programming language, you could use starlark.
        
         | conartist6 wrote:
         | DSL is a term with such fuzzy meaning, I don't like it at all.
         | It's always valid to just say "language". Languages and
         | libraries don't even have to be opposing concepts either. Let's
         | say you write the first ever JSON parsing library. Did you just
         | create a library? Or a language?
        
           | librasteve wrote:
           | I have started gathering DSL specific content over on
           | https://reddit.com/r/domainspecificlangs ... there are
           | several definitions over there. Personally I would
           | distinguish between a drop down DSL and a full blown
           | independent language.
        
       | xigoi wrote:
       | The quotation marks having been stripped from the title changes
       | the meaning quite a bit...
        
         | pfdietz wrote:
         | I admit the article is not what I at first expected. But I
         | liked it. The references to Ruby feel dated, though.
        
       | tonyg wrote:
       | I will not. I refuse
        
       | conartist6 wrote:
       | Yes! This is also why I think it's stupid that languages are now
       | trying to kill their most popular libraries as a matter of
       | principle.
       | 
       | E.g. node says "oh no, you need a library to write tests!" and
       | now that means that you have to have a testing framework built
       | into your runtime. And of course it's just another library,
       | really, that competes with the original one, but this one is
       | blessed with standards so it has a monopolistic advantage that
       | will deter further innovation.
        
         | wiseowise wrote:
         | > And of course it's just another library, really, that
         | competes with the original one, but this one is blessed with
         | standards so it has a monopolistic advantage that will deter
         | further innovation.
         | 
         | It's called convenience. You're free to create a testing
         | library so good that it'll knock socks off the stdlib one.
        
           | conartist6 wrote:
           | My question is so simple: why is a level playing field seen
           | as bad now?
           | 
           | Have we given up on having a market economy? You can't have a
           | fair game when one team playing is also the referee. Yet
           | everywhere I look that's the way of it. Apple runs the app
           | store so that they can also ensures that every successful app
           | is theirs. The supermarket stocks the shelves, but also uses
           | their position of power to kill successful independent
           | brands. Node takes libraries which have taken years of work
           | and shits out builtins with at most a week invested.
           | 
           | I think it's a national embarrassment: anticompetition to the
           | point of communism held up as if it were the genuine spirit
           | of the American Dream.
        
             | Jtsummers wrote:
             | > Node takes libraries which have taken years of work and
             | shits out builtins with at most a week invested.
             | 
             | > I think it's a national embarrassment: anticompetition to
             | the point of communism held up as if it were the genuine
             | spirit of the American Dream.
             | 
             | You think including a testing library in a language
             | implementation or standard tooling is tantamount to
             | communism?
        
               | conartist6 wrote:
               | Yes, I think it's taking several steps on the path away
               | from individual creativity towards society-wide approved
               | ideas.
        
       | CPLX wrote:
       | I know that HN is famously a discussion forum where users comment
       | based on the titles of submitted articles, rather than their
       | content.
       | 
       | With that said, the divergence in comments on this very
       | insightful and well written article will soon provide an
       | unusually clear means of determining who is commenting on the
       | title and who is commenting on the article.
        
         | fredrikholm wrote:
         | The omission of quotations in the title triggered my Lisp-
         | damaged brain to man the walls, only to immediately be met with
         | Ruby and Scheme examples. False alarm.
        
         | tialaramex wrote:
         | That's fair. It's also the case that to some extent HN's
         | article titles serve the same purpose as that one line
         | description in a speed dating event. They're ice breakers,
         | everybody has the same prompt and then writes about that, and
         | _even if they did read the article_ which I agree often they
         | don 't, they come at it from a different angle.
         | 
         | I feel similarly to the article author, it is trivially true
         | that we _could_ express anything in all the general purpose
         | languages, that 's what general purpose even means, but I find
         | for Computer Languages the Weak Sapir-Whorf Hypothesis checks
         | out pretty well. The language changes how you think about the
         | problem.
        
           | CPLX wrote:
           | As a long-time HN contributor, I believe in visualizing
           | myself like water flowing downhill. As such, I certainly
           | would never try to overturn the prevailing culture of
           | commenting on article titles and in fact engaging in it
           | myself from time to time.
        
       | jll29 wrote:
       | The OP's point is well-taken: a new language usually forces you
       | to change 100% of your environment and tooling, whereas a new
       | library respects your habits and preferences.
       | 
       | I follow new language developments with keen interest, but few of
       | them will ever reach the level of maturity to be considered
       | serious candidates for adoption. It's also risky to adopt a
       | language that you cannot easily hire developers for, for example.
       | 
       | Libraries are great, but there is only so much they can address,
       | and that depends on the language, too, as the article correctly
       | points out. And there are two kinds of libries: tool libraries
       | and frameworks. Someone once said it nicely: "Frameworks are like
       | Hollywood - 'You don't call us, we call you!'". Frameworks often
       | require you to submit to their control flow rather the other way
       | round; that's why I prefer tool libraries.
        
         | kayo_20211030 wrote:
         | Agree. I don't know why a statement that uncontroversial got
         | the bums rush.
        
       | dev_l1x_be wrote:
       | I would love to have a scripting language has typed features and
       | you can replace bash with.
       | 
       | What comes close is:                   #! /usr/bin/env elixir
       | Mix.install([:jason])              defmodule JsonPrettyPrinter do
       | def get_stdin_data do             :stdio             |>
       | IO.read(:all)             |> Jason.decode()             |> case
       | do               {:ok, json_data} -> json_data               _ ->
       | raise "Invalid JSON payload was provided"            end
       | end         end              JsonPrettyPrinter.get_stdin_data()
       | |> JsonPrettyPrinter.pretty_print_json()         |> IO.puts()
        
         | PaulHoule wrote:
         | Two interesting options for everyday scripting are Python and
         | Powershell.
        
           | b40d-48b2-979e wrote:
           | A nice part of PowerShell: you can `Add-Type` and embed C#/F#
           | when you want.
        
           | logicallee wrote:
           | you won't believe how powerful Python is with libraries.
           | ChatGPT and Claude made a brand new browser, that isn't based
           | on Chromium or Firefox, and yet still follows many aspects of
           | layout correctly. I read the article we're discussing ("stop
           | designing languages") on this browser and I'm currently using
           | it to post this reply.
        
             | F3nd0 wrote:
             | Knowing that LLM's have been extensively trained on public
             | code, I wonder how much of it _is_ based on Chromium or
             | Firefox.
        
               | logicallee wrote:
               | That's a good question! You can read through the entire
               | source code for the latest version:
               | 
               | https://taonexus.com/publicfiles/jan2026/171toy-
               | browser.py.t...
               | 
               | it doesn't look like it would be easily derived from
               | Chromium or Firefox, because this code is Python and
               | those don't use Python this way.
               | 
               | By the way is there any feature you'd like to see added
               | to the toy browser? The goal is that one day it's a
               | replacement for Chrome, Firefox, etc. It's being built by
               | ChatGPT and Claude at the moment. Let me know if there
               | are any feature ideas you have that would be cool to add.
        
             | PaulHoule wrote:
             | A python-based browser? What are you using for the GUI
             | toolkit?
        
               | logicallee wrote:
               | >A python-based browser? What are you using for the GUI
               | toolkit?
               | 
               | Great questions. 1. Yes, for the moment. Like the title
               | of this article suggests - we're using a library! :)
               | 
               | It's great to iterate in Python, which has a large
               | ecosystem of libraries. Believe it or not, there is a
               | chance that in the future it would be able to translate
               | the language into a different one (for example, C++)
               | while using C++ bindings for the same gui libraries. This
               | would speed up its actions by 40x. However, not all of
               | the libraries used have C++ bindings so it could be
               | harder than it looks.
               | 
               | 2. Here's the current version of the source code:
               | 
               | https://taonexus.com/publicfiles/jan2026/171toy-
               | browser.py.t...
               | 
               | you can have a quick read through. Originally it was
               | using tkinter for the GUI toolkit. I believe it is still
               | using tkinter, but the AI might be leaning on some other
               | library. As you read it, is it using anything but tkinter
               | for the GUI toolkit?
               | 
               | These libraries are doing a lot of heavy lifting, but I
               | think it is still ending up drawing in tkinter (not
               | handing off rendering to any other library.)
        
           | IshKebab wrote:
           | Python is actually kind of awkward for this use case since
           | you can't import from other files easily unless you are in a
           | proper Python package, which isn't usually the case for
           | everyday scripting.
        
             | ActorNightly wrote:
             | Lol what.
             | 
             | Python lets you dynamically import from anywhere. The
             | syntax is a bit funky, but thats what llms are for.
        
               | IshKebab wrote:
               | No it doesn't. You can't do something like `import
               | ../../foo/bar`. You can mess around with PYTHONPATH and
               | importlib to work around that but that's a horrible hack
               | that also breaks all tooling. Not a good idea.
               | 
               | With Deno you can just import by relative file path and
               | it just works like you'd expect and the tools support it.
               | I wish more languages worked like that.
        
               | Jtsummers wrote:
               | > You can't do something like `import ../../foo/bar`.
               | 
               | https://docs.python.org/3/reference/import.html#relativei
               | mpo...
               | 
               | You'd use:                 import ...foo.bar
        
           | bashkiddie wrote:
           | I am unhappy with python. It degrades fast. It deprecates
           | libraries every minor release and that tends to break the
           | applications I use. Recent examples are distutils and
           | opsaudio.
        
             | ActorNightly wrote:
             | Thats why venv exists. Much better solution than lock
             | files.
        
         | qrobit wrote:
         | I wanted to say Haskell with shh[^1] and stack's or nix's
         | shebangs[^2][^3], but interpreted haskell is not particularly
         | fast.
         | 
         | Also I think a Python script is reasonable if you use a type-
         | checker with full type annotations, although they are not a
         | silver bullet. For most scripts I use fish, which is my
         | preferred interactive shell too.
         | 
         | [1]: https://hackage.haskell.org/package/shh
         | 
         | [2]: https://docs.haskellstack.org/en/v3.9.1/topics/scripts/
         | 
         | [3]: https://wiki.nixos.org/wiki/Nix-shell_shebang. On a side
         | note, if you were to use nix's shebang for haskell scripts with
         | dependencies, you should be using https://github.com/tomberek/-
         | instead of impure inputs, because it allows for cached
         | evaluation. I personally cloned the repo to my personal gitlab
         | account, since it's small and should never change
        
         | librasteve wrote:
         | Suggest you take a look at https://raku.org for a strongly (but
         | gradual) typed scripting language.
        
           | dnautics wrote:
           | that's just perl with a new coat of paint
        
             | fn-mote wrote:
             | Perl 5 does not have types, as far as I know.
             | 
             | I'm taking the GP seriously instead of dismissing it. Raku
             | looks like more fun than nushell tbh.
        
               | librasteve wrote:
               | Raku types are a bit thicker than paint https://gist.gith
               | ub.com/raiph/849a4a9d8875542fb86df2b2eda892...
        
             | librasteve wrote:
             | well waiting for Raku (formerly perl6) to be built was like
             | watching paint dry
        
               | DonHopkins wrote:
               | They should have named it Godot. ;) But now that name is
               | taken.
        
             | DonHopkins wrote:
             | Lead paint with asbestos sprinkles and radium racing
             | stripes! ;)
        
             | radiator wrote:
             | it is so much slower to start than perl, that you don't
             | want to run it for quick one-off tasks
        
         | jakkos wrote:
         | Have you seen nushell? It lets me one-liner so many things that
         | would have previously taken breaking out a "real" language to
         | do
         | 
         | Contrived example:                 ls | where type == 'file' |
         | sort-by size | take 4  | each {|f| {n: $f.name, s: ($f.size |
         | format filesize MB) }} | to json
         | 
         | outputs                 {         "n": "clippy.toml",
         | "s": "0.000001 MB"       },       {         "n": "README.md",
         | "s": "0.000009 MB"       },       {         "n":
         | "rustfmt.toml",         "s": "0.000052 MB"       },       {
         | "n": "typos.toml",         "s": "0.00009 MB"       }
        
           | fainpul wrote:
           | In PowerShell:                 gci -file | sort-object size |
           | select name, size -first 4 | % { $_.size /= 1MB; $_ } |
           | ConvertTo-Json
        
           | 0x3444ac53 wrote:
           | I've tried nushell and other shell replacements and it just
           | feels like I'm learning a new programming language for no
           | good reason
        
             | fainpul wrote:
             | Ok if it's not for you. But there _is_ of course a very
             | good reason -- work with objects in the pipeline instead of
             | "dumb text". Also PowerShell and nushell are quite nice to
             | learn, whereas Bash is absolutely horrible.
        
             | bbkane wrote:
             | Yeah... https://www.sophiajt.com/case-for-nushell/ makes a
             | really good case for Nushell as an alternative to Bash.
             | 
             | Unfortunately, I don't think Nushell brings much benefit
             | for folks who already know Bash enough to change
             | directories and launch executables and who already know
             | Python enough to use more complicated data
             | structures/control flow/IDE features
             | 
             | I'm still rooting for Nushell as I think its a really cool
             | idea.
        
               | misir wrote:
               | For me the blocker was having to switch to
               | bash/powershell when moving to a different machine (ie:
               | servers, work machine, etc..). I would end up needing to
               | redo same things to be compatible with the existing
               | tools; eventually I just gave up and got used to readily
               | available shells instead.
        
             | ectospheno wrote:
             | To be fair the example above is easier to remember than:
             | ls -l --sort=size | head -n 5 | tail -n 4 | awk '{print $5
             | " = " $9}' | numfmt --to iec | jq --raw-input --null-input
             | 'inputs | gsub("\r$"; "") | split(" = "; "") |
             | select(length == 2) | {"s": (.[0]), "n": .[1]}'
        
               | fainpul wrote:
               | This example shows nicely how ugly text processing is:
               | you have to use head _and_ tail simply to trim out the
               | first line of ls (the total).
               | 
               | I think it doesn't even work correctly. ls lists files
               | and directories and then picks the first 4 (it should
               | only select files).
               | 
               | And this also uses awk and jq, which are not just simple
               | "one purpose" tools, but pretty much complete programming
               | languages. jq is not even part of most standard
               | installations, it has to be installed first.
        
               | ectospheno wrote:
               | Yes, the point was to show that nushell is pretty
               | awesome. I totally punted on the file only part.
        
               | fainpul wrote:
               | I'm aware ;)
        
               | vidarh wrote:
               | I'd replace the first part with (which isn't any shorter,
               | but in general if I want a list of files for a pipeline,
               | find is usually more flexible than ls for anything but
               | the most trivial):                   find -maxdepth 1
               | -type f -printf '%s %f\n' | sort -n | head -n 5
               | 
               | For the latter part, I'd tend to think that if you're
               | going to use awk and jq, you might as well use Ruby.
               | ruby -rjson -nae ' puts(JSON.pretty_generate({n: $F[1],
               | s: "%.5f MB" % ($F[0].to_i / 10e6) }))'
               | 
               | ("-nae" effectively takes an expression on the command
               | line (-e), wraps it in "while gets; ... end" (-a), and
               | adds the equivalent to "$F = $_.split" before the first
               | line of your expression (-n))
               | 
               | It's still ugly, so no competition for nushell still.
               | 
               | I'd be inclined to drop a little wrapper in my bin with a
               | few lines of helpers (see my other comment) and do all
               | Ruy if I wanted to get closer without having to change
               | shells...
        
               | ectospheno wrote:
               | Ruby is a pretty natural fit for shell scripting.
               | 
               | https://lucasoshiro.github.io/posts-en/2024-06-17-ruby-
               | shell...
        
             | IshKebab wrote:
             | Well, the reason is you can stop using Bash. If you never
             | write Bash scripts already then you probably don't need it
             | (and also congratulations on doing things right), but most
             | people at least have lazy colleagues that write shell
             | scripts. One day I'd like them to be not awful.
        
           | BoppreH wrote:
           | For me the best benefit of nushell is not the easier syntax,
           | but the static type checks. It catches most typos _before_
           | running the script, which is a godsend when the script is
           | slow and /or has destructive operations.
        
           | ifh-hn wrote:
           | Was just about to suggest nushell. I love programming in
           | nushell, the out of the box features are excellent.
        
           | vidarh wrote:
           | With this:                   E = Struct.new(:name, :size,
           | :type)         def ls = Dir.children('.').map{
           | s=File::Stat.new(_1); E.new(_1, s.size, s.file? ? 'file' :
           | 'dir') }
           | 
           | This becomes valid Ruby:
           | ls.find_all{_1.type == 'file'}.sort_by(&:size).take(4).map{
           | {n: _1.name, s: _1.size } }.each { puts
           | JSON.pretty_generate(_1) }
           | 
           | (drops your size formatting, so not strictly equivalent)
           | 
           | Which isn't meant to "compete" - nushell looks nice -, but to
           | show that the lower-threshold option for those of us who
           | don't want to switch shells is to throw together a few
           | helpers in a language... (you can get much closer to your
           | example with another helper or two and a few more "evil"
           | abuses of Ruby's darker corners, but I'm not sure it'd be
           | worth it; I might a wrapper for the above in my bin/ though)
        
         | leonidasv wrote:
         | There's a trick shared here days ago to add a kind of shebang
         | to Go that may interest you: https://lorentz.app/blog-
         | item.html?id=go-shebang
         | 
         | Discussion: https://news.ycombinator.com/item?id=46431028
        
         | ashton314 wrote:
         | If you just wait a few months, then that program _will_ be
         | written in a typed language. The type checker for Elixir is
         | coming along nicely and every release brings more checks.
        
         | frou_dh wrote:
         | OCaml is a scripting language in this sense. No need to compile
         | an executable ahead of time, just have a `#!/usr/bin/env ocaml`
         | shebang (or more realistically: `#!/usr/bin/env -S ocaml -I
         | +unix unix.cma`) at the top of a source file.
         | 
         | Though, I don't think it has the capability for single-file
         | scripts to declare 3rd-party dependencies to be automatically
         | installed.
        
           | IshKebab wrote:
           | It also has poor support for Windows.
           | 
           | The best option I've found for this use case (ad-hoc
           | scripting with third party dependencies) is Deno.
           | 
           | I'm hoping Rust will get there in the end too.
        
         | unpigged wrote:
         | Babashka (https://babashka.org/) is an interesting tool for
         | scripting. It's Clojure, so dynamic typing, but it's data
         | orientation makes it a great fit for something like your
         | example.
        
         | DonHopkins wrote:
         | @dev_l1x_be: The answer isn't a new typed scripting language.
         | It's recognizing what the interpreter already is.
         | 
         | LLMs are eval(). Skills are programs. YAML is the motherboard.
         | 
         | @unkulunkulu nails it -- "library as the final language",
         | languages all the way down. Exactly. Skills ARE languages. They
         | teach the interpreter what to understand. When the interpreter
         | understands intent, the distinction dissolves.
         | 
         | @conartist6: "DSL is fuzzy... languages and libraries don't
         | have to be opposing" -- yes. Traditional DSL: parse -> AST ->
         | evaluate. LLM "DSL": read intent -> understand -> act. All one
         | step. You can code-switch mid-sentence and it doesn't care.
         | 
         | The problem with opinionated frameworks like ROR and their
         | BDFLs like DHH is that one opinion is the WRONG number!
         | 
         | The key insight nobody's mentioned: SPEED OF LIGHT vs CARRIER
         | PIGEON.
         | 
         | Carrier pigeon: call LLM, get response, parse it, call LLM
         | again, repeat. Slow. Noisy. Every round-trip destroys precision
         | through tokenization.
         | 
         | Speed of light: ONE call. I ran 33 turns of Stoner Fluxx -- 10
         | characters, many opinions, game state, hands, rules, dialogue,
         | jokes -- in a single LLM invocation. The LLM simulates
         | internally at the speed of thought. No serialization overhead.
         | No context-destroying round trips.
         | 
         | @jakkos, @PaulHoule: nushell and Python are fine. But you're
         | still writing syntax for a parser. What if you wrote intent for
         | an understander?
         | 
         | Bash is a tragedy -- quoting footguns, jq gymnastics, write-
         | only syntax. Our pattern: write intent in YAML, let the LLM
         | "uplift" to clean Python when you need real code.
         | 
         | Postel's Law as type system: liberal in what you accept.
         | Semantic understanding catches nonsense because it knows what
         | you MEANT, not just what you TYPED.
         | 
         | Proof and philosophy:
         | https://github.com/SimHacker/moollm/blob/main/designs/stanza...
        
         | Pet_Ant wrote:
         | Have you considered PowerShell? It's open-source, and typed,
         | and definitely usable from the command line with lots of
         | resources for.
         | 
         | https://github.com/PowerShell/PowerShell
        
           | fmorel wrote:
           | And _dotnet run_ can now run single files of C# code, with
           | the ability to import other projects and packages if needed.
           | #!/usr/bin/dotnet run
           | 
           | https://devblogs.microsoft.com/dotnet/announcing-dotnet-
           | run-...
           | 
           | https://andrewlock.net/exploring-dotnet-10-preview-
           | features-...
        
       | shevy-java wrote:
       | > But thanks to Ruby on Rails, he doesn't have to! So he said
       | that he has no particular opinion about the Ruby programming
       | language, but he absolutely loves Rails.
       | 
       | Ruby got a hype phase with regards to rails. It then dropped. A
       | lot.
       | 
       | TIOBE, while it is in general crap, is somewhat accurate when you
       | plot things over time:
       | 
       | https://www.tiobe.com/tiobe-index/ruby/
       | 
       | So, ruby peaked with rails between 2006 to 2009 or so, give or
       | take. Then the decline phase set in, and now it is unfortunately
       | also crawling behind perl into extinction. This is very
       | unfortunate - I still use ruby almost daily as the ultimate glue
       | language. But this can not be denied now that ruby is following
       | the extinction path perl already had going some years before.
       | 
       | I was using ruby before rails was created and ruby covers all my
       | web-needs. I had a web-framework in PHP, used it for about three
       | years, ported it into ruby and expanded it massively in the last
       | 20 years or so (well, almost 20 years). I retired from
       | rubygems.org when RubyCentral got crazy in 2024 (and even crazier
       | in 2025 with the mass purge of developers). So, one difference
       | here is that the friend he talks about is using a specific
       | framework. He probably no longer uses ruby nor rails. I use ruby
       | because the language is very well designed and covers (most of
       | my) use cases; the rest I may sprinkle down with java. So whether
       | rails exists or not, makes zero difference to me. Actually
       | without rails it would be better, because people using ruby would
       | be using it because of ... ruby. Even if there are then fewer
       | users. I still think this is better than those who will jump ship
       | anyway because they only use ruby due to rails. These guys are
       | not like in the same boat. They have use cases for getting work
       | done via rails, designing websites, infrastructure related to
       | websites, user-interaction and so forth. But they don't really
       | use ruby as such. Their use case is quite limited. I think this
       | is one of the biggest problems here. It in part explains why ruby
       | dropped down a lot (there are many reasons for this, python being
       | so successful is in my opinion the biggest reason, but the other
       | smaller reasons also add up - that also includes the laughable
       | joke that is documentation in the whole ruby ecosystem. That's
       | inexcusable - note, I am not saying documentation must be
       | perfect, but please look at opal, ruby-wasm or rack - the
       | documentation there is virtually NOT EXISTING.)
       | 
       | > The vast majority of programmers are non-experts, like himself
       | 
       | No, I think he is an expert - just in a specific niche and field.
       | Not all experts know everything equally well.
       | 
       | > Subtle language features like first-class functions, and object
       | systems, are lost on them because they don't really use them
       | anyway.
       | 
       | I don't think this is true. Some language features are very
       | useful. Ruby's blocks for instance. They are probably one of the
       | top three win-win features ruby offers.
       | 
       | > Computer scientists should really be spending their time
       | developing new libraries rather than inventing new programming
       | languages.
       | 
       | I also disagree here. I would, however had, say, that new
       | languages should be well-designed. Many new languages suck. Old
       | languages also suck. Designing a great language is very hard. If
       | it is just a toy or research language then this is fine, but once
       | a language is meant to be "real", it really needs to have
       | compelling use cases and be great in many areas including
       | documentation.
       | 
       | > These features are simply not available in all other languages.
       | Java's meta-programming features, for example, are just not
       | powerful enough to implement a system like ActiveRecords. Rails
       | is only possible because of Ruby.
       | 
       | That's also incorrect. You can create any DSL as you like in Java
       | too. Ruby just makes this a lot easier out of the box. Plus, you
       | can also have great websites without rails.
       | 
       | > Ruby on Rails was designed to make it possible to build
       | websites without understanding type theory, or memory management,
       | or object-oriented design patterns.
       | 
       | Ok so ... why would this not be possible in Java? Why would he
       | have to write Java code for a library to be used in this regard?
       | 
       | > Ruby on Rails provides a concise way for expressing: do this
       | when the button is clicked
       | 
       | But you have the same in many other languages and frameworks too.
       | I mean this is how PHP was started initially.
       | 
       | > The "do this" part is implemented in Ruby as a first-class
       | function. How would it be implemented in languages like Java
       | which don't support them?
       | 
       | Write a solid DSL.
       | 
       | > The programming language directly shapes the design of its
       | libraries.
       | 
       | If this were true, why would GTK have glib+vala? I mean, they
       | could just rely on C directly, right?
       | 
       | Besides, ruby is just a wrapper over C really.
       | 
       | > The more powerful the language, the easier the libraries are to
       | use.
       | 
       | That part is true. A better designed language makes for better
       | libraries or a chance to have better libraries. I noticed this
       | when I compared my PHP code to my ruby code. I am not a good
       | programmer, but my ruby code is much better on every level than
       | the equivalent PHP code. Fewer lines too. While this also has to
       | do with experience, at the end of the day PHP is simply a much
       | worse language than Ruby is. At some point I decided I don't want
       | to invest into languages that suck when I could be using better
       | languages instead. That is also why I stopped writing shell
       | scripts - it is just a waste of time having them.
       | 
       | Rails is also, by the way, fairly well documented. So I am not
       | saying all in ruby has horrible documentation of course.
        
         | CPLX wrote:
         | > now it is unfortunately also crawling behind perl into
         | extinction. This is very unfortunate - I still use ruby almost
         | daily as the ultimate glue language. But this can not be denied
         | now that ruby is following the extinction path perl already had
         | going some years before.
         | 
         | I'm pretty sure that can be denied.
         | 
         | Rails and Ruby (both separately and as a unit) is still
         | absolutely huge. It's launching massive new releases regularly
         | and still underpins a healthy chunk of the top websites on the
         | planet (Shopify, GitHub, Airbnb, Twitch, Hulu, Kickstarter,
         | Zendesk, Basecamp, Crunchbase, Dribbble etc etc) and is still
         | taught to new developers as well.
        
       | librasteve wrote:
       | Well, maybe. The problem is that mature languages and ecosystems
       | are mature and new features have to be shoehorned in. Raku
       | (https://raku.org) on the other hand is intentionally designed as
       | a braid of sub languages (slangs) for quoting, regex, PEG, etc
       | and you can easily make your own slang with eg.
       | https://raku.land/zef:lizmat/Slangify so you get your DSL as a
       | drop down language in a general PL setting.
        
         | jolt42 wrote:
         | There's so many languages out there, I reject Raku out-of-hand
         | simply since IMO the type should follow the variable name.
        
           | librasteve wrote:
           | hmmm Raku is C style                 int number;
           | ... you choose Pascal style            number : Integer;
        
       | zcw100 wrote:
       | I just came across a situation where I had a DSL but it was clear
       | that a language would have been better. What I don't like about
       | this is the dogmatic tone which is pretty common in IT. Don't to
       | it that way, do it my way! Sometimes a DSL is a solid choice,
       | sometimes a language is a better one, sometimes you might want to
       | support both but I guess "Choose the right abstraction for your
       | domain" doesn't make for a clickbait title.
        
         | xnorswap wrote:
         | It's not clear what you're trying to say, because the "L" in
         | DSL is "Language".
        
           | 9rx wrote:
           | All programming languages are domain specific, so presumably
           | he is referring to English (or another natural language of
           | the same nature). Meaning that he must be saying that
           | sometimes letting the vibes flow is best.
        
             | zcw100 wrote:
             | No, I meant a General Purpose Language (GPL) or actually
             | this was an application specific language. You don't need
             | to be so pedantic. Yes, the L is for language but the idea
             | of a DSL is not well defined but these remarks reinforce my
             | argument that people are too dogmatic.
        
               | xnorswap wrote:
               | I wasn't trying to be dogmatic, I was genuinely trying to
               | understand what you were trying to say, because it didn't
               | seem to relate to languages vs libraries, and I found it
               | confusing.
        
       | eklavya wrote:
       | I don't know ruby or rails so probably wrong on this but why does
       | the author say no framework for Java web. How different is Spring
       | from that?
       | 
       | They talk about the programmer which doesn't know neither cares
       | about the language stuff. So what is Spring lacking from that
       | perspective?
        
         | DonHopkins wrote:
         | "Java is a DSL for taking large XML files and converting them
         | to stack traces"
         | 
         | "XML is like violence. If it doesn't solve your problem, you're
         | not using enough of it."
        
           | moffkalast wrote:
           | XML is like a flyer saying "do violence" maybe, it doesn't do
           | anything by itself.
        
             | DonHopkins wrote:
             | That excuse worked for Trump on January 6.
        
       | dominicrose wrote:
       | Rails wouldn't exist without Ruby, Ruby wouldn't exist without C,
       | Rails can't be rewritten in C, Rails isn't a library.
       | 
       | But aren't Rails, Laravel and Django a bit similar? At least for
       | the people not directly involved in coding.
        
         | 9rx wrote:
         | _> Rails can 't be rewritten in C_
         | 
         | It could if you added message passing to C.
         | 
         | Which we have, and DHH admits that Rails took directly from
         | that. Rails is (loosely) a rewrite of what was originally
         | written in C [with extensions].
        
       | rors wrote:
       | I was big fan of Scala a decade ago. The idea of a "scalable
       | language" where DSLs could be built within the type system seemed
       | super powerful. I lost my enthusiasm when the community decided
       | they wanted to use it as Haskell on the JVM.
       | 
       | I'm hoping more recent developments, like WASM or Graal, provide
       | a route for more flexibility when selecting languages. It's nice
       | to see Rust slowly become a serious choice for web development.
       | Most of the time JS is fine, but it's good to have the option to
       | pull out a stricter low-level language when needed.
        
         | vjerancrnjak wrote:
         | Haskell is usually used as a DSL. I believe Haxl is used at
         | Meta and TidalCycles is a good example of another DSL built in
         | Haskell.
         | 
         | Although I agree the usual lens, optics, machines, pipes or
         | other higher kinded libs are completely unnecessary, solving
         | problems you do not want to have and have dire performance
         | implications, but are at least correct and allow you to throw
         | code at problems quickly, even though that code sucks in all
         | ways except correctness.
        
           | antonvs wrote:
           | I don't agree that pipes should be in your list, at least for
           | some use cases. Streaming data through pipes gives
           | capabilities that systems written in more traditional ways
           | often simply don't match. Look at the use of the Stream API
           | in Java for an example of the utility of this outside of the
           | Haskell context.
           | 
           | Pipes also don't necessarily have "dire performance
           | implications", but it depends a lot on the implementation.
           | Haskell libraries don't always emphasize real world
           | performance as a top criterion. E.g. see
           | https://github.com/composewell/streaming-benchmarks for some
           | truly wild variations in performance across libraries
           | (disclaimer: I haven't investigated or verified those
           | numbers.)
        
         | sambuccid wrote:
         | I recently started to learn Scala and I love it, also for it's
         | functional aspect. Regarding your comment, it feels like scala
         | is generic enough to be used also in other ways, and
         | definitively for DSLs. What do you think it's missing?
        
           | hibikir wrote:
           | I think the GP is thinking about how libraries and ecosystems
           | are often more important than the language. Most emphasis in
           | scales is in a collection of competing frameworks that,
           | today, are very FP oriented. Some hide the category theory
           | while others put it up front, but it's ultimately what you
           | do. The libraries that wanted to do imperative OO lost most
           | support.
           | 
           | Also see, for instance, Java. There's Java, the language that
           | keeps improving, and then the Spring ecosystem, which is what
           | 95% of programmers end up having to use professionally, with
           | its heavy "magic" component. Writing services avoiding Spring
           | is going against the grain. It might as well be part of the
           | language as far professional Java use is concerned.
           | 
           | Communities matter more than the language features, and Java
           | is all Spring, and now Scala is really a choice of Zio and
           | Cats
        
         | dkarl wrote:
         | > I lost my enthusiasm when the community decided they wanted
         | to use it as Haskell on the JVM
         | 
         | It's not the whole community, not by a long shot. Don't judge
         | Scala by the Scala subreddit.
         | 
         | Most new things you'll see written about Scala are about
         | solving difficult problems with types, because those problems
         | are inexhaustible and some people enjoy them, for one reason or
         | another. Honestly I think this shows how easy and ergonomic
         | everything else is with Scala, that the difficulties people
         | write about are all about deep type magic and how to handle
         | errors in monadic code. You can always avoid that stuff when it
         | isn't worth it to you.
         | 
         | The type poindexters will tell you that you're giving up all
         | the benefit of Scala the moment you accept any impurity or step
         | back from the challenge of solving everything with types, and
         | you might as well write Java instead, but they're just being
         | jerks and gatekeepers. Scala is a wonderful language, and
         | Scala-as-a-better-Java is a huge step up from Java for writing
         | simple and readable code. It lets you enjoy the lowest hanging
         | fruit of functional programming, the cases where simple
         | functional code outshines OO-heavy imperative code, in a way
         | that Java doesn't and probably never will.
        
         | kayo_20211030 wrote:
         | Reminds me of a joke.
         | 
         | I have a problem.
         | 
         | Right, I'll design a DSL.
         | 
         | Hmm. Now I have two problems.
        
         | Cthulhu_ wrote:
         | That's the main issue I found with Scala, and as I grow older
         | also with certain libraries (especially in unit testing land)
         | that try to add a language / DSL on top. Not only do you need
         | to learn Scala, you need to learn various DSLs on top of that
         | depending on what you use or want to achieve. Some egregious
         | examples here and there.
         | 
         | I'm sure there's good use cases for it - one impressive example
         | at the time was using functional programming to create Hadoop
         | map / reduce jobs, a oneliner in Scala was five different files
         | / classes in Java. But for most programming tasks it's
         | overkill.
         | 
         | You _can_ write boring code in Scala, but in my (limited)
         | experience, Scala developers don 't _want_ to write boring
         | code. They picked Scala not because it was the best tool for
         | the job, but because they were bored and wanted to flex their
         | skills. Disregarding the other 95% of programmers that would
         | have to work with it.
         | 
         | (And since these were consultants, they left within a year to
         | become CTOs and the like and ten years on the companies they
         | sold Scala to are still dealing with the fallout)
        
           | dionian wrote:
           | i use scala because i can write more expressive and
           | simpler/safer code than java language.
        
           | athenot wrote:
           | > You can write boring code in Scala, but in my (limited)
           | experience, Scala developers don't want to write boring code.
           | They picked Scala not because it was the best tool for the
           | job, but because they were bored and wanted to flex their
           | skills. Disregarding the other 95% of programmers that would
           | have to work with it.
           | 
           | Intersting observation.
           | 
           | So basically Scala is to the JVM what Perl is to scripting?
        
             | vaylian wrote:
             | You can write readable Scala code, just like you can write
             | readable Perl code. But both languages allow you to to
             | write very concise and cryptic code as well. Scala doesn't
             | seem to optimize for the "one obvious solution" approach
             | like Python does. Scala seems to be more TIMTOWDY like
             | Perl.
             | 
             | Scala was designed from the beginning to support classical
             | Java-style OOP code and also Haskell-like functional code.
             | These are 2 very different styles in one language. And then
             | Scala supports defining DSLs which give you even more
             | flexibility.
        
           | tasuki wrote:
           | You can write boring code in Scala, but in my (limited)
           | experience, Scala developers don't want to write boring code.
           | Guilty as charged!
           | 
           | > They picked Scala not because it was the best tool for the
           | job, but because they were bored and wanted to flex their
           | skills.
           | 
           | Guilty as charged!
           | 
           | > Disregarding the other 95% of programmers that would have
           | to work with it.
           | 
           | No. Your coworkers end up being the other 5% of programmers
           | that have the same taste as you. Interviewers ask about
           | monads and lenses. It's fine, as long as everyone is on the
           | same page. Which... they kind of have to be.
        
         | morshu9001 wrote:
         | Doing fancy things with types used to interest me, now it's the
         | last thing I want to touch, after being burned too many times
         | by libs trying to be clever.
         | 
         | I used Scala a few times when it was semi popular, just seemed
         | like Java but with lots of redundant features added. Not sure
         | what the aim was.
        
           | dionian wrote:
           | then why is java adding back half baked versions of scala
           | features every major release
        
             | morshu9001 wrote:
             | Cause it actually needed lambdas and things that go with
             | it. Didn't need all the Scala-specific data structs like
             | Array.
             | 
             | And the most important thing Java was always missing until
             | recently, virtual threads, were lacking in Scala too.
        
             | EricRiese wrote:
             | Lambdas weren't simple to shoehorn into Java. But most of
             | the recent changes have been implemented as well or better,
             | or as well as you could imagine while maintaining backwards
             | compatibility and Java-ness.
             | 
             | Records/sealed interfaces (ADTs) are quite clean.
             | 
             | Text Blocks are better in Java IMO. The margin junk in
             | Scala is silly.
        
             | brabel wrote:
             | Saying that the new Java features are half baked, to me,
             | shows you're just feeling hurt because people prefer Java
             | over your favourite language.
             | 
             | Java may not be the pinnacle of programming languages, but
             | since Java 8, pretty much every feature it's added has been
             | absolutely excellently done.
        
               | dionian wrote:
               | i mean, it follows the java philosophy (preseving
               | backward compat). theyve done great work improving java.
               | but i see no reason to use it over scala where i get
               | better features, its more like a java 2.0
        
           | tasuki wrote:
           | > I used Scala a few times when it was semi popular, just
           | seemed like Java but with lots of redundant features added.
           | Not sure what the aim was.
           | 
           | Blub is a great language!
        
         | willtemperley wrote:
         | Hopefully project Panama will see better interoperability with
         | libraries using the C memory model however migration does not
         | appear to be easy. Arrow Java still uses sun.misc.Unsafe for
         | native memory access.
        
         | antfarm wrote:
         | Have you tried Clojure(Script)? It could be just what you need,
         | bottom-up programming in a Lisp-like language essentally means
         | extending the langauge in order to solve the problem at hand.
         | 
         | Or, as Paul Grahmam put it in his 1993 book _On Lisp_ : " _a
         | bottom-up style in which a program is written as a series of
         | layers, each one acting as a sort of programming language for
         | the one above_ "
         | 
         | https://paulgraham.com/progbot.html
         | 
         | https://www.paulgraham.com/onlisptext.html
         | 
         | Here is a talk that explains the concept in Clojure, titled
         | _Bottom Up vs Top Down Design in Clojure_ :
         | 
         | https://www.contalks.com/talks/1692/bottom-up-vs-top-down-de...
        
         | cbeach wrote:
         | Scala is a fantastic language and in fact I'd say it's the
         | language that proves the article wrong.
         | 
         | Java was the language where "write libraries instead" happened,
         | and it became an absolute burden. So many ugly libraries,
         | frameworks and patterns built to overcome the limitations of a
         | simple language.
         | 
         | Scala unified the tried-and-tested design patterns and library
         | features used in the Java ecosystem into the core of its
         | language, and we're better off for it.
         | 
         | In Java we needed Spring (urghh) for dependency injection. In
         | Scala we have the "given" keyword.
         | 
         | In Java we needed Guava to do anything interesting with
         | functional programming. FP features were slowly added to the
         | Java core, but the power and expressivity of Java FP is woeful
         | compared what's available at the core of Scala and its
         | collections libraries.
         | 
         | In Java we needed Lombok and builder patterns. In Scala we have
         | case classes, named and default parameters and immutability by
         | default.
         | 
         | In the Java ecosystem, optionality comes through a mixture of
         | nulls (yuck) and the crude and inconsistently-used "Optional".
         | In Scala, Option is in the core, and composes naturally.
         | 
         | In Java, checked exceptions infect method signatures. In Scala
         | we have Try, Either and Validated. Errors are values. It's so
         | much more composable.
         | 
         | There's so much more - but hopefully I've made the point that
         | there's a legitimate benefit in taking the best from a mature
         | ecosystem and simple language like Java and creating a new,
         | more elegant and complete language like Scala.
        
       | duesabati wrote:
       | I completely disagree with the post.
       | 
       | All programming languages are equivalent meaning their level of
       | expressiveness is the same, it's not an opinion it's a fact. Each
       | language comes with its runtime and its peculiarities but
       | potentially you can always make any feature that another language
       | runtime has with any language, even though probably not with the
       | same performance and efficiency has been that feature native to
       | the runtime itself.
       | 
       | So there are no "more powerful languages" just runtimes that
       | allow you to hide away some stuff considered stable enough that
       | they become some kind of primitive for the programmer, now we may
       | have different opinions on what elegant code is, but personally
       | I'd like to avoid code that directly (i.e. no kind of
       | abstraction) relies on runtime features and instead express
       | clearly my intention in code, but I recognize the productivity
       | gains.
        
         | Verdex wrote:
         | You may be thinking of turing completeness. All turing complete
         | languages can compute the same functions. And in that way they
         | are equivalent.
         | 
         | However, not all languages are turing complete. See, for
         | example, charity: https://github.com/dobesv/charity
         | 
         | Furthermore, turing completeness says nothing about
         | expressiveness or capability. Imagine a language that has no
         | IO. Such a language would be able to compute any function any
         | other language can but not do anything viewable by the rest of
         | the world. So obviously not equivalent.
         | 
         | And w.r.t. expressiveness, there is some academic research into
         | how to quantify that:
         | https://www2.ccs.neu.edu/racket/pubs/scp91-felleisen.pdf
        
           | duesabati wrote:
           | I understand and agree, what I was trying to say is that one
           | should not confine ones thinking by the constraints of a
           | tool, would it be a programming language or whole framework,
           | but to express everything as freely as possible without
           | details of implementation only then one can go deeper and add
           | concreteness that brings its set of constraints and all of
           | this should be possible in any programming languages.
           | 
           | I hope I've cleared my standpoint.
        
         | patrickmay wrote:
         | Are you familiar with https://paulgraham.com/avg.html?
        
           | duesabati wrote:
           | No I wasn't, it was a really interesting read thank you, but
           | that blog post seem to me like an argument for me not the OP
           | point of view, because if you refuse to understand how things
           | work by blindly delegating to libraries and frameworks (like
           | RoR) you become a "Blub" programmer that thinks in the way of
           | constructs and decisions that the library/framework authors
           | made.
        
             | patrickmay wrote:
             | It does directly address your claim that there do not exist
             | "more powerful languages."
        
               | duesabati wrote:
               | Yeah I can see that, but that lisp feature is not
               | exclusive to lisp, if you know what you want and what you
               | are doing you can implement the very same thing in any
               | other language, you may say it is convenient that lisp
               | already has it, but it does not make it more powerful. I
               | don't know list, but there will surely be something that
               | is missing from it that another language has it, now I
               | ask you which is more powerful? See? Everything is
               | relative to what you want to do. The very author of the
               | blog you shared is falling in the same set of programmers
               | he wants to criticize because now he thinks in lisp macro
               | and the very moment he cannot use lisp, he will feel lost
               | but has he stopped and thought that what he needed was
               | something to manipulate code at compile time he could
               | have used any language
        
       | jmmcd wrote:
       | The best example of all is Prolog. It is always held up as the
       | paradigmatic representative of logic programming, a rare language
       | paradigm. But it doesn't need to be a language. It is really a
       | collection of algorithms which should be a library in every
       | language, together with a nice convention for expressing Prolog
       | things in that language's syntax.
       | 
       | (My comment is slightly off-topic to the article but on-topic to
       | the title.)
        
         | bwestergard wrote:
         | Are there any particularly excellent examples of prolog
         | implemented as a library you could point us to?
        
           | chii wrote:
           | not OP, but for clojure : https://github.com/bobschrag/clolog
        
           | khaled_ismaeel wrote:
           | Not exactly prolog, but logic programming implemented as a
           | library/DSL: https://minikanren.org/
        
             | jayd16 wrote:
             | If it's a DSL then it's "writing a new language" and you're
             | just calling from a native API, no?
        
             | EricRiese wrote:
             | Clojure's core.logic is based on minikanren, so that fits
             | the bill.
        
           | exe34 wrote:
           | not prolog but logical programming in python:
           | https://sites.google.com/site/pydatalog/
        
           | ramses0 wrote:
           | My time to shine!
           | https://news.ycombinator.com/item?id=45902088
           | 
           | References were Racket with the Racklog library1. There's
           | also Datalog2 and MiniKanren, picat, flix. There were tons of
           | good comments there which you should check out, but PySwip
           | seemed like "the right thing" when I was looking at it:
           | https://github.com/yuce/pyswip/
           | 
           | ...documentation is extremely sparse, and assumes you already
           | know prolog, but here's a slightly better example of kindof
           | the utility of it:
           | 
           | https://eugeneasahara.com/2024/08/12/playing-with-prolog-
           | pro...
           | 
           | ...ie:                   # ya don't really care how this
           | works         prolog.consult("diabetes_risk.pl")
           | # ...but you can query into it!         query =
           | "at_risk_for_diabetes(Person)"         results =
           | list(prolog.query(query))
           | 
           | ...the point being there's sometimes some sort of "logic
           | calculation that you wish could be some sort of regex", and I
           | always think of prolog as "regexes for logic".
           | 
           | One time I wished I could use prolog was trying to figure the
           | best match between video file, format, bitrate, browser,
           | playback plugin... or if you've seen
           | https://pcpartpicker.com/list/ ...being able to "just" encode
           | all the constraints, and say something like:
           | valid_config = consult("rules.pl")           +
           | consult("parts_data.pl")           +
           | python.choice_so_far(...)             rules.pl: only_one_cpu,
           | total_watts < power_supply(watts)        parts_data.pl:
           | cpu_xyz: ...; power_supply_abc: watts=1000        choices:
           | cpu(xyz), power_supply(abc), ...
           | 
           | ...this is a terribly syntactically incorrect example, but
           | you could imagine that this would be horrific code to
           | maintain in python (and sqrt(horrific) to maintain in
           | prolog), but _that's_ the benefit! You can take a well-
           | defined portion and kindof sqrt(...) the maintenance cost, at
           | the expense of 1.5x'ing the number of programming languages
           | you need to expect people to know.
        
           | dunham wrote:
           | As an example of a use case, "Gerrit Code Review"[1] is
           | written in Java and uses prolog for the submit rules.[2]
           | 
           | I haven't looked into the implementation. But taking a brief
           | glance now, it looks interesting. They appear to be
           | translating Prolog to Java via a WAM representation[3]. The
           | compiler (prolog-cafe) is written in prolog and bootstrapped
           | into Java via swi-prolog.
           | 
           | I don't know why compilation is necessary, it seems like an
           | interpreter would be fast enough for that use case, but I'd
           | love to take it apart and see how it works.
           | 
           | [1]: https://www.gerritcodereview.com/ [2]: https://gerrit-
           | documentation.storage.googleapis.com/Document... [3]:
           | https://gerrit.googlesource.com/prolog-
           | cafe/+/refs/heads/mas...
        
         | chii wrote:
         | i treat it like i treat SQL.
        
         | slaymaker1907 wrote:
         | I think the examples others have highlighted show the problem
         | with just making it a library. They're all lacking a lot of
         | features from Prolog, particularly in terms of optimization.
         | Just use Prolog if you need its features and invoke SWI-Prolog
         | like you'd call any other language's interpreter.
        
           | whstl wrote:
           | Agree. The optimization caveat also applies to OOP, another
           | example someone threw in above.
           | 
           | Sure you can implement OOP as a library in pretty much any
           | language, but you'll probably sacrifice ergonomics,
           | performance and/or safety I guess.
        
         | ModernMech wrote:
         | But why _should_ it be though? You haven't really addressed
         | that. It's like saying "Haskell shouldn't be its own language,
         | it should just be a couple of features like lambdas integrated
         | into a JavaScript library". Well if you do that you get some
         | nice features in JavaScript but you've done away with the whole
         | value proposition of pure functional programming. That's an
         | actual loss, there's something to be said for maintaining a
         | pure set of features that gives languages different properties
         | and guarantees you can't get with "everything is just a lib to
         | an imperative language"
        
           | kevindamm wrote:
           | Pure functional programming _and_ lazy evaluation.. sure, you
           | could create classes and a meta-function that selectively
           | eval 's thunks at a time, but the call site of that kind of
           | library would look atrocious..
           | 
           | You might be able to hack on some of the datatype semantics
           | into JS prototype-based inheritance (I'd rather start with
           | TypeScript at that point, but then we're back at the "why
           | isn't it a library" debate) to keep those ontologies from
           | being semantically separate, but that's an uphill battle with
           | some of JS's implicit value conversions.
           | 
           | I consider Logic Programming languages to be the go-to
           | counterargument to TFA but yeah, anything with lazy eval and
           | a mature type system are strong counterexamples too.
        
         | pjmlp wrote:
         | Except when implemented as library it doesn't take advantage of
         | WAM and related JIT.
        
         | RHSeeger wrote:
         | By that same logic, we don't need object oriented features in a
         | language, because we have closures and can get the same
         | functionality with a library.
         | 
         | Sometimes, having a language with a distinct syntax is nicer.
        
           | HelloNurse wrote:
           | Typically, what's nicer is the absence of other features that
           | interfere with the important ones.
           | 
           | For example, Prolog isn't a general purpose functional or
           | imperative language: you can assert, retract and query facts
           | in the automatically managed database, risking only incorrect
           | formulas, inefficiencies and non-monotonicity accidents, but
           | not express functions, types, loops, etc. which could have
           | far more general bugs.
        
           | vjerancrnjak wrote:
           | I like how classes escape closures but then dependency
           | injection frameworks have to work around that because now it
           | is hard to think of construction as passing arguments to
           | functions in the correct order.
           | 
           | I am so glad LLMs eliminate all of that and just call
           | functions in the right order.
        
             | marcosdumay wrote:
             | > I am so glad LLMs eliminate all of that
             | 
             | When LLMs do something, it's always because everybody was
             | already doing it.
             | 
             | The noise you see online about it exists exactly because
             | most people don't understand and can't use DI.
        
               | vjerancrnjak wrote:
               | No, LLMs like NextJS style injection as much as anyone.
               | 
               | There is nothing magical about topological sort and
               | calling constructors in the right order, which is all DI
               | is.
               | 
               | I dislike it a lot, it is exactly like any other
               | construct that allows you to throw code at anything in a
               | way that sucks (Haskell lens, optics, monad
               | transformers).
               | 
               | It allows people to granularize the whole codebase to the
               | point where you can't do much about it. For most, they
               | should just stick with functions, no one can build 100
               | levels deep function callstacks without it being
               | cumbersome, but DI makes it a breeze.
        
         | JoelMcCracken wrote:
         | The only languages I know that can do prolog-like-constructs
         | as-a-library are lisps, or at least langs that have reasonable
         | symbol constructs. Usability is way way worse if you can't talk
         | about variables as first class objects.
         | 
         | I was talking to Bob Harper about this specific issue (context
         | was why macro systems are important to me) and his answer was
         | "you can just write a separate programming language". Which I
         | get.
         | 
         | But all of this is just to say that doing relational-
         | programming-as-a-library has a ton of issues unless your
         | language supports certain things.
        
           | vlovich123 wrote:
           | I believe Rust uses datafrog, Datalog as a library to
           | implement some of its next gen solvers for traits and
           | lifetimes. Not a lisp and maybe this still isn't as elegant
           | as you had in mind? Curious how this library compares for
           | you.
           | 
           | https://github.com/rust-lang/datafrog
        
             | eru wrote:
             | Haskell can do the same, and does with a lot of little
             | embedded DSLs.
        
             | brabel wrote:
             | If you want to see what it looks like when you actually
             | embed Datalog in your language, have a look at Flix:
             | https://flix.dev/
             | 
             | (Select the "Usinag Datalog..." example in the code sample
             | dropdown)
             | 
             | The Rust code looks completely "procedural"... it's like
             | building a DOM document using `node.addElement(...)`
             | instead of, say, writing HTML. People universally prefer
             | the declarative alternative given the choice.
        
         | bux93 wrote:
         | The main thing about prolog isn't the algorithms. In fact, the
         | actual depth-first search isn't even part of the standard.
         | 
         | The nice thing about prolog is that you write logical rules,
         | and they can get used in whatever order and direction that is
         | needed. By direction, I mean that if you define "a grandparent
         | is the parent of a parent", you can now use that rule not just
         | to evaluate whether one person is a parent (or to find all
         | grandparents) but also to conclude that if you know someone is
         | a grandparent, and they are the parent of some one, then that
         | person is someone's parent. Ok, it can also do recursion, so if
         | you define an ancestor as a parent or the parent of an ancestor
         | it will recurse all the way up the family tree. Neat.
         | 
         | You could write some kind of runtime that takes c code and
         | brute-forces its way from outputs to inputs, except that
         | regular imperative code allows for all kinds of things that
         | make this impossible (e.g. side-effects). So then, you'd be
         | limited to some subset, essentially ending up with a domain
         | specific language again, albeit with the same syntax as your
         | regular code, rather than those silly :- symbols (although LISP
         | looks much sillier than prolog IMHO).
         | 
         | What the article is getting at is that if you use some features
         | specific to a language, it's hard to embed your code as a
         | library in another language. But is it? I mean, DLLs don't need
         | to be written in the same language, there's stuff like JNI, and
         | famously there's stuff like pytorch and tensorflow that runs
         | CUDA code from python.
        
           | eternityforest wrote:
           | Debugging rarely works correctly between languages, and
           | features like "find all references" usually break too. Maybe
           | that's not an issue with Prolog because a C logic solver
           | would also be hard to debug, but it's a problem with many
           | template languages.
        
         | tannhaeuser wrote:
         | The syntax of Prolog is basically a subset of the language of
         | First Order Logic (sans quantifiers and function symbols), it
         | doesn't get any more minimal than that. What's special in
         | Prolog compared to imperative languages including functional
         | languages is that variables aren't "assigned" but implicitly
         | range over potential values until satisfying the context, like
         | in math formulas for sets. Yes you can express that awkwardly
         | with tons of type annotations and DSL conventions so that you
         | never have to leave your favourite programming language. But
         | then there's the problem of a Prolog "engine" doing quite a bit
         | more than what could be reasonably assumed behind a synchronous
         | library call, such as working with a compact solution space
         | representation and/or value factoring, parallel execution
         | environment, automatic value pruning and propagation, etc.
         | 
         | The integration of a Prolog backend into a mainstream stack is
         | typically achieved via Prolog code generation (and also code
         | generation via LLMs) or as a "service" on the Prolog side,
         | considering Prolog also has excellent support for parsing DSLs
         | or request/responses of any type; as in, you can implement a
         | JSON parser in a single line of code actually.
         | 
         | As they say, if Prolog fits your application, it fits _really_
         | well, like with planning, constraint solving, theorem proving,
         | verification /combinatoric test case enumeration, pricing
         | models, legal/strategic case differentiation, complex
         | configuration and the like, the latter merely leveraging the
         | modularity of logic clauses in composing complex programs using
         | independent units.
         | 
         | So I don't know how much you've worked hands on with Prolog,
         | but I think you actually managed to pick about one of the worst
         | rather than best examples ;)
        
         | jandrese wrote:
         | Prolog is great because when it works it feels like magic. You
         | give it some pragmas and it tells you the answer. The downside
         | is when it doesn't work it also feels like magic. It's not easy
         | to reason about the amount of work it needs to do. If your
         | Prolog program is taking a long time to run it is hard to
         | figure out if it is going to take 2 hours or 4,000 millennia.
        
         | nine_k wrote:
         | Prolog is a contrived example. It's small and simple enough to
         | be implemented as a DSL embedded in another language, reusing
         | most of the parser and leaningn its execution logic.
         | 
         | Now try to produce a library that adds compile-time features:
         | static types, lifetimes, the notion of const and constexpr,
         | etc. You can, of course, write external tools like mypy, or use
         | some limited mechanism like Java annotations. But you have a
         | really hard time implementing that in an ergonomic way (unless
         | your language is its own metalanguage, like Lisp or Forth, and
         | even then).
         | 
         | Creating a library that alters the way the runtime works, e.g.
         | adding async, is not entirely impossible, but usually involves
         | some surgery (see Python Twisted, or various C async libs) that
         | results in a number of surprising footguns to avoid.
         | 
         | Frankly, even adding something by altering a language, but not
         | reworking it enough to make the new feature cohesive, results
         | in footguns that the source language did not have. See C#'s
         | LINQ and exceptions.
        
         | rienbdj wrote:
         | Think of Prolog the language as just a serialization of a
         | Prolog AST. The AST could be constructed in any programming
         | language as a library. But what if we want to share and store
         | these ASTs? We can serialize them to Prolog the language! The
         | language has value even if it's a library.
        
       | vhantz wrote:
       | > Stanza provides an optional type system, garbage collection,
       | and a multimethod based object system. But if you don't like
       | Stanza's object system, there is no way to write your own. This
       | is one of the main directions of programming language research.
       | Can we design a language so expressive that library writers can
       | easily write the most appropriate object system, or most
       | appropriate type system, to fit their application? Perhaps one
       | day we'll have such a language.
       | 
       | We already have it. It's an obscure little language called C++.
       | Tise interested in those kinds of extensions to a language should
       | look into Herb Sutter's experiments with cppfront:
       | https://hsutter.github.io/cppfront/welcome/overview/
        
         | lelanthran wrote:
         | C++ is most definitely not it.
         | 
         | Lisp is what you are after if you want to include some object
         | system as a library, or a new type of switch statement as a
         | library or a new kind of if statement as a library.
         | 
         | C++ can do none of that.
        
           | AnimalMuppet wrote:
           | C++ can do some of that. Let's say I want an if statement
           | that takes an integer and three blocks of code. It executes
           | the first block if the integer is less than zero, the second
           | if it is zero, and the third if it is positive.
           | 
           | OK, if you squint enough that by "block of code" you mean
           | closure, or function object, then I can write that in C++. I
           | can make the if statement a free-standing function (that is,
           | not a member of a class), and add it to any library I wish.
           | 
           | Now, you can say that it's going to be tedious to use that,
           | because you have to set up three closures every time you want
           | to call this "super if". And you'd be right, but that's a
           | different argument.
        
             | philipallstar wrote:
             | How can you declare new syntax in C++? Wouldn't it just be
             | a function call?
        
               | AnimalMuppet wrote:
               | Yes, a function call. Not new syntax. But as a function,
               | it would be trivial to add to a library.
               | 
               | My point was that you can often get the effect you want
               | with no new syntax. (Cue 10,000 replies that state "but
               | you can't get _this_ effect without new syntax! " Perhaps
               | not. Many of those tend to be rather contrived, though.
               | I'm more sympathetic to the argument that new syntax
               | would make something less clumsy. If it's something you
               | need to do a lot, that matters.)
        
               | DonHopkins wrote:
               | You can always use macros! Just look at how beautiful and
               | elegant and easy to learn and transparent to debug the
               | Microsoft C++ MFC COM/OLE/IDispatch/ActiveX object system
               | macrology is. /s
               | 
               | https://learn.microsoft.com/en-us/cpp/mfc/tn038-mfc-ole-
               | iunk...
        
             | munificent wrote:
             | One problem is that closures don't actually behave like
             | blocks. Consider that you might want to use this three-
             | legged-if inside a loop. If it's a real statement, then
             | those branches can have `break;` and `continue;` statements
             | which affect the surrounding loop. If those branches are
             | just closures being passed to a function, then they can't.
        
             | lelanthran wrote:
             | > OK, if you squint enough that by "block of code" you mean
             | closure, or function object,
             | 
             | But we aren't squinting here; those closures can't perform
             | a return where your `new-if` function is being used, they
             | can't perform a `return` like a proper `if` can, you can't
             | goto, or break or continue.
             | 
             | It's just a function taking functions, with all the
             | restrictions that that entails.
        
       | css_apologist wrote:
       | > Are Java developers just not as competent as Ruby programmers?
       | 
       | years ago a senior developer close to me said "when screening
       | interviews, if i see rails i throw the resume in the trash"
       | 
       | so ironic how trivial/stupid these language-based judgements are
        
         | unkulunkulu wrote:
         | I couple of years ago I would ask to collect your coworker's
         | garbage bin :)
         | 
         | Not as easy to find in my vicinity, at least good ones, which
         | is of course true for any language and profession in general.
         | 
         | I have RoR on my resume and very fond of it.
        
         | wiseowise wrote:
         | > years ago a senior developer close to me said
         | 
         | What was the senior's stack?
        
           | oompydoompy74 wrote:
           | I'm going to assume Google Docs.
        
         | madmountaingoat wrote:
         | One side of my brain agrees that's a dumb way to judge anyone
         | but then when I think about the accepted filtering mechanism
         | they really aren't any better or any worse. You cannot
         | interview everyone and ultimately you're looking for some
         | combination of competence, alignment, drive and social fit.
         | Filtering on where you worked previously or where you went to
         | school or whether you can pass some coding challenge only
         | partially fills in the matrix. And the size and shape of the
         | organization can drive how much people in the hiring loop look
         | at each data point. This senior engineer's ideal for alignment
         | and social fit probably favored people who think like them or
         | their department's head.
        
         | 725686 wrote:
         | If one is looking for Java developers, it only makes sense to
         | throw rails resumes in the trash. It will save time for both
         | parties.
        
         | 9rx wrote:
         | To be fair, years ago Rails was what all the "bootcamp"
         | programmer mills were pushing. Only you have the full context,
         | but absent of that it is likely that Rails was truly found to
         | be associated with poor applicants. Not because of anything
         | about Rails itself, but because of those "bootcamps" not
         | developing quality people. The culling has to occur at some
         | point. If you throw some great developers out with the
         | bathwater, so be it. There isn't enough time in the day to
         | worry about them.
        
         | kitd wrote:
         | I would go so far as to say the rise of Rails and the downfall
         | of J2EE being concurrent was not entirely accidental. I
         | have/had no particular affiliation for Rails, but it
         | demonstrated how to write simple, opinionated backend code, and
         | that inspired a flurry of Java/JVM web frameworks that tried to
         | follow a similar pattern and eventually gave us libraries like
         | DropWizard, Javalin, SparkJava, even Spring Boot to some
         | extent.
        
         | hansvm wrote:
         | On the one hand, that obviously filters out many qualified
         | candidates.
         | 
         | On the other, you only have so much time in the day. It'd take
         | me 3-6 months to give phone screens to every resume that comes
         | in the door for any one engineering role, 8x that for a full
         | 4-hour interview. I have to filter through them somehow if it's
         | my job to hire several people in a month.
         | 
         | You'll obviously start with things that are less controversial:
         | Half of resumes are bot-spam in obvious ways [0]. Half of the
         | remainder can easily be tossed in the circular filing bin by
         | not having anything at all in their resume even remotely
         | related to the core job functions [1].
         | 
         | You're still left with a lot of resumes, more than you're able
         | to phone screen. What do you choose to screen on?
         | 
         | - "Good" schools? I personally see far too much variance in
         | performance to want to use this as a filter, not to mention
         | that you'd be competing even more than normal on salary with
         | FAANG.
         | 
         | - Good grades? This is a better indicator IME for early-career
         | roles, but it's still a fairly weak signal, and you also punish
         | people who had to take time off as a caretaker or who started
         | before they were mature enough or whatever.
         | 
         | - Highest degree attained? I don't know what selection bias
         | causes this since I know a ton of extremely capable PhDs, but
         | if anything I'd just use this to filter out PhDs at the resume
         | screening stage given how many perform poorly in the interviews
         | and then at work if we choose to hire them.
         | 
         | - Gender? Age? ... I know this happens, but please stop.
         | 
         | If there's a strong GitHub profile or something then you can
         | easily pass a person forward to a screen, but it's not fair to
         | just toss the rest of the resumes. They have a list of jobs,
         | skills, and accomplishments, and it's your job to use those as
         | best as possible to figure out if they're likely to come out on
         | top after a round of interviews.
         | 
         | I don't have any comment on rails in particular, but for a low-
         | level ML role there are absolutely skills I don't want to see
         | emphasized too heavily -- not because they're bad, but because
         | there exists some large class of people who have learned those
         | skills and nothing else, and they dominate the candidate pool.
         | I used to give those resumes a chance, and I can't accept 100:1
         | odds anymore on the phone screen turning into a full interview
         | and hopefully an offer. It's not fair to the candidates, and I
         | don't have time for it either.
         | 
         | And that's ... bad, right? I have some things I do to make it
         | better in some ways (worse in others, but on average trying to
         | save people time and not reject too many qualified candidates)
         | -- pass resumes on to a (brief) written screen instead of
         | outright rejecting them if I think they might have a chance,
         | always give people a phone screen if they write back that I've
         | made a mistake, revisit those filtering rules I've built up
         | from time to time and offer phone screens anwyay, etc -- hiring
         | still sucks on both sides of the fence though.
         | 
         | [0] One of my favorites is when their "experience" includes
         | things like how they've apparently done some hyper-specific
         | task they copy-pasted from the job description (which exists
         | not as a skills requirement but as a description of what their
         | future day-to-day looks like), they did it before we pioneered
         | whatever the tech in question was, they did it at several FAANG
         | companies, and using languages and tools those companies don't
         | use and which didn't exist during their FAANG tenure. Maybe
         | they just used an LLM incorrectly to touch up their resume, but
         | when the only evidence I should interview you is a pack of
         | bold-faced lies I'm not going to give the benefit of the doubt.
         | 
         | [1] And I'm not even talking about requiring specific languages
         | or frameworks, or even having interacted with a database for a
         | database-adjacent role. Those sorts of restrictions can often
         | be too overbearing. Just the basics of "I need you to do
         | complicated math and program some things that won't wake me up
         | at night" and resumes that come in without anything suggesting
         | they've ever done either at any level of proficiency (or even a
         | forward or a cover letter stating why their resume appears
         | bare-bones and they deserve a shot anyway).
        
       | patrickmay wrote:
       | > Can we design a language so expressive that library writers can
       | easily write the most appropriate object system, or most
       | appropriate type system, to fit their application?
       | 
       | Why yes, it can and has been done:
       | https://www.dreamsongs.com/Files/ECOOP.pdf
        
       | unkulunkulu wrote:
       | For me the title is a bit of a contradiction: I always think
       | about the library as "the final language". So author's example of
       | RoR/Ruby is "RoR is a great web service language that uses Ruby
       | as the base, they evolved together and arguably as RoR is the
       | main source of clients for ruby, ruby was as well designed for
       | RoR as RoR for ruby"
       | 
       | I think about programming/design as languages/translation in a
       | lot of ways: its languages all the way down.
        
         | oaiey wrote:
         | I agree. c# and asp.net core also co-developed. Interestingly
         | in both direction, towards users (tons of type inference,
         | removing boilerplate, ...) and system (writing highly optimized
         | web servers with low level paradigms)
        
       | kayo_20211030 wrote:
       | Any language/library needs to communicate in two directions: to
       | the machine and to the people. At the micro-level, machines work
       | with bits, or voltages, or whatever. That's a technological
       | problem, not easy, but tractable in a mechanical sense.
       | 
       | People, on the other hand, work with ideas, metaphors,
       | expressions of intent, etc. If a language/library makes the
       | communication of those things easier/better/faster; if it can be
       | "written down" clearly, and "read" clearly by a person, then does
       | it really matter into which taxonomic category it fits? We pick
       | horses for courses. That seems about right.
       | 
       | If Rails works for you, is complementary with what you want to
       | achieve, is an accelerator, and is generally well-understood by
       | the people with whom you work, then use it. Alternatively, if the
       | answer to all the previous is Stanza then go with that. There's
       | less "right" and "wrong" in those decisions than there is
       | "advance", or "struggle". It sounds trite. But, use what works.
       | If something doesn't work make something that does, _iff_ that 's
       | the most efficient approach.
        
       | igt0 wrote:
       | Logic systems are a good place where the library first approach
       | tends to work well: you keep a small, boring core (the inference
       | engine), and let people extend it with predicates,
       | rules/operators, and domain packages.
       | 
       | I've been experimenting with a small defeasible-logic core
       | (argumentation semantics + priorities + conflict detection) that
       | stays stable, while most of the real meaning lives in extension
       | points. https://github.com/canto-lang/canto-lang
        
       | morshu9001 wrote:
       | "The more powerful the language, the easier the libraries are to
       | use." for anyone thinking of reading the title without the body
       | 
       | It's true, you couldn't really do Express in Java, at least not
       | back then.
        
         | newsoftheday wrote:
         | I don't understand, what's Express? As for libraries and Java,
         | I'd argue Java became a well established enterprise language
         | and platform exactly because it makes such highly effective use
         | of libraries.
        
           | morshu9001 wrote:
           | It's the NodeJS webserver
        
         | oaiey wrote:
         | See C#'s asp.net core minimal apis (a express clone). So it is
         | definitely possible but you need to co-develop the language. I
         | think as you point out.
        
         | didip wrote:
         | It's possible to have something like Express, take a look at
         | Javalin.
         | 
         | But Java problem is not the mechanics, it's that the community
         | doesn't want nice things.
        
           | morshu9001 wrote:
           | Kinda now that Java has lambdas, but still async in that
           | disn't work as easily as JS, which is important. This is only
           | recently starting to change with Project Loom.
        
           | brabel wrote:
           | Javalin was inspired by https://sparkjava.com/ which was
           | inspired by Sinatra (which I think also inspired Express?).
           | 
           | Anyway, libraries like this were only really feasible after
           | Java 8 because of the reliance on lambdas. Having to
           | instantiate anonymous nested classes for every "function" was
           | a total pain before that.
        
       | agumonkey wrote:
       | it's strange cause for some devs (lispers, smalltalkers,
       | forth..ists), the language is the core, and any concept is to
       | become a generic linguistic trait (and everything will be build
       | by composing expressions with these traits).
       | 
       | yet at the same time, clojurists love the idea of doing lots of
       | dsl libraries..
        
       | rambambram wrote:
       | There is a good web framework for C. It's called PHP. ;)
        
         | oaiey wrote:
         | I think you stretch this library thought a bit too far :)
        
       | defactor wrote:
       | Java has Grails web framework. We have designed apps with 75%
       | less resources and time compared to Spring at a big enterprise.
       | But most devs wanted springboot.
        
         | newsoftheday wrote:
         | Grails requires Groovy, though you can integrate Java classes
         | into a grails app.
         | 
         | Now that we can develop script style with Java 21, I'd like to
         | see something like Grails that worked with Java only...that
         | would be a fun way to develop web apps. I liked Grails, just
         | not Groovy.
        
       | sriku wrote:
       | This looks to me like partly a false dichotomy. We can design
       | languages _and_ write libraries. Some would even argue that some
       | kinds of  "libraries" could be viewed as languages themselves, as
       | much as some languages might as well have been written as
       | libraries in another language.
       | 
       | Also often, the language doesn't live isolated from its
       | implementation (compiler or interpreter). While theory looks at
       | languages via its semantics, in practice as the OP notes it is
       | about the quality of the implementation and what can be
       | reasonably done with the language.
       | 
       | A recent [1] case is Julia. I think it has hit a kind of sweet
       | spot for language design where new performant code tends to get
       | written in Julia rather than in some other language and bound to
       | it. At its core, it is a simple "call functions, passing data in
       | and getting results out" kind of language, but what the functions
       | ("methods") mean and how the compiler does just-ahead-of-time
       | compilation with deep type specialized code means you can write
       | high level code that optimizes very well. Those mechanics operate
       | under the hood though, which makes for a pleasant programming
       | experience ... and there are loads of cutting edge packages being
       | written in Julia. It is less interesting to look at Julia as
       | "just the language".
       | 
       | [1] recent in programming languages is perhaps anything <= 15
       | years? .. because it takes time to discover a language's
       | potential.
        
         | jonny_eh wrote:
         | > This looks to me like partly a false dichotomy
         | 
         | Wasn't that the point of the article? That you need both?
        
           | Jtsummers wrote:
           | Yes, but most of the commenters didn't read the article.
        
             | jonny_eh wrote:
             | Yup, articles like this where the title is the opposite of
             | the article's message is a trap to reveal that.
        
       | dieggsy wrote:
       | I think I mostly agree with the thesis here, but I actually liked
       | the point in the title at face value, too. We need both, I think.
       | I guess I'll be another annoying Lisp guy, but:
       | 
       | > At this point, the right question to ask would be, well can you
       | write a static-typing library for Scheme that then automatically
       | checks your code for type errors? And the current answer, for now
       | and for the foreseeable future, is no. No mainstream language
       | today allows you to write a library to extend its type system.
       | 
       | The author seems to provide a counter example themselves(?):
       | 
       | > Racket and Shen provide mechanisms for extending their type
       | systems...
       | 
       | I wonder if this is as clear-cut as the author is making it out
       | to be. Coalton, which is effectively a library (and language) for
       | Common Lisp, seems like it basically does this. Maybe that's not
       | exactly what the author is referring to, because it is
       | essentially a new language on top of Lisp using its meta-
       | programming facilities, as opposed to merely extending the type
       | system. Still, it can be used as a library right alongside Lisp
       | code, so I think it's in the same spirit of of the first question
       | of writing a "static-typing library that automatically checks
       | your code" in a dynamic language.
       | 
       | Standard scheme may or may not be able to do this, but most
       | Scheme implementations have unhygienic macros like CL's too, so
       | I'd assume something similar would be possible. The fact that
       | that these tend to be extensions from implementation designers
       | might align with the article's point though. Also somewhat to the
       | author's point, Coalton does rely strongly on CL's underlying
       | type system, for which there's no real equivalent in Scheme. It
       | also relies on implementation-specific optimizations alongside
       | that.
       | 
       | For what it's worth you can (and indeed people have) written
       | object systems in Scheme, despite the language not having one,
       | though they tend not to be performant, which is likely another
       | point towards using/writing a different language. CL also tends
       | to allow fairly deep extension of its object system through the
       | Meta-object Protocol.
       | 
       | I guess my point is that in my (probably biased) opinion, Lisps,
       | or other languages with very strong meta-programming facilities,
       | are pretty close to the language longed for in "Perhaps one day
       | we'll have such a language." They aren't a silver bullet, of
       | course. CL has no easy way to write performant
       | coroutines/continuations, for example, even given all its
       | extensibility. Scheme has no real type system, etc. etc.
       | 
       | I don't think any of this invalidates the articles points, I'm
       | just not sure I agree with the absolutes.
        
       | bluGill wrote:
       | Languages are "Easy" to design. There is nothing wrong designing
       | a new language and it can be fun.
       | 
       | There is however something wrong with releasing your new
       | language! In most cases you should show it off to close friends,
       | or your professor, and then burn it and all the source. Sure you
       | might be better than the current language, but you won't be
       | enough better as to be worth it. (even if the language is
       | notoriously bad C++ where it is easy to be better - you won't be
       | enough better as to be worth it).
       | 
       | If you want a better language there are two good options: switch
       | to a different one that already exists; or make your language
       | better. There are lots of great choices for languages out there
       | if you want to switch. If the language you are thinking of
       | doesn't have an active community of people working on making it
       | better, it probably isn't a good choice.
       | 
       | Whichever language you choose though, libraries are the hard
       | part. There are a lot of bad libraries, we need someone to write
       | a better one - but only if one doesn't exist! For the great
       | libraries out there, most need someone to contribute.
       | 
       | A large part of libraries is the consistent interface. Often
       | there is a great libFoo and libBar, but their APIs are not
       | consistent and so we need a libBarWithFooStyleInterface, and/or
       | libFooWithBarStyleInterface. Better yet, we need everyone to come
       | together and agree on how the interface should be and then make
       | both use that new standard - cleaning Augean stables with a
       | toothbrush seems like an easier task. Of course in the real world
       | there a hundreds of libraries each with a great interface that is
       | not consistent with the others.
        
         | zabzonk wrote:
         | > then burn it and all the source
         | 
         | Nah, don't do that. You will enjoy looking back at it in your
         | old age. I wish I had all my old code now.
        
           | bluGill wrote:
           | fare enough. So long as you don't inflict it on the world as
           | something they might really use it is fine.
        
       | newsoftheday wrote:
       | The article seems to vibe railing against Java.
        
         | ActorNightly wrote:
         | Nothing wrong with that. Log4shell should have been the end of
         | everyone using Java.
        
       | Arch-TK wrote:
       | The problem is really that sometimes making something feel
       | ergonomic in a language can be a pain.
       | 
       | Although that in itself might be a hint to change language and
       | write your library there, instead of inventing a new one.
        
       | taylorallred wrote:
       | I agree with the sentiment of this article but the question that
       | fascinates me is "when do you need a language feature instead of
       | a library in order to accomplish X, Y, or Z?"
        
         | oaiey wrote:
         | Well there are really bad languages. Like ABAP or SQL. But even
         | in higher languages like Java, you sometimes loose
         | expressiveness
        
       | 6510 wrote:
       | Libraries and languages are not actually about syntax or
       | function. They are communities first. They each have a community
       | of users and one of developers. Depending on their application
       | they each attract very different people - which is wonderful.
       | 
       | The work matters too of course. Frequently used functions should
       | be categorically bagged into libs and if the lib is used often
       | enough some of it's functionality should be baked into the
       | language. If languages require something often enough the
       | language layer above should provide it and if things are
       | frequently needed close to the metal it should be baked in
       | hardware. Possibly as a co-processor and then as part of the cpu.
       | We should even have a similar process moving things in the other
       | direction. I cant wait for the day when floating-point arithmetic
       | becomes a library complete with a community of people who still
       | think it's wonderful. Like a football channel to cleanly contain
       | that kind of undesirable materials. Some
       | libraries/modules/frameworks should also be replaced by competent
       | developers. We don't want a leftpad community.
        
       | kazinator wrote:
       | > In summary, the purpose of a general-purpose programming
       | language is to enable the creation of powerful and easy-to-use
       | libraries.
       | 
       | Close! The purpose of a general-purpose programming language is
       | to enable the creation of powerful and easy-to-use languages, but
       | often just libraries.
        
       | vivzkestrel wrote:
       | - i need a language that looks like typed python
       | 
       | - and runs 50 times faster than c, c++, rust and zig
       | 
       | - comes with a standard library covering 50000 use cases
       | 
       | - has direct integrations with drivers to every major database,
       | crm, analytics provider, key value store, queue systems
        
       | CyberDildonics wrote:
       | Lots of languages could just be implemented with classes in C++.
       | Every "probabilistic language" could just be types that interact
       | with each other properly.
        
       | NoGravitas wrote:
       | Of course, in Lisp, you can implement language features as
       | libraries, which kind of undercuts the point of this article.
        
       | bmc7505 wrote:
       | There are a few approaches if you want to write a new language.
       | One, as the author argues, is to write a library in an existing
       | language, which may require sacrificing ergonomics to fit inside
       | the syntax of the host language, but is safe, modular and
       | reusable.
       | 
       | Many DSLs can be bolted onto an existing language with support
       | for compiler extensions. This approach offers more flexibility,
       | but often leads to fragmentation and poor interoperability in the
       | language ecosystem.
       | 
       | There is third approach, established by a group in Minnesota [1],
       | which is to design languages and tools which are modular and
       | extensible from the get-go, so that extensions are more
       | interoperable. They do research on how to make this work using
       | attribute grammars.
       | 
       | If the host language has a sufficiently expressive type system,
       | you can often get away with writing a fluent API [2] or type safe
       | embedded DSL. But designing languages and type systems with good
       | support for meta-programming is also an active area of research.
       | [3, 4]
       | 
       | If none of these options work, the last resort is to start from
       | tabula rasa and write your own parser, compiler, and developer
       | tools. This offers the most flexibility, but requires an enormous
       | amount of engineering, and generally is not recommended in 2026.
       | 
       | [1]: https://melt.cs.umn.edu
       | 
       | [2]: https://arxiv.org/pdf/2211.01473
       | 
       | [3]: https://www.cs.tsukuba.ac.jp/~kam/papers/aplas2016.pdf
       | 
       | [4]: https://arxiv.org/pdf/2404.17065
        
         | GZGavinZhao wrote:
         | > There is third approach, established by a group in Minnesota
         | [1], which is to design languages and tools which are modular
         | and extensible from the get-go, so that extensions are more
         | interoperable. They do research on how to make this work using
         | attribute grammars.
         | 
         | MLIR [1] has entered the chat :P
         | 
         | I know I know MLIR is an IR and not a programming language, but
         | MLIR does give me the feeling of "an IR to rule them all" (as
         | long as you're ok with SSA representation), and the IR itself
         | is quite high-level to the point it almost feels like an actual
         | programming language, e.g. you can write a MLIR program that
         | compiles to C using the EmitC dialect that feels a lot like
         | writing C.
         | 
         | [1]: https://mlir.llvm.org
        
         | williamcotton wrote:
         | > _If none of these options work, the last resort is to start
         | from tabula rasa and write your own parser, compiler, and
         | developer tools. This offers the most flexibility, but requires
         | an enormous amount of engineering, and generally is not
         | recommended in 2026._
         | 
         | You mean like this?
         | 
         | https://github.com/williamcotton/webpipe
         | 
         | https://github.com/williamcotton/webpipe-lsp
         | 
         | https://github.com/williamcotton/webpipe-js
         | 
         | It's less effort if you, well, you know where I'm going with
         | this...
        
       | tjchear wrote:
       | The author makes a good point about language capabilities
       | enabling certain libraries to be written, just as DSL makes it
       | easier to reason about problems and implement solutions with the
       | right kind of abstractions and language ergonomics (usually at
       | the expense of expressivity and flexibility).
       | 
       | There's a time in my life where I designed languages and wrote
       | compilers. One type of language I've always thought about that
       | could be made more approachable to non technical users is an
       | outline-liked language with English like syntaxes and being a
       | DSL, the shape of the outline would be very much fixed and on a
       | guardrail, and can't express arbitrary instructions like normal
       | programming languages, but an escape hatch (to more expressive
       | language) for advanced users can be provided. An area where this
       | DSL can be used would be common portal admin app generation and
       | workflow automation.
       | 
       | That said, with the advent of AI assistants, I'm not sure if
       | there is still room for my DSL idea.
        
         | whattheheckheck wrote:
         | I mean that's Zapier or n8n?
        
       | hulitu wrote:
       | > "Stop Designing Languages. Write Libraries Instead" (2016)
       | 
       | It looks that somebody listened. We now have 3 GTK libraries in a
       | system, a lot of graphics libraries (cairo, etc) 3d libraries
       | (Mesa, vulkan). It is a mess.
        
       | noreplydev wrote:
       | i think that languages is are for worlds and libraries are for
       | adding ships, planes and cars to that worlds, enabling those
       | worlds itself.
       | 
       | the key is that not all worlds enable the same kinds of
       | libraries.
        
       | OkayPhysicist wrote:
       | I have to disagree about the author's described purpose of
       | programming languages. PLs exist to provide elegant expression to
       | _a curated subset_ of ways of expressing solutions to problems.
       | 
       | At the extremes, we call these paradigms. Functional languages,
       | Object Oriented languages, Array languages, etc. But every
       | language exists to make some subset of "shapes" of solutions
       | easier to read and write. Elixir encourages you to describe your
       | programs as a distributed system of programs each running a
       | series of transformations to data, thanks to its pipeline system,
       | and to push your branching to function-call level with its
       | pattern-matching multiple dispatch.
       | 
       | Java encourages you to write your application as a collection of
       | things, that know stuff and do stuff, including telling other
       | things to do stuff based on things they know.
       | 
       | C and Go encourage you to write your programs as an ordered
       | series of atomic tasks for the computer to complete.
       | 
       | SQL has you describe what you want your output to look like.
       | 
       | Etc, etc. There are inherent trade offs between languages,
       | because what you make inelegant to express or even
       | _inexpressible_ carries value, too.
        
       | scoofy wrote:
       | As a student of philosophy of language, I obviously agree with
       | the author (against the quoted thesis).
       | 
       | The structure of a language matters to the ease and feel of its
       | use, despite even being logically identical. One parallel would
       | be the syntactic benefits of something like Hintikka's
       | independence-friendly logic vs first order logic, even if they
       | are equivalent.
       | 
       | The sentiment shared is that we should sacrifice benefits to the
       | next generation to make our own lives easier. This is a common
       | sentiment, but a sad one. The goal should be a natural language
       | based programming language, that everyone can use, along side a
       | technical programming language that makes unambiguous the
       | interface between the language and the machine.
       | 
       | Everyone seems to endorse their happy medium, and those languages
       | are also perfectly fine.
        
       | butterisgood wrote:
       | I think this thinking makes sense if you've not used enough
       | programming languages pragmatically.
       | 
       | But, if you squint, great API design is a bit like embedded
       | domain specific language design as well.
       | 
       | I think there's room for both.
        
       ___________________________________________________________________
       (page generated 2026-01-07 23:01 UTC)