
Ask HN: How would you modify this list of best Perlis languages? - wrp
Blog aritcles about Perlis languages are popular, but they disappoint me. The surveys are limited by the experience of one individual and the responses are mostly just people giving a shout for their language du jour.<p>"Perlis language" is a subjective term. That is, does a language represent a new way of thinking for <i>you</i>? On the other hand, I think we can agree that a good Perlis language:
    * implements the most powerful and representative features of a paradigm
    * does not require learning much more than what is needed to use the paradigm
    * does not mix non-orthogonal paradigms
    * is developed enough that you can build working applications with it<p>I tried to list every distinct paradigm and match it with the best implementation. Some languages came up as the best for multiple paradigms. There were a few paradigms that I was really interested in but couldn't find a suitable implementation. In the end, I was surprised at how short my list is.<p>What would you change? Would you argue for a different language, or to add/delete a paradigm?<p><pre><code>    C -- procedural
    Forth -- build it yourself
    Emacs Lisp -- macros, code as data 
    Erlang -- impure functional, eager evaluation, dynamic typing, actor concurrency
    Clean -- pure functional, lazy evaluation, static typing
    GNU Smalltalk -- class-based OOP
    Io -- prototype-based OOP, reflection
    APL -- array-based, built on a small set of powerful operators
    Prolog -- unification, backtracking, logic variables</code></pre>
======
wrp
Io was a hot topic around 2005-2006, but interest has faded. My impression is
that the excitement was due to Io's extreme reflection capabilities and
runtime dynamism. These are interesting design features and Io is probably one
of the best languages for exploring them, but I'm listing it here as a case of
protoype-based object-oriented design.

Prototype OOP really was a challenge for this list. Although several
prorotype-based languages have been developed, I think only Io and JavaScript
have made it into production use. (Unless you count the crippled and long-dead
NewtonScript.)

So why not JavaScript? Well, ugh, JavaScript is a mess, not just the language,
but also the production environments, the documentation, and the user
community. In addition to prototypes, JavaScript incorporates the functional
paradigm plus a lot of random warts. Developing JavaScript apps for release is
a nightmare because of platform differences. Documentation is little help,
because even advanced books on JS take the approach that class-based OOP is
what you really want, so they focus on how to hammer JS into something that
looks like Java. They are many excellent 3rd party libraries, but they either
treat JS as a functional language or force it into the class-based mould. So,
I'd answer that you can write good prototype-based code in JavaScript, but you
really need to be proficient before going in.

~~~
johnm
Yeah, Io never got to a (nice/good enough) v1.0 that people could do more than
just play around with it. Secondarily, its radical dynamism makes it slow in
those shootout benchmarks.

------
wrp
Smalltalk is still the gold standard for class-based object-oriented language
design. It doesn't get used much, though. There are the problems with image-
based development, external interfacing, cross-implementation differences,
unwieldy class libraries, and a bunch of other things.

Ruby gets recommended a lot as a modern alternative. It has a very clean
syntax and the OOP machinery is closely copied from Smalltalk. By my
experience is that while Ruby code at first seems clean and elegant, it turns
out to be confusing. The design philosophy is like Perl, have multiple ways to
do anything. The larger and more complicated grammar makes it harder to learn.
I thought that while regexes and class management were smoothly integrated,
many other syntactic features were inconsistent, nonstandard, or ambiguous. In
all, there were just too many other things going on to make Ruby a good
vehicle for dipping into class-based OOP.

Python, also, might be suggested, since Python 3 has made the OOP features
more integrated than once was the case. However, Python is a big language,
there is a lot to become aware of, and the OOP machinery is not all that close
to Smalltalk any more.

GNU Smalltalk is what I recommend. It is a straightforward implementation of
traditional Smalltalk with one big difference. Instead of being image-based
and editable only in the Smalltalk browser environment, GST is text-based. You
write code in a text editor as with any other language, though there is also a
browser environment available. GNU Smalltalk is designed as a scripting
language, so it has the usual facilities for system interaction.

~~~
fractallyte
Part of the charm of Smalltalk (or, more objectively, the _uniqueness_ in a
Perlis-language sense) is its image-based nature. Smalltalk _is_ the image.

A Smalltalk IDE is unlike any other. The integration of language and
'operating system' changes the way you look at most other languages; it's not
just an OO thing. You lose all that if you go running to the familiar,
comfortable 'standard' of a text editor.

Personally, I'd suggest Pharo Smalltalk as an ideal starting point: it's
clean, modern and under vigorous development, with a thriving community.

Also, I strongly disagree with 'unwieldy class libraries' - I've found the
libraries a joy to use. Clear, logical, and very easy to explore even without
reams of documentation.

