
Hey Racketeers, long time no see! I’m currently struggling trying to provide a #lang
as a web service… I’m looking for a way to execute an arbitrary string of text (I get from the network) through a custom reader, then expander, as #lang
usually does. I found make-evaluator
and make-module-evaluator
, but they don’t seem to handle readers correctly. I tried to summarize everything in this stackoverflow question : https://stackoverflow.com/questions/59855704/how-to-tell-make-module-evaluator-to-use-a-custom-reader-like-lang-does I’m currently trying every possible combination of make-evaluator
parameters, with no success… Can you help me out?

@notjack This is what I came up with that worked for my immediate purposes.

@jerome.martin.dev Have you tried read-lang-module
to turn the string into a syntax object representing a module ?

At the moment, I am dog-fooding urlang. The frontend simply sends standard http requests to the server, which responds with json.

I usually get an evaluator, but then when I try to (eval 'meal)
it complains about missing #%top-interaction
.

Then if I provide #%top and co… (which I don’t really want to, but, anyways…) It just complains about the variable meal
missing, and I’m stuck there.

It’s weird because it works perfectly when I require a file the usual way.

It’s like the reader submod is never called.

Are you using a load
or the read-eval-loop
? (I am curious about where #%top-interaction came from)

I guess I am curious about what read-lang-module
returns?

So I tried providing sandbox-reader
. But then the sandbox passes 'program
as the first argument to my read-syntax function! Weird!

read-lang-module
returns a correct module parsed by my reader: #<syntax:private/reader.rkt:41:8 (module program broccoli/private/expander (program (sentence "Hello" "world")))>
But the evaluator fails to call the expander on it.

Fails how?

Either #%top missing or ’meal missing

It’s supposed to expand into (#%module-begin
(provide meal)
(define meal (list 1 2)))
But I never get to that meal…

And the broccoli program runs fine on its own (I mean directly in DrRacket)

yep

if I do: > (require "my-file.meal")
> meal
'(1 2)

with the file being something like #lang broccoli
Hello world!

What does your (make-module-evaluator ...)
expression look like?

> (define module (read-lang-module (open-input-string "#lang broccoli\nHello world!\n")))
> module
#<syntax:private/reader.rkt:41:8 (module program broccoli/private/expander (program (sentence "Hello" "world")))>
> (define eva (make-module-evaluator module))
> (eva 'meal)
; meal: undefined;
; cannot reference an identifier before its definition
; in module: 'program
; [,bt for context]
>

I think you need to use #:lang ...something here...
in order to get the correct namespace.

Well, there’s a #:language parameter, but it just puts a restriction on the module, it doesn’t do anything particular

I was reading this section on make-evaluator
and now I am confused whether it also works like this for make-module-evaluator
:

Oh, hold on, I got it working! > (eva '(require 'program))
> (eva 'meal)
'(1 2)

I need to require the created module inside the evaluator…

Ah!

It’s a bit sad because I wanted to avoid having to provide #%app, #%top, require, quote…

But I guess it’s okay

I may find a way to simplify and secure this further, but for now, it’ll be okay. I’ll just put some statement in my presentation like “please call me if you broke into my server by executing some racket code through my app” and call it a day :stuck_out_tongue:

@soegaard2 As always, thanks for helping me!

Glad to help.

@soegaard2 I see- so the you write your front end with urlang; in turn, urlang sends requests to the server, which responds with json; json is the mechanism by which the front end is displayed?

No the json just contains the data. I have chosen react-bootstrap for the dynamic parts of the gui (and plain bootstrap for the static parts).

But honestly it might be easier to use plain JavaScript in the frontend.

The reason I picked react-bootstrap is that the “hooks” in modern react feels like functional programming.

(The old approach in React used objects.)

@soegaard2 I see — do you have the project you’re building with urlang on github?

Sorry no. At some point I might change http://racket-stories.com\|racket-stories.com to use Urlang for the gui, but I haven’t got any examples on Github yet.

There are some examples with React Hooks though. https://github.com/soegaard/urlang/blob/master/urlang-examples/quiz/quiz.rkt


(the last one might be a bad example - it was an experiment to see how close I could get to the beginner language)

@soegaard2 thanks a lot. My background is Structure and Interpretation of Computer Programs. Now I want to get into web development but I want to use Racket or Haskell. Do you know any good tutorials or books where I can learn the fundamentals of web development?

There are so many options in web programming, so it can be confusing. The JavaScript plethora of libraries is still confusing to me.
A good place to start: https://docs.racket-lang.org/continue/index.html

Also worth a look is https://github.com/soegaard/web-tutorial There are 4 versions of a web-site: listit, listit2, listit3 and listit4. The first one listit is very basic. The code is heavily commented and was meant to be read.
Haven’t written an actual tutorial yet…

Ok thanks. How did you build http://racket-stories.com\|racket-stories.com? It’s pretty cool.

Racket Stories used the Racket web-server. It uses a database to store all information. Everything happens server-side (i.e. no Javascript is used).
The code is available here (but it is worth reading the simpler listit sites first): https://github.com/soegaard/racket-stories

If you need an overview of how the web-site works, then this (very old) blog post on gives some insight. The actual implementation from back then you can ignore. http://www.scheme.dk/blog/2007/01/introduction-to-web-development-with.html

Wow- so a server side application or project can look like http://racket-stories.com\|racket-stories.com?

Yes.

Look in “view.rkt” to see how the html is produced.

That’s so cool. I’m going to take a look at it. Sorry for my ignorance but how did you make it look nice; for example it’s purple and it looks nice. I’m operating on the idea that html alone can’t do that.

I used Bootstrap. When you generate the html, you mark the elements with a class. The browser looks up the classses in the style sheet (css) and draws them accordingly. Bootstrap provides some nice themes - they are way better at design than I am.

I stuck to the default theme, but there are lots of other Bootstrap themes to choose from: https://themes.getbootstrap.com/

This is pretty cool. Inside “view.rkt” you refer to bootstrap by providing a link. Do you get this link when you buy the theme or is this the link for the default theme?

That’s just the default theme. I got the link here: https://getbootstrap.com/docs/4.4/getting-started/introduction/

There are other free themes for Bootstrap, if you look for it.

So I can use racket to build a simple html blog right?

That would be a great project.

You have been really helpful. I can find your email at http://racket-stories.com\|racket-stories.com right?

Yes.

I see in your github that you have written a computer algebra system. I wrote a few toy computer algebra programs. If you have time could you give some feedback on my work?

Sure, what kind of feedback are you looking for?

Well, I would like some feedback to get a better idea of my skill level. and I would like to know if they are any good. here’s one: https://github.com/xsquared93/generic-arithmetic

The code is clear and follows the spirit from SICP.
If I were to change something it would be the representation of values. The SICP authors were forced to use tagged lists, because the Standard Scheme back then didn’t have structures/records/objects.

Another thing to look into, is pattern matching (pattern matching weren’t available in Scheme back then either).

okay, I will look into that. thank you very much.

@mflatt Thanks!
@notjack Entire collection. I want to rename one of my projects without needing users to change their code.

@mflatt Would it be reasonable for me to add code to raco pkg
’s implementation to recognize collection aliases as defined in info.rkt
, or would that overcomplicate things?

Btw Cohen has written two nice books on algebra systems: https://www.ukma.edu.ua/~yubod/teach/compalgebra/%5BJoel_S._Cohen%5D_Computer_algebra_and_symbolic_comp(BookFi.org).pdf

I will check them out. what inspired your computer algebra system?

@deactivateduser60718 How many user-facing modules are there?

@notjack 9.

https://github.com/zyrolasting/polyglot << Counting every module, minus those in private/
and info.rkt

The main structure of racket-cas is inspired by Cohen’s books. But I have also read and enjoyed the algebra section of SICP. There is also a nice chapter in PAIP (by Peter Norvig).

Dusty’s Terminal Phase is on the Hacker News front page: https://news.ycombinator.com/item?id=22095092

@deactivateduser60718 Possibly ok. My first thought was that raco setup
might have some race condition on the filesystem if a module can be accessed by two different names, but I think it’s ok because the compilation lock is based on the resolved path. But I wouldn’t be surprised if I’m overlooking something else like that.

@mflatt I’d have to set aside time to read what’s going on anyway. I imagine this is the kind of thing where whatever I first try will have unexpected side-effects.

yea, I have heard of PAIP. I haven’t read it, though. Maybe, PAIP is good book to read after SICP? you agree? is PAIP relevant if I want to get into the software industry? I believe it will make you a better Lisp programmer and that should transfer to a more popular language. what do you think?

If you liked SICP then I the odds are high, you’ll like PAIP.

speaking of books, have you tackled Purely Functional Data Structures by Chris Okasaki?

Yes, that’s also a great book.

do you feel like it made you a better programmer?

That’s difficult to say. Okasaki’s book is (of course) very focused on data structures, where as Norvig’s book introduces you to a range of topics.
But Okasaki and “Introduction to Algorithms” by Cormen et. al are the first place I look when it comes to data structures.

PAIP is old and Amazon tells me that Norvig soon releases a new book on AI, so maybe it is wise to borrow PAIP from a library to check out rather than buying it.

I don’t think the new book uses Common Lisp though.

I think the new book uses Python. And with respect to data structures, I read that data structures and algorithms are tightly linked. A good choice of data structures will make your algorithms simple, maintainable, and faster. What is your take?

That’s true. And a the choice of data strucure does to some degree how your code will like. However it’s rare that you need to actual implement complicated data structures from scratch. Most often you find a library that provides, say, splay trees and just use them.

You can also use record-merge2
to build a record from arbitrary fields.
(define (record-add-field a-record
kw value)
(record-merge2 a-record
(build-record (lambda (ignore) value)
(keyset-add empty-keyset kw))))

apologies for the formatting

Ooh or for your usecase build-record
may be better.

yea that is the reason people give against studying CLRS. I think studying CLRS will make you a better programmer because it seems like in industry, sometimes, you need to write code that is efficient. you can lose customers, for example, if your system isn’t quick enough. but Dr. Felleisen, in his blog, has written that programming in industry is not algorithmically heavy. He says it is more similar to the things you learn in PL -oriented courses. take a look: https://felleisen.org/matthias/Thoughts/what-is-pl.html

I am sure Felleisen would say CLRS is worth studying :wink: . The context of that blog post seems to be a question of internal politics.

Yea I agree, Dr. Felleisen would say that.

Is there a way to use tech
as contract in defproc
? I felt I have seen this before with some weird quoting tricks but not sure how.

Does anyone have a blog post about making “minimal” docker images for Racket? I’m using rebellion and rash and they both want to (transitively) pull in all of DrRacket.

@notjack perhaps?

If a single package uses docs, then …

Really part of the problem is pulling in everything to build scribble documentation

Ah, it’s #,(tech ...)

(s/part/most/)

Can you install them in the docker container with raco pkg install --binary-lib
? The docker images are configured to use the built-package catalog so that option should download bytecode instead of source code, and it should completely skip installing build-only dependencies.

Also, I should definitely write a post about this for the Racket blog

Ok I was missing the --binary-lib
argument. I’ll give that a try.

Let me know if it actually works. I haven’t tried that myself yet.

@zalp.rogue has joined the channel

I am trying to play around with namespaces and I was running this example from doc https://docs.racket-lang.org/reference/Namespaces.html?q=namespace#%28def._%28%28quote._~23~25kernel%29._namespace-attach-module%29%29 but I am having trouble. (module food racket/base
(provide apple)
(define apple (list "pie")))
(namespace-require ''food)
this gives an error require: unknown module
where it’s the exact same thing from the example. Did something change with namespace-require
?

@zalp.rogue The examples from the doc are meant to be run at a REPL. You might get different results if you put the same code in a file and run the whole file. Is that how you ran it?

oh yes it runs correctly in repl. is there a way to do similar thing in a file?

Yes, you need to change the current namespace to the one “inside” the file (I think). Let me see if I can find an example.

I think, you need something like this: #lang racket
(define-namespace-anchor here)
(define ns (namespace-anchor->namespace here))
(current-namespace ns)

this still gives an error #lang racket
(module food racket/base
(provide apple)
(define apple (list "pie")))
(define-namespace-anchor here)
(define ns (namespace-anchor->namespace here))
(current-namespace ns)
(namespace-require ''food)

IIRC there was a libc problem with Alpine and Racket? (or I’m remembering incorrectly.)

#lang racket
(module food racket/base
(provide apple)
(define apple (list "pie")))
(require (submod "." food))
apple

yes I tried that but I am trying to do the full example of attaching a module to another namespace and instantiating there. Essentially I am trying to instantiate a module separately in a different namespace. namespace-require
says it needs a quoted-raw-require-spec
so '(submod "." food)
should work but that gives an error ; standard-module-name-resolver: no base path for relative submodule path: (submod "." food)

What about ''(submod "." food)
?

The quoted-raw-require-spec always confuses me.

that’s just ?: bad require spec

my understanding was if it works with #%require
and it should work the same after quoting, but apparently that’s not the case.

If we save this in “c.rkt” then I get pie
as output: #lang racket
(module food racket/base
(provide apple)
(define apple (list "pie")))
(require (submod "." food))
(define-namespace-anchor here)
(define ns (make-base-namespace))
(namespace-attach-module (namespace-anchor->namespace here) '(submod "c.rkt" food) ns) ; ns now knows the same instance
(namespace-require '(submod "c.rkt" food) ns)
(eval 'apple ns)

yeah I was able to do that with the filename as well but I don’t have access to the file name all the time. (you don’t even need to anchor in this case just (namespace-require '(submod "c.rkt" food)
will work)

Won’t that require into the wrong namespace?

It will require into the current-namespace which can be just used in same way.

Yeah there was a problem getting racket to compile with musl libc. I think some progress was made on that though, and it might even be fixed. There’s a GitHub issue thread somewhere with the details.

@deactivateduser60718 You could use #lang reprovide
. You’d have to write one file per module, but each file would only have one line of code (not counting the #lang
line). So aliasing oldfoo/bar/baz
to newfoo/bar/baz
would require writing an oldfoo/bar/baz.rkt
file that looks like this: #lang reprovide
newfoo/bar/baz


what could cause racket so that it would not quit with an interrupt. it will not stop with killall
either. only killall -9
worked

usually things just take a sec to shutdown

I’m writing some documentation for Rebellion that gives advice on when to use different kinds of collections. Does this table seem helpful?

@fedreg has joined the channel