hello ! :smile:
im trying to get a little webserver up and running on heroku with https://github.com/lexi-lambda/heroku-buildpack-racket
but i dont think i understand enough about packages & libs etc yet
racket -l my-app/server
<— so i assume this means it will run the “main” file of the locally installed “my-app/server” package ??
that will run the my-app/server.rkt
file
from the local dir ?
chrismatheson:webserver$ ls
info.rkt main.rkt procfile
chrismatheson:webserver$ /Applications/Racket\ v7.2.0.6/bin/racket -l main
standard-module-name-resolver: collection not found
for module path: (lib "main")
collection: "main"
in collection directories:
/Users/chrismatheson/Library/Racket/snapshot/collects
/Applications/Racket v7.2.0.6/collects
... [166 additional linked and package directories]
context...:
show-collection-err
standard-module-name-resolver
module-path-index-resolve
[repeats 1 more time]
module-declared?
no, from the my-app
collection, wherever you installed it
i think the “installing it” might be my falling down point
racket my-app/server.rkt
will run in the local dir
how would i take some files in a directory and “install” them ?
it gets installed right here: https://github.com/lexi-lambda/heroku-buildpack-racket/blob/master/bin/compile#L98
okies. so i could run that locally
but then i assume any changes to source code after installing would require re-installing?
would raco link get round that ?
no it will be picked up automatically
oh ok.
oh, no
it won’t because of --copy
there
you might be interested in https://blog.racket-lang.org/2015/08/modules-packages-and-collections.html
ahhhh something else is going on i think remote: - Unpacking Racket installation
remote: -----> Setting up environment
remote: -----> Installing application package
remote: /app/tmp/buildpacks/3347da99a9f1b1d1e426719515a786a6cc7be978d583fe1e8878145f42195b452af09a6c2f5a58f44a6caa56fe7f3278150d6cfe9980588f2b10a5885ac2a315/bin/compile: line 98: raco: command not found
remote: /app/tmp/buildpacks/3347da99a9f1b1d1e426719515a786a6cc7be978d583fe1e8878145f42195b452af09a6c2f5a58f44a6caa56fe7f3278150d6cfe9980588f2b10a5885ac2a315/bin/compile: line 99: raco: command not found
remote: -----> Discovering process types
remote: Procfile declares types -> (none)
remote:
yes that seems bad
raco not found … maybe this buildpack isnt correct anymore :slightly_smiling_face:
i might go the “build exe & ship as a container ” route instead
Maybe @lexi.lambda knows what went wrong?
That does seem wrong. I can probably look into it later.
@chris613 I can’t reproduce that problem… what do you have set for the value of RACKET_VERSION
?
FWIW, I just deployed this old sample Heroku Racket application I have, using the instructions in the heroku-buildpack-racket README, with RACKET_VERISON
set to 7.3
, and it worked totally fine: https://github.com/lexi-lambda/racket-sample-heroku-app
(hope this isn’t too broad or vague, very new to the subject): If you have a language that isn’t sexpr based, but can implement the actual functionality fairly easily using Racket/Scheme/Lisp, would it make sense to parse the language into a tree, and then just evaluate that tree with a custom eval and/or apply? Most languages are transformed into parse-trees anyway, right? So if you already have experience writing interpreters for various flavours of Lisp (not that I really do, but) does it make sense to just implement the language in Lisp, and then parse the source code/text into a form traversable by Lisp?
Again, apologies if that was a little broad/vague. Before taking advantage of Racket’s DSL-creation facilities, I’d like to try and get a feel for doing it manually, and the general process.
I was toying around with a mock assembly language like this: #lang racket
(define (LDA val flags mem regs k)
(let ([flags (if (zero? val)
(dict-set flags 'z #t)
(dict-set flags 'z #f))]
[regs (dict-set regs 'a val)])
(k flags mem regs)))
(define init.flags (hash 'z #f))
(define init.mem (make-vector 10 0))
(define init.regs (hash 'a 0))
(LDA #x2A init.flags init.mem init.regs (λ (flags mem regs) regs))
Feels like this could be modelled fairly easily like this using continuations and opcode functions that return the new state of the registers, flags, and memory. Therefore, as long as I could parse something like this: LDA #$2A
...
into Scheme code, that could work alright. Eval/expand would just take in opcodes, and transform them into λs with the extra arguments. Just felt I should give some context as to why this came to mind. Thanks :slightly_smiling_face:
> Most languages are transformed into parse-trees anyway, right? So if you already have experience writing interpreters for various flavours of Lisp (not that I really do, but) does it make sense to just implement the language in Lisp, and then parse the source code/text into a form Lisp traversable by Lisp? Yup, it’s a great approach! That’s pretty much how racket’s #lang
mechanism works. Each language has a reader, which turns the textual source code into an s-expression-like object (technically a “syntax object”), and then the language relies on the racket macro expander to do compile-time transformations of that syntax object into regular racket code, which is then run just like any other racket code.
racket #lang
implementations often have very little parsing logic and rarely define their own AST
they just reuse racket’s syntax objects and macro system instead
You certainly aren’t required to do things that way. It just tends to work out nicely.
Awesome! I’d read about the reader/expander in Beautiful Racket, but I found it hard to really grasp which part was doing what and how it all tied together. It makes a lot more sense now. Thanks for helping me match those concepts up in my head, I think I’ll be able to get much more out of it now :slightly_smiling_face:
Happy to help :simple_smile: and let us know how your toy assembly language project goes! It sounds very interesting
I certainly will! Thanks again.