[1] http://lush.sourceforge.net/ [2] https://common-lisp.net/project/ecl/ [3] http://www.ulisp.com/
[1] http://lush.sourceforge.net/ [2] https://common-lisp.net/project/ecl/ [3] http://www.ulisp.com/
Python was already well known as a "scripting" and server-side web development language in the early 2000s, but it's commonly mentioned that it really exploded in the 2010s, where it was the implementation language for several scientific packages, most notably the machine learning eco system.
It seems that the language really found a local optimum that adheres to many different people across disciplines.
This doesn't really scale well, but momentum has a way of making things scale. Especially when most of the popular libs of python are pseudo ports of other language libraries.
I think it caught on because the syntax is clear, the execution model has relatively few pieces of foot gun trivia to memorize, a really nice repl, and most importantly, almost no one doing exploratory work needs anything faster.
That is, your complaint is what I meant about it not scaling. It is terrible. But the momentum behind it is keeping it going, despite being laughably bad in that area.
That's...somewhat misleading. Python was well known for its scientific stack as well as server-side web development and scripting from the early 2000s (or earlier; NumPy, under its original name of Numeric, was released in 1996, BioPython in 2000, matplotlib on 2003, etc.).
In the 2010s, it became known for its machine learning stack, which was built on top of the existing, already solidly established, scientific stack.
It might seem stupid, but operator overloading and metaprogramming features make it fairly simple to emulate the syntax of other languages scientific users would have already been familiar with. Specifically, NumPy, SciPy, and matplotlib quite obviously tried to look almost exactly like MATLAB, and later pandas very closely emulated R. It's a lot easier to target users coming out of university programs in statistics and applied math who have been using R and MATLAB and teach them equivalent Python libraries. Trying to teach people who aren't primarily programmers to use Lisp is going to have a much steeper learning curve.
It really didn't explode in the 2010s, either. You're thinking of Facebook with pytorch and Google with TensorFlow making it dominant in deep learning, but the core scientific computing stack goes back way further than that. As for why Google and Facebook chose Python rather than Lisp, I think it was just already one of their officially supported languages they allowed internal product teams to use. Lisp was not. Maybe that's a mistake, maybe it isn't, but it's a decision both companies made before they even got into deep learning.
Preparing for Y10K? That's exceptionally long-termist.
Lush is uncontroversially a Lisp.
However, the part of this that's relevant to the point I was actually making is that Lush uses S-expression syntax, which is less readable than, for example, Python syntax.
- static binding
- closures (true)
- tail recursion
- garbage collector
s-expression or typing is a matter of choice, but, IMHO, if you lack one of the four previous items, it is not really a lisp.
I'm definitely not an expert in that area, but this list seems kind of arbitrary to me. Especially with s-expressions being optional, which are probably the widest-known feature of the language. According to that definition, Haskell is a "true" Lisp but at least 2 Lisps are not. That makes no sense to me.
I have encountered many functionnal languages when I was student (caml-light (the ancestor of ocaml), lelisp, gofer (a cousin of haskell), miranda, graal, FP systems, yafool).
The typing may be dynamic or static. The evaluation may be strict or lazy. They may have homoiconicity or a more suggared syntax. All theses choices are valid. These languages have in common the list of fundamental properties. IMHO, this list of 4 items encompass many aspects of SICP. When I evaluate a language, this list helps me understand the qualities and limitations of a language. For example, Perl5 does not have a true garbage collector. javascript does not have tail recursion. Knowing these limitations, I will not code the same way. In Perl5, I will take care of breaking unused circular data. In javascript, I will reorganise highly recursive algorithms.
Edit: And to be frank, while dynamic binding may be a horrible mistake in bigger projects, it sometime gives you exactly the easy way out that you may appreciate under time pressure. It's a classical case of "it seemed to be a good idea at the time".
It was definitely dynamically scoped, though.
Emacs Lisp will, I expect, never ever drop 'defvar' dynamic binding. It would break the entire world -- it's relied on far too widely to revoke. Having lexical binding alongside as we do now is probably sufficient.
I agree that it's useful to be able to locally override variables like deactivate-mark and case-fold-search. (This kind of thing makes tail-call elimination more difficult: any dynamically scoped variables must be restored when the "tail-called" function returns.) But there are some other such things in Emacs that can be similarly locally overridden and then restored, but aren't variables: (current-buffer), (point), and (mark), for example, which can be restored with (save-excursion ...). And it's common to have such locally-override-and-restore facilities without using linguistic dynamic scoping for it; PostScript has gsave/grestore, for example, which were copied by Win32 GDI SaveDC and RestoreDC, but that doesn't give C dynamic scoping.
I don't think SaveDC and RestoreDC are known to give rise to problems when "writing a prgoram for other end users that multiple people are working on".
I agree that elisp will never remove dynamically-scoped variables; it would break compatibility with all existing code. Even Common Lisp has "special variables" that behave this way.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Dy...
https://www.gnu.org/software/emacs/manual/html_node/elisp/Le...
______
† Older versions of the Emacs Lisp reference manual mostly did not do this, except for one occurrence of "dynamic binding" in the "implementation of dynamic scoping" section.
It happens that in ordinary Lisps†, the function called by invoking a symbol does depend on the run-time value of a symbol (its function binding in a Lisp-2), and that's the sense in which an ordinary Scheme or (non-generic) Common Lisp function call can be said to be "dynamically bound", but that isn't the case in general. So even in that sense it doesn't correspond to the static/dynamic scoping distinction that they seem to be trying to discuss.
______
† I think this may be one of the points where Lush is atypical; I think its interpreter supports runtime rebinding of the function bindings of symbols, but its compiler doesn't. I'm not sure, though. I may not have used Lush this millennium.
When we "declare dynamic-extent" an object, the compiler may stack-allocate it.
The C language redefined "dynamic" from "stack" to "heap". If you look into the BCPL manual (one predecessor language that inspired Ken Thompson's B), it uses "dynamic extent" to refer to the stack, which C renamed to "automatic storage":
"[T]he extent of a dynamic data item starts when its declaration is executed and continues until execution leaves the scope of the declaration." (1967 BCPL Manual, 7.2)
______
* I'm assuming by "static binding" you mean static scoping; if you actually mean that the association between callsites and functions is statically computable, then it's not even true of Scheme.
There is a series of videos of learning neural networks in APL cited by others here on this thread.
Pandas author, Wes McKinney, cited J as an influence in his work on Pandas.
Extreme Learning Machine in J (code and PDF are here too):
https://github.com/peportier/jelm
Convolutional neural networks in APL (PDF and video on page):
https://dl.acm.org/doi/10.1145/3315454.3329960
A DSL to implement MENACE (Matchbox Educable Noughts And Crosses Engine) in APL (Noughts and Crosses or Tic-tac-toe):
Which implementations are you comparing J to? To my knowledge, all of APLs, K, J are interpreted. BQN is compiled, but still very new. I also know that Dyalog was experimenting on a byte code compiler. I don't think there exists convincing benchmarks comparing those languages.
There's this on the J wiki: https://code.jsoftware.com/wiki/User:Brian_Schott/code/feedf...
And there's this YouTube series for APL: https://youtube.com/playlist?list=PLgTqamKi1MS3p-O0QAgjv5vt4...