public inbox for kawa@sourceware.org
 help / color / mirror / Atom feed
From: Per Bothner <per@bothner.com>
To: Damien MATTEI <Damien.Mattei@unice.fr>,
	Kawa mailing list <kawa@sourceware.org>
Subject: Re: StackOverflowError in a specialized map
Date: Wed, 15 Mar 2017 16:23:00 -0000	[thread overview]
Message-ID: <ed31f1a2-2afa-0248-0150-40c4050e2e0d@bothner.com> (raw)
In-Reply-To: <201703151608.33735.Damien.Mattei@unice.fr>

On 03/15/2017 08:08 AM, Damien MATTEI wrote:
> Hello,
>
> i have a custom definition of map ( https://github.com/damien-mattei/LOGIKI/blob/master/lib/map.scm at  line 392):
>
> ;; map-nil : a map version that exclude nil results
> ;; the same as map-with-lambdas but will exclude from the result list the '() result of function
> ;;
> ;; (map-nil + '(1 2 3) '(4 5 6)) -> '(5 7 9)
> (define map-nil
>   (lambda (function list1 . more-lists)
>     (letrec ((some? (lambda (fct list)
> 		      ;; returns #f if (function x) returns #t for
> 		      ;; some x in the list
> 		      (and (pair? list)
> 			   (or (fct (car list))
> 			       (some? fct (cdr list)))))))
>
>       ;; variadic map implementation terminates
>       ;; when any of the argument lists is empty.
>       (let ((lists (cons list1 more-lists)))
> 	(if (some? null? lists)
> 	    '()
> 	    (let ((funct-result (apply function (map car lists))))
> 	      (if (null? funct-result)
> 		  (apply map-nil function (map cdr lists))
> 		  (cons funct-result
> 			(apply map-nil function (map cdr lists))))))))))
>
> i use it in various project since many years and this times it creates a java StackOverflowError on a big list (22527 elements),

Not unexpected - you're recursing on a big list.

> i'm not sure if it's only in kawa and java that the problem occur so
> i'm near to code this function differently,

Try compiling map-nil with --full-tailcalls.   That might do it.

However, if the stack overflow is in the final apply, that won't be enough,
because that apply is not a tail-call (because of the cons of the result).

You can also try replacing:
    
     (apply map-nil function (map XXX))

by splice-notation:

     (map-nil function @(map XXX))

However, I don't think that would be enough for Kawa to be able to inline the tailcalls.
That would require the splice argument to match up with the more-lists rest argument,
which it doesn't.

If you don't mind using set-cdr! that would be a relatively simple and efficient solution:

   (if (not (null? funct-result))
      (let ((new-cons (cons funct-result '()))
          (if (null? last-pair)
              (set! result new-cons)
              (set-cdr! last-pair new-pair))
          (set! last-pair new-cons))))

Instead of using map, put the above snippet inside a for-each.

(The list1 parameter seems strange, as it isn't used, as far as i can tell.)
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

  reply	other threads:[~2017-03-15 16:23 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-15 15:08 Damien MATTEI
2017-03-15 16:23 ` Per Bothner [this message]
2017-03-16 10:54   ` Damien MATTEI
2017-03-17 11:38     ` Damien MATTEI
2017-03-17 14:07       ` Sudarshan S Chawathe
2017-03-21 14:01         ` Damien MATTEI
2017-03-21 15:47           ` Per Bothner
2017-03-25 22:56           ` Sudarshan S Chawathe
2017-03-26  9:49             ` Damien Mattei
2017-03-26  9:55               ` Damien Mattei
2017-03-26 10:56                 ` Damien Mattei
2017-03-28  8:42             ` Damien MATTEI
2017-03-28 14:21               ` Damien MATTEI
2017-03-17 10:37   ` Damien MATTEI
2017-03-17 16:00     ` Per Bothner

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=ed31f1a2-2afa-0248-0150-40c4050e2e0d@bothner.com \
    --to=per@bothner.com \
    --cc=Damien.Mattei@unice.fr \
    --cc=kawa@sourceware.org \
    /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.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).