From: Liliana Marie Prikler <liliana.prikler@gmail.com>
To: Rostislav Svoboda <rostislav.svoboda@gmail.com>
Cc: 66562@debbugs.gnu.org
Subject: [bug#66562] [PATCH v3] gnu: emacs-haskell-snippets: Use correct directory for snippets.
Date: Tue, 17 Oct 2023 19:29:20 +0200 [thread overview]
Message-ID: <70adcf74508ed4c7c6159d7b904e4ceca5e7a75e.camel@gmail.com> (raw)
In-Reply-To: <CAEtmmezz5uJxBSNeWoPpRec17h1BxP3TGdnWeTi=mgbMpWdgKA@mail.gmail.com>
Hi, Rostislav
Am Dienstag, dem 17.10.2023 um 18:49 +0200 schrieb Rostislav Svoboda:
> […]
> > Plus you're requiring let* instead of let.
>
> Having both variants is a language deficiency, in my opinion. Only
> let should exist, functioning as let* does. This should extend to
> lambda*, define*, etc.
Only let should exist, functioning as let does. let* is sugar on top.
(Not serious about this, there are reasons to have let*, but there are
also reasons it's not the default behaviour.)
> > Btw. don't
> > ((compose
> > (lambda (src dst) (mkdir-p src) (copy-recursively dst src))
> > (lambda (dir store) (values dir (string-append store "/" dir)))
> > "snippets/haskell-mode" (elpa-directory (assoc-ref outputs
> > "out")))
> > to avoid gratuitous repetition.
>
> On the one hand, we face gratuitous repetition; on the other, a
> snippet like this better expresses compositional transformation
> between inputs and outputs, which I find to be a way more important
> that avoiding gratuitous repetition (pun intended). And as a side
> effect it also simplifies debugging:
>
> ((compose
> ;; (lambda (a b) (format #t "[DBG] 3. a: ~a; b: ~a\n" a b) (values
> a b))
> (lambda (src dst) (mkdir-p src) (copy-recursively src dst))
> ;; (lambda (a b) (format #t "[DBG] 2. a: ~a; b: ~a\n" a b) (values
> a b))
> (lambda (dir store) (values dir (string-append store "/" dir)))
> ;; (lambda (a b) (format #t "[DBG] 1. a: ~a; b: ~a\n" a b) (values
> a b))
> )
> "snippets/haskell-mode" (elpa-directory (assoc-ref outputs "out")))
If you need to warp your head around through three debug statements,
I'm not convinced you're improving the overall code all that much.
> And if you insist, the gratuitous repetition could, in theory, be
> avoided:
>
> ((compose
> copy-recursively
> (juxt mkdir-p (partial string-append (elpa-directory (assoc-ref
> outputs "out")) "/")))
> "snippets/haskell-mode")
>
> Only if partial and juxt would exist... and here you go ;-)
>
> (define (partial fun . args)
> "Partial function application."
> (lambda x (apply fun (append args x))))
>
> (define (juxt . fns)
> "Naive implementation. Inspired by Clojure's juxt.
> ((juxt a b c) x) => (list (a x) (b x) (c x))"
> (lambda args
> (map (lambda (fn) (apply fn args)) fns)))
>
> Here yet another pattern appears, the map-reduce. Also the juxt
> function just screams for "let's call the mkdir-p and (partial
> string-append ...) in parallel".
You can do all that, but it does go against the KISS principle :)
> > Btw. don't (compose ...)
>
> Quite the contrary, I think we should do more of (compose ...),
> however functional composition is hard-to-impossible if e.g.:
>
> - essential higher order functions like juxt and partial are not
> available.
We have partial. We call it cut. It's part of SRFI-26.
It even simplifies the definition of juxt:
(lambda args (map (cut apply <> args) fns))
Anyhow, we quite often don't use it because we'd have to add it to
#:modules and the benefit over raw lambdas is often negligible.
> - mkdir-p and copy-recursively from the (guix build utils) aren't
> monadic and mkdir-p returns #t instead of a path-string and
> copy-recursively returns:
>
> scheme@(guile-user)> ,use (guix build utils)
> scheme@(guile-user)> (copy-recursively "/tmp/f1.txt" "/tmp/f2.txt")
> `/tmp/foo.txt' -> `/tmp/fox.txt'
>
> eeeh... what exactly is the return value of copy-recursively? Hmm.
It returns *unspecified*. Yes, most of this stuff is indeed not
monadic. Scheme is not purely functional, so side effects are allowed
:)
> - copy-recursively, although naturally a reducer (i.e. a member of
> the fold-family, think of 'a list of things goes into a container')
> is not implemented as such. Hmm, disappointing... although a <...>-
> fold is used in its implementation. Double hmm.
There is a cost to constructing the return value of a fold. I
personally can do without creating lists that no one will end up
inspecting anyway.
> - in general, the built-in compose function can't be called with zero
> arguments. For that purpose I cobbled myself:
>
> (define (comp . fns)
> "Like `compose'. Can be called with zero arguments. I.e. (thunk?
> comp) => #t
> Works also for functions returning and accepting multiple values."
> (lambda args
> (if (null? fns)
> (apply values args)
> (let [(proc (car fns)) (rest (cdr fns))]
> (if (null? rest)
> (apply proc args)
> (let ((g (apply comp rest)))
> (call-with-values (lambda () (apply g args))
> proc)))))))
I'd argue that compose without procedures is quite meaningless, but
maybe I'm thinking too hard.
> And finally, in the (guix build utils) there's the install-file which
> works with single files. What about adding its recursive version:
>
> (define* (install-recursively source destination
> #:key
> (log (current-output-port))
> (follow-symlinks? #f)
> (copy-file copy-file)
> keep-mtime? keep-permissions?)
> "Recursive version of install-file."
> (mkdir-p destination)
> (copy-recursively source
> (string-append destination "/" (basename
> destination))
> #:log log
> #:follow-symlinks? follow-symlinks?
> #:copy-file copy-file
> #:keep-mtime? keep-mtime?
> #:keep-permissions? keep-permissions?))
There'd be no point in having copy-recursively then. For a more
complete build system that already takes care of all that without
having you fiddling with juxt, partial, etc., just take copy-build-
system. Not that it's needed here, mind you.
Cheers
next prev parent reply other threads:[~2023-10-17 17:29 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-15 15:17 [bug#66562] [PATCH] gnu: emacs-haskell-snippets: Fix haskell-snippets-dir value Rostislav Svoboda
2023-10-15 16:01 ` Liliana Marie Prikler
2023-10-15 17:21 ` Rostislav Svoboda
2023-10-15 18:25 ` [bug#66562] [PATCH v3] gnu: emacs-haskell-snippets: Use correct directory for snippets Liliana Marie Prikler
2023-10-16 10:57 ` Rostislav Svoboda
2023-10-16 16:57 ` Liliana Marie Prikler
2023-10-17 16:49 ` Rostislav Svoboda
2023-10-17 17:29 ` Liliana Marie Prikler [this message]
2023-10-18 8:54 ` Rostislav Svoboda
2023-10-18 21:58 ` Liliana Marie Prikler
2023-10-23 7:58 ` bug#66562: " Liliana Marie Prikler
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=70adcf74508ed4c7c6159d7b904e4ceca5e7a75e.camel@gmail.com \
--to=liliana.prikler@gmail.com \
--cc=66562@debbugs.gnu.org \
--cc=rostislav.svoboda@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/guix.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.