21 ms·
Do I Really Need a Programming Language?
- chattoraj 13y agopg wrote about this years ago. >If you understand how compilers work, what's really going on is not so much that Lisp has a strange syntax as that Lisp has no syntax. You write programs in the parse trees that get generated within the compiler when other languages are parsed. source: http://www.paulgraham.com/avg.html http://www.paulgraham.com/avg.html
- jesstaa 13y agoIt's as if lisp was originally designed to be an intermediate language for computer generated parse trees....and not a language for people to read.
- vog 13y agoIf you say "S-expressions" instead of "LISP", this is perfectly true! The syntax of S-expressions was only meant to be used for LISP data structures, while programming was meant to happen in another syntax called "M-expressions" [1], which was to be converted to S-expressions by the compiler. However, the programmers liked to use S-expressions directly, so M-expressions were never actually implemented. In that sense, the LISP syntax (S-expressions) were ideed designed as an intermediate language, not to be used by programmers directly (except for plain data structures). [1] https://en.wikipedia.org/wiki/M-expression https://en.wikipedia.org/wiki/M-expression
- crntaylor 13y agoThis is really interesting - I didn't know about that snippet of Lisp history. So the expression we'd write today as (car (append '(a b c) '(d e f))) Would originally have been written in M-expression form as car[append[(a b c); (d e f)]] Programming in Lisp might be a very different experience if M-expressions had caught on!
- Anon84 13y agoIt would be called programming in Mathematica ;)
- goldenkey 13y agoIt's not as if..it is truly the case. That's why only nutters use LISP for large projects. Who really wants to wrap every S-Expression in parenthesis? Talk about painstaking and what an eye-sore. If only M-Expressions caught on, LISP could be decent. But really, it's just making you write your program as a data structure because that makes it easier for the compiler to process. So... Ruby: good for developers, bad for the JIT compiler (slow) LISP: awful for developers, good for the compiler -> machine (fast) Is the tradeoff worth it? Not at all. Most LISP intros start by convincing you that you'll eventually get used to your code looking like a sack of parenthesis. No thanks, I shouldn't need to get used to staring at overburdened verbosity for the compilers' sake - build something better. Wait..we have other languages that are fast and look nice. And many even process into a well-formed AST. Okay, thank heavens.
- sklivvz1971 13y agoyeah, the trade off are generally c-based languages.
- aerique 13y agoI disagree that Lisp is awful for developers. To me and many others it looks quite pleasant while the "other languages that look nice" actually look like a needless mess of braces, brackets, asterisks, comma's, etc. etc. Only Python comes close IMHO but has many other downsides.
- goldenkey 13y agoBrackets, asterisks, and commas give array indexing, pointers, and the clean separation of function arguments. (incf (elt vector 2)) ..versus.. ++vector[2] which one is more readable? LISP is not to be taken seriously. It's an academic curiosity, and cute, novel, not a language that needs continued zealots. It has no market share..the reasons are always going to be the same. The language is esoteric. I wouldn't program anything serious in JSON so why would I use LISP, where every semantic is a list..not even a hashmap. http://imgs.xkcd.com/comics/lisp_cycles.png http://imgs.xkcd.com/comics/lisp_cycles.png "These are your fathers' parenthesis"
- velis_vel 13y agoYes, and he's still wrong. You don't write 'directly in parse trees', you write in text that gets converted to parse trees. The conversion is very simple, to be sure, but it still exists.
- Chattered 13y agoWhen writing an S-expression of Lisp code, you're just one quote symbol off writing the list literal that evaluates to the code's parse tree. Modulo whitespace, the parse-tree prints as code. That's what we mean when we say you write directly in parse-trees. You're writing the string representation of those parse-trees.
- velis_vel 13y agoRight, but it seems inaccurate to me to say that Lisp code 'has no syntax'. What do you call the reason that 2927(foo"bar. isn't a valid Lisp program? Alternately: If I augment Python by letting you surround a block of Python code with curly braces in order to get an object representing the corresponding AST, does that mean that I can write Python directly in parse trees? :P
- Chattered 13y agoIt's always called a "read" error. If you're working at the REPL, it's detected at the Read phase of the Read-Eval-Print-Loop. It is, of course, a read-syntax error. But the fact that the Read phase can be usefully separated from the Eval phase is a distinguishing feature of Lisp, and why it makes sense to say, at least, that Lisp has no concrete syntax, only abstract syntax. Lisp programmers fluently think in terms of the abstract syntax their code generates, because they read and write in the string representation of that abstract syntax. That's why it makes sense for the Lisp eval function, unlike the eval function in other dynamic languages, to take lists as input rather than strings. That's why a metacircular interpreter in Lisp will be written to input lists. That's why a DSL in Lisp written as a custom evaluation function will be an interpreter for lists. The Lisp language is defined with respect to the list data-structure, rather than strings. On your Python idea: the problem is that no-one would ever use Python code as the literal representation of Python's abstract syntax. It would be entirely backward, anyway. Lisp starts as a notation for a data-structure rich enough to represent abstract syntax (symbolic expressions) and then defines a language in terms of this data structure. The philosophy of this is understood when we realise that the roots of Lisp are in metalanguages and logic.
- barrkel 13y agoNow show the same tree for a ruby block, a Java inner class, a C# lambda and how they're all the same. Except they're not. Only the simplest ASTs are directly translatable. Language semantics differ wildly when you get into higher level constructs. Not even Lisp is able to help you, as that just changes the problem from one of syntactic representation into one of library implementation.
- theaeolist 13y agoThat's for syntax. Also, for semantics, how do you translate C's pointer arithmetic in Java?
- jdiez17 13y agoAll programming languages deal with pointers at some point or another, so it's just a matter of finding the GCD. At least that's what I think this is about, and Lisp is a good GCD.
- gsg 13y agoLanguage semantics differ, full stop. Say you have x = 2147483647: x + 1 => -2147483648 (Java) x + 1 => Undefined behaviour (C, assuming int32_t and various things about the implementation) (1+ x) => 2147483648.0 (Emacs Lisp) (1+ x) => 2147483648 (Common Lisp) x + 1 => x + 1 (Prolog, using some interpretive license)
- andrewflnr 13y agoThat's not really a critique of the author's main point, I think. Of course you can't directly translate between semantically different features, but the OP's point was about semantically identical programs, and how different syntaxes distract from that. That said, I think it's possible to invent a language in which all the things you mention can be expressed and at least compared. I'll do my best to do it myself if no one beats me to it. Any language with closures is close. Java inner classes and (AFAIK) C# lambdas practically are clsoures. If the only thing ruby blocks add is that returns and similar statements affect the block-creating function, that can be simulated with exceptions.
- wtracy 13y agoWell, you could edit machine code directly, or do the next best thing and write in assembler: cmp eax, 100 jle LESSTHAN mv 10, edx ret LESSTHAN: mv 5, edx ret I doubt that's what the author had in mind, though.
- sheetjs 13y agoI'm surprised the author didn't write a shorter C example: return price > 100 ? 10 : 5;
- yohanatan 13y agoActually LLVM assembly might be a better choice these days.
- deleted 13y ago[deleted]
- waps 13y agoA real programmer would write : 83 f8 64 7e 06 ba 0a 00 00 00 c3 ba 05 00 00 00 c3 Or even : 10000011 11111000 01100100 01111110 00000110 10111010 00001010 00000000 00000000 00000000 11000011 10111010 00000101 00000000 00000000 00000000 11000011 I'd do better still, but I lost my butterfly somewhere.
- sklivvz1971 13y agoA real programmer would hand assemble a LISP interpreter and then pass it the LISP source. Come on.
- tikhonj 13y agoThe real question here is "do I need syntax?", or, more precisely, "do I really need a [complex] grammar?" Any given Lisp is still a programming language--it has some syntax and it has semantics. But it does have a much simpler grammar than any language (save Forth). The grammars exist because programs are made to be read by people, not just computers. A more heterogeneous notation can make for more concise code that's easier to scan and easier to read. Of course, this is not to say that Lisp is unreadable. I actually rather like reading and writing (paredit is awesome) Lisp code. But, after quite a bit of Racket, I've found that I still heavily prefer having infix operators and a bit more syntax. At the same time, I also often want less noise--ie no parentheses. I want all this so that I can quickly scan and comfortably read my code. That's why we need grammars.
- nabla9 13y ago>I also often want less noise--ie no parentheses. You have not reached Lisp enlightenment yet. Because you use Emacs, you can get shortcut to enlightenment by choosing color for parentheses that almost hides them to the background.
- goldenkey 13y agoI prefer rainbow parenthesis based on nesting depth.
- jballanc 13y agoYou could also use a Scheme that has implemented SRFI 49: http://srfi.schemers.org/srfi-49/srfi-49.html http://srfi.schemers.org/srfi-49/srfi-49.html (I think the fact that SRFI 49 is not more popular might say something, though...)
- ww520 13y agoFor simple business rules and logic, I found it useful to just use a table or mini-spreadsheet to represent them. It has strict structure and it's simple to understand and fill in. Business users love them.
- nostrademons 13y agoThis is why everyone should study compilers and machine architecture in college. Anyway, it's interesting that he chose to label what he ended up with as "Lisp". I would've stopped at assembly, eg. in LLVM IR: %result = icmp gt i8 %price, 100 br i1 %result, label %Discount1, label %Discount2 Discount1: ret i8 10 Discount2: ret i8 5 The key idea here is that underneath everything you tell the computer to do is boolean logic and transistor circuits. Yes, even Lisp S-exprs; it's not really correct to say "Lisp has no syntax", it has a very simple syntax that is trivially parseable. Even LLVM assembly is a translation layer, as is LLVM itself; underneath it on my computer is an i86 processor, and underneath it in my phone is an ARM-architecture Snapdragon. Once you understand that, you realize that all of these languages and frameworks and libraries and databases are just tools, and they exist for your convenience. They're there to let computers handle things that humans are really bad at. For example, memorizing memory layouts really sucks; let a computer map out your structs onto memory. Managing heap memory really sucks; let a garbage collector do it. Managing register allocation really sucks; let a compiler do it. Managing syntax kind of sucks; let a parser slap something more friendly on top of it, or don't and use Lisp. Managing vtables kind of sucks; let C++ or Java hide it behind a class, or don't and continue to use C. Once you've gotten into this mindset, you're free from the religious wars that surround technologies, because you realize it's all just tools that compile down to machine code at the end. And you understand when a tool might be useful, and when you could just as easily implement it yourself, and when it once was useful but has since ceased to be.
- chongli 13y agoOnce you've gotten into this mindset, you're free from the religious wars that surround technologies That seems all fine and well, but you're ignoring the elephant in the room: compatibility. You aren't free to choose your tools as you please if compatibility is one of your requirements. This little bit of impurity combines with network effects to create big problems. Compatibility along with all its attendant problems is the single most valid reason for engaging in a religious war over technology.
- tikhonj 13y agoThat's one philosophy. Your code exists to be run by your computer. Personally, I take a different one: the computer exists to run my code. LLVM, x86, ARM... all just implementation details. Sometimes they're unavoidable, but c'est la vie. Ultimately, what I care about is semantics. I care about what my program means--the logic it represents. After all, that's the whole point, the end goal. The fact that it's running on a physical computer is just a detail, albeit an important one. A programming language is more about shaping my thoughts and forming my logic than actually running. Choosing a programming language is incredibly important--it affects what I can say, how I can say it and even how I think. And that's the most important part.
- girvo 13y agoI'm working on a toy programming language at the moment, and I was considering using a LISP dialect of some sort as the IR to be compiled down to. Is this a dumb idea? I had the same sort of epiphany that the OP had, but then I think LLVM IR is a better choice. The only reason I like the LISP-as-IR idea, is that if a programmer wants to get deep and optimise, the tooling can work with lisp instead, which allows for some neat tricks I have in mind.
- jaggederest 13y agoYou're basically reontologizing the history of Lisp, which is that it was originally S-expressions that were the intermediary language for M-expressions, which were the human representation. They never quite got around to making M-expressions though, people found working in S-expressions to be pretty fine. Dylan is sort of a compromise around this area though: http://en.wikipedia.org/wiki/Dylan_(programming_language)#Syntax http://en.wikipedia.org/wiki/Dylan_(programming_language)#Sy...
- ericHosick 13y agoWe've been working on a programming language that is based on composition. This basically leads to a hybrid data structure (not necessarily tree-structured). Here is an example (write out 1 2 4 8 16 32 on different lines): Application ( using Library ( name "Vision.Console" ) action ForEach ( items 1 2 4 8 16 32 action WriteLine ( text CurrentItem () ) ) ) Parts are upper case and properties are lower case. Each Part is a class 1 contained within a given framework.
- dschiptsov 13y agoNice way to discover the if special form. Now its time for short-circuiting.)
- sgt101 13y agoNo one thinking that a contractor might have to maintain it in 5 years time? No? Ahhh the fundamentals!
- DevKoala 13y agoMy exact thought. Moreover, there might be other architectural reasons why he was asked to implement the logic at the higher level. I can see what he is getting at, but not his motives.
- forgottenpaswrd 13y agoOh man, so many people in the world need a better boss... Without him, they will spend most of their lives on mindless debates sucking their creative energy like a vampire blood.
- byuu 13y agoSure, and when you write an expression more complex than a single ternary, you start to see why Lisp is so uncommon in real-world usage. It has a wonderful technical elegance, but the humans that have to write code tend to not think in the same sense. After four or five brace levels it gets very challenging to keep track of everything.
- patricius 13y agoI think that can be said also of most mainstream languages, i.e., that more complex expressions are less comprehensible. The same applies to increasing levels of nesting. Lisp's syntax is so different that it just looks less comprehensible than any language you're more familiar with.
- carlob 13y agoThe overly eager optimizer in me was thinking: (price > 100) * 5 + 5; yay! no branching!
- deleted 13y ago[deleted]
- delinka 13y agoIff in your language of choice a Boolean is always converted to a 1 or 0. In C, at least, that's not necessarily the case. That said, I'm always looking for the least branchy way of doing things.
- dbaupp 13y agoI was under the impression that the C standard does mandate that comparisons give 1 and 0 for true and false. (Other nonzero things are considered true, but a plain comparison won't return them.)
- userbinator 13y agoIt does. ISO/IEC 9899:1999, 6.5.8, p6 has this to say: "Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false. The result has type int."
- praptak 13y agoDoes it compile to a piece of code without any conditional jumps?
- gsg 13y agoIt's not uncommon for machines to have a branchless idiom for generating the value of a condition. For instance, in x86: cmp price, 100 setg reg movzx reg, reg lea reg, [reg + reg*4 + 5]
- mikro2nd 13y agoTo quote Guy Steele, "All programming languages evolve until they become Lisp." (iirc)
- sebastianconcpt 13y agoDidn't knew that one. Heh, it's good!
- juliangamble 13y agoThis is a fascinating quote. It seems to be a combination of either: * Greenspun's 10th rule of programming: "Any sufficiently complicated C or Fortran program contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of CommonLisp." http://c2.com/cgi/wiki?GreenspunsTenthRuleOfProgramming http://c2.com/cgi/wiki?GreenspunsTenthRuleOfProgramming * James Gosling quoting Guy Steele: "Lisp is a Black Hole: if you try to design something that's not Lisp, but like Lisp, you'll find that the gravitational forces on the design will suck it into the Black Hole, and it will become Lisp". http://web.archive.org/web/20091201072950/http://blogs.sun.com/jag/entry/the_black_hole_theory_of http://web.archive.org/web/20091201072950/http://blogs.sun.c...
- Morgawr 13y agohttp://www.youtube.com/watch?v=_ahvzDzKdB0 http://www.youtube.com/watch?v=_ahvzDzKdB0 This video is relevant. Amazing talk.
- Cort3z 13y agoOf course you don't care that much about which language to choose when you just want to do a simple if statement. However when you want to do more complex stuff, like answering a request on port 80 and compile a document that you send back over port 80, making sure to encrypt it properly so that no third party will get a hold of it, then it would be beneficial with some sort of programming language. The question should really be, why does the IT department care if he uses C or Basic? And more over, why did he try to make it in C in the first place if he knows the IT department prefer Basic? This is a case of unprofessional behaviour by the author, not whether or not you need a language to express an if statement. At that point he could just as well have written this is x86. Who needs maintainability anyway?
- wildgift 13y agoHere's the code in either C or C#: return ( (price > 100) ? 10 : 5); Computer languages are for people. It should really be more like this: # # Description of what this does. # PRICE-THRESHOLD = 100 LOWER-PRICE = 5 UPPER-PRICE = 10 IF PRICE > PRICE-THRESHOLD RETURN UPPER-PRICE ELSE RETURN LOWER-PRICE Alternatively, use Excel: =IF( (price > 100), 10, 5 ) Excel is cryptic, but a lot of finance people understand it.
- J_Darnley 13y agoWith C it can be more like what you want. Stop using ?: if you don't like it. if (price > 100) return 10; else return 5; Replace with more named variables if you want.
- the_af 13y agoI'm going to guess wildgift was being sarcastic. COBOL syntax is so needlessly verbose it interferes with the understanding of the actual formula. I contend that return price > 100 ? 10 : 5; is way more readable.
- nkoren 13y agoThat code works in C, C#, and JavaScript.
- weatherlight 13y agoruby too!
- thomasfedb 13y agoIf you expressing what you want the computer to do, and it understands you, you are - by definition - using a language.
- xixixao 13y ago> Among other things, the C parser will look for curly braces, and the VB.NET parser will look for the eye soring Then keyword. Here I would pick up the article and write this: No matter which language I start with, the end result is always the same. So maybe I could simply write out what is important for me: if price > 100 10 else 5 And then I realized I was coding in CoffeeScript.
- collyw 13y agoSomeone influential (was it Joel) said that code gets read a lot more often than it gets written. I am not used to Lisp or VB.net but I do find the first two examples a lot more readable. (Seasoned Lispers, does reading Lisp get easier to read over time? As readable as an imperative language?)
- goldenkey 13y agoIt's a sack of parenthesis anyway you slice it. Of course staring at anything, including parenthesis, gets easier the more often you torture yourself. Just like talking with a lisp, you get used to it...hence they call the language LISP; painfully charming.
- dylandrop 13y agoAlright, that's one anecdote. But take a look at this one. In Python: a = 3 * 4 + 5 In Lisp: (setf a (+ 5 (* 3 4))) Now maybe it's just me, but balancing all those parentheses and thinking in prefix notation gets a little hairy, especially if we introduce more math into a program (think graphics or ML).
- lispm 13y ago3 7 - + - 4 8 Can't write that in Python. Looks like Python does not support even basic math notation. Lisp does not even attempt to do that. We have to write (+ (/ 3 4) (/ 7 8)) or (+ 3/7 7/8) Let's say we want to write a slightly more complicated expression in Python: 2 2 +-+ 3+-+3+-------+2 3+-+2 3+-------+ - 2b x \|3 log(\|a \|b x + a + \|a \|b x + a + a) + 2 2 +-+ 3+-+2 3+-------+ 4b x \|3 log(\|a \|b x + a - a) + +-+3+-+2 3+-------+ +-+ 2 2 2\|3 \|a \|b x + a + a\|3 +-+3+-+3+-------+2 12b x atan(----------------------------) + (12b x - 9a)\|3 \|a \|b x + a 3a / 2 2 +-+3+-+ 18a x \|3 \|a Not possible. It does not know basic math format for roots, exponents, ... Lisp also does not know it. Balancing parentheses in Lisp is usually done with the help of an editor...
- dylandrop 13y agoFor the first part, it's still more intuitive (at least for me personally) to write a = 3/4 + 5/8 than (setf a (+ (/ 3 4) (/ 7 8))) and the primary problem that I have with the parentheses not closing them, but logically seeing how expressions link together. Even if you can click on an end paren and see the expression it closes off (as you can in most IDEs) it would be easier just to not have the extra parentheses there in the first place, so as to avoid the confusion. It's really hard for me to even tell what you're trying to write for the second part -- in Python or Lisp.
- lispm 13y ago(setf a (+ (/ 3 4) (/ 7 8))) I have no problem writing or reading that. Personally I like the parentheses a lot, since they allow me comfortable editing operations for such expressions. Additionally it makes it easy to computationally manipulate those expressions as data.