~~~
wrp
I think this is taking the position that even though the semantics of the
language is the same, changing the interface to it can make for a change in
programming paradigm. I'm skeptical, but it would be interesting to hear this
idea developed more.

------
wrp
C feels like it stands alone. What other language would you use to learn about
the machinery of computing, and put yourself in the position of having to make
everything explicit?

I thought a bit about Google's Go. It gets rid of the preprocessor and cleans
up handling of pointers. But it also does away with manual memory management.
That may be getting too far away from the machine for learning purposes.

I also thought about Ada, but that seems to impose a heavy learning overhead.

What about going the other direction, down to assembly? Unlike many people, I
have no loathing of assembly programming. I find well-structured and commented
assembly code to be just as easy to read as similar quality C code. Although
it has a reputation for being hard, experienced ASM coders tell me it's just a
matter a familiarity. They claim to be just as productive in ASM as in C.

My decision to pass over assembly is because modern processors no longer have
a straightforwardly sequential execution model. The image you get from tracing
assembly code is only an approximation of what will happen in the processor,
which is the same as you can say for C code. So my perception is that there is
no particular benefit to knowing ASM any more. (Unless you are working with
older, simpler designs as in embedded systems.)

~~~
johnm
Re: C -- I agree. It's the only widespread language that really matters for
this.

Re: Assembly -- I disagree. With the increasing popularity of heterogenous
multi-processor systems (cpu + specialized processors like GPUs, etc.)
learning languages that are more constrained to the hardware is still
valuable/important.

Also, note that building specialized code generators (be they stand along or
embedded DSLs) to the assembly language can give you a nice payoff.

~~~
wrp
I would really like assembly to be a viable addition to the programmer's
toolkit. So far, I haven't seen any tutorial material that explains the issues
and best practices in modern x86-64 assembly programming. All the books I've
looked at for Intel assembly assume the old x86 environment.

------
johnwcowan
I'd go for Scheme or even Factor for code-as-data. (Joy, Factor's ancestor, is
_really_ code-as-data, and unlike Emacs Lisp it's hygienic because there are
no variables. Scheme also has the most Perlis-ish macros.

I think either J or K is better than APL in this category.

I would also add Pure <[http://pure-lang.googlecode.com>](http://pure-
lang.googlecode.com>); for general term rewriting (lambda calculus? Just a
special case!)

~~~
wrp
I see your point about Scheme. I had wanted to stay with a Lisp, since the
Scheme family has a different orientation, with the emphasis on functional
techniques among other things. But maybe the more powerful macro system would
justify the extra learning load.

I would need some convincing with J, though. I've studied both and I thought
APL had much better tutorial material, development tools, and conceptual
straightforwardness. I didn't stick with J for very long, so I'm sure I missed
important aspects of its use. Could you explain some ways in which you think J
gives a better demonstration of the possibilities of the array-oriented
paradigm?

------
wrp
Prolog gives you nondeterminism. That is, it can take incomplete or
inconsistent input and provide partial or multiple answers. That's not
behavior you want very often, but when it is, who else you gonna call? The
specific, unique features of Prolog are unification, backtracking, and logic
variables.

People had high hopes for Prolog in the 1970s, but it proved to be a total
disappointment. It was terribly slow and had a complicated performance model.
These days, the niche for which Prolog is a good choice is very small. For
combinatorial problems, Prolog has been superceded by extensions like Choco
and Gecode and by easier and faster dedicated systems like Essence, Minion,
and G12. Prolog is still sometimes chosen for small projects in constraint
programming or text manipulation.

Be sure to read this article on how Prolog really works.
<http://www.amzi.com/articles/prolog_under_the_hood.htm>

~~~
petervanroy
That Prolog is slow and has a complicated performance model is the common
wisdom, but both are completely wrong. For a better view of speed, you should
look at my Ph.D. dissertation of 1990. It explains how to write a Prolog
compiler whose run-time code efficiency rivals that of good C compilers. The
two main ideas are global dataflow analysis and direct compilation to native
code (no WAM bytecode). For a better view of the performance model, you should
read Richard O'Keefe's book from 1990, The Craft of Prolog, which explains
very well how to write beautiful and efficient Prolog code.

------
wrp
Clean is not the language that gets recommended to every pilgrim in search of
functional purity, but I think it should be. The syntax is about the same as
Haskell, but it comes with a polished IDE, a native GUI library, and excellent
documentation.

There is some confusion over the handling of state in Clean versus Haskell. It
is usually said that Haskell uses monads and Clean uses uniqueness types. This
is partly true. A more accurate explanation that monads and uniqueness types
are distinct features that can coincidentally both be used to manage state.
Haskell doesn't have uniqueness types. Clean has both, and you can use either,
but the developers prefer uniqueness types. Having tried both methods, I'd say
that uniqueness types are easier to understand but monads give cleaner
structure to the code.

