Posts tagged racket
Racket executables made by raco exe
are known to be quite large. One of tools that can be used to help reduce the size of produced binaries is the gzexe
program.
gzeze
is a tool that can compress a executable binary. It can be acquired by installing gzip
on most Linux distributions (included in the app-arch/gzip
package on Gentoo).
Creating a hello-world executable with Racket
Write following contents to hello-world.rkt
file:
To make a binary run:
|
raco exe --orig-exe -v -o hello-world hello-world.rkt
|
The file hello-world
will be produced.
This is what file hello-world
says about it:
|
hello-world: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV),
dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2,
for GNU/Linux 3.2.0, stripped
|
This “small” executable weights 46 MB!
In comparison busybox
weights around 2 MB.
Compressing with gzexe
Keep in mind that gzeze
will overwrite the compressed file and create a backup with appended "~".
And this gives us only 8,5 MB. Nice!
In comparison bazel
, which is a single-binary build system written in JAVA, executable takes 33 MB on my Gentoo machine. I tried compressing it with gzexe
and it reduces it only by 10%, to around 29 MB.
gzexe
is not a silver bullet but with Racket exes it works very nicely.
Constructing debugging syntax
I wanted to echo parameter values when I set them in my blog’s frog.rkt
config file.
Nothing simpler in Racket!
First I create this macro for echoing a single parameter value when it is set:
1
2
3
4
5
6
7
8
9
10
11
12 |
(define-syntax-rule (verbose-set-parameter parameter-id parameter-value)
(begin
;; Set the parameter.
(parameter-id parameter-value)
;; Then call the parameter and print is's value.
;; The "'parameter-id" is special syntax
;; for turning a "parameter-id" identifier to a symbol.
;; We can also write it like:
;; > (quote parameter-id)
;; to be less confusing.
(printf "[DEBUG] (~a ~v)\n" 'parameter-id (parameter-id))))
|
then, I create a wrapper for above macro that can take multiple parameter pairs:
|
(define-syntax-rule (verbose-set-parameters (parameter-id parameter-value) ...)
(begin
;; Unpack a chain of "(parameter-id parameter-value)" pairs
;; using the "..." syntax.
(verbose-set-parameter parameter-id parameter-value) ...))
|
Using the macro
Afterwards we can call it like so:
|
(verbose-set-parameters
(current-title "XGQT's blog")
(current-author "Maciej Barć"))
|
Notice that even the form of setting a parameter, that is (parameter-procedure "value")
, remains the same, but in reality it is just similar to how the syntax macro pattern-matches on it.
Inspecting macro expansion
In racket-mode
inside GNU Emacs we can inspect the macro expansion with racket-expand-region
. Stepping through the expansion provided this result:
|
(begin
(begin
(current-title "XGQT's blog")
(printf "[DEBUG] (~a ~v)\n" 'current-title (current-title)))
(begin
(current-author "Maciej Barć")
(printf "[DEBUG] (~a ~v)\n" 'current-author (current-author))))
|
Equality methods
By implementing a method for equality equal-to?
and two extraction methods equal-hash-code-of
and equal-secondary-hash-code-of
we can define our own object comparison rules.
For more info see Object Equality and Hashing.
Consider the following example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 |
|
If we create a new integer%
object we can notice that it is not transparent (we can not inspect values of any of it’s fields).
|
(new integer%)
;; => (object:integer% ...)
|
But if we compare two fresh integer%
objects they will be equal.
Transparent class
A transparent cvlass is a class with the inspect
expression valuye se to #false
.
From Racket documentation Creating Classes:
Just as for structure types, an inspector controls access to the class’s fields, including private fields, and also affects comparisons using equal?.
Consider the following example:
If we create a new integer%
object we can see it’s field values.
|
(new integer%)
;; => (object:integer% 0)
|
And if we compare two fresh integer%
objects they will be equal.
Intro
Instead of changing CSS style for Your Racket projects documentation, You may be interested in compiling Markdown files generated form Scribble source into HTML documentation website.
Creating MkDocs project
-
Create docs
directory and mkdocs.yml
config file in current directory, along with a dummy index.md
file in docs
folder.
-
Edit the name of the project.
Replace Racket-Project
with your project name.
|
---
site_name: Racket-Project
|
Building Scribble
Generate markdown files form scribble documentation.
Replace Racket-Project.scrbl
with path to your scribble documentation main source file.
|
scribble --markdown --dest ./docs --dest-name index.md Racket-Project.scrbl
|
Building Markdown
Compile HTML documentation from the markdown source.
HTML files should appear in the site
directory.
Running the server
Some features, like search for example are only available when running the mkdocs server.
Caveats
Some scribble functions do not look good or work correctly for markdown-to-HTML compilation by MkDocs.
Example configuration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 |
site_name: Racket-Ebuild
site_author: xgqt@riseup.net
site_description: library to ease ebuild creation
site_url: https://gitlab.com/gentoo-racket/racket-ebuild
repo_name: gentoo-racket/racket-ebuild
repo_url: https://gitlab.com/gentoo-racket/racket-ebuild
plugins:
- search
theme:
name: material
extra:
social:
- icon: fontawesome/brands/gitlab
link: https://gitlab.com/gentoo-racket/racket-ebuild
|
Also see: Fast-Racket at Racket's GitHub Wiki
Creating binaries
You can create portable binaries with Racket's raco
command! Use raco exe
and raco distribute
.
More -> https://docs.racket-lang.org/raco/exe.html
Sample games
Racket provides a executable plt-games
, when ran (from console) it opens a menu of miscellaneous games, among them: jewel, minesweeper, aces, spider, checkers. & more (20 games total).
Plots
You can plot data in 2d & 3d forms.
2D
Sample code:
|
#lang racket/base
(require racket/gui/base racket/math plot)
(plot-new-window? #true)
(plot (function sin (- pi) pi #:label "y = sin(x)"))
|
3D
Sample code:
|
#lang racket/base
(require racket/gui/base racket/math plot)
(plot-new-window? #true)
(plot3d
(surface3d (lambda (x y) (* (cos x) (sin y)))
(- pi) pi (- pi) pi)
#:title "An R × R → R function"
#:x-label "x" #:y-label "y" #:z-label "cos(x) sin(y)")
|
Browser
There's a included library to render web pages, just "(require browser)".
Sample code:
|
#lang racket
(require browser)
(open-url "https://xgqt.gitlab.io/")
|
FFI
You can use Racket's Foreign Function Interface to interact with non-Racket libraries to make use of very fast libraries written in (mainly) FORTRAN & C.
For example sci uses FFI for CBLAS & LAPACK.
Parallelism
For greater speed up with parallel execution there are futures, places and distributed places (for distributed programming).