6 ms·
Is Lisp a Blub Language?
- programnature 16y agoPattern matching is the missing feature. I keep thinking about switching to Clojure from Mathematica, but then I think "How can anyone get anything done in Clojure? It doesn't even have pattern matching." Its not something that can get patched in a library, because the way symbols and evaluation need to work is different (and simpler) than in a Lisp. There is no distinction between macro-s and nonmacros - everything is just a tree transformation. The main benefit of first-class pattern matching is that your function definitions get a lot more succinct and expressive, since you can encode quite a lot of information in the structure of the arguments, and elegantly unfold the definition from the short and common case to a parameterized sequence of generalizations.
- jpr 16y agoIf you don't know how to write a pattern matching library in Lisp, you don't really know Lisp and should probably refrain from spreading misinformation about it.
- lispm 16y agoPutting structure assumptions into function argument lists is not necessarily a good idea. One exposes the implementation. Pattern matching function definitions are easy to do in Lisp. But given the nature of Lisp, much of the pattern matching then needs to be done at runtime - which leads to less efficient code and invites people to write totally inefficient code.
- programnature 16y agoConsider the Mathematica function Take[], which would save millions of man hours if it existed in other languages. Take[{a,b,c,d},2] --> {a,b} Take[{a,b,c,d},-2] -> {c,d} Take[{a,b,c,d},{1,3}] -> {a,b,c} Take[{a,b,c,d},{1,-1,2}] -> {a,c} Take[{{a,b,c,d},{1,2,3,4},{5,6,7,8}},2,2] -> {{a, b}, {1, 2}} etc. In my book this is clearly useful, and its only scratching the surface. ( {} is actually List[] in Mathematica FullForm ... ) The point of symbolic representation is to represent the intended meaning. Its nothing about the "internal" implementation. Using symbols and simple tree structures to compactly express stuff is extremely powerful, and not coincidentally the essential way that human language works. Sure, with a sufficiently dynamic language you can implement such functionality. The problem with Lisp is that by default symbols want to evaluate, and if you want to treat them symbolically you have to operate in a "special" mode. This makes things too complicated. There is a reason you don't see meaning represented by structure in pretty much any other language besides Mathematica.
- lispm 16y agoIt looks like you have never programmed in Lisp. A function like Take is easy to write in Lisp. Lisp has many similar functions like that - but with a better interface. > There is a reason you don't see meaning represented by structure in pretty much any other language besides Mathematica. Could it really be that you missed the AI software that has been written in Lisp in the last five decades?
- programnature 16y agoWhat is ' other than a special mode? The fact is that symbols are treated more systematically in Mathematica, and that makes it easier to assemble and dissemble symbolic structures of all sorts. Sounds like a case of blub. You look at Mathematica and see some weird stuff that is probably equivalent in power to multimethods or whatever, I look at Lisp and think how can I possibly live without civilized pattern matching. As far as Lisp-based AI goes, its in fact very easy to miss it, but this is probably not the thread to get into Lisp's cultural issues.
- smanek 16y agoI certainly miss ML-style pattern matching when I'm in Lisp. I sometimes find myself (poorly) simulating the idea with a whole bunch of multi-method specializers. Based on my limited experience, it seems like you'd really need a more static type system to make the most of pattern matching though. Are there any dynamically typed languages with powerful/useful pattern matching?
- _delirium 16y agoAs far as doing it in Lisp goes, this is an interesting attempt: http://common-lisp.net/project/cl-match/doc/clmatch.htm http://common-lisp.net/project/cl-match/doc/clmatch.htm
- lispm 16y agoProlog
- silentbicycle 16y agoProlog has unification, which is considerably more powerful than just pattern matching. The semantics of Prolog require the ability to unify data structures with some parts not-yet-specified, and backtrack later if they cannot be bound to something valid. In contrast, pattern matching happens all at once and is unidirectional. (Though even basic pattern matching is tremendously useful, IMHO.) Erlang's pattern matching is somewhat like Prolog's, but with backtracking removed. (Backtracking clashes with Erlang's other semantics.)
- kunley 16y agoErlang of course.
- noelwelsh 16y agoWhat exactly do you mean by pattern matching? I understand it in the ML sense. The Lisp language I use, PLT Scheme, has extensible pattern matching: http://docs.plt-scheme.org/reference/match.html http://docs.plt-scheme.org/reference/match.html The implementation isn't simple but the techniques are published (see "Pattern matching for Scheme" http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.53.2004 http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.53.2...) so any Lisp language could implement this. Clojure has less powerful pattern matching, but it does the most common stuff. The linked article is really about Common Lisp, where the issue is a standard that hasn't been updated in a long time. This doesn't stop individual implementations from making their own advances but in my limited knowledge of the CL implementations this doesn't seem to be occurring.
- lispm 16y agoyou might check sometimes the documentation of CL implementations for the advances that they provide over the standard
- aerique 16y agoThis is actually occurring. Most advances are made in cross-platform libraries (networking, regexps, threading, pattern matching, lazy evaluation, etc.) but some implementations have their own extra that make them interesting (by no means an exhaustive list): ABCL (http://common-lisp.net/project/armedbear/ http://common-lisp.net/project/armedbear/) runs on the JVM. CCL (http://www.clozure.com/clozurecl.html http://www.clozure.com/clozurecl.html) has excellent integration with Objective-C and Cocoa on OS X. ECL (http://ecls.sourceforge.net/ http://ecls.sourceforge.net/) is easily embeddable in C / C++. The commercial offerings Allegro CL (http://www.franz.com/products/allegrocl/ http://www.franz.com/products/allegrocl/) and LispWorks (http://www.lispworks.com/ http://www.lispworks.com/) keep on improving and extending their own implementations in interesting ways.
- programnature 16y agoGood question. Here is what I mean: 1. Pattern matching as the basis for function definition, to determine which code executes and expedite argument destructuring. 2. Patterns themselves should have first-class representation (preferably symbolic), so you can generate them in one place and use them in another. 3. Implicit in this is that the structure of the language is systematic enough to make this worthwhile, meaning something s-expression based, or perhaps something like Scala that achieves similar ends in a much different way.
- Zak 16y agoA little bit of googling gave me the sense that pattern matching in Mathematica is different from the pattern matching present in several functional languages. Please let me know how these Clojure features differ from that: Clojure has pattern matching for the arguments in a function definition similar to ML or Haskell. It's often used as a more verbose alternative to optional args, but it's more powerful fundamentally. Clojure has destructuring in binding forms like let, described here: http://clojure.org/special_forms http://clojure.org/special_forms Clojure has multimethods which let you pick the method to use based on an arbitrary dispatch function. There's a pattern matching macro that seems to be the beginning of a DSL for predicates: http://www.brool.com/index.php/pattern-matching-in-clojure http://www.brool.com/index.php/pattern-matching-in-clojure
- programnature 16y agoThere is 1 mechanism instead of 4, and it also happens to be the fundamental basis of evaluation. There is no way to measure "absolute power" of elegance, which is the issue being gotten at here. Not to say Mathematica has it gotten it perfect either, because it hasn't. But I have yet to see a superior implementation, and have seen a lot of clunky ones in my search.
- jjs 16y agoBlubness of a language comes from its practitioners not knowing about useful features from a higher-level language (or not grasping the utility of such a feature). If your favorite Lisp lacks a certain feature you want, it's easy to add, making Lisp the anti-Blub. (And if your favorite Lisp makes it hard to add it, you've picked the wrong favorite!)
- fauigerzigerk 16y agoSome things are difficult to add even to Lisp. Static typing being an example.
- lispm 16y agoright, that's a good example
- fauigerzigerk 16y agoOn the other hand you could make an argument that static typing isn't actually a language feature as much as it is a step in the process of programming. Static typing consists of (a) tagging variables with their type and (b) running a program that uses these type tags to check and/or rewrite the program. It's easy to add type tags to a lisp program. It's just that Lisp doesn't specify that second program that checks and transforms the first. So I would say Lisp is half way there when it comes to static typing. That's a pretty contrived argument though... :-)
- lispm 16y agono, adding type declarations to Lisp is the easy part. when it comes to static typing, standard Common Lisp offers very little. Declaring types? That has been done. In Common Lisp: (defun twice (n) (declare (number n)) (the number (* n 2))) The difficult parts are: * the type system and its capabilities * make the operations of the type system sound * determining sub-types * type inference * integration with the rest of the language (where data objects also have something like types) Common Lisp provides lots of infrastructure for all kinds of things, but very little for a type system. For example in Lisp one can determine the value of an expression via EVAL, but there is no function to compute the type of an expression (other than a type of the computed value).
- Estragon 16y agoWere there any interesting suggestions in the reply to the op?
- Zak 16y agoI find in certain cases that I'm looking across the power spectrum from the Lisp point of view. I recently ported some code from Haskell to Clojure and occasionally found myself missing Haskell's amazingly expressive type system. Trying to give Lisp such a type system would make a lot of things that are currently easy in Lisp hard or impossible. There are certain kinds of mutually exclusive features that make certain kinds of problems easier or harder. Examples that come to mind are mutability vs immutability and static typing vs dynamic. Most of the things I sometimes find lacking in the Lisps I'm familiar with are of this sort.
- silentbicycle 16y ago> There are certain kinds of mutually exclusive features that make certain kinds of problems easier or harder. Right. The fundamental problem with the whole "blub" argument is that there isn't one linear continuum of language power. There are problems for which Erlang's supervision hierarchy and distribution primitives or Prolog's backtracking are a killer feature. This doesn't mean they're "More Powerful than Lisp", just better suited to certain kinds of problems because they committed to some very specific trade-offs. But, these same trade-offs have far-reaching implications for the language semantics, so you can't just use macros to graft them on after the fact. You can embed a mini-Prolog in Lisp, sure, but adding fully native logic variables (as in Prolog or Oz) would be far from trivial.
- defdac 16y agoSo how many here can take any problem and use any language to solve it language-optimally with all known best practices with the least amount of code? How do you figure out that one language is better than another for a given context where hundreds of people with 10 years of experience with language X would solve a problem faster and more elegant with language Y and zero experience? Are the people finding certain languages unreadable and ugly really the people that should decide what language to use for a problem at hand? Or the experienced craftsmen with expertise in their old, ugly and "unredable" language? Personally I find it rather funny and ironic that noobs are the ones driving the language of choice because they have learned how good their new and powerful language is - and because they are having trouble reading anything else. In this way the noobs get an edge over Old-timers with years of experience that actually know how to write beautiful code in their old ugly language. The noobs doesn't realize this until their favourite language is considered old and obsolete by even newer noobs, and they start to call themselves Old-timers.. I think most people will have a native language where they express themselves better and more elegant than any other language. They will probably solve any problem faster with their native language compared to the optimally correct besserwisser language. I bet their solution would be more readble and elegant too, compared to be using a language they don't have any experience with.
- programnature 16y ago(@lispm Looks like our symbolic language flame war has exceeded yc metrics) Yes, I understand what ' does. You are manually controlling evaluation. The same way, once upon a time, people manually controlled garbage collection. Having a+a explode by default means that the whole time you have to be juggling what is intended to be used symbolically or not. This seems to not be a 100% perfect realization of the code == data paradigm. I'm glad you now agree that structure is a good way to encode meaning. Now, what is a more idiomatic way to manipulate that information? Walking the tree manually, or expressing those patterns of structure directly? Unfortunately, in Lisp, you need to "evaluation manage" those structures. And its not just quote, its the whole macro language with its own idiosyncrasies. Its just a lot easier to have a single elegant system with the right defaults. I'm the kind of person who implements models of computation as a recreational activity. I've probably wished for more granular evaluation control 1% of the time, but having civilized pattern matching (and representation) has vastly increased productivity and code density.
- lispm 16y agoI haven't said anything about encoding of meaning, you are dreaming. You are the kind of person of Xah Lee...
- deleted 16y ago[deleted]
- silentbicycle 16y agoDo you know Prolog? It sounds like it might appeal to you. Rather than evaluating expressions, it does pattern matching (unification, really) on data structures, rewriting and evaluating them as specified. It can pass around uninstantiated variables and do depth-first search* through known facts/rules to find complete matches, backtracking when it hits dead ends or alternative solutions are requested. Rather than saying Prolog has pattern matching, it almost makes more sense to say it is pattern matching. It's very central to its model of computation. * Breadth-first and other search techniques are easy to write, depth-first is just the default.
- 16y ago
- cabalamat 16y agoNo. I'll explain why: all languages are in some sense equally expressive, because they are Turing-complete. But some languages don't have particular abstractions, for example classes; so in that sense they are not expressive, because you can't express those abstractions. But Lisp has macros. This means that any abstraction it doesn't yet support, you can add.
- silentbicycle 16y agoNo, because you can't add language invariants (guarantees that thing X will never happen), and without invariants such as pervasive immutability, certain features are impossible to add. While it's possible to add features to Lisp that are at odds with its fundamental model of evaluation, it's usually done by adding an interpreter (or, occasionally, compiler) for a nested sublanguage. There are several interpreters in SICP and EoPL, several Lisp books have a mini Prolog, etc. This is handy (and Lisps do make it relatively easy), but you can't graft something like Erlang's entire semantics onto Lisp with just macros.
- cabalamat 16y ago> No, because you can't add language invariants (guarantees that thing X will never happen) That's true. Macros aren't a perfect solution. > without invariants such as pervasive immutability, certain features are impossible to add. As are certain optimisations. > While it's possible to add features to Lisp that are at odds with its fundamental model of evaluation, it's usually done by adding an interpreter (or, occasionally, compiler) for a nested sublanguage. Indeed, which is in a certain sense cheating. If one is designing a language, and one hopes that one's language will become popular, then it's likely (in fact inevitable) that the language will be used for tasks that the designer hasn't anticipated. So how can a designer cater to this? Macros are one way, and IMO a powerful one. Another is to make the language so that it is easy to mix-and-match it with other languages, so that it can call code in other languages, be called by other languages, use common data structures and serialisation formats, etc. Implementing in the JVM goes some way to meeting this goal.
- ramchip 16y ago
- mixmax 16y agoAren't all languages blub languages depending on the usecase? If you write AI programs c++ is a blub language. How can you get anything done without macros? If you program drivers PHP is a blub language. How can you get anything done without direct access to the hardware? If you're doing webapps lisp is a blub language. How can you get anything done with a syntax that's so different from HTML and so difficult to read? The whole premise of a blub language depends entirely on what you're trying to accomplish - the right tool for the right job. Disclaimer - I'm not much of a programmer, so maybe my examples don't hold up, but you get the idea :-)
- swannodette 16y agoI actually picked up Clojure because I was: Tired of having to write C++ to get decent graphics performance. Tired of having to write C++ to get decent audio performance. Tired of my cool dynamic web programming languages not being fast enough to do the above. Tired of Python, Ruby, C++, C, Java, Objective-C, JavaScript having so little to offer in the way of elegant concurrency. So I picked a Lisp because it could do more.
- zephjc 16y agoDisclaimer noted, but as to your lisp/HTML example, HTML and lisps actually have a lot in common - if you strip away the end tags and the angle brackets, you get something very lispy looking <div> <span>Hello</span> </div> has the same (prefix) order of operators and operands as (div (span "Hello")) Off the top of my head, the "hiccup" package for Clojure has an 'html' function (macro?) that translates just that sort of stuff directly into html