On Wed, Mar 10, 2021 at 09:44:15AM -0500, Matthias Felleisen wrote:
> 
> Hi, are you aware of rash?  Different goals but perhaps a merger of your 
> package with rash would give us a heck of a new shell :-) 

Hey, I took a look at rash, but racket (with fluent) turned out to be better 
suited to my needs. I definitely find myself turning to racket more often now 
for tasks I would have normally done with bash (which was the whole point). 
Racket startup time is quite a bit slower, but I got over it. Not sure if I'd 
take on the bold task of releasing a new shell though.

> 
> 
> 
> > On Mar 9, 2021, at 10:20 AM, Roger Keays <[email protected]> wrote:
> > 
> > Hi all,
> > 
> > I recently publish a new package called *fluent* which adds some syntax 
> > enhancements to Racket. Links and README below. Let me know what you 
> > think...
> > 
> > Roger
> > 
> > https://pkgs.racket-lang.org/package/fluent
> > https://github.com/rogerkeays/racket-fluent/
> > 
> > # fluent
> > 
> > UNIX style pipes and a lambda shorthand syntax to make your Racket code 
> > more readable.
> > 
> > ## ? Unpopular So LISP Is Why
> > 
> > Let's be honest. LISP missed a huge opportunity to change the world by 
> > telling developers they have to think backwards. Meanwhile, UNIX became 
> > successful largely because it allows you to compose programs sequentially 
> > using pipes. Compare the difference (the LISP example is actually racket):
> > 
> >    UNIX: cat data.txt | grep "active" | cut -f 4 | uniq | sort
> >    LISP: (sort (remove-duplicates (map (λ (line) (list-ref (string-split 
> > line) 4)) ((filter (λ (line) (string-contains? line "active")) (file->lines 
> > "data.txt"))))))
> > 
> > Using *fluent*, the same racket code can be written according to the UNIX 
> > philosophy:
> > 
> >    ("data.txt" > file->lines >> filter (line : line > string-contains? 
> > "active") >> map (line : line > string-split > list-ref 4) > 
> > remove-duplicates > sort)
> > 
> > You can use unicode → instead of > if you prefer. It is more distinctive 
> > and a bit easier on the eyes:
> > 
> >    ("data.txt" → file->lines →→ filter (line : line → string-contains? 
> > "active") →→ map (line : line → string-split → list-ref 4) → 
> > remove-duplicates → sort)
> > 
> > ## Function Composition
> > 
> > Using the function composition operator (> or →), *fluent* inserts the left 
> > hand side as the first parameter to the procedure on the right hand side. 
> > Use >> (or →→) to add the left hand side as the last parameter to the 
> > procedure.
> > 
> >    (data > procedure params)     becomes    (procedure data params)
> >    (data >> procedure params)    becomes    (procedure params data)
> > 
> > This operation can be chained or nested as demonstrated in the examples.
> > 
> > ## Lambda Shorthand
> > 
> > The : operator allows you to easily write a lambda function with one 
> > expression. Parameters go on the left, the expression on the right, no 
> > parentheses required. For example:
> > 
> >> ((x : + x 1) 1)
> >    2
> >> ((x y : + x y) 1 2)
> >    3
> >> (map (x : string-upcase x) '("a" "b" "c"))
> >    '("A" "B" "C")
> > 
> > ## Math Procedures
> > 
> > Since this library uses > for function composition, the built in 
> > greater-than procedure is renamed to `gt?`. Note, this could break existing 
> > code if you are already using the > procedure. Other math procedures are 
> > also renamed for consistency, and because the text versions read more 
> > naturally when using function composition.
> > 
> >> gt?
> >    < lt?
> >> = gte?
> >    <= lte?
> >    + add
> >    - subtract
> >    * multiply
> >    / divide
> > 
> > ## Convenience Procedures
> > 
> > *fluent* works best when the data (input) parameter comes first. Most 
> > racket functions do this out of the box, but many functions which take a 
> > procedure as a parameter put the data last. That's fine, because you can 
> > just use >>. Alternatively you can wrap and rename the procedure, which is 
> > what we've done for these functions:
> > 
> >    original   data-first version
> >    -----------------------------
> >    for-each   iterate
> > 
> > example:
> > 
> >> ('(1 2 3) → iterate (x : displayln x))
> >    1
> >    2
> >    3
> > 
> > ## Comparison to Clojure's Threading Macro
> > 
> > Clojure's threading macro is a prefix operator, which means it is less 
> > readable when nested and requires more parentheses. You could say that the 
> > *fluent* infix operator acts as one parenthesis. Compare:
> > 
> > CLOJURE (prefix):
> > 
> >    (-> (list (-> (-> id3 (hash-ref 'genre "unknown")) normalise-field)
> >              (-> (-> id3 (hash-ref 'track "0")) normalise-field)
> >              (-> (-> id3 (hash-ref 'artist "unknown")) normalise-field)
> >              (-> (-> id3 (hash-ref 'title "unknown")) normalise-field)) 
> > (string-join "."))
> > 
> > FLUENT (infix):
> > 
> >    (list (id3 → hash-ref 'genre "unknown" → normalise-field)
> >          (id3 → hash-ref 'track "0" → normalise-field)
> >          (id3 → hash-ref 'artist "unknown" → normalise-field)
> >          (id3 → hash-ref 'title "unknown" → normalise-field)) → string-join 
> > ".")
> > 
> > Fluent's infix approach also makes it easier to combine thread-first (→) 
> > with thread-last (→→).
> > 
> > ## How to enter → with your keyboard
> > 
> > → is Unicode character 2192. On linux you can enter this using 
> > `shift-ctrl-u 2192 enter`. Naturally, if you want to use this character, 
> > you should map it to some unused key on your keyboard. This can be done 
> > with xmodmap:
> > 
> >    # use xev to get the keycode
> >    $ xev
> > 
> >    # check the current mapping
> >    $ xmodmap -pke
> > 
> >    # replace the mapping
> >    $ xmodmap -e "keycode 51=U2192 Ccedilla ccedilla Ccedilla braceright 
> > breve braceright"
> > 
> > Making this change permanent depends on your session manager. Search 
> > duckduckgo for details.
> > 
> > ## Installation
> > 
> > This library is available from the Racket package collection and can be 
> > installed with raco:
> > 
> >    $ raco pkg install fluent
> > 
> > All you need to do is `(require fluent)`. You can try it out in the REPL:
> > 
> >> (require fluent)
> >> ("FOO" > string-downcase)
> >    "foo"
> >> ((x y : x > add y) 1 2)
> >    3
> > 
> > -- 
> > You received this message because you are subscribed to the Google Groups 
> > "Racket Users" group.
> > To unsubscribe from this group and stop receiving emails from it, send an 
> > email to [email protected].
> > To view this discussion on the web visit 
> > https://groups.google.com/d/msgid/racket-users/sigid.1702887e81.20210309152029.GA3105%40papaya.papaya.
> 

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/sigid.070424dcf4.20210311162023.GA7111%40papaya.papaya.

Reply via email to