"What if programming notation were more like music notation?" -> if you look at the denotational semantics listings on the latest Scheme Reports you will see something that could be equated to music notation (i.e. they're both instructions on how something should work, and they're sufficient information to get there).
I oftentimes think about these same issues regarding the syntax of different languages. I work in Ruby and I think it's a comfortable language to express ideas in. Scheme is also comfortable and I like it more conceptually, since it gives me this strange comfort of thinking "well, if Scheme disappears forever, at least I have books that can help me make another one", which I never think of languages like Ruby and Perl.
That's why I'm now finally learning Perl; I want to have a better perspective on what I actually like. If it turns out I'm a thousand times more comfortable with Perl than I'd ever be with a Lisp, then I guess I'll just learn to accept that I can't (or don't need to be able to) build the language I use from scratch.
It's just a weird feeling and I'd be curious to know if it's just me. It's this sense of bootstrapping that if I'm not using my own tools all the time (including the language) that I at least need to know how to make them.
What would actually stop you from building a language like Perl or Ruby from scratch?
Once you've parsed them (which is admittedly much more difficult than Perl), writing a relatively slow interpreter for the core language in C or similar wouldn't be that difficult.
What would actually stop you from building a language like Perl or Ruby from scratch?
Perl currently has no specification, other than the latest release of the interpreter. What the interpreter does may be decided to be incorrect by consensus at some point, and changed (although Perl has a very strong history of backwards compatibility so it's unlikely to change unless it was unuseful before), but there is no external resource besides the code and the compiled interpreter to explain how it should behave in every case.
No, but I have my own mental model of how it works, and if I were trying to preserve my own Perl code I'd only need the subset of Perl that I understand and use. I could reconstruct that from scratch with no reference other than my own Perl source code.
That's true. And with CPAN Testers and the output of the tests of all the modules against the latest version, you have a pretty damn good reference to go by.
If it turns out I'm a thousand times more comfortable with Perl than I'd ever be with a Lisp, then I guess I'll just learn to accept that I can't (or don't need to be able to) build the language I use from scratch.
You can also see how you like Perl 6, which has a specification and multiple implementations being built. It's not the same as Perl 5, but it's not meant to be (think of it as a sibling, not a successor).
I get the same feeling. That's why I always have this idea in the back of my head that I should learn to make a computer from the sand on a beach in case I'm ever marooned on an island on an alien planet.
But I recognize that it's entirely impractical to start from literally nothing.
I also keep around my old computers and/or make sure I have emulators that can run my old stuff. E.g. a TRS-80 emulator for the Basic II programs I first learned to write. Or a Mac OS 9 emulator to open Claris Works 4 files I wrote in high school. I rarely use such things, but I feel better knowing my data is not truly lost.
For varying contexts of bad. It impedes on things like static analysis.
You don't want the surface area of your programming language confined to 1) runtime 2) being run by a specific binary. Where is the offline tooling? Where is the variety?
This handicap makes me despise Perl. And I say that as a long time professional Perl engineer.
The idea of saying “Here is some file and I can't tell you whether it is valid Perl without executing it.” is magnitudes worse than all the C++ macro preprocessor and template hell combined.
Something like that is pretty much the worst imaginable thing to happen in language design, especially because we know at least since Chomsky, Rice and Turing how to do better.
And why that information may be valuable? You cannot say anything about whether it works or it doesn't. "This is valid C++ code, but it dumps a core on null pointer dereference here and there." -- is that information very useful? How exactly?
I see an only one ephemerical goal that was a Holy Grail for academia and static analysis was primarily developed to approach it -- formal verification. But it's dead and buried outside an academia and noone cried at the funeral.
The notion that programming languages would accumulate more syntax as the discipline of software engineering matures and more conventions become universal, while appealing to me personally, is, in my opinion, naive. These times are not like the past centuries over which Mathematics matured, our culture has changed and it's pervading on the progress of science, we now favor instant gratification, quick results, getting started easily, all accomodating short attention spans.
Of course, that says nothing of academic and niche languages; those will develop in every way possible. But as for what's to become popular, I think programming is bound to drop more specific syntax and become increasingly like natural language. This will be facilitated not only by our culture, but by advances in AI and natural language parsing. Much like the text editors themselves will tend to be increasingly facilitated by visual and audio input, and by intelligent computer assistance, in ways envisioned by Bret Victor, instead of going the way of the full control beasts that are vim and emacs. Which is a shame just the same.
EDIT: Care to make a counter argument instead of just downvoting?
Counter-arguments: I take it as axiomatic that if someone says our times are different from all the rest of history, they are wrong. I can't imagine that our need for unambiguous syntax is going to decline, since our programs are still going to need to be precise in a way that is not well-served by natural language. I think your whole argument is hand-wavy and, in my opinion, naïve.
I don't think that human nature changes over history, but culture does. I agree that attention spans have become shorter, but I don't see how that relates to whether programming languages will expand their palette of symbols.
>I think programming is bound to drop more specific syntax and become increasingly like natural language
Why do you think that? Programming has never been like writing in a natural language, nor would it be useful for it to be. Natural language is inherently filled with subtleties and imprecision, both of which are anathema to the typical process of programming. When I write something for the computer to consume then I want to be able to know with 100% certainty what it is going to do, the probablistic parsers typically used for NLP couldn't guarantee that.
> we now favor instant gratification, quick results, getting started easily, all accomodating short attention spans.
This is not new. It is part of being human. Humans, being mammals, are inherently lazy and eager for shortcuts; it's why we have programming languages and computers to begin with. If you want industrious, look at the insects.
Applescript forms an interesting counter-point to your argument - it attempted to use something as close to natural language as possible. As a result it is verbose, complex to debug, and difficult to guess at the syntax as applications often use slightly different concepts for the same things. It's never been a popular language with programmers, and has only seen more widespread use by non-programmers when it was hidden from sight with Automator.
In contrast many (but not all) of the popular languages to program in today are as simple as possible (Ruby, Python, Go, etc...), and have a tightly controlled syntax and limited keywords, partly inspired by the example of Lisp. They may allow constructing simple sentences with verbs (functions) and nouns (variables), but they are carefully limited in the sentences and syntax they allow, and often don't require any UI other than a plain text editor. They certainly don't require NLP or AI and I can't see any move in that direction.
As a scala user/fan I spend a lot of time thinking about this; I think the scala community is at a crossroads in terms of syntactic convention.
Personally I feel symbols make a language less readable, and I'd hold up python as the best example. It's more readable than either perl or lisp; the larger-scale structure of a program is immediately apparent (partly thanks to "the whitespace thing") as with perl, but then in the small the use of words rather than symbols ("or", "in") makes it readable without learning, like lisp. One has to rely on syntax highlighting to show the differences between values and operators - but even in a language that uses symbols for operators, one needs to be able to distinguish between values and functions (and in scala in particular, a visual distinction between functions and operators would be actively unhelpful).
I know usability studies have found buttons with text are easier to understand than those with icons; I wonder if the comparison extends to symbols.
but even in a language that uses symbols for operators, one needs to be able to distinguish between values and functions
Which is the whole point of sigils in perl, and a different sigils to denote the different core types. They hint the type for the reader.
Some people are very adverse to the idea of sigils, but really it's like any other bit of syntax in a language, once you know what it is and can pick it out, you can then use it as a useful additional channel of information when reading and writing code (channel of information to future readers of the code, that is).
Firstly, the sigils on variables are only a small part of perl's legendary unreadability; there's also a plethora of operators called things like <=> and ~/, along with a bunch of magic implicit variables ($_ is common enough to be memorable, but it's not the only one).
And the sigils are a bad idea for the same reason that operators with sigil names are a bad idea: it creates this artificial distinction between what's built-in and what's user-defined (though in this case we're talking about types rather than methods).
The article says that having the syntax is not a bad thing but doesn't really say what it has over LISP's simple syntax, expressiveness? easy to read for people unfamiliar with the language? AFAIK the one thing it definitely allows is to be able to write a program and common tasks in just a few characters, which is great and all but not the strength of perl and definitely not needed in all situations.
LISP syntax OTOH is as he said easy to pick up and parse while still allowing all the expressiveness any other language can have (even without more syntax like the lambda character).
But there is a similarity between the two, the outstanding syntax. I don't know about others but I'd attribute it to C's popularity more than anything else and with most other languages following it (JS, C++...) it seems like it should be standard or something, I've seen far too many people avoid learning languages due to syntax without realizing something much more important: They might be turning down a language that can save them tons of trouble later if they just get past the one time step of learning the syntax, so listen to the author, perl is a great CGI language, and if that's what you need just learn it. other languages may be easier to learn, may be what's hip now but I'd bet perl is still better.
The concluding question—"What if programming notation were more like music notation?"—is an interesting one. Music notation achieves a pretty impressive information density when you think about it. And it offers an interesting way of describing concurrent processes. (edit: I should say it offers an interesting way of describing parallel processes) I suppose it would be closest to a declarative programming paradigm?
But there are going to be some inevitable problems when drawing comparisons to programming languages. One of which is that music notation occupies a kind of hybid position between a natural language and a machine language. Certain aspects of notation like pitch and rhythm are totally unambiguous (at least in the abstract) but others (volume, timbre, attack, phrasing) are more connotational and thus up to performer interpretation. Then there's something like tempo which may be a mixture of both: a metronome mark is unambiguous but an accelerando isn't.
Also, although I agree that "people learn to read it fluently with a little training," I don't think it follows that they can write it correctly with a little training. It's actually an enormously subtle, complex mode of expression. Take just one example: enharmonic spelling. Even in a purely diatonic harmonic context, understanding when to use a g-sharp versus and a-flat requires a pretty extensive understanding of music theory. Take a bit of time to peruse something like Gardner Read's "Music Notation: A Manual of Modern Practice" with its 400+ pages detailing all the edge cases and tiny details and you'll see just how hard it can be to notate music properly.
"Music notation does not express concurrency easily [in enough generality to do most of the interesting things that aren't simple parallelism]. It expresses parallelism easily."
I'm not sure what the right words are for the post you replied to, but they are honestly different and have different capabilities.
For "concurrency" think of the operation, "You go off and take care of that. I'll take care of this. We might meet up later."
For "parallelism" think of performing a sequence of operations in lock step, while standing next to each other.
That these are independent can be seen in programming when you compare multi-threaded programming (concurrent but in no way parallel) with programming for the GPU (very parallel, but none of the type of concurrency that I'm discussing).
Returning to music notation, it is like a GPU - everything goes in lock step. Stuff happens simultaneously, but not independently.
There's an analog in music to the notion of concurrency, which is the polyphonic melody -- a single melodic line that, by jumping between disparate registers, expresses the simultaneous sounding of two (abstract) voices moving against each other. Of course, this depends on the assumption that pitches can be implied even at times when they're not sounding, which intuitively seems to hold: see Bach's Cello Suites for a canonical example of this practice in action.
I completely agree with this. Perhaps expanding the idea further however, it makes sense IMHO to see a multi-staff score (this could mean either a score written for multiple parts, or as something like piano scores which typically have a staff for each hand) as parallelism.
I think this will be rant about the list/scalar context or scalar/array/hash context. Like a pointers in C that are extremely useful features and at the same time are surprisingly hard to understand for many people.
If so, that would be a shame. There's already far to much "Hey, that's not how C behaves! [insert lang here] is stupid because it doesn't do what I expect, and I expect it to be C."
I've lost you here. My C pointers analogy was relevant only in that is surprisingly hard to get by many people, and I don't know why is that so.
The only thing in Perl that clearly imitates C pointers syntax and semantics is a hash/array reference element access '->' and I like it because it clearly distinguish from actual hash/aray access '.' and understandable for any person who knows C.
Oh, I understood your meaning, it was just similar enough to another theory of mine[1] that I sort of launched into that frame of mind immediately.
In short, people often expect other languages to act like C, and where they differ they get a bad rap (even through they often differ at that point for a reason, and it's often considered a strength by proponents). For example, caring about return context in Perl.
I think you get into the apple in quote you referenced, understand vs think they understand looks like core problem with many non-trivial and often actually very well designed things.
Another example of this kind I see too often is a CPAN to <choose-a-language> guy. He thinks he understand what it is ("That's simple! Just a bunch of libraries packed in tar.gz available via FTP and HTTP, right? Oh, and there is the search field to find them, yeah. We also have such thing in <our-language> - see, ftp://...").
edit: Another good example is a Trackpoint clearly.
As a musician, I would disagree heavily with the author's statement that "people learn to read [musical notation] fluently with a little training".
A few certain individuals can be musical without being musically literate but understanding musical notation definitely requires training. It's like literacy, it's not something you just pick up out of nowhere. It's intentional, it's practiced, and it is honed.
Consider Fortress'[1] syntax, its designed to completely typeset and look amazingly readable. [2] has a pretty nice rundown of the syntax, with [3] being a talk at ScalaDays 2012 on what Fortress and Scala can learn from each other syntactically.
Fortress has the concept of juxtaposition: things like:
2 3
evaluate to 6, because thats the scientific convention. Integer types are also represented as the mathematical symbol for Ints etc, the language looks beautiful and how you'd write it on the whiteboard.
I like the simplicity of the big operators and the ideas on parallelism they were considering. What a huge disappointment that they aren't going to continue work on it.
Also take a look on mathematica. It has both a textual and a mathematic representation for everything making it both look good while it cooperates with existing source control tools. It's a shame more languages aren't designed like this. I would like to call it extreme syntax highlighting rather than extreme syntax.
Some might argue that 'sum(myArray)' is both more readable and occupy less vertical space than the mathematical sum-operator but when it comes to skimming through large pieces of code having distinctive characters can really help. Where it really shines is when you are editing large matrices that automatically get aligned. Long mathematical expressions involving division is also a good example, here you get fractionals displayed nicely instead of having to nest everything in paranthesis.
The music analogy is tempting, but has a serious problem. The same music when interpreted by different people, results in a different sounding piece. There is some level of control on this, but not as much as I think would be necessary for most programs.
That just means the semantics are not precisely defined. Have a look at the C specification for things that are left undefined. The same C program, when interpreted by different compilers (esp. on different architectures) will have different behavior.
Right. I had thought most folks wanted less "undefined" behavior in a program.
And, most of the type of "undefined" you are referring to are in places where folks are supposed to avoid, right? That is, I thought most were "undefined" and generally considered programmer error.
And what with "syntax doesn't matter" people? You know, the ones that now both Perl and at least three Lisps, and then twenty other languages, the ones that say that syntax is just a minor detail, and if you're irritated enough you can always write a "transpiler"? Where did all these people go (long time ago)?
Also, I prefer maths from before 20th century. You could get knowledge out of it without relying on an additional skill, which math-reading nowadays is.
On a related note: I don't believe that "you spend more time using the language than learning it". I need to think it about it some more, but I have a feeling that almost everything we do as a programmers is learning.
On a related note: I don't believe that "you spend more time using the language than learning it". I need to think it about it some more, but I have a feeling that almost everything we do as a programmers is learning.
Yes, but how much of that is learning the language, and how much is learning about programming and/or computer science in general?
But how much of that learning is really empirically necessary, and how much is just keeping up with industry fads and trends just to stay marketable?
I've learned way too many languages over the last fifteen years just in the process of being a web developer. I'm not sure if any of them by themselves made me a radically better at web development. More frequently they were learned to get access to a bit of tooling or some other benefit that only one language had.
Think of all the people who learned Ruby in order to use Rails, for instance, or who learned JavaScript to do front-end scripting. Is it really something about Ruby-the-language or JS-the-language that made them so compelling? Not really. It was the productivity gains you could get by getting access to their ecosystems, rather than the languages themselves.
For this reason I have some envy for the folks you meet who've been working in Lisp, or Perl, or C, or COBOL, or some other language consistently for decades. They get to reach a level of proficiency and sophistication in how they use their tools that are out of reach when you're constantly bouncing from language to language.
I agree that I'd like to have the chance to get really good in a language that I use for a long time. (As long as it's enjoyable, e.g. I wouldn't want to be stuck in VB forever.) At one point I worked almost entirely in Java (up until around Java 1.5). Another few years it was mostly PHP. But since then it's been a bit of everything.
Useful lessons from learning:
- Javascript -> Callback passing for an asynchronous computing paradigm. Object-array duality and prototype-based inheritance.
- Ruby -> Rubyists often like to be clever with chaining several functions on one line to do something succinctly. This is kinda like functional programming (operations like map, inject, fold, etc.) but just one small piece of it. Ruby also has lots of metaprogramming magic to make DSLs, but that can bite you really bad when you have to debug RoR GEMs.
"Is it really something about Ruby-the-language or JS-the-language that made them so compelling?"
Well... It obviously depends on a person. What is compelling to you may not be so for me and the other way around. And in this instance it depends on what you know already.
So, in other words, are JS and Ruby compelling to someone who learned Pascal or C in school and writes PHP for a living? Hell yes! Are they going to make him a better developer? There's a high chance they will.
Ruby sports an object system that is somewhat similar to Smalltalk, with many idioms borrowed from it. That's completely different Object Orientation and learning it can have benefits. If nothing more, it gives you another way of modeling problem domains, which is always a good thing.
JavaScript was an objective-functional mesh long before Scala. Coming from C or PHP, seeing first class functions with implicit state (closures) can open your eyes for yet another way of modeling things. Building, in essence, your own object system when you use a language is a valuable experience, too.
Different languages have different semantics and knowing many of them helps in expressing yourself. I hear that what we think is constrained by the language we know. That's true for programming languages too.
It also partly depends on how often you switch jobs that require you to learn a new programming language. So far in my career I've had to learn new languages quite often, esp. on hacked-together projects with 3+ languages. It's not just learning the syntax but also the common idioms. Still, I'm pretty sure at least more than 50% of the time was using the language and not learning it, so the original statement stands.
I mostly do s-expression -> language, because it lets me do code generation.
The thing is, writing your own code generation tools is only really useful if you are capable of applying 'more difficult' to grok computer science concepts. For example, the intersection of 'working programmers' and 'people who really understand state machines' is (sadly) tiny.
I'd even say that the syntax doesn't bother me because I don't really 'write' lisp code. The lisp code I write is solely done in order to generate much more complex code. So I would never actually implement an entire piece of software in common lisp (for example). I implement it in a variety of lisp-like dialects which accurately represent the problems presented by different modules inside the piece of software. Unfortunately this requires some forethought, some skill at language design, and an unwavering faith in ontology.
To me, this is the best type of process for implementing a unique piece of software from scratch, and is the approach that should be taken in any language. (It's basically the logical conclusion of the idea of structured programming... except you don't implement 'loops' and 'if' statements).
Common Lisp actually has a suprising amount of syntax, from the obvious ', to all of the standard dispatch reader macros starting with # (#', #., #=, ...), to block comment syntax #| ... |#. Pure lisp has no syntax, but practical lisp has quite a bit. Trying to read arbitrary symbols from external sources can lead to quite a shock without hacking the reader to disable many of it's syntactical features.
Which further proves the author's point that adding syntax makes things easier, since even the pure Lisp land is speckled with extra syntax to make it work.
When you have 2 extremes the real solution is almost always somewhere in the middle. I think a good solution to the syntax amount problem is Python, but I still don't like significant whitespace.
One comment on the article mentioned that programming languages need to have many concepts, and concepts built on concepts, and concepts built on those. So you can't have a new symbol for each concept since you build more and more concepts.
I think Lisp has too few symbols. I completely agree with the author on this.
I think there's a balance where we use enough symbols to make the structure of the code stand out but don't try to make everything into a symbol since the language is essentially extensible by the user in building the tower of concepts.
Next question: is operator overloading good? It lets you write extensions that feel like they are part of the language, but it also makes the code difficult to evaluate mentally since you might not know that an operator means something different now.
I've always found it rather annoying to use collection APIs in Java, or big num libraries, since you have to call long-named functions for simple operations. In C++ you can overload operators to concatenate, iterate, and inspect collections. But this can be misused (in C++, Lisp, and other languages) to make code harder to figure out.
Math notation, though, does have overloading. "+" is not just add two integers, it can be used for set operations sometimes. Also some notation is used differently in different disciplines, like math-like notation in some computer science papers (e.g. describing a type system or Lambda calculus evaluation) look similar to operators used in logic or calculus but mean different things. So operator overloading is common. Is it good?
Operator overloading is good if the operator continues to mean the same thing across domains. If I have two integers and I want to add them together to create a new integer, that's pretty clear. It's still clear that if I have two complex numbers or fractions that I would want to immutably add them up and create a new number. And so on with things like lists and sets, which as you pointed out are set operations.
I would be less inclined to extend this to domains that aren't about numbers or sets, like
genie + bottle
What exactly does that do?
It's kind of like implementing an interface. The implementation should do what it says on the box. In this case the box is the sign for addition.
73 comments
[ 5.7 ms ] story [ 148 ms ] threadI oftentimes think about these same issues regarding the syntax of different languages. I work in Ruby and I think it's a comfortable language to express ideas in. Scheme is also comfortable and I like it more conceptually, since it gives me this strange comfort of thinking "well, if Scheme disappears forever, at least I have books that can help me make another one", which I never think of languages like Ruby and Perl.
That's why I'm now finally learning Perl; I want to have a better perspective on what I actually like. If it turns out I'm a thousand times more comfortable with Perl than I'd ever be with a Lisp, then I guess I'll just learn to accept that I can't (or don't need to be able to) build the language I use from scratch.
It's just a weird feeling and I'd be curious to know if it's just me. It's this sense of bootstrapping that if I'm not using my own tools all the time (including the language) that I at least need to know how to make them.
Once you've parsed them (which is admittedly much more difficult than Perl), writing a relatively slow interpreter for the core language in C or similar wouldn't be that difficult.
Perl currently has no specification, other than the latest release of the interpreter. What the interpreter does may be decided to be incorrect by consensus at some point, and changed (although Perl has a very strong history of backwards compatibility so it's unlikely to change unless it was unuseful before), but there is no external resource besides the code and the compiled interpreter to explain how it should behave in every case.
You can also see how you like Perl 6, which has a specification and multiple implementations being built. It's not the same as Perl 5, but it's not meant to be (think of it as a sibling, not a successor).
But I recognize that it's entirely impractical to start from literally nothing.
I also keep around my old computers and/or make sure I have emulators that can run my old stuff. E.g. a TRS-80 emulator for the Basic II programs I first learned to write. Or a Mac OS 9 emulator to open Claris Works 4 files I wrote in high school. I rarely use such things, but I feel better knowing my data is not truly lost.
Not actually true otherwise no Perl code could be run at all :)
A more accurate description would be - Perl cannot be parsed unambiguously without runtime information.
For more detailed|interesting discussion about that Perlmonks post see this HN submission from 3 years ago - https://news.ycombinator.com/item?id=761103
You don't want the surface area of your programming language confined to 1) runtime 2) being run by a specific binary. Where is the offline tooling? Where is the variety?
This handicap makes me despise Perl. And I say that as a long time professional Perl engineer.
>being run by a specific binary
That's a not so appealing argument in particular case of Perl which level of reverse compatibility is hard to beat.
Also, what does reverse compatibility have to do with ease of parsing?
So, whether ease of parsing is a goal per se, or serve some purpose - what such a purpose can be in particular case of Perl?
Something like that is pretty much the worst imaginable thing to happen in language design, especially because we know at least since Chomsky, Rice and Turing how to do better.
And why that information may be valuable? You cannot say anything about whether it works or it doesn't. "This is valid C++ code, but it dumps a core on null pointer dereference here and there." -- is that information very useful? How exactly?
I see an only one ephemerical goal that was a Holy Grail for academia and static analysis was primarily developed to approach it -- formal verification. But it's dead and buried outside an academia and noone cried at the funeral.
You just can't imagine how incredibly ridiculous it appears to the non-US world to use “academic” as a slur.
Of course, that says nothing of academic and niche languages; those will develop in every way possible. But as for what's to become popular, I think programming is bound to drop more specific syntax and become increasingly like natural language. This will be facilitated not only by our culture, but by advances in AI and natural language parsing. Much like the text editors themselves will tend to be increasingly facilitated by visual and audio input, and by intelligent computer assistance, in ways envisioned by Bret Victor, instead of going the way of the full control beasts that are vim and emacs. Which is a shame just the same.
EDIT: Care to make a counter argument instead of just downvoting?
Why do you think that? Programming has never been like writing in a natural language, nor would it be useful for it to be. Natural language is inherently filled with subtleties and imprecision, both of which are anathema to the typical process of programming. When I write something for the computer to consume then I want to be able to know with 100% certainty what it is going to do, the probablistic parsers typically used for NLP couldn't guarantee that.
This is not new. It is part of being human. Humans, being mammals, are inherently lazy and eager for shortcuts; it's why we have programming languages and computers to begin with. If you want industrious, look at the insects.
In contrast many (but not all) of the popular languages to program in today are as simple as possible (Ruby, Python, Go, etc...), and have a tightly controlled syntax and limited keywords, partly inspired by the example of Lisp. They may allow constructing simple sentences with verbs (functions) and nouns (variables), but they are carefully limited in the sentences and syntax they allow, and often don't require any UI other than a plain text editor. They certainly don't require NLP or AI and I can't see any move in that direction.
Personally I feel symbols make a language less readable, and I'd hold up python as the best example. It's more readable than either perl or lisp; the larger-scale structure of a program is immediately apparent (partly thanks to "the whitespace thing") as with perl, but then in the small the use of words rather than symbols ("or", "in") makes it readable without learning, like lisp. One has to rely on syntax highlighting to show the differences between values and operators - but even in a language that uses symbols for operators, one needs to be able to distinguish between values and functions (and in scala in particular, a visual distinction between functions and operators would be actively unhelpful).
I know usability studies have found buttons with text are easier to understand than those with icons; I wonder if the comparison extends to symbols.
Which is the whole point of sigils in perl, and a different sigils to denote the different core types. They hint the type for the reader.
Some people are very adverse to the idea of sigils, but really it's like any other bit of syntax in a language, once you know what it is and can pick it out, you can then use it as a useful additional channel of information when reading and writing code (channel of information to future readers of the code, that is).
And the sigils are a bad idea for the same reason that operators with sigil names are a bad idea: it creates this artificial distinction between what's built-in and what's user-defined (though in this case we're talking about types rather than methods).
LISP syntax OTOH is as he said easy to pick up and parse while still allowing all the expressiveness any other language can have (even without more syntax like the lambda character).
But there is a similarity between the two, the outstanding syntax. I don't know about others but I'd attribute it to C's popularity more than anything else and with most other languages following it (JS, C++...) it seems like it should be standard or something, I've seen far too many people avoid learning languages due to syntax without realizing something much more important: They might be turning down a language that can save them tons of trouble later if they just get past the one time step of learning the syntax, so listen to the author, perl is a great CGI language, and if that's what you need just learn it. other languages may be easier to learn, may be what's hip now but I'd bet perl is still better.
But there are going to be some inevitable problems when drawing comparisons to programming languages. One of which is that music notation occupies a kind of hybid position between a natural language and a machine language. Certain aspects of notation like pitch and rhythm are totally unambiguous (at least in the abstract) but others (volume, timbre, attack, phrasing) are more connotational and thus up to performer interpretation. Then there's something like tempo which may be a mixture of both: a metronome mark is unambiguous but an accelerando isn't.
Also, although I agree that "people learn to read it fluently with a little training," I don't think it follows that they can write it correctly with a little training. It's actually an enormously subtle, complex mode of expression. Take just one example: enharmonic spelling. Even in a purely diatonic harmonic context, understanding when to use a g-sharp versus and a-flat requires a pretty extensive understanding of music theory. Take a bit of time to peruse something like Gardner Read's "Music Notation: A Manual of Modern Practice" with its 400+ pages detailing all the edge cases and tiny details and you'll see just how hard it can be to notate music properly.
It can do this each part can be played in isolation - in other words, they are pure.
For "concurrency" think of the operation, "You go off and take care of that. I'll take care of this. We might meet up later."
For "parallelism" think of performing a sequence of operations in lock step, while standing next to each other.
That these are independent can be seen in programming when you compare multi-threaded programming (concurrent but in no way parallel) with programming for the GPU (very parallel, but none of the type of concurrency that I'm discussing).
Returning to music notation, it is like a GPU - everything goes in lock step. Stuff happens simultaneously, but not independently.
The only thing in Perl that clearly imitates C pointers syntax and semantics is a hash/array reference element access '->' and I like it because it clearly distinguish from actual hash/aray access '.' and understandable for any person who knows C.
In short, people often expect other languages to act like C, and where they differ they get a bad rap (even through they often differ at that point for a reason, and it's often considered a strength by proponents). For example, caring about return context in Perl.
[1]: https://news.ycombinator.com/item?id=5657901
Another example of this kind I see too often is a CPAN to <choose-a-language> guy. He thinks he understand what it is ("That's simple! Just a bunch of libraries packed in tar.gz available via FTP and HTTP, right? Oh, and there is the search field to find them, yeah. We also have such thing in <our-language> - see, ftp://...").
edit: Another good example is a Trackpoint clearly.
A few certain individuals can be musical without being musically literate but understanding musical notation definitely requires training. It's like literacy, it's not something you just pick up out of nowhere. It's intentional, it's practiced, and it is honed.
It seems like it's more important to read Fruity Loops or Ableton filter notation nowadays.
Fortress has the concept of juxtaposition: things like:
evaluate to 6, because thats the scientific convention. Integer types are also represented as the mathematical symbol for Ints etc, the language looks beautiful and how you'd write it on the whiteboard.[1] - http://en.wikipedia.org/wiki/Fortress_(programming_language)
[2] - http://www.slideshare.net/alexmiller/project-fortress
[3] - http://skillsmatter.com/podcast/scala/scala-days-keynote-301...
Some might argue that 'sum(myArray)' is both more readable and occupy less vertical space than the mathematical sum-operator but when it comes to skimming through large pieces of code having distinctive characters can really help. Where it really shines is when you are editing large matrices that automatically get aligned. Long mathematical expressions involving division is also a good example, here you get fractionals displayed nicely instead of having to nest everything in paranthesis.
And, most of the type of "undefined" you are referring to are in places where folks are supposed to avoid, right? That is, I thought most were "undefined" and generally considered programmer error.
Also, I prefer maths from before 20th century. You could get knowledge out of it without relying on an additional skill, which math-reading nowadays is.
On a related note: I don't believe that "you spend more time using the language than learning it". I need to think it about it some more, but I have a feeling that almost everything we do as a programmers is learning.
Yes, but how much of that is learning the language, and how much is learning about programming and/or computer science in general?
I've learned way too many languages over the last fifteen years just in the process of being a web developer. I'm not sure if any of them by themselves made me a radically better at web development. More frequently they were learned to get access to a bit of tooling or some other benefit that only one language had.
Think of all the people who learned Ruby in order to use Rails, for instance, or who learned JavaScript to do front-end scripting. Is it really something about Ruby-the-language or JS-the-language that made them so compelling? Not really. It was the productivity gains you could get by getting access to their ecosystems, rather than the languages themselves.
For this reason I have some envy for the folks you meet who've been working in Lisp, or Perl, or C, or COBOL, or some other language consistently for decades. They get to reach a level of proficiency and sophistication in how they use their tools that are out of reach when you're constantly bouncing from language to language.
Useful lessons from learning: - Javascript -> Callback passing for an asynchronous computing paradigm. Object-array duality and prototype-based inheritance. - Ruby -> Rubyists often like to be clever with chaining several functions on one line to do something succinctly. This is kinda like functional programming (operations like map, inject, fold, etc.) but just one small piece of it. Ruby also has lots of metaprogramming magic to make DSLs, but that can bite you really bad when you have to debug RoR GEMs.
Well... It obviously depends on a person. What is compelling to you may not be so for me and the other way around. And in this instance it depends on what you know already.
So, in other words, are JS and Ruby compelling to someone who learned Pascal or C in school and writes PHP for a living? Hell yes! Are they going to make him a better developer? There's a high chance they will.
Ruby sports an object system that is somewhat similar to Smalltalk, with many idioms borrowed from it. That's completely different Object Orientation and learning it can have benefits. If nothing more, it gives you another way of modeling problem domains, which is always a good thing.
JavaScript was an objective-functional mesh long before Scala. Coming from C or PHP, seeing first class functions with implicit state (closures) can open your eyes for yet another way of modeling things. Building, in essence, your own object system when you use a language is a valuable experience, too.
Different languages have different semantics and knowing many of them helps in expressing yourself. I hear that what we think is constrained by the language we know. That's true for programming languages too.
I mostly do s-expression -> language, because it lets me do code generation. The thing is, writing your own code generation tools is only really useful if you are capable of applying 'more difficult' to grok computer science concepts. For example, the intersection of 'working programmers' and 'people who really understand state machines' is (sadly) tiny.
I'd even say that the syntax doesn't bother me because I don't really 'write' lisp code. The lisp code I write is solely done in order to generate much more complex code. So I would never actually implement an entire piece of software in common lisp (for example). I implement it in a variety of lisp-like dialects which accurately represent the problems presented by different modules inside the piece of software. Unfortunately this requires some forethought, some skill at language design, and an unwavering faith in ontology.
To me, this is the best type of process for implementing a unique piece of software from scratch, and is the approach that should be taken in any language. (It's basically the logical conclusion of the idea of structured programming... except you don't implement 'loops' and 'if' statements).
I think Lisp has too few symbols. I completely agree with the author on this.
I think there's a balance where we use enough symbols to make the structure of the code stand out but don't try to make everything into a symbol since the language is essentially extensible by the user in building the tower of concepts.
Next question: is operator overloading good? It lets you write extensions that feel like they are part of the language, but it also makes the code difficult to evaluate mentally since you might not know that an operator means something different now.
I've always found it rather annoying to use collection APIs in Java, or big num libraries, since you have to call long-named functions for simple operations. In C++ you can overload operators to concatenate, iterate, and inspect collections. But this can be misused (in C++, Lisp, and other languages) to make code harder to figure out.
Math notation, though, does have overloading. "+" is not just add two integers, it can be used for set operations sometimes. Also some notation is used differently in different disciplines, like math-like notation in some computer science papers (e.g. describing a type system or Lambda calculus evaluation) look similar to operators used in logic or calculus but mean different things. So operator overloading is common. Is it good?
I would be less inclined to extend this to domains that aren't about numbers or sets, like
genie + bottle
What exactly does that do?
It's kind of like implementing an interface. The implementation should do what it says on the box. In this case the box is the sign for addition.