guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: (ice-9 nice-9) module update


From: Panicz Maciej Godek
Subject: Re: (ice-9 nice-9) module update
Date: Wed, 2 Sep 2015 17:29:41 +0200

(sorry that I'm sending this for the second time, but it happened to me, as frequently does, that I forgot to choose the "reply to all" option)

2015-09-02 16:48 GMT+02:00 Taylan Ulrich Bayırlı/Kammer<address@hidden>:
Hmm, I just looked a bit closer into your other email:

Panicz Maciej Godek <address@hidden> writes:

> * blends named-let with match-let and srfi-71-style let for multiple
> values, legalizing usages like
>
> (let loop ((a (b c) (values 1 (list 2 3))))
>   ...
>   (loop (values 4 (list 5 6))))
>
> (although this may not seem to be a good way of programming, I think
> that imposing artificial limitations on how the language can be used
> would be even worse)

How does that one work?  AFAIUI, 'loop' would need to be a macro,
because otherwise you're returning multiple values to a single-value
continuation (<operand> slot of a procedure-call _expression_).


I didn't manage to figure out how the reference implementation of srfi-71 does that, but I indeed implemented that as you said, i.e. as a macro.
 
I haven't seen many uses of named-let where the name was being used for
anything else than directly calling it (though I have seen some, or at
least one, in GNU Guix's code), so maybe making it a macro would not be
too bad normally, but it goes against existing practice.

It only becomes a macro in the most general case, and not in the most typical ones, so I guess that's not a big issue, but I do agree that there's something untasteful in that. (But to be quite honest, I have always been perceiving multiple values as an abuse)
 
> * allows to destructure arguments to lambda, e.g.
>
> (map (lambda ((a . b)) (+ a b)) '((1 . 2) (3 . 4) (5 . 6)))
>
> [...]
>
> * allows to use curried definitions like (ice-9 curried-definitions),
> but such that are already blended with the pattern-matching lambda
>
> (define ((f (a b)) (c))
>   (list a b c))

Do you mean it allows currying *and* destructuring?  To be absolutely
honest, I would probably go mad while trying to read code using such a
feature. :-)

Yes, it does look crazy, I agree. But I can see no other reason why it shouldn't be possible in principle

I'm not sure how often currying is used in Scheme.  Maybe it's just me;
do others use it occasionally?  I never felt like I needed such a
feature so far.  Would be a different thing is *all* procedures were
implicitly curried, but that's not the case...

Well, as I wrote in an earlier e-mail from that thread, this is just being consequent with mapping

(define (f . args) . body)

to

(define f (lambda args . body))

I have to admit that do find the generalization useful from time to time. Even the code that I just wrote for my own purpose looks like this:

(publish
 (define above? (line-relation positive?))
 (define below? (line-relation negative?))
 (define on? (line-relation zero?))
 where
 (define ((line-relation predicate) point line)
   (let (((direction . displacement) line))
     (predicate (cross direction (- point displacement)))))
 (define (cross a b)
   (- (* (real-part a) (imag-part b))
      (* (real-part b) (imag-part a))))
 )

BTW as you can see, I didn't dare to use currying and destructuring in function header at the same time. Not because that wasn't impossible, but because it wouldn't be obvious to the reader that (direction . displacement) is a representation of a line.

If it's common to use currying in specific problem domains, such as
classical mechanics (since you mention SICM in the original email
starting this discussion), then IMO such extensions to 'define'
etc. should be kept private to code-bases working on such specialized
problem domains.  They shouldn't leak out to the general-purpose parts
of the language.

Well, actually I don't think they interfere with anything.
 
Supporting destructuring (and only that) in 'lambda' doesn't sound too
bad at face value, since I can't imagine many other possible semantics
for parenthesized forms in an argument list, but it worries me a bit
because then we will probably want to make 'let' consistent with
'lambda', and then we're again at the point where we discriminate
against other possible extensions to 'let'.


Yes!
 
Therefore, in my opinion it's best to keep lambda and let pure, and just
use match-lambda, let-values, match-let, etc. where desired.  That's the
most "frictionless" way to go as I see it.


That's reasonable, and so I don't want to force anyone to the choices that I made
 
Sorry if I'm being negative in some regards.  All just my honest/blunt
opinions.

You're kidding, I think that it's absolutely great :)
We clearly have different views, and so we both disagree with some of the assumptions of the other side, but I like the rigidity of arguments used in the discussion.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]