Live data from Hacker News

Racket – Lisp beyond Clojure

slides.com

41–50 of 179 posts

Re: Racket – Lisp beyond Clojure

#42
post #26

Earlier quoted context omitted.

Can you be more specific? In particular, about stuff you'd consider to be lacking in Clojure?

Conditions and restarts, read macros, interactive debugging, native code compilation, extremely easy interface with C, intrinsics, compiler macros, full control of code generation, built-in disassembler and so on and so forth. Clojure is ok if all you're doing is based on the JVM. If that's not the case, then it simply doesn't exist.

You're just saying 'Clojure isn't as good as CL because it's not CL'. When one of the the biggest selling point is "it works seamlessly on the JVM" it's a bit disingenuous to say "it's not as good as CL because it doesn't have a good C interface".

Re: Racket – Lisp beyond Clojure

#43

Earlier quoted context omitted.

"The whatever subjective suckage they introduce is their own. If you want racket-style modules, hack them up." I don't think it really makes sense to try to roll your own module system? I mean, the whole point is to be able to easily share code with the community, right?

> I don't think it really makes sense to try to roll your own module system? Obviously Fare Rideau thought it was a good idea when he started hacking on ASDF. He could just have used Defsystem or whatever. It's very popular now, but its name stands for " another system definition facility" for Lisp! If you don't like anything, roll your own. Sharing with the community isn't the entire point of a module system; it's a…

ASDF was originally not written by Fare Rideau. It was developed by Dan Barlow in 2001/2002. He did not use MK-DEFSYSTEM, because he wanted a free/open-source DEFSYSTEM with an implementation using more of CLOS and easier to maintain. ASDF was later developed into ASDF2 and 3 with a lot of work by Fare Rideau and others.

Re: Racket – Lisp beyond Clojure

#44
post #26
post #16

Earlier quoted context omitted.

TBH, almost any Lisp is beyond Clojure. Don't get me wrong, Clojure is an amazing tool. While it addresses a very specific use case (functional programming on the JVM) that use case is common enough that it's a very useful tool. But when compared to other Lisps in a context where non-JVM toolsets are acceptable, Clojure leaves a lot to be desired.

Can you be more specific? In particular, about stuff you'd consider to be lacking in Clojure?

Restarts, call/cc, reasonable error reporting, reasonable error reporting, real tail-call elimination.

Re: Racket – Lisp beyond Clojure

#45
post #44
post #26

Earlier quoted context omitted.

Can you be more specific? In particular, about stuff you'd consider to be lacking in Clojure?

Restarts, call/cc, reasonable error reporting, reasonable error reporting , real tail-call elimination.

Got you.

Once upon a time, there was a serious continuations-on-the-JVM proposal, but it fizzled. Rather sad.

Fixnums would also help Clojure.

Re: Racket – Lisp beyond Clojure

#46

I find DSLs to be extraordinarily powerful for writing and working with my own programs. I find them painful when I'm trying to work with other people's programs. Making a DSL lets me construct a language to express my program that meshes with the way I think. Unfortunately, we all think differently, and what is intuitive and friendly for me is hostile and awkward for others. While reading someone else's program that…

I think this conceptual disconnect can happen even without a DSL. So, then you have the huge amount of code, plus, a bunch of new and confusing concepts applied in ways that don't fit with your understanding of those concepts.

A DSL may mean that the language doesn't fit how you think about a given problem, sure, but a poorly fitting abstraction can happen with or without those language abilities. I tend to think that having those poorly fitting abstractions expressed in a compact form is probably better than having them expressed in libraries with very large surface area and oddly connecting/dependent parts.

Now, I don't actually know this to be true; my experience with Lisp projects is very limited. I have worked with Perl and Tcl that made use of higher level capabilities of those languages to create little DSLs for specific tasks, and I didn't find it problematic; but neither is as far along as Lisp on the DSL spectrum. But, I have also worked with big projects in languages like PHP that get the abstractions very wrong (at least, wrong from my perspective), and have found the verbosity to be exhausting...saying so much in order to accomplish so little (and to do it wrongly) seems even worse than tiny amounts of code that don't fit my mental model.

Re: Racket – Lisp beyond Clojure

#47
post #42

Earlier quoted context omitted.

Conditions and restarts, read macros, interactive debugging, native code compilation, extremely easy interface with C, intrinsics, compiler macros, full control of code generation, built-in disassembler and so on and so forth. Clojure is ok if all you're doing is based on the JVM. If that's not the case, then it simply doesn't exist.

