6 ms·
It's a nice perspective. Very practical and down to earth. There is another side though, and that is that learning to think of code as data is extremely empow
by einhverfr 10y ago
It's a nice perspective. Very practical and down to earth. There is another side though, and that is that learning to think of code as data is extremely empowering and translates well when working with a fairly large set of other languages (Perl, Python, Ruby, and now even Java). Learning Lisp turns you into a better programmer.
- agentgt 10y agoI like Scheme/Lisp but I don't know if I buy the whole "learning Lisp turns you into a better programmer". Maybe more knowledgeable but not necessarily a better a developer. In some ways learning a really flexible language like Lisp can turn you even into a really bad developer. I say "developer" instead of "programer" because I want to emphasize working with others and thus sharing code with others. Of course this is based on some past observations working with MIT grads and various other academia so take my opinion with a grain of salt. IMO the language that really changed everything for me was the ML family of languages and maybe C. I would say knowing C and ML is more worthwhile than Lisp (Lisp is not exactly hard to learn anyway... the basics that is).
- ohyes 10y agoI'm biased, but there's a big difference between "learning lisp" (well enough to transliterate that python program) and really getting the code as data concept. I'd say that learning X really well is always a positive because whenever you learn something in depth you can then apply the concepts elsewhere. And there are still lisp-only concepts, so learning lisp is positive. ML is good too. Also spending time with a well designed concurrent language is beneficial.
- agentgt 10y agoWith Lisp I get the data thing but with ML you learn almost everything is a language. I can't really explain it but the whole variant/ADT pattern matching really forces to make you think of your problem domain as a specification or language (e.g. DSL). It is one of the reason why I think so many compilers are written in ML (that and the toolset is awesome for it).
- catnaroek 10y agoAnother important feature of ML is abstract data types (opaque signature ascription), which forces abstraction clients not to rely on implementation details. It's Dijkstra's “separation of concerns”, integrated into the type checking process! See: https://existentialtype.wordpress.com/2011/04/16/modules-matter-most/ https://existentialtype.wordpress.com/2011/04/16/modules-mat...
- einhverfr 10y agoThat description of ML reminds me what I really like about REBOL and RED as well.
- catnaroek 10y agoWith the “slight” difference that ML actually enforces that your program is consistent with your description of the problem domain.
- spdionis 10y agoPattern matching is the feature i enjoy most in functional languages. It's simple to use and comes with great value.
- ohyes 10y agoHaving looked up variants just now, I can definitely see how it would be useful. It seems (to me) to fall into the same category of macro-like things that enhance the expressiveness of the language. I think the most important point is the idea of lifting the programming language into the problem domain. When you can do this in a clean way, the result is a very readable solution that you can reason about.
- AnimalMuppet 10y agoI think there's a difference, though. With ML (IIUC), you build a language on top of ML that is a set of functions (and the data structures they operate on) that make it easy to express the program. With Lisp macros, though, you change the syntax of Lisp. You take things that were not valid Lisp syntax, and you make them valid for your program. So ML "language building" is in terms of semantics, but in Lisp, it's both semantics and syntax. (Again, IIUC).
- hellofunk 10y agoI personally think the "code as data" concept is not so important in lisp. It is critical to writing macros, but you often don't write macros and beginners to lisp often abuse macros. I've written Clojure professionally now for a couple years and am pretty fast and proficient at it, but when I write a function call, I don't think of it as a list, even though that is what it is. I don't think any lisper does. It's just a function with arguments and I'm writing in the syntax necessary, which happens to be a list. In those rare occasions where I think a macro is necessary, sure, it helps that a function call is a list, but that's hardly the main role in a day's work.
- ohyes 10y agoWith respect to Clojure, you don't write macros, but many of the really interesting language features within Clojure are built upon macros. (core.async and core.match come to mind). It would be difficult to add them without macros. I do actually think of my code as a tree/graph structure. Not just in lisps but in other languages as well, I'm always manipulating a stack of trees and thinking about how the data flows through the branches.
- hellofunk 10y ago> many of the really interesting language features within Clojure are built upon macros That's true with any lisp. But that doesn't mean the the ability to write macros is a requirement for most development work on a daily basis, and homoiconicity is often touted as amazing specifically because of its help in writing macros. Therefore, since writing macros is not super common or necessary most of the time, I would say that "code as data" is also not a big deal most of the time. I really like lisp, I just don't think some of its unique features are as big a deal as they advertise.
- einhverfr 10y agocode as data, however, does become an important concept in becoming really good at Perl or Python (and I would assume Ruby etc), and understanding common pitfalls here also helps one spot, for example, LSP problems and provide better solutions (because most LSP problems can be solved by replacing a mutator with something that returns a new object). In Javascript, also, effectively you have to work with code as data. So this isn't just about writing macros. There are a lot of areas where this does touch things.
- einhverfr 10y agoIt is also worth noting that failure is often a step on the path to success. Learning to apply the "code is data" principle in other programming languages is not without pitfalls as you say and falling on one's face sometimes is to be expected. However, that's part of the process too as is learning when to use a hammer vs a wrench vs a screwdriver. There is the point in learning a new tool where everything looks like a nail. Yes, people will really mess things up by applying the wrong concepts but how else do we learn?
- lispm 10y agoThere are some Lisp-related things which provide developers with new tools and new ways to think, maybe making them better: a) code as data b) interactive software development c) user-defined language extensions where the developer is part-time language designer, syntactic abstraction d) dynamic object-oriented programming e) meta-object programming
- AnimalMuppet 10y agoCould you expand on d)? What specifically is different between what you get with Lisp here and OO in the C++/Java sense?
- lispm 10y agoCommon Lisp allows us to develop object oriented software while it is running. Interactively. It changes classes and other objects, based on programmer changes. We can also add behavior to OOP mechanisms, like instance creation, slot allocation, slot access, class redefinition. One can add/change/delete methods at runtime. You can even change the class of an instance. This enables you to have large OO applications running and change them while they are running. This enables interactive incremental development. Interaction with LispWorks: Define a class with a slot. CL-USER 61 > (defclass person () ((name :initarg :name))) #<STANDARD-CLASS PERSON 4020002153> Create an instance of that class. CL-USER 62 > (defparameter *p1* (make-instance 'person :name "Drumpf")) *P1* What is it? CL-USER 63 > (describe *p1*) #<PERSON 402000DE43> is a PERSON NAME "Drumpf" Hmm, let's make a politician class, with person as superclass and a slot TYPE. CL-USER 64 > (defclass politician (person) ((type :initarg :type))) #<STANDARD-CLASS POLITICIAN 4020284743> We change our object to the new class and add information about the new slot content: CL-USER 65 > (change-class *p1* 'politician :type 'populist) #<POLITICIAN 402000DE43> What is it now? CL-USER 66 > (describe *p1*) #<POLITICIAN 402000DE43> is a POLITICIAN TYPE POPULIST NAME "Drumpf" Class of the instance has changed, the new slot has been added, and the old slot is still there.
- junke 10y ago
- hellofunk 10y agoI think that more specifically, "Learning FP makes you a better programmer", and you often learn FP when learning lisp, so the original statement is often true as well.