From: Xah Lee
Subject: Re: Partition for Emacs Lisp
Date: 
Message-ID: <631809cb-3385-4429-9d65-ef504de6d68f@l12g2000yqo.googlegroups.com>
On Jun 28, 6:26 am, Marc Tfardy <····@cyk.cyk> wrote:
> Hi!
>
> I looking for a ELISP function that do the job like Partition in
> Mathematica. The simplest case:
>
> (partition '(a b c d e f) 2)
>
> should return:
> ((a b) (c d) (e f))
>
> Is there something ready out from the box?
>
> In more sophisticated cases one can define overlap with offset and much
> more interesting things - look at:http://documents.wolfram.com/mathematica/functions/Partition

there's no such function. You have to write it yourself.

my experiences with lisps from Mathematica is that, most basic list
processing functions in Mathematica does not exist in lisp, and in
general, there's no coherent libraries to use either. Everyone just
write it from scratch. (it's not easy to write them either, due to the
cons business)

things like Partition, Flatten, Part, Level, etc gets asked every
maybe 3 months for example in comp.lang.lisp over the past decade, and
the answers are always wild.

might be of interest:

• Xah Lee's Computing Experience Bio
  http://xahlee.org/PageTwo_dir/Personal_dir/xah_comp_exp.html

• Fundamental Problems of Lisp
  http://xahlee.org/UnixResource_dir/writ/lisp_problems.html

the first one is some of my experience from Mathematica to lisp. The
second one is about the cons business, and the shock that lisp doesn't
do list procesing well.

  Xah
∑ http://xahlee.org/

☄

From: Vassil Nikolov
Subject: Re: Partition for Emacs Lisp
Date: 
Message-ID: <snztz1zkgtk.fsf@luna.vassil.nikolov.name>
> On Jun 28, 6:26 am, Marc Tfardy <····@cyk.cyk> wrote:
>> ...
>> (partition '(a b c d e f) 2)
>> 
>> should return:
>> ((a b) (c d) (e f))
>> 
>> Is there something ready out from the box?

  (Define "out from the box"...)

    (when (and (fboundp 'featurep) (featurep 'emacs))  ;seen in comp.lang.lisp
      (require 'cl))

    (defun partition (l n)  ;"demo" grade, cursorily tested
      "Return a list of L's consecutive sublists of length N."
      (assert (zerop (mod (length l) n)))
      (loop for l on l by #'(lambda (l) (nthcdr n l)) collect (subseq l 0 n)))
  
    (partition '(a b c d e f) 2)
    => ((a b) (c d) (e f))

  ---Vassil.


-- 
Vassil Nikolov <········@pobox.com>

  (1) M(Gauss);
  (2) M(a) if M(b) and declared(b, M(a)),
  where M(x) := "x is a mathematician".
From: Marc Tfardy
Subject: Re: Partition for Emacs Lisp
Date: 
Message-ID: <h28ipv$pg3$1@news.onet.pl>
Xah Lee schrieb:

 > On Jun 28, 6:26 am, Marc Tfardy <····@cyk.cyk> wrote:
 >> Hi!
 >>
 >> I looking for a ELISP function that do the job like Partition in
 >> Mathematica. The simplest case:
 >>
 >> (partition '(a b c d e f) 2)
 >>
 >> should return:
 >> ((a b) (c d) (e f))
 >>
 >> Is there something ready out from the box?
 >>
 >> In more sophisticated cases one can define overlap with offset and much
 >> more interesting things - look at:http://documents.wolfram.com/mathematica/functions/Partition
 >
 > there's no such function. You have to write it yourself.
 >
 > my experiences with lisps from Mathematica is that, most basic list
 > processing functions in Mathematica does not exist in lisp, and in
 > general, there's no coherent libraries to use either.

This is unfortunately my experience too. After 10+ years with
Mathematica and after my swtich to (Emacs) Lisp I miss many of
mathematica functions and concepts. (for explanation - I used
mathematica primary in non-mathematical way, simply as all purpose
programming language.)

 > Everyone just write it from scratch. (it's not easy to write them
 > either, due to the cons business) things like Partition, Flatten,
 > Part, Level, etc gets asked every maybe 3 months for example in
 > comp.lang.lisp over the past decade, and the answers are always wild.

I wonder that no one implemented this stuff years ago in Common Lisp
(and of course in ELISP). This would be so useful!


 > might be of interest:
 >
 > • Xah Lee's Computing Experience Bio
 >   http://xahlee.org/PageTwo_dir/Personal_dir/xah_comp_exp.html
 >
 > • Fundamental Problems of Lisp
 >   http://xahlee.org/UnixResource_dir/writ/lisp_problems.html
 >
 > the first one is some of my experience from Mathematica to lisp. The
 > second one is about the cons business, and the shock that lisp doesn't
 > do list procesing well.

I flew over your articles and I must say I don't agree with your opinion
at 100%. Mathematica as language is very pretty and incredible clear,
indeed (I love this, really), but it have some serious diseases: it is
not free, it is very expensive, no compiler - not even one that generate
some special binary code independent from whole big and expensiv
mathematica as application, no real debugger (at least up to mathematica
5 - my last version), and at the beginning i was in addition slow,
sometimes very slow. By contrast Common Lisp is since years ANSI
standardized, wide variety of implementation, compiler and iterpreter
available - free and commercial, CL can generate very fast code and...
the language is still very, very consistent and pretty - simple and
powerful. I love Lisp, too.

regards
Marc
From: TomSW
Subject: Re: Partition for Emacs Lisp
Date: 
Message-ID: <6e5e0d4c-0a47-4805-bc69-111fc0d1f20f@c36g2000yqn.googlegroups.com>
On Jun 28, 10:11 pm, Marc Tfardy <····@cyk.cyk> wrote:

> This is unfortunately my experience too. After 10+ years with
> Mathematica and after my swtich to (Emacs) Lisp I miss many of
> mathematica functions and concepts. (for explanation - I used
> mathematica primary in non-mathematical way, simply as all purpose
> programming language.)
>
>  > Everyone just write it from scratch. (it's not easy to write them
>  > either, due to the cons business) things like Partition, Flatten,
>  > Part, Level, etc gets asked every maybe 3 months for example in
>  > comp.lang.lisp over the past decade, and the answers are always wild.

After learning a bit of Haskell I was surprised that CL doesn't have
functions like dropWhile, takeWhile etc. So naturally, I implemented
them asap (curiously, the existence of cons proved no hindrance) - and
then didn't really use them much.

Lisp's macros can be an reason for using a more imperative style (and
a lot of elisp code favours the imperative style for performance
reasons). For example, if you want to consume the partitions of your
list immediately, you could make a do-groups macro:

(do-groups ((a b c) list)
  (foo (+ a b) c))

regards
Tom SW
From: Tobias C. Rittweiler
Subject: Re: Partition for Emacs Lisp
Date: 
Message-ID: <874ou09gmm.fsf@freebits.de>
TomSW <...> writes:

> After learning a bit of Haskell I was surprised that CL doesn't have
> functions like dropWhile, takeWhile etc. So naturally, I implemented
> them asap (curiously, the existence of cons proved no hindrance) - and
> then didn't really use them much.

Well, dropWhile is there---under disguise: MEMBER-IF-NOT. :-)

  -T.
From: TomSW
Subject: Re: Partition for Emacs Lisp
Date: 
Message-ID: <9cbac72f-5d25-4e48-8e9b-7dcc2f2b2798@y9g2000yqg.googlegroups.com>
On Jun 28, 11:45 pm, "Tobias C. Rittweiler" <····@freebits.de.invalid>
wrote:

> Well, dropWhile is there---under disguise: MEMBER-IF-NOT. :-)

True.

"take" would be like a reversed version of member. Depending on the
implementation one could probably return the remaining sublist as the
second value at no extra cost.
eg

(rmember 'x '(z y x w v u t))

->

(z y z)
(w v u y)

Tom SW
From: Vassil Nikolov
Subject: Re: Partition for Emacs Lisp
Date: 
Message-ID: <snzocs7kfu5.fsf@luna.vassil.nikolov.name>
On Sun, 28 Jun 2009 15:05:39 -0700 (PDT), TomSW <·············@gmail.com> said:
> ...
> (rmember 'x '(z y x w v u t))

-> 

> (z y z)
> (w v u y)

  As in

    ((lambda (x l)
       (let ((r (rest (member x l))))
         (values (ldiff l r) r)))
     'x '(z y x w v u t))
    => (Z Y X)
       (W V U T)

  I presume?

  ---Vassil.


-- 
Vassil Nikolov <········@pobox.com>

  (1) M(Gauss);
  (2) M(a) if M(b) and declared(b, M(a)),
  where M(x) := "x is a mathematician".
From: TomSW
Subject: Re: Partition for Emacs Lisp
Date: 
Message-ID: <21c63971-80b7-4f80-8740-a78ae24a8a3b@x5g2000yqk.googlegroups.com>
On Jun 29, 3:07 am, Vassil Nikolov <········@pobox.com> wrote:
> On Sun, 28 Jun 2009 15:05:39 -0700 (PDT), TomSW <·············@gmail.com> said:
>
> > ...
> > (rmember 'x '(z y x w v u t))
>
> ->
>
> > (z y z)
> > (w v u y)
>
>   As in
>
>     ((lambda (x l)
>        (let ((r (rest (member x l))))
>          (values (ldiff l r) r)))
>      'x '(z y x w v u t))
>     => (Z Y X)
>        (W V U T)
>
>   I presume?

In fact I had thought that collecting both parts at the same time
would be more efficient, ie, something like

(defun rmember (item list)
  (labels ((aux (sublist &optional acc)
             (when sublist
               (let ((first (car sublist)))
                 (if (eq first item)
                     (values (nreverse acc)
                             sublist)
                     ;;
                     (aux (cdr sublist) (cons first acc)))))))
    (aux list nil)))

- but the performance appears very similar, and the ldiff version is
much easier to graft onto the standard member{-if,-if-not,} functions.

Regards,
Tom SW
From: Vassil Nikolov
Subject: Re: Partition for Emacs Lisp
Date: 
Message-ID: <snz63efjnjx.fsf@luna.vassil.nikolov.name>
On Mon, 29 Jun 2009 00:58:59 -0700 (PDT), TomSW <·············@gmail.com> said:
> In fact I had thought that collecting both parts at the same time
> would be more efficient

  It may be only when the element does occur in the list _and_ the
  first part is long.  I don't know if this is worth the more
  complicated implementation.

  ---Vassil.


-- 
Vassil Nikolov <········@pobox.com>

  (1) M(Gauss);
  (2) M(a) if M(b) and declared(b, M(a)),
  where M(x) := "x is a mathematician".
From: DanL
Subject: Re: Partition for Emacs Lisp
Date: 
Message-ID: <5031f6f3-147f-4a74-8157-2c83854518f4@g19g2000yql.googlegroups.com>
> After learning a bit of Haskell I was surprised that CL doesn't have
> functions like dropWhile, takeWhile etc. So naturally, I implemented
> them asap (curiously, the existence of cons proved no hindrance) - and
> then didn't really use them much.

Using series (not CL, but in CLTL2), until-if provides takeWhile's
functionality:

DHL> (until-if #'plusp #z(-1 -2 3 4 -5 6))
#Z(-1 -2)

I couldn't find a counterpart for dropWhile, but it could be
implemented (naively) like this:

(defun take-while (predicate series)
       (declare (optimizable-series-function))
       (subseries series 0
                  (collect-length (until-if (complement predicate)
                                           series))))

Or maybe:

(defun take-while (predicate series)
  (declare (optimizable-series-function)
           (off-line-port series))
  (producing (out) ((in series)
                    element)
     (loop
         (tagbody
            (setq element (next-in in (terminate-producing)))
            (unless (funcall predicate element)
              (terminate-producing))
            (next-out out element)))))

DHL> (take-while #'minusp #z(-1 -2 3 4 -5 6))
#Z(-1 -2)

Regards,

dhl


Disclaimer: I am by no means a series expert, so any tips, especially
concerning efficiency, are appreciated.