[HN Gopher] How big should a programming language be?
___________________________________________________________________
How big should a programming language be?
Author : ltratt
Score : 79 points
Date : 2023-03-24 07:49 UTC (1 days ago)
(HTM) web link (tratt.net)
(TXT) w3m dump (tratt.net)
| margorczynski wrote:
| What is important is not really size but consistency and "self-
| containment" - are the language constructs and semantics
| (including the std library) semantically and logically consistent
| with one another.
|
| If that's not the case it gets much harder to get your head
| around how it all works as you cannot effectively apply some
| simple pattern to all the stuff you see and you need to juggle
| different ways of thinking when doing basic stuff. And this
| propagates even further and harder to other libraries.
| voidhorse wrote:
| There's also the problem of determining how semantics and
| comprehensibility of the whole are affected by the interaction
| of parts.
|
| Adding new features to a language is always costly because you
| not only have to deal with the new semantics of the new
| feature, but with the _emergent semantics_ of how that feature
| interacts with the existing feature set. The cost of adding
| some new semantic and syntax is not just N, but N*M, where M is
| the subset of existing features that the new feature may
| interact with in some meaningful way. For example, if you add
| support for declaring a constant (separate from a variable)
| this is not just the addition of some new, isolated meaning,
| but introduces semantic difference--the programmer now needs to
| reason about variables as opposed to constants and also needs
| to discern this difference in all scopes in which the
| distinction is valid...
| bandrami wrote:
| C is about right. Common Lisp is too big and Scheme is too small.
|
| The language itself should be small but its standard library
| should be extensive, and largely written in itself. If the
| language's own implementors don't want to program in it neither
| do you.
| tmtvl wrote:
| CL too big? I dunno, the spec doesn't include very standard
| stuff that we get through the de facto standard libraries like
| ASDF, UIOP, Bordeaux threads, et cetera.
| bandrami wrote:
| The full BNF of CL's `loop` is longer than many languages'
| entire grammars, and the `format` function is Turing
| complete.
| Turing_Machine wrote:
| > Scheme is too small
|
| Some would argue that R6RS is too large, while others argue
| that R7RS (small) is too small. Maybe there's a Goldilocks
| Scheme in the middle that's just right. :-)
|
| Of course, most types of Lisp-ish languages let you grow the
| language in a way that C doesn't really (yeah, there's the C
| preprocessor, but it's far more limited that the macro
| facilities provided in most Lisp-ish languages).
| IncRnd wrote:
| > How Big Should a Programming Language Be?
|
| As big as it needs to be and no bigger.
|
| A programming language is almost always built for a purpose - to
| solve a problem or fit into a certain domain. We've all seen the
| needless complexities in programming languages that accrete new
| features, year after year, just to have new features.
| tasuki wrote:
| > A programming language is almost always built for a purpose -
| to solve a problem or fit into a certain domain.
|
| Is it? Most general programming languages have certain design
| goals, but I find these often unrelated to the domains in which
| the language ends up being used.
| orf wrote:
| I started Python with 2.4 or 2.5. It's not big, it's been many
| years since I've been actually surprised about something.
|
| Evolution, or incrementing version numbers, don't necessarily
| equal increased size.
|
| For example Python now has async functions. But it had them in
| Python 2.5 as well when it introduced generators (see the
| twisted.deferred decorator) - you'd just use "yield" rather an
| "await".
| laurentlb wrote:
| In the last 4 years, Python added features like:
|
| - new syntax for exception groups (except*)
|
| - assignment expressions (the := operator)
|
| - positional-only parameters (with a / in the parameter list)
|
| - `=` support in f-strings, e.g. f'{user=!s} {delta.days=:,d}'
|
| - new type annotation features, e.g. for variadic generics,
| type guards, unions
|
| - structural pattern matching
| orf wrote:
| With the exception of exception groups, these are all very
| simple and small additions.
|
| Does it mean Python is small? No. But that doesn't make it
| big.
| patrickkidger wrote:
| I think of Python as being a pretty big language.
|
| At a feature level there are things like descriptors and
| metaclasses, which are complex and rarely-used.
|
| There's a huge number of obscure magic methods/attributes:
| __origin__, __orig_bases__, __prepare__, __mro_entries__,
| etc.
|
| It's full of gotchas: methods are looked up on the
| instance, _except_ magic methods which are looked up on the
| class, _except except_ __getattr__ and __dir__ on module
| types. There are both __getattr__ and __getattribute__ and
| they do different things. Most `typing.Foo` (and also
| modern `list[int]`) aren 't `isinstance`-able. The use of
| += with tuples. The lack of any coherent numeric tower.
| Etc. etc.
|
| I think it's very clear that Python has grown organically,
| and is now struggling under the weight of all its bolted-on
| extra bits, or sheer unnecessary complexity. I would love
| to throw it all out and start again.
| mixmastamyk wrote:
| Guido pushed back on most new features for a long time,
| but almost a decade ago changed his tune to yes for
| anything reasonably useful. Guessing due to envy of all
| the nifty features dropping from Ruby and JS to C# and
| Kotlin.
|
| Personally, I'm not enthusiastic about the things that
| came after the f-string. (Although dict unions should
| have landed a decade prior.)
| rockzom wrote:
| I don't know, but there has to be a reason Gamemaker Language is
| so easy to pick up and play with. Imagine if C let you get away
| with murder and still compiled.
| krapp wrote:
| > Gamemaker Language var _xx = 100;
| mystruct = { a : 10, b : "Hello World",
| c : int64(5), d : _xx + 50, e : function(a, b)
| { return a + b; }, f : [
| 10, 20, 30, 40, 50 ], g : image_index };
|
| It's been a _long_ time since I 've look at GML but it looks
| like it's turned into Javascript-lite. I do wish C had flexible
| array shorthand and something higher than function pointers to
| work with.
| analog31 wrote:
| I've always figured you can ignore the features of a language
| that you don't like, but a drawback of a giant language is that
| it's hard for beginners to read code, or to make sense of
| tutorials that all use different ways of doing something.
|
| You can always put extra features into a library, and identify
| certain libraries as "standard." So it seems reasonable to demand
| that actual language changes are limited to those where the
| readability benefit outweighs the need for everybody to learn the
| new feature in order to read code.
|
| As mentioned in other posts, a huge sprawling language makes it
| hard to gauge whether someone is proficient in a language when
| applying for a job. I don't really know how important that should
| be.
|
| In my case, I got a low score on a Python knowledge test because
| I've been programming in Python for a decade but haven't kept up
| with the latest features. Not that I'm looking for a job, but I
| was just curious, and it was part of figuring out what kind of
| training I should get.
| pavlov wrote:
| To me, Objective-C 1.0 was the perfect size (before Apple added
| properties and stuff in 2007). As long as you avoided the
| weirdest undefined corners of C, it felt like you could
| understand every construct available and its performance
| implications without needing to read the docs or ask Google.
|
| Maybe it's just the rose-colored memories of a first love.
| boucher wrote:
| I totally agree. I loved that you could understand more or less
| the entire language's set of additions to C by reading one
| relatively short document.
|
| JavaScript used to have the same appeal, before it started
| evolving. Despite the rough edges and some poor decisions, you
| could still grok the entire thing pretty quickly and appreciate
| how it works.
|
| Of course, I have my own bias here, but it really did feel like
| they fit well together in Objective-J.
| yannis wrote:
| The core language should be small enough so that a programmer can
| remember all its features. This makes for efficient and quick
| programming. The rest should be in standard or community
| libraries. In my book over the last few years only Go and Lua
| meet the criteria.
| craftuser wrote:
| This Guy Steele talk is related to this topic:
| https://www.youtube.com/watch?v=lw6TaiXzHAE
|
| A good watch for the fine people in this thread (and please
| ignore explicit or implied linkages to Java--it's full of the
| broad concepts, not narrowly JVM stuff)
| golem14 wrote:
| "big enough to reach the ground" ?
| erik_seaberg wrote:
| If a language ignores common problems we all face, it's too
| small.
|
| If a competent professional can't become fluent in a year, it's
| too big. But I have pretty low regard for people who complain
| when it takes longer than a weekend. This is part of what we're
| paid to do, and the investment in your toolbox will pay off for
| the rest of your career. I still use _ideas_ that came from
| languages I can't officially use right now.
| ipaddr wrote:
| PHP always had everything you needed built into the language.
| Coming from a C background and moving to a Javascript lifestyle
| php always offered you everything you need out of the box and
| extensions for that little bit more.
| mamcx wrote:
| What is very, very tricky is that the language get bigger the
| harder is to do composability. And "composability" is far bigger
| and broader than the normal understanding.
|
| For example, consider Rust that is built around the idiom of
| composability (aka: Traits).
|
| Is nice, until you get async, custom allocaters + runtimes,
| const, how do macros, type reflection, code generation, etc...
|
| Each thing is something user want to make code more composable
| and flexible. But each thing is also a big thing: You can make a
| WHOLE LANG around just one of that!
|
| ---
|
| Lisp, Forth and similar make easy "syntax composability" -not
| solve all the rest- that is probably the bare minimum. This is
| the MAJOR "flaw" of algol-like languages.
|
| For example, I wish Rust allow: struct Person
| {name:String} struct User: +Person {pwd:String} //not
| inheritance: Copy of fields! let u = User {..}
| let p = Person::copy_from(u) for f in p.iter_fields():
| //walk over name:String, pwd:String
|
| With lisp/relational/array like paradigms this stuff is easy. But
| algol-like languages are too "nominal" and lack the ways to
| manipulate the construct without resorting to macros, that are
| for most cases a band-aid.
| ChadNauseam wrote:
| Type theorists have been talking about this too. The search
| term is "rows" or "row polymorphism". They're awesome but no
| mainstream language uses rows. I wrote about them in my blog
| post about 4 issues facing functional programming [0]. Also,
| check out Unison [1], which is mostly structural but "pretends"
| to be nominal in a way that I feel would be very appealing to
| most programmers.
|
| [0]: https://chadnauseam.com/coding/pltd/four-issues-facing-fp
|
| [1]: https://www.unison-lang.org/
| justinpombrio wrote:
| OCaml has row polymorphism. The syntax for a function that
| prints `name` from a record that has `name` and possibly
| other fields is: val print_name: <name:
| string; ..> -> unit
| magicalhippo wrote:
| > For example, I wish Rust allow:
|
| What kind of problems would this solve? Not trying to be
| snarky, just to understand the feature.
| mamcx wrote:
| What this example show is that you can't manipulate the
| "things" that are expressed in syntax as data, so you can't
| have the same way to deal with both types and values:
| struct Person{name:String} + struct User{pwd:String} = FAIL!
| ["Person", ("name", "String")] + ["User", ("pwd", "String")]
| = possible!
|
| Because types are not even third-class, you need to resort to
| "hacks" like macros, generics and other stuff like that.
|
| Now, what it solve? almost _everything_.
|
| (you can see how this could work in static lang with Zig
| comptime https://kristoff.it/blog/what-is-zig-comptime/)
|
| In short, you get what inheritance promise without the OO,
| easy reflection, easy code generation, simpler macro
| implementation, easy way to do generics, easy way to copy
| to/from different types that are almost similar (ie:
| structurally)...
|
| The amount of stuff you will simplify is massive.
|
| Some of this feel is what make the "dynamic" languages their
| power. Now making it work on static lang is more tricky (you
| wanna keep everything as if you were coding it by hadn't and
| the types all resolved at compile time) so is likely required
| to be restricted and only a second-order citizen, but it will
| make some much easier!
| magicalhippo wrote:
| Seems like you want a code generator. For some problems I
| admit I have missed a proper, integrated code generator. C
| macros is, like you say, hacky.
|
| However, personally I strongly dislike dynamic languages
| for anything beyond simple programs, ie <100 LOC. Gets way
| to hard to reason about the code, since you never know what
| a function returns. In Python for example I invariably end
| up sprinkling dir(...) all over when modifying code.
|
| So it would have to be used sparingly I think.
| Vanit wrote:
| Hard to do the wrong thing, easy to do the right thing.
| WoodenChair wrote:
| This is related to my main issue with Swift.
|
| It started out as a very usable, mid-sized language, with many
| tooling issues. Now it is a kitchen-sink language with almost
| every imaginable feature (and more coming!) that still has
| tooling issues. It's no longer as pleasant to read unless you
| keep up on the latest additions. You can't easily read code that
| uses the myriad of new features without a long weekend learning
| what every property wrapper in this particular program means and
| how to use the new feature of the month.
|
| In my opinion while it was still a mid-size language, they should
| have fixed all of the tooling issues, and then very incrementally
| over a long period of time added new features. Instead it's more
| of a "move fast and break things" culture. Which is not what I
| want in the evolution of a programming language.
| rubiquity wrote:
| I completely agree. It feels like the designers of Swift gazed
| into the C++ abyss too much. I really wanted it to be an
| ergonomic systems language. Zig now fills that void for me.
| b3morales wrote:
| Some core designers of Swift, at least Doug Gregor, John
| McCall, Dave Abrahams, were very much part of the C++ world.
| Abrahams mentions Gregor's proposals for C++ here:
| https://youtu.be/6JYAXADQmNQ?t=1157
| Conscat wrote:
| Yet still Swift can't even get move semantics. :/
| saagarjha wrote:
| They're working on it; it's a complicated feature.
| nurettin wrote:
| It feels like swift went into an evolutionary arms-race against
| csharp and typescript.
| Someone wrote:
| I have the feeling Swift is more complex than it needs to be,
| too, but can new high-level languages really be simple?
| Nowadays, you need a memory model, async, generics, value and
| reference types, move semantics, concurrency, full Unicode
| support, etc.
|
| Go tries to solve that, but gets criticized for its simplicity.
|
| Also, I suspect part of the friction writing Swift isn't
| language complexity but tooling issues. to what effect that's
| true is hard to say of course. For example, compilation
| slowness introduces friction, but I wouldn't know whether
| that's inherent or solvable.
|
| There also are a lot of "the compiler could be smarter" things
| that do not change the vision of the language, but do affect
| its ease of use. Such warts make the language harder to write
| than necessary. _If_ those issues can be fixed, the language
| can become easier to write. An example is
| https://github.com/apple/swift-
| evolution/blob/main/proposals....
|
| As to that _if_ , I wouldn't know whether that holds. For
| example, https://github.com/apple/swift-
| evolution/blob/main/proposals... begot
| https://github.com/apple/swift-
| evolution/blob/main/proposals.... Both were implemented in 5.7,
| but I wouldn't know whether those left any rarer warts or even
| introduced new ones, or if that process ever will stop.
|
| If that process cannot stop, I think it's better to leave a few
| warts that programmers will soon encounter and learn about than
| many very rare ones that, when encountered, will make
| programmers pull all their hairs out because googling them only
| produces "I changed Foo and the compilation error went away"
| results or StackOverflow pages without answers.
| Larrikin wrote:
| Any specific examples?
|
| I looked at Kotlin and Swift at the same time some years back
| and they seemed extremely similar. I didn't enjoy ios
| development and am currently an Android developer. I've been
| using Kotlin for a while now and it's easily my favorite
| language.
|
| Did Swift take a wrong turn somewhere that set it on such a
| different path from Kotlin?
| crop_rotation wrote:
| Golang is really the best example of a minimal language (Yes yes
| I know late to generics and all that). I think it works because
| they have spent huge amounts of effort to create a well designed
| and fairly comprehensive standard library. The best example of
| this is io.Copy. You give it a reader and writer and it does an
| optimal copy in almost all cases.
|
| A minimal language that doesn't have resources like Golang to put
| in the stdlib is just not gonna work.
| voidhorse wrote:
| I agree. I've grown to really love Go the more I've used it and
| gotten the chance to compare it to other languages. There's a
| certain "completeness" and philosophical consistency to it
| that's really hard to find in other languages these days imo
| (some older languages, like Standard ML, C, Scheme, and some
| others also achieve this) because I think a lot of language
| designs now evolve more organically instead of being formally
| thought out up front.
| pcwalton wrote:
| Go evolved very organically. Look at the inconsistency in the
| way nil slices vs. maps work, for instance, or the way
| comparisons against nil for interfaces work. Go may be simple
| to explain at a high level, but the details are very complex.
| fndex wrote:
| You might like Clojure.
| capableweb wrote:
| For me, C-like languages like Golang don't come close to be as
| minimal as lisp-like languages. I agree that the standard
| library of Golang is smaller compared to it's contemporaries,
| but the language itself is not small, there is a bunch of
| syntax to be learned compared to languages like Clojure, where
| the actual language is tiny, and the standard library on the
| bigger side.
| raincole wrote:
| Technically it's true. But Lisp-like language (e.g. Scheme)
| is so minimal, to a point that everyone basically invented
| their own DSL inside it to get the jobs done. And the you
| ended up with a minimal language... and several sub-
| languages.
| thrown123098 wrote:
| [dead]
| crop_rotation wrote:
| A language like scheme is much simpler yes, but scheme or
| even Common Lisp don't have anywhere near as comprehensive a
| lib as Golang, which is what you need to create real systems.
| erik_seaberg wrote:
| There's a lot missing from Go's stdlib, including obvious
| uses for its builtin types. If you want Common Lisp's
| (remove-if-not #'oddp #(1 2 3 4 5))
|
| you have to write a loop from scratch, and then everyone
| has to read it carefully to learn what it's doing (and
| especially what it's not).
|
| Don't get too excited about having HTTP or JSON built in,
| we weren't using those in 1990 and they'll surely be
| replaced by 2050.
| epgui wrote:
| This probably won't make sense to most people who haven't
| used lisp at work for real work, but...
|
| You just really don't need much to get stuff done with a
| lisp.
| mattbee wrote:
| Your example exposes an edge of Go that speaks to this essay.
|
| Yes io.Copy works with any Reader and Writer but dig into the
| documentation and there's a _runtime_ check for the revised
| ReaderFrom and WriterTo interfaces that you might also
| implement for faster performance. It 's just something you have
| to know, otherwise you will _not_ get an optimal copy.
|
| Go 1 is right on the edge of being a big language, but what
| might stop it is that Google don't need it to get any bigger.
| ojkelly wrote:
| As much as I've been loving Rust, there's no doubt it's a hard
| but rewarding journey to learn it.
|
| Go on the other hand, is a language I'm still confident I can
| teach a junior enough to be useful in an afternoon.
|
| The restraint shown by the Go team is admirable in how well
| they've stuck to their vision.
| Animats wrote:
| > I think it works because they have spent huge amounts of
| effort to create a well designed and fairly comprehensive
| standard library. ... A minimal language that doesn't have
| resources like Golang to put in the stdlib is just not gonna
| work.
|
| Yes. Rust suffers from this problem. The language is now
| reasonably solid, but library quality and stability is all over
| the place. I've been annoying people in the Rust community by
| saying that it's time to get all widely used crates (over a
| million downloads, or depended upon by a widely used crate) to
| version 1.x. After that, no breaking changes without a major
| version change. Crates with re-exported types from lower levels
| force groups of crates into lockstep update.
|
| The big advantage of Go is that the libraries for doing server-
| side web stuff are the ones used internally by Google. So
| they've been thoroughly exercised. The obscure case that comes
| up once in a trillion transactions probably happened a hundred
| times in the last hour in a Google server farm.
| fbdab103 wrote:
| I want a step further than upgrading libraries to 1.0. I
| really want the Rust foundation to package up the essential
| libraries (bikeshedding to ensue, but something akin to
| Python or Go), and release those as a single, annual
| distribution. Even better if they could standardize the API
| across all of the packages, ensure minimal unsafe, etc. The
| `rust_stdlib_v2023` could only depend upon itself, and would
| be a basis for which other projects could then build from
| there.
|
| It annoys me to no end the huge number of packages I pull in
| for doing something "simple". It is great that packages can
| be so small and focused, but now I have a real trust problem.
| How am I possibly supposed to ensure there are no malicious
| actors in my dependency tree?
| Animats wrote:
| There's already a standard library. After that, there's
| just whatever anybody decided to upload to "crates.io".
| Nothing in between. Some form of curation and quality
| control is needed, at least for crates depended upon by
| other widely used published crates.
|
| The Rust foundation's crate manager job is apparently
| vacant until at least April, so nobody is officially in
| charge of this.
|
| Relevant XKCD: [1]
|
| My take on this for game development: [2]
|
| [1] https://imgs.xkcd.com/comics/dependency_2x.png
|
| [2] https://www.reddit.com/r/rust_gamedev/comments/11b0brr/
| were_...
| fbdab103 wrote:
| Well that is exactly what I think should change. I do not
| want to have to pull in a package for regex, parsing
| json, generating a random number, counting the number of
| available cpus, etc. Quite a lot of standard
| functionality required across a broad swath of projects.
| I understand Rust does not want to bring them into core,
| but I think there should be a middle ground that offers
| richer functionality to the language without the wild-
| wild-west of crates.io.
| danpalmer wrote:
| There's a pre-supposition in the community that bigger languages
| are typically worse, but I'm not sure that's true. There are also
| multiple ways to measure language "size" and most arguments I've
| seen conflate language features and standard library (which can
| often have overlap).
|
| As counter-examples, I'd raise the Wolfram language (and maybe
| Matlab, but I haven't used that) as an example of a truly _vast_
| language - in terms of "standard library". On the other hand
| almost all criticism of Go has historically revolved around it
| being too small.
| simonw wrote:
| I've started pondering what a language would look like that was
| optimized for LLMs, where token length is the most important
| budget.
|
| Maybe a language with 10,000 keywords would actually be better in
| LLM world?
| bruce343434 wrote:
| Fewer "decorations". I imagine it would look more like Ocaml
| than Rust or C++ because the grammar of Ocaml is such that you
| don't really need brackets or braces or parentheses most of the
| time. And "system" languages like C++ and Rust are notorious
| for being symbol soup, which is unavoidable if you want to
| control every single detail of every single thing.
| boucher wrote:
| Are you designing for LLM to LLM communication, or do you still
| expect humans to understand and work with this language?
| tester756 wrote:
| I don't see problem with growing languages as long as designers
| are doing their job.
|
| There's difference between adding features randomly and putting
| effort into making it obvious, transparent, integrated well into
| the ecosystem and overall UX.
|
| UX is something that languages and API designers must put more
| effort into.
|
| Start creating APIs with assumption that people have no access to
| documentation - it makes everybody's life easier. Just take a
| look at .NET BCL - it's very well designed. They even wrote a
| book about framework / libraries design basing on their decades
| of experience.[0]
|
| Also "small language" is relative.
|
| If you have started doing X lang development decade ago then that
| version of language is "small" to your perception. For somebody
| who started 5 years ago it was small 5 years ago.
|
| The point is that at every point language have some features
| which aren't popular because they serve some specific cases which
| are required for somebody.
|
| Very often those features are required for base class libraries
| makers so they can create either good API, or have good
| performance/safety, or anything else.
|
| For me it seems like programming languages and its ecosystems
| lack of deprecation process which actually removes stuff.
|
| [0] - Framework Design Guidelines: Conventions, Idioms, and
| Patterns for Reusable .Net Libraries
| CharlieDigital wrote:
| C# is getting "too big", IMO. (20+ years as my primary lang but
| doing a lot of TypeScript over the last 3)
|
| There's really good new stuff like switch expressions and
| pattern matching.
|
| But it feels like TypeScript is in a better place. I would love
| to see a "T#" - a trimmed down, more modern C# that makes
| certain tradeoffs and defaults.
|
| Maybe that's F# (spent some time with it), but it diverges a
| bit too much from C family syntax.
| burakemir wrote:
| There are two different ways to go about this question:
|
| - asking about the scope of a programming language is asking
| about the intended programming situations one wants to cover.
|
| - what is a good balance between convenience (sytactic sugar,
| "features" and abstractions) and asking the programmers to write
| out things explicitly.
|
| - more subtly: who is using the language, what concepts can be
| expected to be known to the programmers.
|
| These are of course connected: a particular type of recurring
| programming situation may lead one to think of patterns and a
| need to abstract them, whereas to someone who intentionally
| constrains the scope to a specific area, it can be easier to keep
| the number and kind of source or "programmer intent" abstractions
| low.
|
| Often these discussions happen in the context of a general
| purpose language but there is little consideration that some
| programming situations are better served by DSLs.
|
| Also a decision on "MIT vs "New Jersey" (worse-is-better) style
| affects the whole thing, as the notion of correctness is at some
| level always one of programming situations (a higher level
| discussion on using the API right way, checking error conditions
| etc)
|
| Thus is a long-winded way to say: in the end the starting point
| matters. C++ can be considered a failure language design if you
| consider it from the readability/cognitive load angle but design
| choices seem to consistently be about permitting all possible
| choices. This is why Stroustrup can claim things like "you can
| write memory safe C++" and not even be wrong. Java can be
| considered a failure in concision but tool support means that
| programmers do not pay the cost of writing everything out
| explicitly.
|
| Haskell and anything in the academic tradition will emphasize
| abstractions and demand more and more knowledge from users
| whereas industry tradition will be biased towards low (or lower)
| cognitive overhead, but if one is willing to specialize, there is
| an infinite number of nuances of possible points in the design
| space. We will see more programming languages and come to accept
| that there will be many that we use at the same time.
|
| So rather than asking how big, maybe we should wonder how to
| understand the involved trade-offs.
| SideburnsOfDoom wrote:
| > know a lot less about languages like C# and the like, but I
| wouldn't be surprised if they've gone, or are going, through
| something similar.
|
| 100% true, it is. More keywords in each release. More ways to do
| things.
|
| e.g. Now we use "record" and "with" keywords, and operators such
| as "a!.b" or "a?.b" .
|
| And we set projects up with "implicit usings", and "file-scoped
| namespaces" which do the same thing will less indenting.
|
| While I like all of these, the downside is yes, it's an ever-
| expanding language.
| christophilus wrote:
| I programmed in C# for roughly the first 15 years of my career.
| Then, Ruby, Go, TypeScript. Going back to C#, it does feel
| bloated. It's accreted a lot more complexity since I stopped
| using it (just before .Net Core).
|
| I'd love to have a TypeScript language with the standard
| library, single binary output, and build speed of Go.
| schemescape wrote:
| What you're describing sounds a lot like Deno (or at least
| where Deno is headed):
|
| https://deno.land/manual@v1.32.1/tools/compiler
| tester756 wrote:
| While I could agree with you about those "!" "?"
|
| then definitely disagree about implicit using or file scoped
| namespaces
|
| There's nothing new in terms of keywords about them, concept
| itself very simple
|
| and makes code more readable and shorter, that's it.
|
| It's just: "hey, some namespaces are very, very popular - let's
| make it this way, that you don't have to include them
| everywhere"
|
| and "hey, why every code is one level indented if everyone is
| using one namespace per file anyway?"
|
| It just simplifies stuff, can we honestly call it an expansion
| of language?
| foobarbaz33 wrote:
| > hey, why every code is one level indented if everyone is
| using one namespace per file anyway?
|
| I would even take it 1 step further. Specify the class name
| at the top of the file, 0 indentation for functions.
| Kwpolska wrote:
| C# does not mandate having one class per file. (Java
| doesn't for non-public classes either.) While I suppose
| many (most?) devs/projects have adopted this rule, there
| are cases where it makes more sense to keep related stuff
| in one file.
| SideburnsOfDoom wrote:
| C# also did not mandate having one namespace per file.
| Devs have adopted a "one namespace per file" rule because
| it's generally a good idea. So now the new "file scoped
| namespaces" allows only 1 namespace per file; and if you
| want more than that, well then your namespace can't be
| file-scoped, by definition. You can still use namespaces
| with { } in that case.
|
| The same _could_ be done with type declaration such as
| classes and interfaces. If it would be beneficial idea is
| another thing.
| Kwpolska wrote:
| Sure, but "one namespace per file" is a much more obvious
| idea than "one class per file" (especially with C# IDEs
| aggressively tying namespaces to the filesystem layout).
| SideburnsOfDoom wrote:
| > There's nothing new in terms of keywords about (implicit
| using or file scoped namespaces)
|
| And I didn't imply that they were new keywords, they were
| examples of the second category, "new ways of doing things".
| The text "do the same thing" alludes to that.
|
| > and makes code more readable and shorter, that's it.
|
| Correct, but each new ways of doing things comes at the cost
| of there now being (at least) two ways to do the same thing.
|
| > It just simplifies stuff, can we honestly call it an
| expansion of language?
|
| If a source file that was not legal in language version 9, is
| now legal in language version 10, then yes we honestly can
| and must call it that. It is literally an expansion of the
| subset of all possible source files, that are legal source
| files in the language.
|
| Does it "simplify stuff" if there are now 2 ways of doing a
| thing, when previously there was only one? The parser has to
| deal with both now. It depends on how you look at it, I
| think. e.g. It depends on if your code mixes them. If not
| then the code can be simpler, but as coders we have to still
| know both as we might encounter both.
| jasperkhan5 wrote:
| I'm still not clears of what it means to be big? Is the API big?
| The lines in the stand library make it big? Available syntax
| options?
| jmclnx wrote:
| I think they are referring to reserved words. Regular c list of
| reserved words has stayed rather static except for various data
| types. Where python kept added reserved works as time went on.
| skitter wrote:
| As far as I know, the C standard reserves words that
|
| - start with two underscores
|
| - start with one underscore (file scope)
|
| - start with is, to, str, mem, atomic_ or a bunch of other
| prefixes and continue with a lower case letter, consist of E
| followed by a number, and more.
|
| So the list of reserved words is rather long (infinite), and
| includes words like `string`.
| noloblo wrote:
| Haskell was a small clean language but now with the innumerable
| language extensions has become large
|
| Bash is a small clean language that has maintained its clean core
|
| Golang is the archetype of a small clean effective language that
| has tried intentionally not to become cpp and it shows the amount
| of wrangling needed to add generics to golang is a testament to
| their focus on a small language albeit imperative
| 1bent wrote:
| I haven't paid attention in many years, but at least for the
| first few years (after it grew from a data format to a scripting
| language), each release of Lua was more powerful, faster, and
| smaller in executable size, than its predecessor.
| schaefer wrote:
| I am a team lead in c++ shop. Every interview, I ask: tell me
| about c++'s std::move().
|
| Not a single interviewee has even had a good guess in 2 years of
| open job recs.
|
| It really has me reconsidering. I'm a language nerd through and
| through. I love C++. But I also have to be honest and say there's
| such a thing as "the average amount of c++ the team knows".
|
| To me, the biggest threat to C++ isn't rust, but rather the speed
| at which the language is changing. It's already past the tipping
| point.
|
| In my domain, embedded programming, I'm keeping an eye on zig
| with fingers crossed.
| lunfard000 wrote:
| man I use C++ on personal projects for opencv (and python
| perfomance is pretty bad for my use case) but oh god, I don't I
| could ever get a C++ job, there is a universe of features I
| won't dare to touch anytime soon. I just use the "modern" and
| simple stuff and code look pretty good (imo), don't have to
| deal with gibberish compiler errors (except when std::format
| goes crazy). std::move is cool though, rvalue and lvalue is bit
| too much but the performance, clear "giving up" resource and
| dont having to use pointers is worth it (I just use it for
| rvalue passing, prob there is more to it).
| jpace121 wrote:
| You could get a C++ job. One of the issues with C++ is most
| people using it for anything useful only need to know some
| particular subset, only actually know that subset, and then
| get bit when the subset they know changes.
| qsort wrote:
| > I ask: tell me about c++'s std::move()
|
| Honest question: what do you expect the answer to be?
| Pedantically, the "correct" answer is that it statically casts
| its argument to an xvalue. Is this a way to tell if the
| candidate understands value categories?
| saurik wrote:
| I think it would be more elucidating to consider the myriad
| common incorrect answers you expect to get when asking that
| question--which is what I expect they are dealing with, given
| the more about how rare even having "a good guess is"--as
| opposed to whether they are expecting a single particularly-
| correct answer.
| saagarjha wrote:
| Anything that's not that is generally incorrect in some
| way, though. std::move doesn't move, or take ownership.
| People use it anyways. The same applies to constructs like
| std::forward, or the dozen ways to do initialization. C++
| has a standard that incomprehensible to most people because
| it bends over backwards to try to come up with a unified
| set of rules for disparate behavior. Unless you're a
| library author knowing these things off the top of your
| head doesn't show much about your ability to understand
| some sort of understanding of the how C++ works, because
| there is no consistent understanding to be made. It might
| make sense to ask how std::move might work in Rust but it's
| basically trivia for C++.
| saurik wrote:
| Yeah, but like, the egregiously wrong answers you are
| likely to get that aren't even close--not to the
| underlying behavior but even to the way it is commonly
| used--are apparently so wrong you don't even list them in
| your list of wrong answers ;P.
|
| Someone who doesn't know how it works but successfully
| have ever written a move constructor (which is a bit more
| advanced than merely using one) are going to come up with
| an answer that I would personally (as not the person who
| said this... for all I know they also will be super
| pedantic) claim is "close".
|
| But, I would fully expect the majority of people you ask
| that question to will, for example, actually claim stuff
| like that the prior value is completely destroyed... not
| even merely deconstructed (which is already problematic),
| but somehow deallocated even if located on the stack,
| which is way more wrong than merely thinking std::move
| "takes ownership".
|
| I don't know if you play chess at all, but a book I
| really enjoyed (and read probably about when I was your
| age? and the existence of which--honestly more than the
| specific content--massively informed my teaching style)
| was The Amateur's Mind, which was a chess master going
| back and attempting to not as much teach chess from his
| vantage point to an amateur but to go back and explore
| the misunderstandings amateurs have about chess by way of
| interviews with amateurs about games and then trying to
| work within that mental model. I think that, even though
| we were all amateurs at one point--or even might have a
| long way to go still--it can be difficult to really
| conceptualize the gulf between what an amateur thinks and
| what you might even assume is the mistake they are
| making.
| rolenthedeep wrote:
| I have the same issues with C#. I came up in the days of .net
| 4.5, in the years since I've watched Microsoft bolt an entire
| language worth of features on top of C#. I didn't use the
| language for the last five or so years, and I feel so lost that
| I avoid using it now.
|
| And that doesn't even begin to touch on the absolute disaster
| of the net framework/core/standard/mono/uwp runtime situation.
|
| C# as a language just doesn't seem very stable. I really don't
| enjoy using it anymore.
| shrimp_emoji wrote:
| That anyone could ever have enjoyed Microsoft Java seems
| crazy to me. :p
|
| (I can't justify why I feel that way. I have middleware-
| corporate-lang dysphoria for some reason.)
| kmac_ wrote:
| I have quite opposite opinion. Every extension increased
| readibilty and cut the cruft. For example, even simple
| changes, like native tuples or expression bodied members
| tremendously changed how the language should be used and how
| the "correct" code looks.
| metaltyphoon wrote:
| Agreed, C# was too verbose and its way less now.
| programmer_dude wrote:
| C# syntax is gradually approaching F#. I'd say just use
| F# and skip the bloat.
| GiorgioG wrote:
| Maybe if Microsoft bothered to invest in and promote F#.
| teh_klev wrote:
| > C# as a language just doesn't seem very stable
|
| In what way do you think it isn't stable? I've upgraded code
| written in C# v1 to the latest and greatest and never had a
| breaking change (well except for one time where it was my own
| fault for abusing reflection).
|
| Ultimately you can use as much of the language as you want
| to, the "old" ways haven't been removed and you can still
| code like it's 2002 :)
| rolenthedeep wrote:
| I'm aware that I'm yelling at a cloud, but what really did
| it for me was nullable reference types. I get it, I
| understand why nulls are a problem and how annoying they
| can be. I've done my time in the trenches tracing nullrefs
| in production.
|
| But I just really, strongly dislike the way Microsoft went
| with the problem. Declaring types nullable with the `?`
| just puts me off. `Nullable<T>` was always something to be
| avoided, and I find the syntax just as annoying as null
| checks.
|
| Ultimately most of my complaints can be boiled down to "too
| much changed and now things are different"
| dehrmann wrote:
| > Not a single interviewee has even had a good guess in 2 years
| of open job recs.
|
| Unless a good explanation is an insta-offer, why do you still
| ask a question you've gotten zero signal from?
| [deleted]
| josephg wrote:
| > why do you still ask a question you've gotten zero signal
| from?
|
| Interview questions aren't just for comparing candidates with
| each other. It's also useful to know how a candidate's
| knowledge compares to the knowledge of the team. The best of
| a bad bunch might still be unhirable. It's often better to
| leave a role vacant than fill it with someone mediocre.
|
| If the GP can't find anyone in the hiring pool who knows C++
| well, that's a valuable insight. Maybe they need to expect
| less C++ from candidates and plan for more on the job
| training.
|
| Or change languages.
| archsurface wrote:
| Zero answer is not zero signal.
| assbuttbuttass wrote:
| std::move is kind of essential, no? You can't really use
| std::unique_ptr without it.
| sidlls wrote:
| You might be surprised at how little some (many?) programmers
| with C++ experience actually know about the language. Or any
| language, really. Our industry doesn't reward that kind of
| knowledge very much.
| johannes1234321 wrote:
| You can use std::unique_ptr without explicit std::move for
| scope bound pointers, with class members and you can even
| return unique_ptrs without std::move due to RTO. The only
| time you need std::move is when passing ownership via a
| function call. That's quite a lot of practicla use cases
| available.
|
| But I think the concern is not about being able to use it,
| but to understand what it does, std::move is nothing but a
| cast. Itself it doesn't move anything. And then there is the
| whole fun with the state of the noved-from object afterwards.
| Quite some depth to uncover.
| yeputons wrote:
| One can get really far without ever touching `std::move` or
| `std::unique_ptr`. Especially when taught about
| `new`/`delete` first. Lots of courses still teach C-esque C++
| first and students just keep to it because it's more
| explicit.
| WalterBright wrote:
| I've been reading through the proposed C23 spec. Looking at
| what's happening with enums, it's amazing how suddenly a simple
| feature became a far more complicated one. I read the spec on
| enums over and over, and still don't understand it.
|
| They're just enums, geez.
| Animats wrote:
| > I read the spec on enums over and over, and still don't
| understand it.
|
| That's from someone who has written C++ compilers.
|
| Some of the insane complexity being added to C++ comes from
| trying to emulate Rust move semantics without a borrow
| checker. An xvalue is what's left behind after you do a move.
| In Rust, the compiler guarantees that you can never access
| the remnants after a move. But in C++, someone will somehow
| manage to leak a raw pointer to something, then move it. So
| users have to know about xvalues.
|
| (Could be worse. Trying to emulate Javascript async semantics
| in everything else has resulted in some real horrors. Only Go
| has a sane solution.)
| _a_a_a_ wrote:
| The guy is not distinguishing clearly between language and
| library which undermines his point.
| steveBK123 wrote:
| I'd argue pretty small.
|
| I primarily work in a language out of the APL family.
|
| When I first started it, the entire reference page of every
| function/command/flag fit on a double sided printout in regular
| sized font.
|
| Past a certain point you just end up with overlapping versions of
| the same thing maintained for backward compatibility or slight
| differences of opinion & behaviour.
|
| I feel the same way about framework ecosystems. Some languages
| almost have too many, to the point that they are constantly being
| introduced, changed in ways that make old code non-portable, and
| then sunsetted. It's hard to keep internal corporate software
| running when if you choose something mainstream it's less than 5
| years from EOL, but if you choose something emerging it may never
| go mainstream. A lot of it seems like reinventing the wheel.
| hazelnut-tree wrote:
| There is something very appealing about learning a small(ish)
| language. However, a small language does not always mean simple.
| And it means code can be difficult to unravel.
|
| Niklaus Wirth, the creator of Pascal, Modula-2 and Oberon,
| believe strongly that teaching programming is most effective when
| students can grasp the entirety of a small language.
|
| From a 2018 interview with Wirth on the topic:
|
| > "In order to do a good experience, you have to have a clean
| language with a good structure concentrating on the essential
| concepts and not being snowed in."
|
| > "That is my primary objection to the commercial languages -
| they're simply too huge, and they're so huge that nobody can
| understand them in their entirety. And it's not necessary that
| they're so huge."
| aatd86 wrote:
| That's exactly why I appreciate Go as far as I'm concerned. =)
| And now with AI code completion, it's even better.
| rowls66 wrote:
| I am new to go, but to me, the language looks bigger than it
| needs to be. Why do slices and maps need to be part of the
| language and not just part of a standard library? I suppose
| the reason is special syntax, but having to learn that
| special syntax makes the language feel bigger.
| yakubin wrote:
| They are part of the language, because they require
| generics to be implemented if you want to implement them in
| the standard library. Go didn't use to have generics, so
| those constructs were hacked into the core language.
| rowls66 wrote:
| I see. That makes sense. So maybe it is generics that are
| so fundamental that they need to be part of any language.
| Seems that Java, C#, and Go have all learned this lesson.
| aconbere wrote:
| We, as a field, should be very careful about forgiving our
| tools of the sin of complex and tedious design because those
| flaws can possibly be remediate with LLMs.
|
| The complexity of boilerplate does not only exist for the
| author but every future author.
|
| It is not my experience that LLMs and other complex
| automations are nearly as good as refactoring and changes as
| they are at generating boilerplate in the first place. In the
| end this code lives on as a human concern despite the
| automation.
| aatd86 wrote:
| I agree. I also don't think there is a single perfect
| programming language yet.
|
| I do think however that programming languages and libraries
| are the assembly language for AIs to interface with legacy
| systems targeting human usage.
|
| So it's important for these to be easily understandable.
|
| Go fills that sweetspot better imo. Until something else
| appears perhaps.
|
| But you're absolutely right that we should make sure to
| still improve these languages and it is right to worry that
| LLM don't incentivize new languages (smaller code corpus,
| less data?). As for Go, it is improving steadily so I'm
| still confident in that regard.
| bradrn wrote:
| An interesting example of this I came across recently is Pico:
|
| > Pico is a tiny but expressive programming language that was
| especially designed to teach advance computer science concepts
| to students in other sciences than computer science ...
| Currently Pico is no longer used as a tutoring language for its
| target group, but this is more a consequence of politics than
| of the astounding results we got with teaching Pico. Today,
| Pico is used as a means to teach principles of language design,
| interpreters and virtual machines in a sophomore course for
| computer scientists and in an adjacent course in a masters
| program in applied computer science.
|
| http://pico.vub.ac.be/
| ellisv wrote:
| This makes me think of how the R language has been "slow" to make
| (some) changes and many people now use packages from the
| tidyverse. Writing R with the tidyverse can be practical
| unrecognizable to people writing with base R (and vice versa).
| smadge wrote:
| If you feel the need for a new feature in a language, you should
| ask why the language does not make it easy to build that feature
| in the language itself.
| laurentlb wrote:
| In the design of Starlark
| (https://github.com/bazelbuild/starlark), I often had to push
| back against new feature requests to keep the language simple. I
| explicitly listed simplicity as a design goal.i
|
| Of course, the scope of the language is not the same as general
| purpose languages, but there's always pressure from the users to
| add more things. I also think many people underestimate the cost
| of adding new features: it's not just about adding the code in
| every compiler/interpreter, specifying every edge-case in a spec,
| updating all the tooling for the language and writing tutorials;
| it's also a cost on everyone who will have to read any of the
| code.
| dehrmann wrote:
| A recent comment on another post described Starlark as "I can't
| believe it's not Python."
| brazzy wrote:
| It's absolutely a tradeoff requireing a cost-benefit analysis.
|
| Prior to Java 5, the language was quite simple, the spec
| readable and understandable without requiring deep knowledge of
| compilers.
|
| The introduction of generics and lambdas _massively_
| complicated the language specification. But those features also
| were huge improvements that pretty much anyone would consider
| worth the cost.
| saagarjha wrote:
| Starlark is basically just a clone of Python is it not? What's
| the policy for adding new features?
| dmurray wrote:
| > it's also a cost on everyone who will have to read any of the
| code.
|
| Everyone who will have to read the code in the compiler or
| interpreter? Or everyone who reads code in the language?
|
| I'm not so sure the latter should be a consideration. If you
| don't give people some feature they would use, they will
| develop their own idioms to accomplish the same with what the
| language does provide. And the reader then has to become
| familiar with those idioms, and repeat the process for every
| new codebase they encounter in the language. Better to have one
| good way to do it.
| laurentlb wrote:
| Of course, the feature itself brings value, so you have to
| balance the cost and the value.
|
| If something is used a lot, you can expect the reader to
| learn the pattern quickly. If something is not super common
| and not intuitive, it can make the code less readable (and
| the reader might spend a lot of time searching in the
| documentation).
|
| Two examples I've seen this week: - Python has a new keyword
| `except*` - C# has a prefix operator ^
|
| It's not obvious to me that these features are beneficial in
| general.
| shanebellone wrote:
| I love except. I use it for error handling and recovery.
| randallsquared wrote:
| `except*` seems hard to search for and easy to confuse
| with `except`, raising some ambiguity about what you
| meant, here.
| aranchelk wrote:
| Glossed over in the brief analysis of Haskell is that the
| expansion of features are:
|
| 1) Not in the language spec, just options in the de facto-
| standard compiler 2) Are often shunned by industrial users, see
| "Simple Haskell" 3) Are, among other reasons, there to support
| experimentation and research which is an important use case for
| the language 4) Are opt-in and largely unnecessary in practice,
| in my code I generally only use a couple of well known
| extensions.
| epgui wrote:
| Exactly, I really don't think they should have been considered
| in the analysis. A mention would have been appropriate.
| alwaysbeconsing wrote:
| Surprised to see no mention of Elixir so far. Its designers have
| explicitly focused on "a compact and consistent core". And indeed
| I found it very pleasant and rewarding to learn for that reason.
| Everything fits together nicely.
|
| From https://elixir-lang.org/development.html
|
| > Since v1.0, the language development has become focused to
| provide a compact and consistent core. The Elixir team focuses on
| language features that: > > 1. are necessary for developing the
| language itself > 2. bring important concepts/features to the
| community in a way its effect can only be maximized or leveraged
| by making it part of the language
|
| In other words, as I've heard it put, the language is mostly
| _not_ growing anymore. It probably helps that it has strong
| metaprogramming facilities.
| noloblo wrote:
| FP like erlang, elixir and haskell are perfectly elegant if
| only their core language features are used.
| alwaysbeconsing wrote:
| Limited experience with Haskell personally but my impression
| is that Elixir really only has the core, whereas in Haskell
| it is effectively standard to use language extensions? I
| don't know how that changes the experience.
| epgui wrote:
| We shouldn't be counting Haskell's language extensions imo.
| They're extensions because they were not accepted in the
| language (and might never be).
| anfilt wrote:
| As big as C or only a tiny bit bigger.
| lithos wrote:
| Then you end up with a JS like ecosystem where build systems
| are more complex than the language.
| kstenerud wrote:
| I'm facing this dilemma now with the Dogma metalanguage [1]. On
| the one hand, I want it to be small so that it can be picked up
| quickly and mastered easily (very important since its primary use
| case is documentation). On the other hand, it needs enough power
| to actually be useful in the real world.
|
| In the end I opted to avoid most conveniences since they can
| easily be built using a few common macros such as `u16(v) =
| ordered(uint(16,v))` and the like, except for cases where it
| would be just silly not to (like strings as syntactic sugar for
| concatenated codepoints, and regex-style repetition chars ? * +
| instead of {0|1} {0~} {1~}).
|
| But even then the spec is over 2000 lines long (admittedly the
| examples take up a fair bit of room, though).
|
| [1]
| https://github.com/kstenerud/dogma/blob/master/v1/dogma_v1.m...
| sys_64738 wrote:
| Somewhere between the size of C and C++ probably.
___________________________________________________________________
(page generated 2023-03-25 23:01 UTC)