all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Partition for Emacs Lisp
@ 2009-06-28 13:26 Marc Tfardy
  2009-06-28 17:52 ` Pascal J. Bourguignon
  2009-06-28 17:53 ` Xah Lee
  0 siblings, 2 replies; 13+ messages in thread
From: Marc Tfardy @ 2009-06-28 13:26 UTC (permalink / raw)
  To: help-gnu-emacs

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

regards
Marc



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Partition for Emacs Lisp
  2009-06-28 13:26 Partition for Emacs Lisp Marc Tfardy
@ 2009-06-28 17:52 ` Pascal J. Bourguignon
  2009-06-28 18:34   ` Marc Tfardy
                     ` (2 more replies)
  2009-06-28 17:53 ` Xah Lee
  1 sibling, 3 replies; 13+ messages in thread
From: Pascal J. Bourguignon @ 2009-06-28 17:52 UTC (permalink / raw)
  To: help-gnu-emacs

Marc Tfardy <bum@cyk.cyk> writes:

> 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))

(defun partition-list (list length)
  (loop
     while list
     collect (subseq list 0 length)
     do (setf list (nthcdr length list))))

(defun partition-vector (vector length)
  (loop
     for i = 0 then (+ i length)
     while (< i (length vector))
     collect (subseq vector i (+ i length))))
     
(defun partition (sequence length)
   (etypecase sequence
      (list   (partition-list sequence length))
      (string (partition-vector sequence length)) ; emacs lisp strings are not vectors! 
      (vector (partition-vector sequence length))))