I see so many laments from people who tried Haskell and gave up. My guess is
that there would be a much lower attrition rate if they started with Clean
instead.

------
wrp
APL is an array language, with an exceptionally concise syntax allowed by
restricted function arity, many operators, and strict right-to-left
evaluation. It is still heavily used in the financial industry but little
known elsewhere. Since APL is basically a powerful calculator, programmers
usually don't take a close look. OK, so APL doesn't cover a lot of the usual
territory, but what it does have is really cool. Besides, it's a small
language and the best learning tools are free. APL won't take you long to
understand and it will give you a better appreciation for the possibilities of
array-oriented algorithms in R, MATLAB/Octave, or Python+NumPy.

I like Dyalog and they have a free book (<http://www.dyalog.com/intro/>) but
there are others (<http://www.rexswain.com/aplinfo.html>)

------
dmbarbour
More paradigms:

Maude. Pure. OBJ3 - term rewriting

Inform 7 - object-relational

Kaleidoscope. - constraint imperative

Bloom. Dedalus. - Temporal Logic; monotonic data.

Excel. Spreadsheets. - reactive dataflow.

Conway's Game of Life - Cellular automata.

Oz/Mozart - distributed unification.

I would suggest Dedalus (datalog + time) as a cleaner example than Prolog of
how to lift logic programming into general purpose computation.

------
wrp
Forth brings to mind stack-based languages, but I didn't bill it as
representative of that paradigm. For one thing, I'm not sure "stack-based" is
a whole paradigm unto itself, rather than just a syntactic convention. Joy and
Factor are two languages normally associated with Forth because of the similar
syntax, but their development models are very different.

Forth isn't just a framework for expressing algorithms, it's a whole
philosophy of system development. You start with nearly nothing, sometimes not
even an operating system, and build up precisely and only what you need.
[http://www.yosefk.com/blog/my-history-with-forth-stack-
machi...](http://www.yosefk.com/blog/my-history-with-forth-stack-
machines.html)

~~~
johnm
Yeah, it's a different philosophy taken to an extreme. :-)

That said, from a practical standpoint, Factor is excellent.

In fact, I'm surprised that more of the recent language implementations
haven't used Factor as their backend rather than e.g. llvm.

------
wrp
Lisp has that whole homoiconicity thing going, the code-is-data syntax that
makes macro writing super convenient. The thing about Common Lisp, though, is
that you have to learn an awfully big chunk of it before you can start
building interesting things. That's why I recommended Emacs Lisp. Sure, it's
small and has dynamic rather than lexical scoping, but it still has macros.
Think about the great development environment it's built into. If you learn
E-Lisp, not only can you start doing interesting things from day 1, you gain
better command of a useful tool even if you later decide not to continue with
Lisp.

~~~
johnm
There are a number of other homoiconic languages floating about so I think
that's much less an issue other than the fact that "lisp" is the poster child.

Alas, CL is an old, bloated nightmare. :-( :-)

I think the new poster child for "Lisp" is Clojure.

Also, for learning programming, I'm still a big fan of Scheme.

~~~
wrp
Agree about Clojure. The main reason I didn't choose it is that I thought a
good Perlis language should not require learning much that wasn't directly
related to using the new paradigm. With Clojure, you have the whole Java
platform to deal with as well.

Of course, there are tons of Java programmers out there and several really
interesting languages for the JVM. I have thought that there should really be
a list similar to mine, for people who are already working in the Java
environment.

------
wrp
Erlang has so many good things going for it, I think it stands head and
shoulders above other dynamic, impure functional languages. Heck, it has
actor-based concurrency, failure tolerance, bit-level pattern matching, an
excellent development and testing environment, industrial quality libraries,
and Prolog syntax. (OK, not everybody thinks that last one is a big plus.)

~~~
johnm
The prolog-ish syntax is to Erlang as parentheses are to Lisp -- a humungous
barrier to entry for a lot of developers.

I think Erlang's legacy is the fact that it's exposing those other features
that you mention to a wide audience of language aficionados that they are
spreading (gaining legitimacy/traction) within other languages / libraries.

~~~
wrp
I _like_ Erlang's syntax. The punctuation rules make sense to me and I
appreciate how it allows greater code density on the page. When I do have
trouble scanning code, it's generally due to the heavy use of pattern matching
for flow control. So, I really don't have any feeling for how much of a
problem this is for people.

That said, I want to recommend languages that introduce people to new ideas
with a minimum of distractions. If the syntax is an issue, then I should point
to alternatives. For the important concepts in Erlang, I'd appreciate
suggestions.

