Racket 7.3
download.racket-lang.org
download.racket-lang.org
Unlike most minimalist LISP languages with a community of individual hackers who each have their own macros and packages, this one is battery included while still being the most flexible with the #lang header. Seriously, it comes with awesome data structures (actuelly more than Python).
The only thing that prevents me from using it as much as Python or C++ is the lack of tools for major editors. DrRacket is NOT ok, I would like a langserver and vscode extension so badly! When I have a bit of free time and have finished other projects with a higher priority, I'll definitely give it a try. (yes I'm aware there are some langservers but none of them is really production ready)
Could wish for similar modes for SublimeText and VisualCode though.
https://marketplace.visualstudio.com/items?itemName=evzen-wy...
I also didn't know there was a Chez version. Racket already has a native AOT compiler, right? What would the advantage be to run on Chez, faster or smaller compiled code?
If it's the former, I found this little article helpful when I was new to Scheme:
0. https://docs.racket-lang.org/syntax/Parsing_Syntax.html 1. https://www.greghendershott.com/fear-of-macros/ 2. https://summer-school.racket-lang.org/2018/plan/
As opposed to the larger group who think they understand them. I was once in that group, but now I've just given up.
defmacro was a lot easier, but I understand the aversion to it, even if it was rare that it was/is a problem.
[0] syntax-rules based macros are cake, naturally, but they're also incredibly limited, although I have seen people implement massive complex OO systems using a sort of ad-hoc state machine built in pages upon pages of syntax-rules rules.
This talk[0] by Robby Findler helped me a ton when I was first learning about macros in Racket. I've found that the best way to learn, though, is by doing: when you find a use case for a macro, figure out how to do that particular thing and, slowly but surely, things will start to click.
#lang racket
(define-syntax-rule (run3times code ...)
(begin
(begin code ...)
(begin code ...)
(begin code ...)))
(define x 0)
(run3times
(set! x (add1 x))
(display x)) ; shows ==> 123
As other comment said, you have to find some good opportunity to use a simple macro.(In this case, it is better to use the build-in `for`. Actually, `for` is defined in a macro, it is not part of the internal "secret" low level language.)
Once you are confident and you grok the difference between a macro and a function, you can try the other ways to define macros. These other ways are more flexible and can make weirder macros, and have better support when the macro is used wrongly. There are good links in the sibling comments.
You were asking for threads, and gambit has lightweight threads, so I assumed there was a way to use them via ln. Multi-core threading is a different story though.
I guess at the end of the day it's very hard to compete with the JVM.
Kawa Scheme - compile to java bytecode - https://www.gnu.org/software/kawa/index.html
Chez Scheme - compile to C - POSIX & Windows - https://cisco.github.io/ChezScheme/
Cyclone Scheme - compile to C - Linux only - https://justinethier.github.io/cyclone/index
Guile - VM + JIT compiler - POSIX & Windows - https://www.gnu.org/software/guile/
Bigloo - compile to C and java bytecode - POSIX, Windows, Mac, Android - https://www-sop.inria.fr/mimosa/fp/Bigloo/
REPL based development, Interactive development are also features. Multi-core isn't probably the top most thing on everybody's list of things.
* it has support for OS-level threads via places[0]
* it can produce binary distributions via `raco distribute`[1] by packing together the interpreter and your compiled code into a single executable
* while the current implementation is based on a bytecode-compiler and VM, I believe the Chez implementation actually compiles to native code (although the whole process is transparent to the user)
* it is possible to run Racket on ARM devices, in fact there was a recent thread[2] about that on the mailing list
I realize this isn't 100% what you're looking for, but Racket does come with many nice features. Alternatively, you might also want to take a look at CHICKEN Scheme[3].
[0]: https://docs.racket-lang.org/guide/parallelism.html#%28part....
[1]: https://docs.racket-lang.org/raco/exe-dist.html
[2]: https://groups.google.com/forum/#!topic/racket-users/YEajWJe...
[3]: https://call-cc.org/
[0]: https://docs.racket-lang.org/ts-guide/optimization.html
AFAIK typed racket does type-checking during compilation (via raco); the resulting code is no slower than normal Racket, although I'm not sure if it's faster either.
The contract system is different; it works on normal, untyped Racket code and performs checks at runtime; similar to using Python decorators to check the input and output of a function. This slows things down, so it's recommended to only check things at module boundaries. For example:
#lang racket
(require racket/contract)
(require racket/match)
(provide factorial)
(define/contract (factorial n)
(-> exact-nonnegative-integer?
exact-nonnegative-integer?)
(fact n))
(define (fact n)
(match n
[0 1]
[_ (* n (fact (- n 1)))]))
This module exposes the `factorial` function, which checks (at runtime) whether its argument and return value are non-negative integers (i.e. 0, 1, 2, ...). The actual calculation is done by the `fact` function, which is private and doesn't do any checks. If we don't separate the checks from the calculation, we would end up running the checks on every recursive call, which would slow things down a lot.As far as I'm aware, Racket's gradual typing is done by contracts at the interface between typed and untyped code. Hence it's not that typed racket is slow, it's that passing untyped values into typed functions can be slow, if we want accurate blame information for errors.
http://www.ccis.northeastern.edu/home/types/publications/gra...
But also it's important to note that it's not Typed Racket or Racket in isolation that are slow, but the inter-mingling of the two due to contract overhead.
Figure 3 in that paper is enlightening: the fully typed version takes 0.7x as long as the untyped version, so Typed Racket is slightly faster than normal Racket. Most of the partially-typed versions take 50x to 100x as long, as you say, showing that it is indeed the contracts that slow everything down.
Of course, the formatting is broken anyway, because two of the continuation lines of bullet-pointed lines are underindented by one space.