
Why Racket? Why Lisp? - alokrai
https://beautifulracket.com/appendix/why-racket-why-lisp.html
======
civility
I think one of the most amazing parts of Racket, and one of the reasons
someone should try it out if they haven't, is that the source code and
evaluator support images and not just text. The following link shows one
aspect of this:

[https://docs.racket-lang.org/quick/](https://docs.racket-lang.org/quick/)

Just being able to put an image in a comment explaining your algorithm into
your code would be huge improvement over the traditional syntax colored ascii
you get with most languages and editors. There are many times I've written an
algorithm which is difficult to understand without the associated diagram I
drew on the whiteboard or in an image editor. Racket lets you insert that
image or photo directly into your source, and I think this is a significant
improvement over putting a link to that image in a comment.

Racket also goes a step beyond that by letting images be values which can be
assigned to variables or returned from functions. The link above shows this
clearly. I'm sure there is some value in this as a teaching aid, and I think
that's why they did it, but you can also return mathematical plots from your
functions and so on. This feature is similar to the various interactive
notebooks people use for Mathematica or Python, so it's not really specific to
Racket, but it is interesting to play with.

Obviously there are downsides to putting images in your source. After you do
that, your code is no longer ascii, and it won't be something you can edit
with vi, emacs, or any non-Racket IDE. Also I doubt it will play nicely with
git any time soon. However, it's a neat feature of Racket whereas many of the
other benefits in the article apply to any Scheme (Chez, Gambit, Chicken,
Guile, etc...) or lisp.

I wish there was some reasonable standard (like a better version of Rich Text)
that was commonly adopted so other languages could put graphical pictures in
the source code.

~~~
dbcurtis
> I wish there was some reasonable standard (like a better version of Rich
> Text) that was commonly adopted so other languages could put graphical
> pictures in the source code.

I have felt exactly the same for many years. It would need to be something
that was totally open (to achieve wide adoption), and reasonably easy to
support in IDE's for edit and preview. And git-friendly. Belly-flopping on an
existing standard is probably the easiest way to make that happen.

One thought is to presume a block comment with a language-specific marker, and
make the contents a restricted subset of Postscript. a) You get one or two
open-source fonts. Deal with it. b) The rendering area is strictly limited, c)
the operator subset is limited to something reasonable -- like just enough to
do a monochrome version of 80% of the kind of graphics that PowerPoint-ish
programs give you.

Of course, you would never want to write Postscript by hand (although it isn't
hard) but an IDE should be able to support a graphical editor plug-in. Or in a
pinch you could even use another tool that left the rest of the code alone,
and just edited the graphical block comments.

