Posts tagged dev


Comparing objects in Racket

:: dev, lisp, tutorial

By: Maciej Barć

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
(define integer%
  (class* object% (equal<%>)
    (super-new)

    (init-field [value 0])

    (define/public (equal-to? other-object recur)
      (= value (get-field value other-object)))

    (define/public (equal-hash-code-of hash-code)
      (hash-code value))

    (define/public (equal-secondary-hash-code-of hash-code)
      (hash-code value))))

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).

1
2
(new integer%)
;;  => (object:integer% ...)

But if we compare two fresh integer% objects they will be equal.

1
2
(equal? (new integer%) (new integer%))
;;  => #true

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:

1
2
3
4
5
6
7
8
(define integer%
  (class object%

    (super-new)

    (inspect #false)

    (init-field [value 0])))

If we create a new integer% object we can see it’s field values.

1
2
(new integer%)
;;  => (object:integer% 0)

And if we compare two fresh integer% objects they will be equal.

1
2
(equal? (new integer%) (new integer%))
;;  => #true

Mkdocs with Scribble

:: dev, lisp

By: Maciej Barć

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

  1. Create docs directory and mkdocs.yml config file in current directory, along with a dummy index.md file in docs folder.

    1
    mkdocs new .
    
  2. Edit the name of the project.

    Replace Racket-Project with your project name.

    1
    2
    ---
    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.

1
scribble --markdown --dest ./docs --dest-name index.md Racket-Project.scrbl

Building Markdown

Compile HTML documentation from the markdown source.

1
mkdocs build

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.

1
mkdocs serve

Caveats

Some scribble functions do not look good or work correctly for markdown-to-HTML compilation by MkDocs.

  • table-of-contents - looks like a source block

  • index-section - letter links do not work

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

Portage CI

:: dev, gentoo, linux

By: Maciej Barć

Potential benefits

Running tests

  • test BEFORE (src_test) and AFTER (pkg_postinst) installation
  • test if and how services break if they are not reloaded
  • test buildsystem configuration
  • sandbox enforces strict and consistent build rules
  • benchmarking with different compilation flags and libraries versions/releases

Configuration matrix

We can test across Cartesian product of different configuration settings, like:

  • USE flags
  • MAKEOPTS
  • CFLAGS, CXXFLAGS, CPPFLAGS, LDFAGS, RUSTFLAGS, etc.
  • arches (cross-compilation or run in qemu)
  • static linking
  • supported releases & versions of libraries (eg. glibc & musl)

Also, we could create diffs of installed files across different merges.

Reproducibility

  • mini overlay with ::gentoo or any other (eg. company's own) as master
  • record VCS (eg. git) hash of the dependent overlays

Binaries

  • grab dependencies from binhosts
  • distribute built binaries (maybe upload to a company's own artifacts server)
  • make AppImages

Getting there

How do we run this?

Do we want to write a proper tool, which we probably do or do we just run Portage + shells scripts?

Do we want to run under root, user, in eprefix, maybe all in docker?

Configuration files

The .portci directory contains the configuration.

Bug 799626

Link: bugs.gentoo.org/799626

Instead of using Ansible, Python, Yaml or Scheme we might use something similar to this for simple configuration, or if gets merged to upstream Portage the better.

Worth mentioning is the idea from Michał Górny who proposes to configure portage with toml files, like the example given in the bug report.

1
2
3
4
5
6
7
8
[package.unmask]
~virtual/libcrypt-2

[package.use.mask]
sys-libs/libxcrypt -system -split-usr

[package.use.force]
sys-libs/glibc -crypt

Also, package.x + Toml == a match made in heaven, it looks very nice!

Awesome Racket language features

:: dev, lisp

By: Maciej Barć

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:

1
2
3
4
5
6
#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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#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:

1
2
3
4
#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).

How to read this blog

:: dev, rss

By: Maciej Barć

Git

Because contents of this blog are stored in a git repository you can just

1
git clone --verbose --recursive https://gitlab.com/xgqt/blog

then, read the "raw" ORG files in 'posts' directory or make the HTML version executing the 'dev.sh' script (remember that you will need GNU Emacs to render the posts into HTML files).

Then, you can just git pull to read the news whenever you wish, maybe do it with cron or a script that will pull many repos at once, for example with this script.

RSS

Org-Static-Blog creates a RSS Feed file rss.xml, so to subscribe add the link https://xgqt.gitlab.io/blog/rss.xml to your favorite RSS reader.

You can also subscribe to the GitLab repository Atom feed.