(partition '[a b c d e f] 2)  -> ([a b] [c d] [e f])
(partition '(a b c d e f) 2)  -> ((a b) (c d) (e f))
(partition '"abcdef" 2)       -> ("ab" "cd" "ef")


> Is there something ready out from the box?

Perhaps.  But if you didn't search in the manual, it must be because
it would take more time than to write partition yourself, so I didn't
search in the manual either, and wrote it to steal you the fun of
writing it yourself.


-- 
__Pascal Bourguignon__


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Partition for Emacs Lisp
  2009-06-28 13:26 Partition for Emacs Lisp Marc Tfardy
  2009-06-28 17:52 ` Pascal J. Bourguignon
@ 2009-06-28 17:53 ` Xah Lee
  2009-06-28 20:11   ` Marc Tfardy
  2009-06-29  0:46   ` Vassil Nikolov
  1 sibling, 2 replies; 13+ messages in thread
From: Xah Lee @ 2009-06-28 17:53 UTC (permalink / raw)
  To: help-gnu-emacs

On Jun 28, 6:26 am, Marc Tfardy <b...@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/^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Partition for Emacs Lisp
  2009-06-28 17:52 ` Pascal J. Bourguignon
@ 2009-06-28 18:34   ` Marc Tfardy
  2009-06-28 20:16   ` Marc Tfardy
  2009-06-28 20:53   ` Johan Bockgård
  2 siblings, 0 replies; 13+ messages in thread
From: Marc Tfardy @ 2009-06-28 18:34 UTC (permalink / raw)
  To: help-gnu-emacs

Pascal J. Bourguignon schrieb:
 > Marc Tfardy <bum@cyk.cyk> writes:
 >
 >> 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))
 >
 > (defun partition-list (list length)
 >   (loop
 >      while list
 >      collect (subseq list 0 length)
 >      do (setf list (nthcdr length list))))
 >
 > (defun partition-vector (vector length)
 >   (loop
 >      for i = 0 then (+ i length)
 >      while (< i (length vector))
 >      collect (subseq vector i (+ i length))))
 >
 > (defun partition (sequence length)
 >    (etypecase sequence
 >       (list   (partition-list sequence length))
 >       (string (partition-vector sequence length)) ; emacs lisp strings are not vectors!
 >       (vector (partition-vector sequence length))))
 >
 > (partition '[a b c d e f] 2)  -> ([a b] [c d] [e f])
 > (partition '(a b c d e f) 2)  -> ((a b) (c d) (e f))
 > (partition '"abcdef" 2)       -> ("ab" "cd" "ef")

Thanks a lot!!


 >> Is there something ready out from the box?
 >
 > Perhaps.  But if you didn't search in the manual,

I did search in the manual and in internet but without success.


 > it must be because it would take more time than to write partition
 > yourself

Sure, but my lisp skills are not so brilliant, so after ca. one hour
searching I've capitulate and posted my question. I had already
suspected the loop as a possible solution but the loop syntax was so
harrowing that I've given up.


 > so I didn't search in the manual either, and wrote it to steal you the
 > fun of writing it yourself.

Oh my friend - it is no problem! :-) Thanks again!

regards
Marc




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Partition for Emacs Lisp
  2009-06-28 17:53 ` Xah Lee
@ 2009-06-28 20:11   ` Marc Tfardy
  2009-06-28 21:10     ` TomSW
  2009-06-29  0:46   ` Vassil Nikolov
  1 sibling, 1 reply; 13+ messages in thread
From: Marc Tfardy @ 2009-06-28 20:11 UTC (permalink / raw)
  To: help-gnu-emacs

Xah Lee schrieb:

 > On Jun 28, 6:26 am, Marc Tfardy <b...@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



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Partition for Emacs Lisp
  2009-06-28 17:52 ` Pascal J. Bourguignon
  2009-06-28 18:34   ` Marc Tfardy
@ 2009-06-28 20:16   ` Marc Tfardy
  2009-06-28 20:46     ` TomSW
  2009-06-28 20:53   ` Johan Bockgård
  2 siblings, 1 reply; 13+ messages in thread
From: Marc Tfardy @ 2009-06-28 20:16 UTC (permalink / raw)
  To: help-gnu-emacs

Pascal J. Bourguignon schrieb:
> Marc Tfardy <bum@cyk.cyk> writes:
> 
>> 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))
> 
> (defun partition-list (list length)
>   (loop
>      while list
>      collect (subseq list 0 length)
>      do (setf list (nthcdr length list))))
> 
> (defun partition-vector (vector length)
>   (loop
>      for i = 0 then (+ i length)
>      while (< i (length vector))
>      collect (subseq vector i (+ i length))))
>      
> (defun partition (sequence length)
>    (etypecase sequence
>       (list   (partition-list sequence length))
>       (string (partition-vector sequence length)) ; emacs lisp strings are not vectors! 
>       (vector (partition-vector sequence length))))

Is there some reason (performance?) to write partition as above
and not as:

(defun partition (sequence length)
   (cond ((listp sequence)
          (partition-list sequence length))
         ((stringp sequence)
          (partition-vector sequence length)) ; emacs lisp strings are not vectors!
         ((vectorp sequence)
           (partition-vector sequence length))))


regards
Marc


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Partition for Emacs Lisp
  2009-06-28 20:16   ` Marc Tfardy
@ 2009-06-28 20:46     ` TomSW
  0 siblings, 0 replies; 13+ messages in thread
From: TomSW @ 2009-06-28 20:46 UTC (permalink / raw)
  To: help-gnu-emacs

On Jun 28, 10:16 pm, Marc Tfardy <b...@cyk.cyk> wrote:

> Is there some reason (performance?) to write partition as above
> and not as:
>
> (defun partition (sequence length)
>    (cond ((listp sequence)
>           (partition-list sequence length))
>          ((stringp sequence)
>           (partition-vector sequence length)) ; emacs lisp strings are not vectors!
>          ((vectorp sequence)
>            (partition-vector sequence length))))

etypecase has three advantages over cond. It clearly documents the
fact that what you're interested in is the type of the argument, it
saves you repeating the name of the argument in every clause - making
the type more salient, and it raises an error if the argument isn't
one of the types catered for (that's the "e" in etypecase).

regards,
Tom SW


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Partition for Emacs Lisp
  2009-06-28 17:52 ` Pascal J. Bourguignon
  2009-06-28 18:34   ` Marc Tfardy
  2009-06-28 20:16   ` Marc Tfardy
@ 2009-06-28 20:53   ` Johan Bockgård
  2 siblings, 0 replies; 13+ messages in thread
From: Johan Bockgård @ 2009-06-28 20:53 UTC (permalink / raw)
  To: help-gnu-emacs

pjb@informatimago.com (Pascal J. Bourguignon) writes:

>       (string (partition-vector sequence length)) ; emacs lisp strings are not vectors! 
>       (vector (partition-vector sequence length))))

arrayp





^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Partition for Emacs Lisp
  2009-06-28 20:11   ` Marc Tfardy
@ 2009-06-28 21:10     ` TomSW
  2009-07-01 22:32       ` DanL
  0 siblings, 1 reply; 13+ messages in thread
From: TomSW @ 2009-06-28 21:10 UTC (permalink / raw)
  To: help-gnu-emacs

On Jun 28, 10:11 pm, Marc Tfardy <b...@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




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Partition for Emacs Lisp
  2009-06-28 17:53 ` Xah Lee
  2009-06-28 20:11   ` Marc Tfardy
@ 2009-06-29  0:46   ` Vassil Nikolov
  2009-06-29  8:56     ` Andreas Röhler
  1 sibling, 1 reply; 13+ messages in thread
From: Vassil Nikolov @ 2009-06-29  0:46 UTC (permalink / raw)
  To: help-gnu-emacs


> On Jun 28, 6:26 am, Marc Tfardy <b...@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 <vnikolov@pobox.com>

  (1) M(Gauss);
  (2) M(a) if M(b) and declared(b, M(a)),
  where M(x) := "x is a mathematician".


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Partition for Emacs Lisp
  2009-06-29  0:46   ` Vassil Nikolov
@ 2009-06-29  8:56     ` Andreas Röhler
  2009-06-29 19:22       ` Sean Sieger
  0 siblings, 1 reply; 13+ messages in thread
From: Andreas Röhler @ 2009-06-29  8:56 UTC (permalink / raw)
  To: Vassil Nikolov
  Cc: Marc Tfardy, Xah Lee, Bastien, Pascal J. Bourguignon,
	help-gnu-emacs, TomSW

Vassil Nikolov wrote:
>> On Jun 28, 6:26 am, Marc Tfardy <b...@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.
>
>
>   


Hi,

I'm wondering for some time how to preserve all this
interesting snippets of code conveniently.

Thanks all participants BTW.

Digging the mail archive user by user seems not the
best method, so I tried to extract some matter.

Please have a look at

http://repo.or.cz/w/elbb.git?a=blob;f=code/help-gnu-emacs.el

Emacs Lisp Bill Board still isn't in the shape
qualifying for Βeta, principle should be visible
nonetheless.

Comments welcome.

Thanks again

Andreas Röhler





^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Partition for Emacs Lisp
  2009-06-29  8:56     ` Andreas Röhler
@ 2009-06-29 19:22       ` Sean Sieger
  0 siblings, 0 replies; 13+ messages in thread
From: Sean Sieger @ 2009-06-29 19:22 UTC (permalink / raw)
  To: help-gnu-emacs

Andreas Röhler <andreas.roehler@easy-emacs.de> writes:

    Please have a look at

    http://repo.or.cz/w/elbb.git?a=blob;f=code/help-gnu-emacs.el

    Emacs Lisp Bill Board still isn't in the shape
    qualifying for Βeta, principle should be visible
    nonetheless.

Thank you, Andreas; .emacs snippets I'd rather not leave in my .emacs as
commented out, let alone threads constituted by code (and their headers)
... yeah, thank you, now I've got what I didn't know I needed.





^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Partition for Emacs Lisp
  2009-06-28 21:10     ` TomSW
@ 2009-07-01 22:32       ` DanL
  0 siblings, 0 replies; 13+ messages in thread
From: DanL @ 2009-07-01 22:32 UTC (permalink / raw)
  To: help-gnu-emacs

> 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.



^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2009-07-01 22:32 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-06-28 13:26 Partition for Emacs Lisp Marc Tfardy
2009-06-28 17:52 ` Pascal J. Bourguignon
2009-06-28 18:34   ` Marc Tfardy
2009-06-28 20:16   ` Marc Tfardy
2009-06-28 20:46     ` TomSW
2009-06-28 20:53   ` Johan Bockgård
2009-06-28 17:53 ` Xah Lee
2009-06-28 20:11   ` Marc Tfardy
2009-06-28 21:10     ` TomSW
2009-07-01 22:32       ` DanL
2009-06-29  0:46   ` Vassil Nikolov
2009-06-29  8:56     ` Andreas Röhler
2009-06-29 19:22       ` Sean Sieger

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.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.