Skip to content

Latest commit

 

History

History
191 lines (153 loc) · 5.12 KB

DEV.org

File metadata and controls

191 lines (153 loc) · 5.12 KB

TILDA -*- mode: org; fill-column: 82 -*-

Tilda

Either netlify or publish docs on github.io

  • scrbl -> html
  • deploy to github pages or netlify
  • use fullmeta.me subdomain

setup CI to auto-test and deploy docs

travis?

Publish tilda as Racket package

Document tilda.rkt

Scribble tilda.rkt

[2019-06-26 Wed]

README.org for tilda.rkt

  • State “DONE” from “TODO” [2019-09-08 Sun 13:48] [2019-06-26 Wed]

default to thread first unless ~ is present

  • State “DONE” from “TODO” [2019-08-14 Wed 09:43]

Imo this makes for a reasonable default and cleaner code:

(~> val
    (foo)
    (bar)
    (last a b ~)
    (another)
    (finally c ~))

change #:as semantics

  • State “DONE” from “TODO” [2019-08-14 Wed 09:43]

#:as v binds ~ to v and suspends threading for the next clause, restarts threading after it. This one little trick makes if, cond, let etc possible, doesn’t break threading and lets us both restart and bind intermediate threaded values.

;; if, cond, let and friends
(~> val
    (foo)
    #:as a
    (let (let-clause
          let-clause)
      new-value-to-thread)
    (bar a ~)
    (another)
    #:as b
    (if (test b) (then a b) (else 42))
    (finally a b ~))

;; forget and restart
(~> val
    (foo) #:as _
    (bar)
    (last a b ~))

move tilda out of prelude

  • State “DONE” from “STARTED” [2019-06-25 Tue 10:23]
    tilda now resides in its own single collection package
  • State “STARTED” from “TODO” [2019-06-25 Tue 09:57]

allow table syntax

  • State “CANCELLED” from “TODO” [2019-06-25 Tue 06:38]
    Now that I think about it, the feature doesn’t make any sense. When threading all it takes to mimic the same semantics is to add an extra key lookup step. With the two : and :: procedures that I now have both table and key could be computed.

~:key ~.key ~::key ~..key

t:~ t.~ t::~ t..~

also undefined aware versions

~:key? ~.key? ~::key? ~..key?

t:~? t.~? t::~? t..~?

don’t forget that ~id is also possible

Consider replacing all occurrences of ~ in clauses

so we don’t have to do intermediate #:as binding e.g.

;; atm have to write this
(~> '()
    (cons 1 ~)
    (~> ~
        #:as a
        #:when list? a
        (cons 2 ~))
    (cons 3 ~))

;; but I'd rather write this
(~> '()
    (cons 1 ~)
    (~> ~
        #:when list? ~
        (cons 2 ~))
    (cons 3 ~))

We’ll have to recognize clauses like that and lift ~ value so we don’t recompute for every ~.

short circuit ~> [2/2]

  • State “DONE” from “TODO” [2019-06-25 Tue 17:57]

#:when and #:unless to take predicate and escape value

  • State “DONE” from “STARTED” [2019-06-25 Tue 16:05]
    Wow. I found use for both syntax-parameter and make-rename-transformer!
  • State “STARTED” from “TODO” [2019-06-25 Tue 15:08]

dealing with expression in the first position for these is awkward. We pretty much always want to test something (probably ~) and either escape or report an error.

Most common escape value is probably just #f. Otherwise its an expression to compute the value used as the resurt of the entire ~>. Could just as easily throw an error.

Because we can report errors here, there is no longer any need to #:guard, so we’ll drop it.

treat ~pred? to short circuit unless (pred? ~)

  • State “DONE” from “STARTED” [2019-06-25 Tue 17:56]
    seems to work
  • State “STARTED” from “TODO” [2019-06-25 Tue 16:37]

Technically #:when and #:unless suffice, but they stand out and require the 2nd argument as the value to escape with. Typically we just want to return #f (the Racket default in such cases). Hence this syntactic convenience:

(~> t
    (get ~? :foo)
    (get ~table? :bar))

;; equivalent to =>

(~> t            #:unless ? #f
    (get ~ :foo) #:unless table? #f
    (get ~ :bar))

note that ~id e.g. ~table are treated normally not as predicates to be checked therefore they serve as reading aids.