You're just saying 'Clojure isn't as good as CL because it's not CL'. When one of the the biggest selling point is "it works seamlessly on the JVM" it's a bit disingenuous to say "it's not as good as CL because it doesn't have a good C interface".

The c interface is a bit silly, but the rest of the points are pretty good. Clojure is a reasonable lisp-on-the-JVM, but lacks some of the really good things about lisps.

Re: Racket – Lisp beyond Clojure

#48
post #21

Earlier quoted context omitted.

Are there (m)any advantages to doing this? I've seen a number of shell-interop modules for various languages but they all appear to add an extra layer that reduces portability or ease of maintenance.

> Are there (m)any advantages to doing this? [trigger warning: cynicism distilled from 15+ years of bitter tears] More fun and better job security for the current maintainer. The former because one hacks away in the preferred language, the latter because one cannot be replaced easily by some unix geek unless s/he happens to speak the same language fluently. One can chose from various implementations in various langua…

Remind me never to hire you for anything ever. You've truly internalized the Tao of the BOFH.

Re: Racket – Lisp beyond Clojure

#49
post #41

How I am supposed to read the slides? Top to bottom, left to right? It is not intuitive.

Top to bottom. The "top row" of slides are section headers. Go down from a section header to see the section. When you get to the bottom of a section, go right, and it will put you at the top of the next section.

Re: Racket – Lisp beyond Clojure

#50

I've recently started porting some bash scripts over to Racket, using https://docs.racket-lang.org/shell-pipeline and it's been pretty straightforward and painless so far!

Are there (m)any advantages to doing this? I've seen a number of shell-interop modules for various languages but they all appear to add an extra layer that reduces portability or ease of maintenance.

> Are there (m)any advantages to doing this?

In the general case, as always, "it depends". I'm of the opinion that shell scripts are very powerful for quickly prototyping something, but as soon as you need to do real software engineering (e.g. test suites, etc.) then it's probably worth porting over to a saner language (yes, there are test frameworks for bash; no, that doesn't make bash's semantics any more sane ;) )

Piping data between subprocesses is almost universally painful in anything other than a shell, so these sorts of libraries are great for that sort of glue; I wouldn't use them for anything that's not a bog-standard "foo | bar | baz | ..." though, since that's what the rest of the language is for!

In this case it was a no-brainer: the project requires a lot of s-expression manipulation, which is implemented as small racket scripts; these are called from bash scripts which contain the main logic, data flow, etc. I wrote it this way since I'd never used racket before, but figured it would be better suited to this s-expr manipulation than bash, python, haskell, etc. (which it is!); the remaining parts were simple enough to do with bash.

This worked fine for a while, but a recent change in requirements has invalidated a lot of the code's assumptions, so I need to ensure I'm making changes in the right place, that test cases are updated to reflect the changes, etc. which motivates porting to something more sophisticated, and racket is the clear choice here.

I wanted to use a shell-interop library after previously finding Scala's "process" package to be very pleasant to use. It's certainly made the porting job much more manageable, as it just becomes a case of recursively refactoring each part:

    bash:
    echo "foo" | ./bar.sh  | ./baz.sh  | grep "quux"

    racket:

    ---- Convert shell scripts to racket functions

    bash:
    echo "foo" | ./bar.rkt | ./baz.rkt | grep "quux"

    racket:
    (define (bar) ...)
    (define (baz) ...)

    ---- Move pipeline over to racket
    
    bash:

    racket:
    (define (bar) ...)
    (define (baz) ...)
    (run-pipeline '(echo "foo") '(./bar.rkt) '(./baz.rkt) '(grep "quux"))

    ---- Call racket functions directly, rather than invoking scripts

    bash:

    racket:
    (define (bar) ...)
    (define (baz) ...)
    (run-pipeline '(echo "foo") `(,bar) `(,baz) '(grep "quux"))

    ---- Encapsulate stdio

    bash:

    racket:
    (define (bar) ...)
    (define (baz) ...)
    (with-input-from-string
      (with-output-to-string (lambda ()
        (run-pipeline '(,bar) '(,baz) '(grep "quux")))
      "foo")

    ---- Replace stdio with arguments and return values

    bash:

    racket:
    (define (bar x) ...)
    (define (baz x) ...)
    (string-join (filter (lambda (line)
                           (string-contains? line "quux"))
                         (string-split (baz (bar "foo"))
                                       "\n")))

    ---- Replace strings with more useful datastructures

    bash:

    racket:
    (define (bar x) ...)
    (define (baz x) ...)
    (filter (lambda (line)
              (string-contains? line "quux"))
            (baz (bar "foo")))
Post reply on HN