8 ms·
I think this roughly reflects my philosophy in languages as well. You basically have two options: you can bend your problem to your language or your language to
by tikhonj 14y ago
I think this roughly reflects my philosophy in languages as well. You basically have two options: you can bend your problem to your language or your language to your problem. The former is epitomized by Java and Python--all Java and Python code looks the same, regardless of what it's actually doing. The latter is the domain of Lisp and Haskell and Forth and so on.
I'm unabashedly in favor of the latter.
Ultimately, it's easier to reason about some domain in that domain. I would love my code for any particular project to look very similar to what I would write on a whiteboard when solving the problem. If I'm solving something inherently mathematical, I want the code to resemble math notation. If I'm writing some parsing code, I want it to resemble a grammar. If I'm writing an interpreter, I want it to resemble the operational semantics of the language. This fits into more "practical" domains as well: if I'm writing a web app, I want the routing to look like, well, routing and the database code to look as close to the database structure as possible.
Any details in the implementation rather than the domain should be separated from the domain logic. If you're trying to make the domain logic mirror the domain itself, this is essentially inevitable. This makes your code more general and easier to debug. You can redirect your domain logic to a different backend, and it's much easier to figure out whether you have a problem in the implementation or the logic.
More generally, such a strict separation of concerns is extremely important. The difficulty of a problem increases exponentially with its complexity: all the parts affect each other. If you manage to neatly split a problem like this in two, each sub-problem will be less than half as difficult as the main problem. So splitting away the high-level logic from the IO and the memory management and the other implementation details is inherently valuable. In fact, this is valuable even if the sum of both sub-problems is a bit greater than the original problem.
The malleable language approach gives you a very natural way to split your problems up: one part is implementing the DSL, modifying the host language or writing a library--creating abstractions. The other part is actually using these abstractions. I find this sort of split to not only be very useful but also very natural; it mirrors how I usually think about things.
One very interesting recent development taking this idea to the extreme is OMeta. There your program is essentially a tower of DSLs, with the base language just being a simple way to specify the DSLs. This idea really is extreme: for example, the code for implementing TCP is actually the ASCII art diagrams describing it! [1]
Of course, all the usual suspects like Lisp and Haskell are also worth looking at. Embedded DSLs in these langauges can go quite far, and they have some of their own advantages to consider.
[1]: http://www.moserware.com/2008/04/towards-moores-law-software-part-3-of-3.html http://www.moserware.com/2008/04/towards-moores-law-software...
- gbog 14y agoDon't you think that with lisp you also need to bend your problem to the particular of lisp? I speak fluently three human languages, and I also have to bend to them when I want to express myself. The more proficient I am the less the bending is noticed, but it is still there. I'd say it is the same with all good computer languages. You can express whatever you want in python and lisp, but following different grammar.
- namank 14y agoI am studying engineering, which is all about OOP. HN is making me so uncontrollably curious about the functional stuff!
- lclarkmichalek 14y agoTry it. Its not the silver bullet it sounds like when you listen to people rave about it, but it is worth learning.
- babarock 14y agoKeep in mind that functional isn't better or worse than OOP. What you see on HN is merely a reaction to the trend in the past decade (a trend still going on today) to teach OOP as the only de facto paradigm to use. If Functional Programming was mainstream, everyone here would be raving about OOP and its benefits. Ultimately what you want is to borrow the good ideas of different paradigms to create elegant and practical code.
- npsimons 14y agoKeep in mind that functional isn't better or worse than OOP. What you see on HN is merely a reaction to the trend in the past decade (a trend still going on today) to teach OOP as the only de facto paradigm to use. To put it another way, OOP is a pretty nice hammer, but so many people have been using it to bash screws in (including ridiculous cases like concrete!) that others have reacted by using screwdrivers for everything (including nails). Pick the right tool for the job.
- oh_sigh 14y ago