Lisp-Flavored Programming Languages
github.com
github.com
It's also an actively developed modern language not stuck in the 80s.
Only thing that’s difficult for me right now is named parameters because I’ve been using Objective C which is really clear on that front.
If they can be hooked together too...that would be fun :)
https://franz.com/success/customer_apps/scheduling/siscog.lh...
Knowledge and skill useful for finding a job is not all the knowledge that is good.
Clojure was developed by someone called Rich Hickey. Not only were there no Clojure jobs when he started hacking, there was no Clojure. That's a textbook example of an energy-consuming and impractical waste of time.
For almost every piece of technology listed in a job ad that you think is worth knowing, someone had to put in a whole lot of time and energy, not knowing if it will pan out at all, and often that time and energy were uncompensated by anything other than the existence of the thing in the end.
I'm not even criticizing, most of these are hobby projects and you can code how you like. I just think it's funny how hard Lisp clings onto the parenthesis thing while claiming the parenthesis thing doesn't matter.
The advantage of the regularity isn't its human readability, but its ability to macro, no?
What I'd like to see is better tools for reading and editing such a regular syntax. Probably I should just learn emacs, but I'm thinking someone could make a more intuitive structured editor for LISP syntax. No need to mush around blobs of text when everything is nested lists.
This.
You can write macros for less regular languages, but there's always additional friction involved. At some point, it comes down to whether you think LISP is a "programmable programming language."
If you do, macros are a core part of the paradigm, and s-exprs make macros easy to work with.
No ambiguity; no brain cycles required to work out what element is a child or sibling of what element. Great editing ergonomics.
> If you already love s-expressions then lisp-flavored languages will make it nicer when you need to build on existing platforms. In case the target language does not support advanced features like macros and REPL-driven development, these can often be easily added by using the s-expressions layer.
To the comment about "parenthesis-laden syntax", I find that, if I actually count the characters, my Java code tends to have just as many parens as my Clojure code. I suspect that there's just a tendency, if all you've ever known is algol-style syntax, to hyper-fixate on lparens that appear to the left of the function name. I think maybe the only programmers who get to criticize others for overuse of parenthesis are Forth, ML, and Haskell programmers.
))))))))))
that ends some lispy code. }
})
]}
}])
}
}
}
}And it's very different from other Lisps in the sense it's trying hard to be an ecosystem for language-oriented programming, which is probably taking the idea of macros to a new level.
I've used Common Lisp and Clojure for many years, but Racket looks more and more appealing to me.
this is actually a problem in my eyes and will prevent it from gaining industrial traction. for example, this keeps the main developers as a revolving door of graduate students writing code and the core maintainers as full professors who have priorities different from industrial users. secondly, the culture of racket is as a research language. they just replaced the runtime (loads of risks for industrial users), and now they are replacing the syntax. this does not create an environment enticing to industrial users. the racket team feels these changes will increase its user base, but i believe if that ever happens, these changes are deferring such an increase well into the future.
The lack of syntax matters in the sense that once you don't have any you realise that it just gets in the way. Having lots of parentheses is a small price to pay for powerful tools so that's why "it doesn't matter". Non-lispers generally don't understand how lisp is different from their language of choice and therefore don't understand why the lack of syntax is an advantage.
of s-expressions. Lisp has an additional layer of syntax on top of s-expressions.
For example the DEFINE-CONDITION operator has this syntax:
define-condition name (parent-type*) ({slot-spec}*) option* => name
slot-spec::= slot-name | (slot-name slot-option)
slot-option::= [[{:reader symbol}* |
{:writer function-name}* |
{:accessor symbol}* |
{:allocation allocation-type} |
{:initarg symbol}* |
{:initform form} |
{:type type-specifier} ]]
option::= [[(:default-initargs . initarg-list) |
(:documentation string) |
(:report report-name) ]]
function-name::= {symbol | (setf symbol)}
allocation-type::= :instance | :class
report-name::= string | symbol | lambda expression
with even more syntax for things like lambda expressions and type specifiers.I just feel that when someone says that Lisp does not have syntax or that syntax is not important, it's plain wrong...
I completely agree. I just feel that not every programming language needs to have the same approach to syntax. Lisp is different from most languages in its way to have a data syntax in which programs are written. Thus the data syntax is textual (s-expressions) and the program syntax is structural (based on data structures like lists, symbols, numbers, ..).
Every function and macro description in the HyperSpec has a "Syntax:" synopsis right at the top.
Section 2 of the standard is "Syntax".
This enables a bunch of stuff: code can be relatively easily treated as data. It allows easy code generation, transformations (-> macros), traversal (-> interpreters/compilers) or editing.
The parentheses are just a part of the s-expression textual syntax. The s-expressions then are used by basic operations like READ, MACROEXPAND, PRINT and EVAL. Additionally many of the primitive data functions can be used to manipulate code: first/rest, list, append, reverse, map, ...
All the beautiful aspects of lisp make it decidedly unwieldy in production software. There’s a tendency of projects written in lisps to be unwritten in lisps as they mature.
If a piece of code is read more often than it's interpreted, written, and compiled, it's probably example code.
In a Lisp system, the code is always there and not just in textual forms.
> All the beautiful aspects of lisp make it decidedly unwieldy in production software. There’s a tendency of projects written in lisps to be unwritten in lisps as they mature.
There are two main factors which lead to Lisp software being rewritten:
1) deployment. In the early days it was the lack of resources (memory, speed, ...), but there are other factors like having a robust runtime or the ability to integrate in larger software around it.
2) familiarity. There are not many people available to maintain Lisp software. Not because the syntax is strange, but because the whole language is strange. There are no major other programming languages which work like Lisp, so few people can productively program in it. There are exceptions to it, like the simple Lisp used in AutoCAD and related software. These have millions of installations and the complexity on the Lisp side is not that huge - there it's mostly used as a simple interactive programming language.
What makes Lisp actually difficult for programmers is not the syntax, but the pervasive use of code as data, code transformations, various ways of meta-programming, etc. It's the features it was developed for: computing with symbolic expressions - here even applied to itself.
The language Lisp was built to compute with symbolic expressions, then the idea that a Lisp program is itself a symbolic expression is tempting... this then leads to center programming activities around this idea.
There's quite a lot of big systems written in Lisp. Unfortunately they rarely ever were opensourced, and we get to have blinders made out of our own limited experiences and common generational knowledge loss in IT.
S-expressions in memory are a really really good idea and chronically underused in modern programming languages.
The parentheses are irrelevant to the core ideas of lisp. You can make a lisp using C-like braces and infix notation - what makes a lisp is the representation of the program in memory as a tree and the operations you can perform on that representation.
All the interesting macro expansion in lisp is performed after parsing, unlike in the C preprocessor, so you can write your programs using Egyptian hieroglyphics for all lisp cares.
That was thought around 1960. Lisp had m-expressions in books. The actual Lisp system used s-expressions. The next few decades were often spend trying to get rid of s-expressions on the surface. Most of these attempts failed. If they succeeded they were something different. Like ML. One can think of the early ML as a kind of typed Lisp with a different syntax.
What Lisp made attractive was the similarity between internal and external representation. The Lisp system was internally manipulating programs as s-expressions - that was easier to understand when the external representation is similar.
> The parentheses are irrelevant to the core ideas of lisp.
S-expressions are an actual core idea of Lisp, while you focus on a minor aspect of s-expressions-> that s-expressions use parentheses to denote cons cells and lists.
Since the Lisp uses a certain data representation internally, it is much easier to use a simple textual format for that data externally too - one which makes the mental transformation easy. Using a complex and unrelated syntax does not make that easier, it makes it actually harder.
> All the interesting macro expansion in lisp is performed after parsing, unlike in the C preprocessor, so you can write your programs using Egyptian hieroglyphics for all lisp cares.
Actually that's not true: that's one of the ideas of Lisp and large programming system have been built around this. A Lisp system will expose its inner working to the programmer. Live and interactive systems are not an exception, they are the default.
If you are a JS programmer or God-forbid a C++ programmer, you are already living in a world where the transformation from lexical syntax to AST is dozens or hundreds of pages with weird edge cases (e.g. JS semicolon insertion or C++ most vexing parse). If that can be reduced to 1 or 2 pages it's still a massive improvement from their perspective even if it looks like a downgrade to a hardcore lisper who eats parentheses for breakfast, lunch and dinner.
Lisp programmers's don't 'like parentheses' - parentheses is not what makes Lisp.
Lisp was designed to do programming with s-expressions (aka nested lists). That's its core original purpose. Lisp even means 'List Processor'. It was then early detected that this can be applied to Lisp itself, for example by interpreting s-expressions as Lisp programs.
'Parentheses' are just a part of the notation. If you take away the feature of s-expressions on the surface and thus also the notation, you are no longer programming on the surface in classic Lisp. You can always use alternative notations, but that will take away the seamless symbolic programming.
> failure in the sense that they have prevented lisp's cool semantics from reaching a broader audience
'parentheses' did not prevent that.
Over decades lots of original Lisp stuff was moved to other languages (garbage collection, image-based programming, functional programming, macros, etc.).
There are lots of languages which are somewhat re-invented or re-designed Lisps: Logo, Dylan, Julia, Ruby, ... One can already use those.
Lisp should drop s-expression-based syntax, so that C++ or JavaScript become different internally? This makes no sense.
> If you are a JS programmer or God-forbid a C++ programmer, you are already living in a world where the transformation from lexical syntax to AST is dozens or hundreds of pages with weird edge cases (e.g. JS semicolon insertion or C++ most vexing parse). If that can be reduced to 1 or 2 pages it's still a massive improvement from their perspective even if it looks like a downgrade to a hardcore lisper who eats parentheses for breakfast, lunch and dinner.
Complain to those. Not to a Lisp programmer.
I think an interesting synthesis is Haskell, where function calls are simply juxtaposition. Parenthesis are just grouping like most languages, but it ends up feeling quite Lispy.
You might want to rethink that hurried statement just a tad:
// C
for ((i = 0; i < MAX; i++)) {...}
printf(("hello, %", name));
#if defined ((__GNUC__))
# Shell
var=$((cat /etc/motd))
# Pascal
type color_type = ((Red, Green, Blue));But if you want to be technical, most of your examples would not be considered expressions in the given language.
int j = i = 0; i < MAX; i++; /* ? I think not. */
But sure, many languages also use parenthesis for things besides general expressions. Ultimately this argument is anti-productive nitpicking.So that's a piece of cognitive load that you have to carry to know when the parentheses are on an expression, and do not change the meaning if compounded, versus when they are around something else where they may not be removed or compounded.
In Lisp, everything is an expression, and no there is no willy-nilly removal of nesting or compounding of nesting. That's less to remember.
Even fragments of forms are expressions, according to ANSI CL glossary terminology. If we have (let ((a b)) ...) then a, b, (a b), ((a b)) and let are all expressions. With the exception of b, what they are not is forms: expressions presented for evaluation.
> Ultimately this argument is anti-productive nitpicking.
Who started it?
WTH? You, by nitpicking a general statement meant to connect two perspectives and maybe allow some synthesis between two starkly divided worlds.
I've had the Lisp kool-aid. I agree it makes for a great time. I can do without the proselytizing blast.
FWIW "in Lisp [parenthesis] also mean another level of application" is also technically incorrect (nesting is not always application), but I think it gets the actual point across better than being more abstract.
Of course it matters; it just doesn't matter in the sense of not being a problem.
Your argumentation is rooted in drifting across different semantics of the phrase "doesn't matter".
> Syntax, interestingly, complects meaning and order often in a very unidirectional way. Professor Sussman made the great point about data versus syntax, and it's super true. I don't care how many you really love the syntax of your favorite language. It's inferior to data in every way.
Rich Hickey
Pixie uses the RPython toolchain and is totally its own language, with its own VM and JIT.
Hy appears to be python with lisp syntax.
Both sound fascinating.
Pixie does look very cool, but the project on github seems dead?
Took a look at the github of Pixie: "pre-alpha" and no docs whatever. Not for the student.
Hy is cleanly packaged, installed with pip3, has complete(ish) docs[1], great. So I installed it and started it, it puts up a REPL prompt, and I paste in one of the functions I've worked out:
(defun hello ()
(write-line "this is the prompt:")
(let ( (name (read-line)) )
(format t "Hello, ~A.~%" name)
)
)
Error message: "empty expressions are not allowed at top level"Sorry? Exactly that usage, an empty expression when a function takes no argument, is used on (I just checked) page 20 of Graham. But ok, I try it without, "(defun hello" etc.
Error message: "NameError: name 'defun' is not defined"
You what? defun is introduced on page 14, and defined in the "Language Reference" Appendix of Graham. OK, wait, what does Hy use, if not defun? Search their tutorial chapter: "Define named functions with defn".
OK, this is a deal-breaker for somebody trying to learn (ahem) COMMON Lisp. Why would you do that, just arbitrarily change the probably third or fourth name a student learns after car, cdr and setv? And more importantly, if you have taken it on yourself to dick around with (ahem) Common Lisp at this basic point, what else have you changed that will break the examples in my textbook or online tutorial?
pip3 uninstall hy
[1] https://docs.hylang.org/en/master/index.htmlBut is not, and does not claim to be, an implementation of Common Lisp, so judging it harshly for being inconsistent with—and a poor tool for learning—Common Lisp makes as much sense as complaining C++ is a poor tool for learning Algol 68.
My arguments are not on the familiarity side (with the infix notation), but on the psychological one:
1. S-expressions are not the most simple, natural, or uniform surface form (as they claim); they do have syntactic sugar (quote, even lists themselves!, etc.), so why not to add some more sugar (but sufficiently abstract of course)?
2. Humans' brain has limited "stack" space (especially when closing parentheses); infix forms may "cascade" and do not consume the stack (equally machine on human, due to possibility of "tail recursion")
3. Lack of diverse "visual clues" for humans (note how most natural languages have 40-60 phonemes, and none less than 15)
4. S-expressions and homoiconicity are related but orthogonal features (so the homoiconicity argument is often not valid)
Having that said, when I finally managed to write a working 50+-lines program in Scheme, with "proper" indentation, I was just proud of it, and I said, "Wow, it looks cool!". But I am still on the side of the above rational arguments! My point is that as my experiment demonstrates, it is probably too easy to get on an emotional side of computer-human interaction once you accomplished something a bit challenging (like speaking in classic S-expressions)?
That said, I would hate to write Lisp code with Notepad. Fortunately nobody does this. In conjunction with a paren-matching, auto-indenting programmer's editor (which is roughly all of them these days), S-expressions are easy. A good editor is vital not just for writing Lisp programs but also for reading them.
I will not claim parentheses are mandatory. I find Haskell just as simple, unambiguous, and composable without (many) parens but that's only because it has automatic currying, and that takes a bit of practice to wrap one's head around.
I know it's heresy in a Lisp thread to claim that it's possible for a language to have too little syntax, but I can write Javascript, C and C++ just fine in Notepad or Sublime Text if I want.
This looks like another instance of slapping a pseudo-scientific veneer on top of conclusions driven more by untrained gut feeling in order to pretend one's subjective impressions are firmly grounded in objective reality. It's like the phrenology of programming languages.
For 3, that's one reason why I like Clojure's syntax: it has just enough extra syntax to break up the code and provide visual cues, at least for me.
Re 4, sure, you can even enable macros without homoiconicity, but with s-expressions, I find it to be mentally much simpler because I can just write a template and fill in the gaps and its natural since my code is in that form already. Overall, though, in all but a few cases, I think macros should be avoided in favour of pure data structures and functions, when possible.
LISP really deserves to be "grandfathered in" as the original functional programming language, but if it were discovered today, we'd likely call it a multi-paradigm language that supports functions as first-class entities.
And as a "programmable programming language," we can use LISP to implement many other paradigms, including what we now consider "functional" programming.