Skip to content

Instantly share code, notes, and snippets.

@samdphillips
Last active October 29, 2021 14:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samdphillips/9254e25bf620ef449e212402572b959c to your computer and use it in GitHub Desktop.
Save samdphillips/9254e25bf620ef449e212402572b959c to your computer and use it in GitHub Desktop.
Kicking the tires of the Rhombus prototype

Kicking the tires of Rhombus

NOTE The Rhombus proposal is not stable. This example should be considered a point in time example. I may or may not update this to reflect newer versions of the proposal.

2021/08/04

This is a translation of a kind of scraping script I've written in Racket.

Some notes:

  • I'm avoiding making new syntax, some things (with-handlers*, with-disposable) could look nicer with special syntax. I'm not quite up to speed on the macro system, and I wanted to get something working.
  • shim.rkt avoids the problem where requiring racket/base will shadow the rhombus names and then Bad Things(TM) start happening. Like none of the infix operators work and syntax like if and define get shadowed.
  • Racket identifiers are not the same as Rhombus identifiers so a lot has to be renamed.

2021/08/05

  • Based on update to the implementation changed:
    • Name changes:
      • value -> val
      • define -> def
      • function -> fun
      • require -> import
    • Imports places names into a namespace object so now imported names are dotted.
    • Made a shim like module for each import from Racket code.
    • Wrote a mostly automatic renaming function to use with filtered-out from the shim modules.
#lang racket/base
(require (for-syntax racket/base
"rhombus-names.rkt")
disposable
racket/provide)
(provide
(filtered-out
(rhombus-rename)
(all-from-out disposable)))
#lang racket/base
(require (for-syntax racket/base
"rhombus-names.rkt")
net/http-easy
racket/provide)
(provide
(filtered-out
(rhombus-rename)
(all-from-out net/http-easy)))
#lang racket/base
(require (for-syntax racket/base
"rhombus-names.rkt")
keyring
racket/provide)
(provide
(filtered-out
(rhombus-rename)
(all-from-out keyring)))
#lang rhombus
import:
d = "disposable.rkt"
"http.rkt"
"keyring.rkt"
rkt = "racket.rkt"
"url.rkt"
val jobs_url:
url.string_to_url("https://my-webservice.com")
fun keyring_auth(service_user_lookup, auth_proc):
fun(a_url, headers, query):
val (service_name, user_name): service_user_lookup(a_url, headers, query)
val password: keyring.get_password(service_name, user_name)
auth_proc(user_name, password)(a_url, headers, query)
val service_auth:
keyring_auth(fun(u, h, q): values("splunk", "my-username"),
http.basic_auth)
val http_request:
rkt.make_keyword_procedure(
// XXX: in a general case use a rest-arg but there is only one positional
// argument we care about here.
fun(kws, kwargs, uri):
val max_tries: 10
val pos_args: rkt.list(http.current_session(), uri)
fun request_retry(tries_left):
val should_retry:
if tries_left == 0:
| fun(exn): #false
| rkt.is_exn_fail
rkt.proc_with_handlers(
should_retry,
fun(e): request_retry(tries_left - 1),
fun(): rkt.keyword_apply(http.session_request, kws, kwargs, pos_args))
d.disposable(
fun(): request_retry(max_tries),
http.response_close))
keyring.default_keyring(
keyring.make_keyring_from_string("keychain://"))
val job_doc:
d.call_with_disposable(
http_request(jobs_url,
'auth': service_auth),
http.response_json)
#lang racket/base
(require (for-syntax racket/base
"rhombus-names.rkt")
racket/provide)
(provide
proc_with_handlers
(filtered-out
(rhombus-rename)
(combine-out
exn:fail?
list
keyword-apply
make-keyword-procedure)))
;; one case handling exception handling
(define (proc_with_handlers exn? exn-handle body)
(with-handlers* ([exn? exn-handle])
(body)))
#lang racket/base
;; My completely unofficial rules for renaming Racket names to Rhombus
(provide rhombus-rename)
(define ((rhombus-rename [override null]) name)
(define (rename name)
(cond
[(assoc name override)
=> (lambda (p) (cdr p))]
[(regexp-match #px"^(.*)\\?$" name)
=> (lambda (m) (rename (string-append "is_" (cadr m))))]
[(regexp-match #px"^(.*)!$" name)
=> (lambda (m) (rename (cadr m)))]
[(regexp-match #px"->" name)
(rename (regexp-replace* #px"->" name "_to_"))]
[(regexp-match #px"/" name)
(rename (regexp-replace* #px"/" name "_with_"))]
[(regexp-match #px":" name)
(rename (regexp-replace* #px":" name "_"))]
[(regexp-match #px"-" name)
(rename (regexp-replace* #px"-" name "_"))]
[else name]))
(rename name))
#lang racket/base
(require (for-syntax racket/base
"rhombus-names.rkt")
net/url
racket/provide)
(provide
(filtered-out
(rhombus-rename
'(["file://->path" . "file_url_to_path"]))
(all-from-out net/url)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment