5 ms·
While I don’t disagree with Josh’s blog, concentrating on just language features leaves out the style of Lisp development: bottom up REPL style development. Whe
by mark_l_watson 5y ago
While I don’t disagree with Josh’s blog, concentrating on just language features leaves out the style of Lisp development: bottom up REPL style development. When I have to use Haskell or Python, I find myself working as if I were using Lisp: I still favor the REPL and building up from primitive functions to the top level application. This is probably a bad habit but it is the way I work. BTW, using the standard Emacs support for Python works very well: load a file, then re-evaluate just changed classes and functions (not Lisp, but a good work flow anyway).
- convolvatron 5y agodo you struggle with bottom-up-Haskell? I always associated Haskell with a very opinionated top-down process
- mark_l_watson 5y agoI like Haskell, but my Haskell skills are weak. I experiment in the REPL to see what works and then write functions in an editor. Also, I like writing pure Haskell code, and when I need to do network or file access, etc., then I find appropriate code on the web that I can learn from. So, my use of Haskell is fairly simplistic. I even wrote a very short book using the small subset of Haskell that I am comfortable with and use for my own projects.
- exdsq 5y agoWhen I worked in Haskell I always found a type-driven top-down approach helped me work out what I needed to do literally starting from something like App :: Input -> Output Out of interest where are you working such that you're using Lisp? Pretty sure I've actually asked you before ha, but can't remember. Every-time I get burned out with frameworks and polygot development I end up daydreaming of using a stable language like common lisp for the remaining ~40 years of my career.
- mark_l_watson 5y agoI have used Common Lisp for a ton of paid work since 1982. That said, in the last 7 years people have paid me to do deep learning work, so that work uses Python. Follow the money. I am deeply bound up in Common Lisp because of my history. However, if I may make a suggestion: you might want to take a careful look at Racket: easy to make standalone apps, good libraries, large community, and if you don't like Emacs, the Racket IDE is really pretty good. Sit in on one of the online Racket conferences to see many kinds of cool applications and libraries people use Racket for.
- tikhonj 5y agoI've done a lot of Haskell, and my approach tends to be a mix of the two. There's a natural split: • types let me play with the architecture and interfaces top-down • the REPL lets me write more complex logic bottom-up Usually there are a few "hotspots" in the codebase that require a lot of logic and are easier to develop bottom-up; the rest of the codebase is focused more on organization, domain modeling and information flow, where top-down design works really well. In actual practice I expect my mode tends to vary even more than that, but this division seems like a good approximation of how I think about it.
- klipt 5y agoI feel like the bottom up style is possible in static languages like C++ too, except instead of manually testing small functions in the repl, you can write small unit tests for them instead. In a way it's even better because a test written once can be run many times, while testing in the repl requires a manual test with every change.
- cerved 5y agoI'm guessing the draw is in the immediate feedback. Like iteratively creating a chain of commands in shell pipe. Compiling and then executing typically takes a minimum of a few seconds before you get feedback
- jlarocco 5y agoThat works in Lisp, too though, but it's easier and faster to run the tests in the REPL, so you get the best of both worlds. When I write Lisp I usually start testing in the REPL, iterate until the test code gets to be a few lines long, and then copy it over to the package's unit tests. Then I can keep iterating on both the test code and the code being tested. I'll do something like this in the REPL: (ql:quickload :mylibrary.test) (mylibrary.test:my-test-function) "mylibrary.test" will depend on "mylibrary", so quickload will load both packages when they've been changed, and I can re-run the test quickly using Alt-P to call up the previous REPL input. And the REPL is also really great for "what if" testing that you may not want to keep forever, like, "What happens if I call this function with an invalid parameter?" Hopefully there's a test for that, but it's often a lot faster to just call the function and see what happens rather than go dig through the test code and lose your focus.
- gumby 5y agoThis is how I develop in C++, though I am a Lisp programmer
- nwallin 5y agoconstexpr and static_assert make this a ton easier in C++. If your "unit tests" are static_asserts, the IDE will just highlight the broken parts. C++17 made this minimally useful, and things got spectacularly better with C++20 and constexpr vector/string. 23 is shaping up to move even more of the standard library to constexpr.
- _0ffh 5y agoI must admit although I was never much focused on either Lisp or Forth I tend to do lots of bottom up, no matter in what language. If I know I'll need a certain thing, for example a type to represent some kind of node or whatever, I'll build that thing before I write any code that would need to have that thing available in order to work. By the time I get started on the main task I usually have most or all of the necessary components verified. And I don't see why one should be apologetic about preferring that style.