[HN Gopher] Programming Bottom-Up (1993)
___________________________________________________________________
Programming Bottom-Up (1993)
Author : tzury
Score : 32 points
Date : 2023-12-07 07:03 UTC (2 days ago)
(HTM) web link (www.paulgraham.com)
(TXT) w3m dump (www.paulgraham.com)
| dang wrote:
| Related:
|
| _Programming Bottom-Up (1993)_ -
| https://news.ycombinator.com/item?id=16933030 - April 2018 (64
| comments)
| smlavine wrote:
| I've heard this about Lisp, but I don't really get how this
| doesn't apply to other languages. How is writing special
| operators in Lisp different from writing special functions in any
| other language?
| marcosdumay wrote:
| PG has other essays where he claims it's because the lisp
| version of operators can just do more things.
|
| And that's true, lisp macros are way more powerful than what
| most languages support. The newer ones (and some "progressive"
| old ones) got template systems that are almost as powerful, but
| the most used languages simply don't have anything comparable.
|
| That said, nowadays using a lot of that kind of feature is
| normally frowned upon.
| leetrout wrote:
| I have a theory it is frowned upon because there are not a
| lot of small shops left. Everyone wants be a cog at a big
| tech co where its leetcode interviews and code that large
| groups can (somewhat) easily maintain.
|
| In these cases the languages used are generally uniform so
| your skills easily transfer and you aren't suffering as many
| 200% problems by learning both the language and the authors
| peculiar add-ons.
|
| Of course it still happens just not as easy with rigid
| languages such as Go.
|
| It's all tradeoffs.
| jksmith wrote:
| Extreme reinforcement of your point: Read Leo Brodie's classics
| "Starting Forth" and "Thinking Forth."
| Jtsummers wrote:
| > I've heard this about Lisp, but I don't really get how this
| doesn't apply to other languages.
|
| It can be, and he even says as much:
|
| >> Bottom-up design is possible to a certain degree in
| languages other than Lisp. Whenever you see library functions,
| bottom-up design is happening.
|
| I'll also point to kazinator's quote of Ken Thompson in the
| previous discussion linked by dang:
|
| >> It is the way I think. I am a very bottom-up thinker. If you
| give me the right kind of Tinker Toys, I can imagine the
| building. I can sit there and see primitives and recognize
| their power to build structures a half mile high, if only I had
| just one more to make it functionally complete. I can see those
| kinds of things. The converse is true, too, I think. I can't--
| from the building--imagine the Tinker Toys. When I see a top-
| down description of a system or language that has infinite
| libraries described by layers and layers, all I just see is a
| morass. I can't get a feel for it. I can't understand how the
| pieces fit; I can't understand something presented to me that's
| very complex. Maybe I do what I do because if I built anything
| more complicated, I couldn't understand it. I really must break
| it down into little pieces. - Ken Thompson, Unix and Beyond: An
| Interview with Ken Thompson, 1999
|
| And if you use a TDD style of development (in particular, but
| test-heavy in general with frequent use of unit and integration
| tests below the full end-to-end-test level) you'll also likely
| stumble onto a similar bottom-up style of development.
|
| I think, circa 1993, his emphasis on Lisp and bottom-up
| development made a lot more sense than it does today with the
| increasing availability of interactive development environments
| (essentially every dynamically typed language, pretty much; but
| even many others like Java and C#) and increased emphasis on
| test-heavy development methodologies.
| norir wrote:
| A function call has runtime overhead that a macro may not.
| There are also things that can be difficult to express as a
| function in the language type system but that are
| straightforward to implement as a macro. Lisp isn't the only
| language with a strong macro system but it disproportionately
| attracts programmers who value the power and expressivity that
| a strong macro system provides.
|
| There are a number of reasons that bottom up programming in the
| style PG seems to be advocating for is not popular in industry.
| Industrial programming favors the median developer while bottom
| up is a technique that works best with small teams of skilled
| programmers. Big cos obviously prefer "safe" languages, but
| even startups are generally conservative due to the vc induced
| pressure towards hypergrowth, which also favors the median
| developer since hypergrowth requires hiring.
|
| Writing good programs from the bottom up requires more
| skill[1], but can lead to substantially better programs by
| certain criteria. But it may also be considered inscrutable by
| the median developer. The median developer can also misuse the
| power afforded by the bottom up language and write something
| much worse than they would have been able to in a more
| conservative language. This isn't a knock on the median
| developer, btw, just my perspective on why this style is rarely
| found in industry.
|
| [1] neither LLMs nor stack overflow are of much help when you
| have essentially written a new language to solve your problem.
| liampulles wrote:
| For me the key thing is that if you are doing "bottom-up"
| programming, then those macros/functions/etc. should be abstract
| and not related to business rules. Else you are doing premature
| abstraction, and you'll end up creating big rocks you have to
| carry on your back when you want to make a change.
|
| As a consequence, I personally practice bottom-up very sparsely
| and carefully.
| sillysaurusx wrote:
| If you want to see this principle in action, I've been updating
| Arc for the last five years. If you clone
| https://github.com/shawwn/sparc, you should be able to run
| bin/arc news.arc and see a clone of hacker news running on
| http://localhost:8080. No need to install anything if you're on
| Linux or Mac; it downloads a minimal racket locally. Windows
| users just need to install racket normally.
|
| I use it as a bookmark aggregator, since I can submit things and
| leave myself notes. The first account you create will become an
| admin, and any future accounts are regular users. Passwords are
| bcrypted rather than sha1'd. Windows works too, but for some
| reason the repl seems to block all other threads from making
| progress, so Microsoft users will have to run it with DEV=0 to
| disable the news.arc repl on startup.
|
| It's not ready to show yet in general, but there are a lot of
| advances. My design goal is that if pg ever sees it, he'd want to
| use it himself.
|
| It incorporates some ideas from Bel, too. I'll be doing a big
| write up of all the changes.
|
| The biggest advance from a language standpoint is probably
| keyword arguments. If there's any interest, I'll go into more
| detail.
|
| The biggest advance from a usability standpoint is that arc is
| now a thin wrapper over racket. There's no FFI and no need to
| translate anything. Arc lists are racket lists. Ditto for hash
| tables and everything else. You can write racket code in arc by
| prefixing code #'(like this), which the arc compiler turns into a
| racket expression (like this). So #'(require (rename-in
| racket/system [system racket-system])) will do what you'd expect
| it to do in racket. You can mix racket code and arc in two ways:
| (#'foo bar baz) will compile bar and baz as arc expressions, but
| will call foo in functional position. So (#'begin0 (+ "x" 'y) 'z)
| will give "xy", because begin0 is a racket special form that
| returns its leftmost expression.
|
| The other way is an equivalent of quasiquoting: #`(let ((x #,(obj
| a: 1))) x) will return a hash table with 'a set to 1.
|
| The unit tests in test.arc are probably the best way to see all
| the language features, but it's hard to read at times. (The
| writeup will introduce each concept in a bel-like fashion, but
| it's not ready yet.)
|
| news.arc is where most of the power is on display. Making a new
| endpoint is extremely easy. And prompt.arc shows how you can
| write a dynamic application without using databases or needing to
| store any state. The state is in the closures.
| sillysaurusx wrote:
| Speaking of closures, remember how HN used to run out of RAM
| because each page refresh would create new ones? That doesn't
| happen here, because no new closure is created if both the
| lexical environment and the compiled code are identical. The
| number of fns are displayed at the bottom when you're logged in
| as an admin, so you can verify nothing new is created when you
| refresh.
|
| Dan has a good writeup about why HN got rid of them, but
| unfortunately I can't seem to find it. There are still reasons
| to avoid them (e.g. if you need a stable url), but I'm happy
| that performance is no longer one of them.
| briantakita wrote:
| > Whenever you see library functions, bottom-up design is
| happening.
|
| I'm glad he acknowledged that library functions is the majority
| implementation of "bottom up design". In that case extracting
| primitive api functions & layers composed of these functions is
| effective at reusing logic & creating appropriate levels of
| abstraction.
|
| That being said, many frameworks do not offer these layers of
| abstraction so create a sort of "complexity lock in"...where one
| has to use the entire framework in order to use a few useful
| parts of the framework. I find this complexity lock in to be
| unfortunate as it not only couples the programmer to the entire
| framework, even if the majority of the framework is not useful.
| It also creates noise in the conversation, making it more
| difficult to search for the appropriate solutions at the
| appropriate level of abstraction.
|
| There is a cost to integrating other libraries into the
| framework.
|
| Frameworks also tend to become an institution in search of
| increasing market share. This means there are changes done to the
| framework. Some of these changes are breaking changes that don't
| necessarily improve the core development experience in meaningful
| ways.
___________________________________________________________________
(page generated 2023-12-09 23:00 UTC)