I like this a lot! Great job!

--
Jay McCarthy
Associate Professor @ CS @ UMass Lowell
http://jeapostrophe.github.io
Vincit qui se vincit.

On Tue, 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/CAJYbDakMqcK_ss6eaNsXywgRKbGRNL_CFCjezxyoKog72aQvhw%40mail.gmail.com.

Reply via email to