Racketscript
racketscript.org
racketscript.org
And to answer the questions every Schemer will have, no the runtime doesn't yet support tail calls or continuations.
A Wasm target of the Chez/Racket compiler might be an easier way to get fast and proper evaluation in Web browsers.
Having this as guarantee allows all the control flow concepts to be reduced to recursion and function calls.
A kind of purity when we reduce a programing language to the basic set of primitives that provide the building blocks to create any kind of programming paradigm, this is in a way the beauty of Scheme, moreso than Lisp.
However as great as tail calls are they can't practically implement all control flow concepts. Eg they aren't really all that great for modelling exceptions, I think.
TCO is technically in the ECMAScript specification (since 2015) but hasn’t been implemented across browsers or runtimes (with a few exceptions).
Dr. Axel has written a good explainer of TCO in the context of Javascript here https://2ality.com/2015/06/tail-call-optimization.html
Do you use this strategy for implementing recursion? Are there consequences or trade offs?
For others who are curious, see
1) https://stackoverflow.com/questions/25228871/how-to-understa..., and 2) https://raganwald.com/2013/03/28/trampolines-in-javascript.h...
It's not the only strategy though.
It has tail calls, continuations and even green threads (SRFI 18 compliant), and a decentralized module system that can load libraries directly from github and a JS FFI! See this paper for advanced examples that you can copy-paste to the REPL: http://www.iro.umontreal.ca/~feeley/papers/BelangerFeeleyELS...
Parenscript: https://cliki.net/Parenscript
This is really something you will get used to very quickly, and dare I say, learn to appreciate.
I don't think so. AFAICT, people do hate parenthesis, no matter how long they use Lips/Scheme. They just simply get used to the clutter.
Also, when writing code, you can spam ")" to close functions/expressions. It takes only few brain cycles if the editor highlights matching parenthesis. This makes it easier to move code around. Copy-paste-))))))...
People see trees and not parens. People who complain about parens are still stuck in the "code is text" mind set rather than the "code is a tree" mind set.
>Also, when writing code, you can spam ")" to close functions/expressions. It takes only few brain cycles if the editor highlights matching parenthesis. This makes it easier to move code around. Copy-paste-))))))...
We've had editors since the 1970s that can take you to where a matching paren is closed. You then copy/paste the whole function without needing to add or remover parens.
Codes are still text unless you're using tree-based editors. Maintaining tree on text editors requires careful editing and strict practices, which human brains aren't good at. The "tree" will get broken at some point, but, in this school of thought, the recovery strategy is unclear and inconsistent at best. This becomes annoying pretty quickly.
The real tree, at the end of the day, is formed by line breaks and indents, not parenthesis. Codes are also for human consumption after all. Now there are two trees to manage - semantic indentation and parenthesis - which is bad. Luckily we can induce parenthesis from the semantic structure, so we only care about the semantics, and naturally trailing ")" becomes completely redundant.
We've had editors that automatically do that since the 70s. Here's a live demo hot from 1986: https://youtu.be/-J_xL4IGhJA?t=2416
>The real tree, at the end of the day, is formed by line breaks and indents, not parenthesis.
It isn't. You're not the type of person who lisp is for, which is fine. There are lots of languages suited for people like you.
But I'd be curious to know what language you think uses nothing but line breaks and indents to describe its AST.
The process in the video still perfectly aligns with my description. Actually, I reached that conclusion by observing people writing Lisp code. That is, when you're writing Lisp code, that's exactly what people next you would see, no matter what you think.
Also, trailing ")"s are clearly a burden, as people do spend their brain cycles to properly match them.
> It isn't. You're not the type of person who lisp is for
You sound like you're right in the middle of Lisp fever, which is fine. Everyone goes through that.
> But I'd be curious to know what language you think uses nothing but line breaks and indents to describe its AST.
You simply didn't get what I was saying. Even when all the parens were stripped off from a Lisp code, you can easily reinsert parens based on line breaks and indents. So people rely more on indentations for correctly putting parens, rather than being cautions w/ every single editing operation.
People don't match them. The editor does. Computers are very good at this. Code editing isn't a spectator sport where you can judge how easy something is by watching someone else do it. Try par-edit-mode from emacs, it's a tree editor in a text editor. You'd have your mind blown from this piece of technology from the 90s that uses nothing but plain text to edit a tree using parens.
>You simply didn't get what I was saying. Even when all the parens were stripped off from a Lisp code, you can easily reinsert parens based on line breaks and indents. So people rely more on indentations for correctly putting parens, rather than being cautions w/ every single editing operation.
Really?
So given
f a b
which of (f a b)
(f (a b))
((f a) b)
did I strip the parens from?> People don't match them. The editor does. Computers are very good at this.
Fixing parenthesis is a semi-automatic operation, performed by people aided by machine. People spend brain cycles on it, still in 2022.
The tree-editing stuffs are in the same line. It's whole purpose is avoid dealing with parens and nested structures, but using it requires in-brain abstraction and getting used to a different set of operations. Extra costs to cognition and operation of the editor. Nothing difficult, but you have other dozens of "nothing difficult" to stack on top of it. Welcome to the world of complexity.
> Try par-edit-mode from emacs
ParEdit is an addition to text editor, and it doesn't block you from introducing mismatched parenthesis. It's actually an important feature, because an editor that forbids this will be more painful to use than manually fixing parens. So we still fix parens in 2022.
Maybe I should compare this to ";" in C-like languages. There are editors, extensions, and formatters that can automatically insert semicolons, but, for whatever reason, semicolons go missing, so people fix it manually, still in 2022. Worse, in Javascript, missing semicolons often causes unintended behaviors, which makes it difficult to debug. Such a nice bug to have in 2022 on a language from 1990s.
Holy Jesus, is this really what we should be dealing with until the last day in our lives? Including all the ancient craps that predates myself? I don't think so.
> did I strip the parens from?
Your example doesn't have any visual structure, and, in practice, we can just refer to the definition of `f` to solve that. Not an actual problem.
What I was talking about is something like this:
defun find-frame-class name
cond
and char= char name 0 #\T
not member name '"TXX" "TXXX" :test #'string=
ecase length name
3 'text-info-frame-v2.2
4 'text-info-frame-v2.3
string= name "COM" 'comment-frame-v2.2
string= name "COMM" 'comment-frame-v2.3
t
ecase length name
3 'generic-frame-v2.2
4 'generic-frame-v2.3
(The original code is from https://gigamonkeys.com/book/practical-an-id3-parser.html )The tree structure is visually represented in the indented code, which is far much easier for human brain to process. You almost immediately notice where parens should go.
To recover parens without lines breaks, you should go over each symbol one by one, tracking their contexts. You know, state is evil.
So the information embedded in code format is redundant to parens. IIRC, there were people who tried to abuse this to eliminate parens. Not really sure how that went.
_It does._ This is like trying to explain red to a very obstinate man wearing a blind fold their whole life.
>What I was talking about is something like this:
I have no idea which of:
(ecase length name)
(ecase (length name))
((ecase length) name)
you want.What you're complaining about is that operators of arbitrary arity need a termination symbol. That is a feature, not a bug. Basically your code is very simple and you're not using higher order functions. At which point you might as well go back to python.
To actually encode the information you're talking using nothing but white space you'd need to do the following:
find-frame-class
name
cond
and
char=
char name 0
#\T
not
member
name
quote
"TXX"
"TXXX"
:test #'string=
ecase
length
name
3
'text-info-frame-v2.2
4
'text-info-frame-v2.3
t
ecase
length
name
3
'generic-frame-v2.2
4
'generic-frame-v2.3
or some such. I lost interest in getting it correct since I wasted a rather long time trying to fit a tree in a 2d page at university. The key point is that a tree can be infinite dimensional and a page isn't. When you know that you rather quickly realize that all syntactic sugar is doomed and you spend your life doing more productive things with it.You are working with shapes of data, not lines of text. Using tools like Paredit you can get into an incredible flow akin to that of Vi/Emacs mastery, with the added layer that you are moving entire blocks rather than single words (that may or may not end up being valid code).
https://journal.stuffwithstuff.com/2013/07/18/javascript-isn...
How someone who supposedly liked, wanted and had experience with Scheme ended up creating a language with a function-scoped var binding construct, which then took twenty more years to finally get a block-scoped let.
It's about as random as requiring mammals to be warm blooded.