~~~
pjc50
You mean like the 'pic' language?
[http://floppsie.comp.glam.ac.uk/Glamorgan/gaius/web/pic-20.h...](http://floppsie.comp.glam.ac.uk/Glamorgan/gaius/web/pic-20.html#20.%20Some%20Larger%20Examples)

Developed in 1982. Present on almost every UNIX-like system and integrated
into the manpage generator.

Probably the main reason we've not seen things like this achieve wide adoption
is the small but very influential subset of programmers who refuse to use
anything that isn't a pure text terminal for development.

~~~
civility
Interesting. I'm not familiar with "pic", but I'll check it out. I've never
seen a manpage with that in it.

A terminal with graphics in it would be nice too. Maybe if Tek4014 (and the
Tek emulation in xterm) had graphics and _useful_ text simultaneously it
would've been more popular than the modal approach. I've also heard of Sixel,
but never seen it live.

------
mark_l_watson
I have written books on Common Lisp and Scheme. Their power feature to me is
the combination of functional programming (functions without side effects) and
how these small functions can be built bottom-up in an interactive repl. Other
languages like Python and Ruby also support repl style development, but aren't
sufficiently functional. A little off topic, but I am working on a commercial
product (KGcreator, a tool for generating graph data for knowledge graphs) and
started prototyping in both Racket and Haskell. It was a tough call but I
chose Haskell. I think of Haskell as being another Lisp language that also
supports repl style development.

~~~
soapdog
Tell us more about your books. I'm addicted to scheme books :-)

Also, what made you choose Haskell for your project? Can you share some of the
reasoning?

~~~
mark_l_watson
I think the deployment story for Haskell is better than Racket. It is easy
enough make standalone Racket executables but with stack and cabal it is baked
in to easily build multiple executables, separate libraries, keep everything
tidy.

Racket is much better to get something done and working quickly. Same comment
for Common Lisp.

Haskell has great support for strongly types web services (servant) and lots
of great libraries. Racket has a very rich ecosystem of libraries, custom
languages (like Typed Racket). Both are great.

EDIT: It takes me longer to get to working code in Haskell but once written
the code has higher value to me because it is so much faster/easier to
refactor, change APIs, reuse in other projects, etc. I just did a major
refactoring/code-tidying this morning, and it was very simple to do.

------
ken
> If __ are so great, then it should be possible to summa­rize their bene­fits
> in concise, prac­tical terms. It should be possible to demon­strate the
> power of __ in one hour, not 100. If __ advo­cates refuse to do this, then
> we shouldn’t be surprised when __ remain stuck near the bottom of the
> charts.

This paragraph seems like it would be equally true for almost any subject you
filled in the blanks with.

As someone who had to learn a foreign (natural) language in school, I can see
the benefit now, but there's no way I could explain it, and certainly not in
an hour. It's a type of learning which causes a change in how you organize
things you already know. How do you sell that?

(No, I don't believe "so you can talk to people in that language" is a
realistic benefit. I don't think even my school thought that. The selection of
languages offered is simply not useful. I've never met anyone this side of
Stuttgart with which to use my German. Of the top 10 non-English languages
spoken in my state, only 1 was offered as a class at my school. It almost
looked like they went out of their way to find teachers in less common
languages.)

(BTW, that's also the same answer as "If Lisp is so great why isn't anyone
using it?" It works for any subject. If trig is so great, why aren't you using
it? If music is so great, why did you stop playing after you graduated, and
were no longer required?)

I'm not trying to downplay the importance. It's a real problem, for many
fields. As a Lisp programmer, it's my nature to try to sell everyone on
learning Lisp even if they won't use it, and also to over-generalize problems
to nearly the point of absurdity.

How do you get someone to want to learn something when it may have no
immediate and apparent practical value to them? Especially today when their
whole "learning" slice is competing with Netflix and Facebook and all the
rest. I guess the trendy answer right now is something in the neighborhood of
"freemium gamification" and for reasons I can't explain that makes me sad.

~~~
gameswithgo
The problem of people failing top provide empirical evidence for claims of
things is indeed universal and common. But it is possible to do so, sometimes
it requires a ton of work, but if we want to know things, we have to do that
work. Until we do, we don't know things.

------
cracauer
In my mind there is one killer feature in Lisp, and that is Compile-Time-
Computing.

You have a macro system that isn't some lameass additional language with
severe limitations like the C preprocessor or C++ templates. You have _all_
the language available both at compile time and at run time. You can even use
functions you already have (and tested) in both places.

This allows you to leave every single assumption you make during programming
in one place. You don't have to splatter uncertainty about what the program is
supposed to do into multiple places because you language isn't expressive
enough, e.g. you cannot just redefine control structures to express an
assumption. That is what leads to "changeable software", not just "readable
software".

My writings on the subject: [https://medium.com/@MartinCracauer/a-gentle-
introduction-to-...](https://medium.com/@MartinCracauer/a-gentle-introduction-
to-compile-time-computing-part-1-d4d96099cea0)

[https://medium.com/@MartinCracauer/a-gentle-introduction-
to-...](https://medium.com/@MartinCracauer/a-gentle-introduction-to-compile-
time-computing-part-2-cb0a46f6cfe8)

Example - using scientific units attached to literals in source code, but keep
them at compile time and don't slow down runtime with unit checking:
[https://medium.com/@MartinCracauer/a-gentle-introduction-
to-...](https://medium.com/@MartinCracauer/a-gentle-introduction-to-compile-
time-computing-part-3-scientific-units-8e41d8a727ca)

And speaking about early or late (static/dynamic) type checking. If you have
compile-time computing you don't have to choose. How silly would it be to make
a programming language that can only do one or the other.
[https://medium.com/@MartinCracauer/static-type-checking-
in-t...](https://medium.com/@MartinCracauer/static-type-checking-in-the-
programmable-programming-language-lisp-79bb79eb068a)

Finally, there is turnaround time during development:
[https://hackernoon.com/software-development-
at-1-hz-5530bb58...](https://hackernoon.com/software-development-
at-1-hz-5530bb58fc0e)

~~~
benji_is_me
You should check out Zig. Here's the part of the documentation concerning
compile-time code.

[https://ziglang.org/documentation/master/#comptime](https://ziglang.org/documentation/master/#comptime)

------
geokon
I've done some elisp (and a tiny bit of racket) and some Clojure and honestly
I struggle to see why I would ever pick a racket/scheme/elisp over Clojure
unless I desperately needed to do a ton of C ffi. Clojure is much more
opinionated but I never find myself feeling like it's constraining or a
straightjacket

When do people say to themselves "screw this, I need a more flexible tool like
Racket"? Is it when you get super deep in the macro magic? (I'm not reallt
sure how the Clojure macro system compares to the Scheme one)

~~~
dmos62
I've done way more Clojure than any other Lisp, and I'm now transitioning to
Racket. Primarily, because I want to get away from the JVM. One thing about
Clojure that is not easy to put into words, and that I miss, is just how
"smooth" working on it is. The Clojurisms, as they come to be known, are very
well thought out, and the whole language fits together like a perfect puzzle,
or at least in my experience. To come back to the JVM thing, I find that
Clojure is applicable only serverside, where you can have the slow starting
hundreds-of-megabytes JVM running non-stop, or in the browser, through
ClojureScript, and it's really perfect for those environments. Though as I
shifted more towards non-server environments, and I need to use FFIs, Racket
is the right blend of expression and performance.

~~~
dorfsmay
Have you played with the different schemes or just jumped on racket? If the
former, I'd be interested to know why racket over gambit or chicken?

~~~
dmos62
No, Racket is my first Scheme.

------
leetrout
That’s a longer read than I expected but there are some good, frank points
like non programmers seeing some of the praise for Lisp called
“unsub­stan­ti­ated hoodoo”.

I like that the author addresses the “what’s in it for me” head on as well.
Makes it a bit more clear what some of the immediate benefits are.

------
sleibrock
I've been using Racket for a few years now as my main "fun" toy language and I
can't stop using it or trying to come up with new ideas for it. I'm currently
writing my new website's publishing code in Racket, using Racket programs to
create my static pages.

For anyone who enjoys programming language dives, I recommend Racket fully.
It's simple and powerful in various ways.

~~~
abhiyerra
I'm wondering if combining Racket with AWS Lambda
([https://github.com/kpiljoong/aws-lambda-
racket](https://github.com/kpiljoong/aws-lambda-racket)) would be a good way
to play with Racket and do cool things with it. I've done a bunch with Emacs
Lisp but always felt weird writing a server application with elnode.

------
i_am_proteus
I've read this article a few times and every time he takes beef with Python:

    
    
      x + (if is_true(): 1 else: 2)
    

I think he just got he syntax wrong, it's supposed to be:

    
    
      x + (1 if is_true() else 2)
    

And basically can't follow the rest of the argument. I have yet to learn a
Lisp. Honestly, what am I missing?

~~~
jbotz
The point of the "if" example is that there is a difference between
expressions and statements... yes, Python has a conditional expression (since
Python 2.5, before it didn't), but it _had_ to be a different syntax for that
reason; the "if" expression is a completely different thing than the "if"
statement (it's what's sometimes called a "ternary conditional") it just
happens to use the same keywords (but without the ":"). In LISP everything is
an expression, the syntax is totally uniform.

~~~
i_am_proteus
Interesting, and thank you for the explanation!

------
gaze
More lines of prose praising lisp are being written than lines of lisp these
days it seems.

I recently asked how to write a tree shaker in #sbcl because I thought it’d be
cool. All I got was a “why would you do that?” and “ok fine your time to
waste” and no substantial answers. The Common Lisp community is small and
curmudgeonly. Who needs this?

~~~
rayiner
Some things, like tree shaking, trigger some, in my opinion justifiable,
bitterness in the Lisp community. People said Lisp couldn’t take off unless it
competed with C for speed and image size. Tons of resources were invested on
that front, building tree shakers and type inference engines. Then, JavaScript
comes along and proves that none of that was necessary. Individual web pages
are as big as some Lisp’s entire core images. The language spec might as well
have been written in crayon. While Lisps were developing sophisticated numeric
towers, JS does not even distinguishing between integers and floats! Dynamic
typing languages won, with a language that was inferior in every way to Lisp,
except popularity.

~~~
debug-desperado
It's a bit anachronistic to compare Lisp's goals from 40 years ago to current
JS situation. The latter we're stuck with for political reasons, while the
former really did need to overcome hardware limitations to be successful in
that era.

Also with Typescript being adopted by most major JS projects, I wouldn't say
that dynamic typing "won."

~~~
gaze
Python is also really really popular these days. Maybe they haven't so much
won but they've definitely become extremely significant, and they haven't
lost.

~~~
anoncake
Python has an optional type checker these days so you can write fairly
statically typed Python if you want.

------
todd8
One of the benefits of Lisp based languages is that they usually come with
powerful macro based meta-programming facilities.

I've use macro systems quite often in more or less complicated ways: as a
professional assembly language programmer, in school when studying Lisp DSLs,
when using my favorite editor Emacs and its elisp, in systems I've built
similar to Moores TRAC programming language, M4, my extensive use of TeX and
LaTeX for decades, C++ STL, sendmail configurations, etc.

Over the years, I've lost my enthusiasm for powerful meta-programming
facilities like Lisp macros. The underlying languages are Turing complete and
don't strictly need meta-programming, and most modern languages aren't lacking
in abstraction mechanisms available to programming without meta-linguistic
alterations.

Like operator overloading, sophisticated macro systems change the semantics of
program source code in ways that are not obvious. They allow new variants of
the programming language to be created willy nilly placing demands on me the
reader, maintainer, or user of a programming language package to fully
understand the implementation of the meta-linguistic features. Powerful macro
systems encourage a thick frosting of magic to be applied on the
implementation of complex systems.

Some systems, like Lisp or Scheme or TeX, would be difficult to use without
macro extensions, but it seems to me that identifying a good set of built-in
abstractions for writing programs and building the language around them is a
better approach. I am so grateful for the TicZ graphics package for LaTeX,
it's all built out of TeX's crazy flexible macro system, but I'm even more
grateful that I've never had to touch the source for it. Take a peek at: [1].

[1] [https://github.com/pgf-tikz](https://github.com/pgf-tikz)

~~~
wtetzner
I think it all comes down to what kind of programs you're writing.

For example, without a powerful macro system, something like the nanopass
framework [1] would not have been possible.

Sure, you could write an external code generator, but at that point you've
just implemented a bad macro system.

[1] [https://github.com/nanopass/nanopass-framework-
scheme](https://github.com/nanopass/nanopass-framework-scheme)

------
scotty79
I only learn new languages to be able to do something new. I learned BASIC to
make my atari do what I want. Then 6502 assembler and ACTION to make it do it
faster. Then Pascal to have complete flexibility of data structures. I learned
C++ as a Pascal with dumb syntax but never used it before Pascal went
completely out of style because there was nothing new C++ could do for me.
Then I learned Java because you could do applets with that. Then HTML because
you could make the browser display what you want. Then PHP and SQL because you
could build websites with that. Then Python because PHP sucked for console
programs and JS because you could make things happen without bothering the
server. Then some XML and XSLT because that could process a lot of data fast
on client side. Then C# because that was the comfiest way to make desktop apps
since Delphi kicked the bucket. Then I learned Ruby because I was assigned to
project written in it, but promptly forgot it since then because it could do
only the things Python could already do. Then I got back to Java since you
could make your phone do what you want with that but Java is (was then?) worst
language I know so it was short lived. I still retain it though for occasional
utiliy, like extrnding Solr or playing with Apache NiFi.

The only language that kind of breaks away from this pattern of necessary
imediate empowerment was CoffeeScript. It just exactly mirrors my way of
thinking and was just an inch away from pseudo code I used for my notes since
primary school. But then ES6 came and gave me enough CoffeeScript to almost be
fine without it. Final nail was TypeScript that gave me stuff I wanted, smart,
fast code completion and typechecking for places where I wanted types. Now if
I could just have an editor that could display curly braces as indented blocks
(python and coffee style) I'd be perfectly happy with state of browser coding.

I tried Go, Elm, Haskel, Scala but nothing stuck or even went beyond simple
programs. Nim was interesting because allowed you to run code at compile time
to transform code (like Racket macros). I might use it for console programs
that need speed (although I'll probably just dust off C++).

Rust so far has the biggest potential because it allows you to have code
running concurently without crazy bugs by forcing you to specifically track
who owns what and for how long. That might be useful for me to make programs
faster at some point since multicore is now firmly a thing.

------
namelosw
I love Scheme and Racket. Personally, I prefer Scheme over Clojure and Common
Lisp. It supports multiple paradigms well but not too bloated as Common Lisp,
having a really good optional gradual type system, really easy to use reader
macro system, etc.

I always wanted to use Racket in a bigger project to have a deeper
understanding of macro/language creating. I always believe to achieve real
'domain driven design' is to create a layer of real business language which
could interpret to a software system.

However, every time I want to do this I found Clojure is actually a much
better choice. I guess to be fully practical is not #1 priority for Racket
right now. But I really hope Racket can improve some of the following:

1\. Encourage efficient data structures by default. I know lists are the soul
of lisp but it's not good to use lists for everything. Clojure by default let
you use highly optimized persistent data structures -- namely vectors and hash
maps. These two data structures are highly practical, performant in most of
the cases.

On the other hand, lists are more like write-heavy data structure, with really
bad reading performance. This is like, a plain file system writes faster than
databases, but most of the websites use a database because most of the
business has much more reads than writes.

2\. ClojureScript. JavaScript is a big thing until WASM fully arrives. Clojure
has several really solid ClojureScript workflow, which makes me feel
ClojureScript is really a first-class citizen.

3\. IDE and debugging. I use Emacs + Geiser for editing, but Drracket for
debugging. Drracket is really good, but still not great for editing hundreds
of files. For Clojure, Cider and Cursive are IDEs makes me feel solid and
complete.

4\. Frameworks. I guess if the other 3 points are really good there would be
many good frameworks come out every day.

~~~
neilv
I have to type this as a quick stream right now.

> _1\. Encourage efficient data structures by default. I know lists are the
> soul of lisp but it 's not good to use lists for everything. Clojure by
> default let you use highly optimized persistent data structures -- namely
> vectors and hash maps. These two data structures are highly practical,
> performant in most of the cases._

Scheme has vectors, and Racket adds hash tables and structs:

[https://docs.racket-lang.org/guide/vectors.html](https://docs.racket-
lang.org/guide/vectors.html) [https://docs.racket-lang.org/guide/hash-
tables.html](https://docs.racket-lang.org/guide/hash-tables.html)
[https://docs.racket-lang.org/guide/define-struct.html](https://docs.racket-
lang.org/guide/define-struct.html)

There's also some work on matrices and arrays (beyond Scheme vectors):
[https://docs.racket-lang.org/math/index.html](https://docs.racket-
lang.org/math/index.html)

There are some older libraries where lists (or alists) are used, when today
you'd probably use hashes or structs. We could consider this an educational
opportunity: there are still times when knowing how to do old-school list-
processing is exactly what you need, and it's pretty fundamental data
structures (e.g., singly-linked lists, trees), so we could consider it
practice. :)

BTW, one difference between modern Racket lists and Scheme's is that Racket's
default pairs are immutable. This turns out to be useful for optimizations, as
well as encourage a healthy amount of functional programming.

Regarding #2, good point. I raised the WASM issue a couple years ago, and my
thinking then (and now) is to build it for the forthcoming Chez backend, while
getting plugged into the WASM standards work in the meantime. There are
various ways to do JS with Racket (a big HTML5 Offline app of mine does it by
generating JS and HTML from Racket), but WASM seems most promising.

Regarding #3, if Geiser works for you, great. You might also take a look at
Greg Hendershott's racket-mode for Emacs:
[https://github.com/greghendershott/racket-
mode](https://github.com/greghendershott/racket-mode)

I appreciate that DrRacket's student-emphasizing IDE is very different than
most IDEs, and it's missing some things I'd like, for editing many modules at
once. If you're up to adding some features you'd like, there's an extension
mechanism, and you can also do git pull requests to the DrRacket source
itself. [https://docs.racket-lang.org/drracket/extending-
drracket.htm...](https://docs.racket-lang.org/drracket/extending-
drracket.html) [https://docs.racket-
lang.org/framework/index.html](https://docs.racket-
lang.org/framework/index.html)

Regarding #4, there are Web frameworks, and the main Racket Web Server (which
you don't have to use; you can also do things like SCGI or proxy another HTTP
server implementation), and you can also whip up your own frameworks very
rapidly in Racket unlike many languages. I'm hoping a couple startups use
Racket to get to launch, and release the light frameworks that they make along
the way.

Regarding reader extensions, Racket has those, as well as a ton of great
syntax extension mechanisms: [https://docs.racket-lang.org/guide/hash-
reader.html](https://docs.racket-lang.org/guide/hash-reader.html)

~~~
no_identd
An addendum to point 3:

Racket has an AMAZING debug instrumentation & tracing library, which,
unfortunately, most people don't know about:

First, there's Medic:

Source:
[https://github.com/lixiangqi/medic](https://github.com/lixiangqi/medic)

Docs: [https://docs.racket-lang.org/medic/index.html](https://docs.racket-
lang.org/medic/index.html)

Demos:
[https://www.youtube.com/playlist?list=PL_U7i0VKF_mh7Vh3o2Yyt...](https://www.youtube.com/playlist?list=PL_U7i0VKF_mh7Vh3o2YyteoTL1tErHY64)

Paper:
[https://www.cs.utah.edu/plt/publications/fpw15-lf.pdf](https://www.cs.utah.edu/plt/publications/fpw15-lf.pdf)

Li, Xiangqi; Flatt, Matthew - Medic: Metaprogramming and Trace-Oriented
Debugging (2015)

Building on top of Medic, but unfortunately still not packaged (unlike Medic),
Li & Flatt developed (the somewhat ill-named, due to that name overlapping
with something from the cryptocurrency crowd) 'Ripple', which makes debugging
Domain specific languages a lot slicker:

[http://www.cs.utah.edu/plt/publications/sle17-lf.pdf](http://www.cs.utah.edu/plt/publications/sle17-lf.pdf)

Li, Xiangqi; Flatt, Matthew - Debugging with domain-specific events via macros
(2017)

There's a YouTube demo here:

[https://www.youtube.com/playlist?list=PL_U7i0VKF_mjF_SMiPbz-...](https://www.youtube.com/playlist?list=PL_U7i0VKF_mjF_SMiPbz-
P_vUkNGHHjm8)

The published version of the above paper sits behind an ACM paywall, however,
the download of the 'artifact' is open/free…:

[https://dx.doi.org/10.1145/3136014.3136019](https://dx.doi.org/10.1145/3136014.3136019)

…and currently unfortunately represents the only way one can acquire the
Ripple source code - and the artifact consists of a 2.4GB VM! :| (I understand
why, and I consider it good scientific praxis - but I'd still appreciate a
public repository in addition.)

Direct link to the artifact, for the impatient:

[https://dl.acm.org/ft_gateway.cfm?id=3136019&type=zip&path=%...](https://dl.acm.org/ft_gateway.cfm?id=3136019&type=zip&path=%2F3140000%2F3136019%2Fsupp%2Fsle17%2Dsle17main7%2Daux%2Ezip&supp=1&dwn=1)

Note that the artifact actually contains two very slightly different versions
of the Ripple source code, a diff of which I posted over here on Github:

[https://github.com/vygr/ChrysaLisp/issues/5#issuecomment-424...](https://github.com/vygr/ChrysaLisp/issues/5#issuecomment-424144727)

(it's a two line difference in main.rkt)

If you do any of the in Racket, I can most highly recommend giving Medic (and
Ripple, if you need it.) a try!

------
soapdog
I really recommend that book, not just this section. I really enjoyed it and
it was crucial for me in creating a talk I gave after reading it about the fun
in creating little languages.

------
revskill
As i understand, the beauty of languages like LISP and Racket, is that, you
can easily compose functions. Basically, as i read source code, i'm reading a
"programming composition sheet", just like music sheet.

The only annoying thing, is how to reduce brackets ( and ) from distracting
content from its layout.

Of course Python is not the answer (due to its strict identation on
space/tabs)

If i could teach newscomer about programming, i would say: Programming =
composition of functions.

------
sctb
A couple prior discussions:

[https://news.ycombinator.com/item?id=9268904](https://news.ycombinator.com/item?id=9268904)

[https://news.ycombinator.com/item?id=8206038](https://news.ycombinator.com/item?id=8206038)

------
hzhou321
> 1\. Every­thing is an expres­sion.

I am not sure this argument is given.

Immediately, I see there is a mismatch between what I want to program -- an
objective, an algorithm, a procedure, a series of side effects that is outside
the axioms of the programming language can support -- a mismatch between these
objectives and this confinement of everything being an expression. An
expression is a value. So to program in a language where everything is an
expression is to map our idea into a (list of) value. This may be natural for
programs that is seeking a value, but often not so. Even for programs that is
seeking a value, the bulk of the program is to control the process of finding
this value. There is no easy way or even correct way to map a process and side
effects into a value. Math is logic or equivalency. To establish equivalency
is to discard the effect of path or side effects. Therefore, to map the
desired process and side effects into value, we have to add back the implicit
knowledge of how these values are actually transformed. In stead of directly
stating the transformation of values -- an imperative programming style -- we
express that with dependency and relying on the understanding how these
dependency is being resolved. The latter is very hard.

Of course, in practice, we have to give up on the fine control of our program
to some extent and relying on the compiler implementation giving us desired
result (the path and its side effects), then we only need worry about the
value. When it works, it works great; when it does not work, we need either
lower our expectations or give up the language, or transfer the burden/blame
to compilers.

The argument for everything being an expression is the composability(although
I thought the reason was ease and flexibility of writing compilers for it).
This is similar to the argument that: if every object is a lego piece, then
building something is easy. Well, it depends. First we need accept that lego
pieces are all what we have. Second, we have to contend that what lego pieces
can build is good for our needs. There are amazing lego projects, but they are
nowhere I would find easy.

~~~
lispm
Well, in languages like Scheme and Lisp, expressions are returning a value.
But they can also be control structures. For example IF forms are an
expression, but IF is also a control structure:

    
    
       (if (rocket-engine-running?)
          (start-rocket)
          (start-engine))

~~~
hzhou321
When expression is not pure value -- they also can be control structures --
the arguments for "everything is an expression" is being defeated, right? A
control structure is for defining the path -- control flow. The values in a
control structure is a side effect just as the control-flow is a side effect
in an expression language. When control flow is the center of logic, won't a
control-flow oriented language -- imperative programming -- be more straight
forward?

In your example, after you started the engine, don't you still need `start-
rocket`? The bug sneaks in due to discrepancy that while the syntax is all
about values, the semantics is all about flows.

~~~
lispm
It gives us as a developer the freedom to decide: do I want control flow,
return values or both?

------
strangattractor
Racket is great and fun. I find it truly amazing that after all these many
years people are still trying to justify Lisp. Frankly - if it was going to be
adopted in mass it would have happened by now and no amount of explaining is
going to change that. There are many reasons why languages get adopted and
"logic" is not the primary one. Take JS for example - it would have been in
the dust bin if not for the fact it is the only language that runs in
browsers.

------
yepguy
Does Racket have a nice DSL for wrapping web APIs? I have a hard time
believing it doesn't, but I can't find it. I'm thinking of something like API-
Wrap.el
([https://github.com/vermiculus/apiwrap.el](https://github.com/vermiculus/apiwrap.el)),
but any approach that drastically reduces the boilerplate is fine by me.

~~~
xrayspec
Riposte?

[https://docs.racket-lang.org/riposte/](https://docs.racket-lang.org/riposte/)

~~~
yepguy
Riposte doesn't look all that useful outside of a test framework. I want to be
able to use REST APIs in a full Racket program, which seems impossible in a
DSL without control flow or functions.

------
truth_seeker
Nice write-up.

Waiting for Racket-on-Chez effort to come with more optimizations and multi-
core access

~~~
xfer
Just to be clear: multi-core already works with racket places(basically
running a separate racket vm thread) :).

Chez-scheme has a pthread-style interface to OS threads, which has it's own
set of problems with respect to concurrency(knowing which operators are thread
safe). Not sure how racket would expose this.

------
bitmadness
Beautifully written post.

------
craftinator
I've long stayed away from Lisps, precisely because of what the author
describes in the first section, that there is a huge amount of praise over all
of it's wonders, without ever specifying what those wonders are or how they
are actually good things. I've had similar issues with the cargo-cult
following of Rust; yes I have heard it is great, but WHY!? Great article, it
de-mystifies these vague praises and addresses them clearly and specifically.
I'm gonna try Racket this afternoon =D

~~~
Gene_Parmesan
I'm no 'rustacean,' but rust's benefits have always seemed fairly
straightforward. The borrow checker provides static guarantees for thread- and
memory-safety, and allows for safe, performant low-level systems code without
the need for a GC.

~~~
craftinator
Now that is some good straightforward information! Much more clear than most
other comments I've read, and a better aggregate of features than Rust
documentation offers. Thanks for chiming in!

------
crimsonalucard
This guy makes some statements about python that are completely and utterly
wrong.

He implies python doesn't have an "if" expression. It does.

He specifically claims this is invalid in python implying that "if"
expressions don't exist in python:

    
    
       x + (if is_true(): 1 else: 2)
    
    

The following is written in python and is correct syntax:

    
    
       x + (1 if is_true() else 2)
    

Although it's not "pythonic" to use python functionally, Python is a multi-
paradigm language and has the facilities to be used as a very powerful
functional language. It's not just a "functional" library. Functional is built
into python syntax. The following is correct python syntax that will pass a
type checker process as well.

    
    
       #List comprehensions using map and filter:
       x: List[int] = [i+2 for i in range(100) if i%2 == 0]
       #anonymous functions:
       x: Callable[[int], int] = lambda a: a + 2
    
       
    
    
    

With mypy, type annotations or any other external type checker, python
approaches the power and correctness of typed functional programming languages
like haskell or Ocaml, though it is missing many features.

~~~
jbotz
The OP isn't trying to criticize Python... he was just trying to give an
example of what it means for everything (in LISP) to be an expression. He
didn't say that Python doesn't have an "if expression"... just that you can't
use the if statement in an expression context.

~~~
crimsonalucard
OP literally says this:

 _In Python, an if condi­tional is a state­ment, and can only be used in
certain posi­tions._

This is categorically wrong. In python the if conditional exists in statement
form and expression form. The if-expression also basically exists in every
other imperative language out there, usually in this form:

    
    
       x + (is_true() ? 1 : 2)
    

I know he's not trying to criticize python. Just want to correct his mistake
and emphasize that python has intrinsic design features that can make it very
very functional.

~~~
hencq
I think you just misinterpreted the point he's making. Yes, Python has an
expression form for if, but it's a separate form. You can definitely write
functional Python, but the point he makes is that Python differentiates
between expressions and statements.

~~~
crimsonalucard
No I made no mistake. I get his point. Look at my reference. I literally
posted the statement that is categorically wrong. He literally says that in
python the if-conditional is a statement. This is False.

I also offer some proof as to why python is a bad choice for his examples
because python is actually a highly functional language. It's like trying to
use haskell to prove racket is more expressive. It's a bad choice.

Sometimes I don't understand people. I literally posted just factual errors,
no opinions on his article and then people misinterpret everything I said as
opinion and proceed to tell me I misinterpreted things, then vote me down.
Seriously.

