kzccm1d4if10m2xaz1wqy3xar821pp1r-my-site-anaphoric-git.test.suzanne.soy-0.0.1

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit ff1ad651f38225c0fe9eb03d0beba69985317dd6
parent c5ef4cc0cfd557027fc343b119a8af56ee5f7667
Author: Georges Dupéron <georges.duperon@gmail.com>
Date:   Mon,  8 Aug 2016 12:15:17 +0200

Added if-let when-let and cond-let, as per Alex Knauth's suggestion. Closes issue #1.

Diffstat:
Acond-let.rkt | 18++++++++++++++++++
Aif-let.rkt | 11+++++++++++
Minfo.rkt | 2+-
Mscribblings/anaphoric.scrbl | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Awhen-let.rkt | 9+++++++++
5 files changed, 119 insertions(+), 5 deletions(-)

diff --git a/cond-let.rkt b/cond-let.rkt @@ -0,0 +1,17 @@ +#lang racket + +(provide cond-let) + +(define-syntax (cond-let stx) + (syntax-case stx (else) + [(cond-let [[identifierᵢ conditionᵢ] . bodyᵢ] ... [else . else-body]) + #'(cond [conditionᵢ => (λ (identifierᵢ) . bodyᵢ)] ... + [else . else-body])] + [(cond-let [[identifierᵢ conditionᵢ] . bodyᵢ] ...) + #'(cond [conditionᵢ => (λ (identifierᵢ) . bodyᵢ)] ...)] + + [(cond-let identifier [conditionᵢ . bodyᵢ] ... [else . else-body]) + #'(cond [conditionᵢ => (λ (identifier) . bodyᵢ)] ... + [else . else-body])] + [(cond-let [[identifierᵢ conditionᵢ] . bodyᵢ] ...) + #'(cond [conditionᵢ => (λ (identifierᵢ) . bodyᵢ)] ...)])) +\ No newline at end of file diff --git a/if-let.rkt b/if-let.rkt @@ -0,0 +1,10 @@ +#lang racket + +(provide if-let) + +(define-syntax-rule (if-let [variable condition] true-branch false-branch) + (let ([tmp condition]) + (if tmp + (let ([variable tmp]) + true-branch) + false-branch))) +\ No newline at end of file diff --git a/info.rkt b/info.rkt @@ -6,5 +6,5 @@ (define scribblings '(("scribblings/anaphoric.scrbl" ()))) (define compile-omit-paths '("test/")) (define pkg-desc "Anaphoric versions of `if`, `when` and `cond`. They bind the value of the condition expression to `it`.") -(define version "0.0") +(define version "0.1") (define pkg-authors '(|Georges Dupéron|)) diff --git a/scribblings/anaphoric.scrbl b/scribblings/anaphoric.scrbl @@ -2,11 +2,13 @@ @require[@for-label[anaphoric racket/base]] -@title{anaphoric} -@author{georges} +@title{Anaphoric conditionals} +@author+email["georges.duperon@gmail.com"]{Georges Dupéron} @defmodule[anaphoric] +@section{Overview} + This package provides anaphoric versions of @racket[if], @racket[when] and @racket[cond]. These bind the syntax parameter @racket[if] to the value produced by the @@ -45,4 +47,78 @@ appears in a sequence of else branches: 'not-executed (aif (eq? 'second 'no) 'not-executed - (displayln it)))] -\ No newline at end of file + (displayln it)))] + +This package also provides the hygienic versions +@racket[if-let], @racket[when-let] and @racket[cond-let], +for which the user needs to specify an identifier instead of +using @racket[it]. + +@section{The anaphoric conditionals @racket[aif], + @racket[awhen] and @racket[acond]} + +@defidform[it]{ + Syntax parameter which acts as a rename transformer for + the result of the condition expression, when bound by + @racket[aif], @racket[awhen] or @racket[acond]. + + Raises a syntax error when used outside of the + @racket[_true-branch] of an @racket[aif] or the body of an + @racket[awhen] or the body of a non-@racket[else] case in + @racket[acond].} + +@defform[(aif condition true-branch false-branch)]{ + Variant of @racket[if] which binds @racket[it] to the + value of @racket[condition] in @racket[true-branch]. + @racket[condition] is only evaluated once. In the + @racket[false-branch], @racket[it] is left unchanged.} + +@defform[(awhen condition body ...+)]{ + Variant of @racket[when] which binds @racket[it] to the + value of @racket[condition] in @racket[body ...+]. + @racket[condition] is only evaluated once.} + +@defform*[#:literals (else) + [(acond [conditionᵢ bodyᵢ ...+] ...) + (acond [conditionᵢ bodyᵢ ...+] ... [else body ...+])]]{ + Variant of @racket[cond] which binds @racket[it] to the + corresponding @racket[conditionᵢ] in the non-@racket[else] + cases. More precisely, in each @racket[bodyᵢ ...+], + @racket[it] is bound to the value of the corresponding + @racket[conditionᵢ]. Each @racket[conditionᵢ] is evaluated + at most once (evaluation stops at the first successful + @racket[conditionᵢ]).} + +@section{The hygienic versions @racket[if-let], + @racket[when-let] and @racket[cond-let]} + +@defform[(if-let [identifier condition] true-branch false-branch)]{ + Variant of @racket[if] which binds @racket[identifier] to + the value of @racket[condition] in @racket[true-branch]. + @racket[condition] is only evaluated once. In the + @racket[false-branch], @racket[identifier] is left unchanged.} + +@defform[(when-let [identifier condition] body ...+)]{ + Variant of @racket[when] which binds @racket[identifier] to + the value of @racket[condition] in @racket[body ...+]. + @racket[condition] is only evaluated once.} + +@defform*[#:literals (else) + [(cond-let [[identifierᵢ conditionᵢ] bodyᵢ ...+] ...) + (cond-let [[identifierᵢ conditionᵢ] bodyᵢ ...+] ... [else body ...+]) + (cond-let identifier [conditionᵢ bodyᵢ ...+] ...) + (cond-let identifier [conditionᵢ bodyᵢ ...+] ... [else body ...+])]]{ + Variant of @racket[cond] which binds each + @racket[identifierᵢ] to the corresponding + @racket[conditionᵢ] in the non-@racket[else] cases. More + precisely, in each @racket[bodyᵢ ...+], the corresponding + @racket[identifierᵢ] is bound to the value of the + corresponding @racket[conditionᵢ]. + + The last two variants are shorthands for using the same + @racket[identifier] in all cases (except the @racket[else] + case) + + Each @racket[conditionᵢ] is evaluated at most once + (evaluation stops at the first successful + @racket[conditionᵢ]).} +\ No newline at end of file diff --git a/when-let.rkt b/when-let.rkt @@ -0,0 +1,8 @@ +#lang racket + +(provide when-let) + +(define-syntax-rule (when-let [variable condition] . body) + (let ([variable condition]) + (when variable + . body))) +\ No newline at end of file