This is the mail archive of the kawa@sourceware.org mailing list for the Kawa project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: StackOverflowError in a specialized map


i wrote something wrong, there is a way to do it in scheme without
_reverse_ and _apply_ ,here it is:

;; map-nil-iter-optim-tail-calls-fast : 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-iter-optim-tail-calls-fast + '() '((1 2 3) (4 5 6)))  -> '(9 7 5)
;; (map-nil-iter-optim-tail-calls-fast (lambda (a b) (if (= a 2) '()
(+ a b))) '() '((1 2 3) (4 5 6))) -> '(9 5)
(define map-nil-iter-optim-tail-calls-fast

  (lambda (function lists)

    (letrec ((some?
          (lambda (fct list)
        ;; returns #t 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.

      (if (some? null? lists)

      '()

      (let ((funct-result (apply function (map car lists))))

        (if (null? funct-result)

        (map-nil-iter-optim-tail-calls-fast function (map cdr lists))

        (cons
         funct-result
         (map-nil-iter-optim-tail-calls-fast
          function
          (map cdr lists)))))))))


;; (map-nil-iter-optim-tail-calls-fast-call +  '(1 2 3) '(4 5 6))  -> '(5 7 9)
;; (map-nil-iter-optim-tail-calls-fast-call (lambda (a b) (if (= a 2)
'() (+ a b))) '(1 2 3) '(4 5 6))  -> '(5 9)
(define map-nil-iter-optim-tail-calls-fast-call
  (lambda (function list1 . more-lists)
    (apply map-nil-iter-optim-tail-calls-fast
       function
       (list
        (cons list1 more-lists)))))

but unfortunately i have no more tailcalls optimisation with Kawa,even
with the option (unless the option does not works at REPL but only in
compiled code,will test it monday...) :

albedo-2:Jkawa mattei$ kawa --full-tailcalls
#|kawa:1|# (require 'regex)
#|kawa:2|# (include-relative  "../git/LOGIKI/lib/first-and-rest.scm")
#|kawa:3|# (include-relative  "../git/LOGIKI/lib/syntactic-sugar.scm")
#|kawa:4|# (include-relative  "../git/LOGIKI/lib/display.scm")
#|kawa:5|# (include-relative  "../git/LOGIKI/lib/case.scm") ;; for
CASE with STRINGS
#|kawa:6|# (include-relative  "../git/LOGIKI/lib/list.scm") ;; for
remove-last used by map.scm
#|kawa:7|# (include-relative  "../git/LOGIKI/lib/map.scm") ;; for map-nil*
#|kawa:8|# (define wds-url
"http://ad.usno.navy.mil/wds/Webtextfiles/wdsnewref.txt";)
#|kawa:9|# (define wds-data-str &<{&[wds-url]}) ;; could take a few
seconds to GET file
#|kawa:10|# (define wds-data-str-split (regex-split (string
#\linefeed) wds-data-str))
#|kawa:11|# (length wds-data-str-split)
22569
#|kawa:12|# (define test (map-nil-iter-optim-tail-calls-fast-call
(lambda (x) x) wds-data-str-split))
Exception in thread "main" java.lang.StackOverflowError
    at gnu.lists.SeqPosition.<init>(SeqPosition.java:45)
    at gnu.lists.ExtPosition.<init>(ExtPosition.java:12)
    at gnu.lists.LListPosition.<init>(LListPosition.java:44)
    at gnu.lists.LList.getIterator(LList.java:100)
    at gnu.lists.AbstractSequence.getIterator(AbstractSequence.java:195)
    at gnu.lists.AbstractSequence.iterator(AbstractSequence.java:210)
    at gnu.lists.Sequences.getIterator(Sequences.java:94)
    at atInteractiveLevel-7.lambda14$X(stdin:10569)
    at atInteractiveLevel-7.apply(stdin:10550)
    at gnu.mapping.CallContext.runUntilDone(CallContext.java:227)
    at gnu.mapping.CallContext.runUntilValue(CallContext.java:303)
    at gnu.expr.ModuleMethodWithContext.applyN(ModuleMethodWithContext.java:63)
    at gnu.kawa.functions.ApplyToArgs.applyN(ApplyToArgs.java:141)
    at gnu.mapping.ProcedureN.apply3(ProcedureN.java:48)
    at atInteractiveLevel-7.lambda14$X(stdin:10579)
    at atInteractiveLevel-7.apply(stdin:10550)
    at gnu.mapping.CallContext.runUntilDone(CallContext.java:227)
    at gnu.mapping.CallContext.runUntilValue(CallContext.java:303)
    at gnu.expr.ModuleMethodWithContext.applyN(ModuleMethodWithContext.java:63)
    at gnu.kawa.functions.ApplyToArgs.applyN(ApplyToArgs.java:141)
    at gnu.mapping.ProcedureN.apply3(ProcedureN.java:48)
    at atInteractiveLevel-7.lambda14$X(stdin:10579)
    at atInteractiveLevel-7.apply(stdin:10550)
    at gnu.mapping.CallContext.runUntilDone(CallContext.java:227)
    at gnu.mapping.CallContext.runUntilValue(CallContext.java:303)
    at gnu.expr.ModuleMethodWithContext.applyN(ModuleMethodWithContext.java:63)
    at gnu.kawa.functions.ApplyToArgs.applyN(ApplyToArgs.java:141)
    at gnu.mapping.ProcedureN.apply3(ProcedureN.java:48)
    at atInteractiveLevel-7.lambda14$X(stdin:10579)
    at atInteractiveLevel-7.apply(stdin:10550)
    at gnu.mapping.CallContext.runUntilDone(CallContext.java:227)
    at gnu.mapping.CallContext.runUntilValue(CallContext.java:303)
    at gnu.expr.ModuleMethodWithContext.applyN(ModuleMethodWithContext.java:63)
    at gnu.kawa.functions.ApplyToArgs.applyN(ApplyToArgs.java:141)
    at gnu.mapping.ProcedureN.apply3(ProcedureN.java:48)
    at atInteractiveLevel-7.lambda14$X(stdin:10579)
    at atInteractiveLevel-7.apply(stdin:10550)
    at gnu.mapping.CallContext.runUntilDone(CallContext.java:227)
    at gnu.mapping.CallContext.runUntilValue(CallContext.java:303)
    at gnu.expr.ModuleMethodWithContext.applyN(ModuleMethodWithContext.java:63)
    at gnu.kawa.functions.ApplyToArgs.applyN(ApplyToArgs.java:141)
    at gnu.mapping.ProcedureN.apply3(ProcedureN.java:48)
    at atInteractiveLevel-7.lambda14$X(stdin:10579)
    at atInteractiveLevel-7.apply(stdin:10550)
    at gnu.mapping.CallContext.runUntilDone(CallContext.java:227)
    at gnu.mapping.CallContext.runUntilValue(CallContext.java:303)
    at gnu.expr.ModuleMethodWithContext.applyN(ModuleMethodWithContext.java:63)
    at gnu.kawa.functions.ApplyToArgs.applyN(ApplyToArgs.java:141)
    at gnu.mapping.ProcedureN.apply3(ProcedureN.java:48)
    at atInteractiveLevel-7.lambda14$X(stdin:10579)
    at atInteractiveLevel-7.apply(stdin:10550)
    at gnu.mapping.CallContext.runUntilDone(CallContext.java:227)
    at gnu.mapping.CallContext.runUntilValue(CallContext.java:303)
    at gnu.expr.ModuleMethodWithContext.applyN(ModuleMethodWithContext.java:63)
    at gnu.kawa.functions.ApplyToArgs.applyN(ApplyToArgs.java:141)
    at gnu.mapping.ProcedureN.apply3(ProcedureN.java:48)
    at atInteractiveLevel-7.lambda14$X(stdin:10579)
    at atInteractiveLevel-7.apply(stdin:10550)
    at gnu.mapping.CallContext.runUntilDone(CallContext.java:227)
    at gnu.mapping.CallContext.runUntilValue(CallContext.java:303)
    at gnu.expr.ModuleMethodWithContext.applyN(ModuleMethodWithContext.java:63)
    at gnu.kawa.functions.ApplyToArgs.applyN(ApplyToArgs.java:141)
    at gnu.mapping.ProcedureN.apply3(ProcedureN.java:48)
    at atInteractiveLevel-7.lambda14$X(stdin:10579)
    at atInteractiveLevel-7.apply(stdin:10550)
    at gnu.mapping.CallContext.runUntilDone(CallContext.java:227)
    at gnu.mapping.CallContext.runUntilValue(CallContext.java:303)
    at gnu.expr.ModuleMethodWithContext.applyN(ModuleMethodWithContext.java:63)
    at gnu.kawa.functions.ApplyToArgs.applyN(ApplyToArgs.java:141)
    at gnu.mapping.ProcedureN.apply3(ProcedureN.java:48)
    at atInteractiveLevel-7.lambda14$X(stdin:10579)
    at atInteractiveLevel-7.apply(stdin:10550)
    at gnu.mapping.CallContext.runUntilDone(CallContext.java:227)
    at gnu.mapping.CallContext.runUntilValue(CallContext.java:303)
    at gnu.expr.ModuleMethodWithContext.applyN(ModuleMethodWithContext.java:63)
    at gnu.kawa.functions.ApplyToArgs.applyN(ApplyToArgs.java:141)
    at gnu.mapping.ProcedureN.apply3(ProcedureN.java:48)
    at atInteractiveLevel-7.lambda14$X(stdin:10579)
    at atInteractiveLevel-7.apply(stdin:10550)
    at gnu.mapping.CallContext.runUntilDone(CallContext.java:227)
    at gnu.mapping.CallContext.runUntilValue(CallContext.java:303)
    at gnu.expr.ModuleMethodWithContext.applyN(ModuleMethodWithContext.java:63)
    at gnu.kawa.functions.ApplyToArgs.applyN(ApplyToArgs.java:141)
    at gnu.mapping.ProcedureN.apply3(ProcedureN.java:48)
    at atInteractiveLevel-7.lambda14$X(stdin:10579)
    at atInteractiveLevel-7.apply(stdin:10550)

On Sun, Mar 26, 2017 at 11:54 AM, Damien Mattei <damien.mattei@gmail.com> wrote:
> part of the answer that did not reached the mailing list was here:
>
> https://groups.google.com/forum/#!msg/comp.lang.scheme/40wwKHG43Uw/wq71EH4nCQAJ
>
>
> Damien
>
> On Sun, Mar 26, 2017 at 11:49 AM, Damien Mattei <damien.mattei@gmail.com> wrote:
>> Hi Chaw,
>>
>> thank for your message,
>> i have posted an answer friday unfortunately it does not correctly the
>> mailins list due to copy-carbon i think, i have not the text of my
>> answer here but i  will be able to repost it on monday.
>>
>> basically it works now in kawa without use of --tail-calls option,
>> the only penality is that i need in my solution ,as of yours to use a
>> _reverse_ call ,
>> but there is nothing else to do unfortunately ,except use some
>> iteration and set-cdr! because in LisP and Scheme lists are "linked"
>> in only one way from begin to tail (end)  ,and you cannot explore the
>> list in reverse starting from tail (end) to begin , because CAR is
>> pointing to element and CDR to rest of the list,when you have a PAIR
>> you can find the CDR but with the CDR you cannot get the previous
>> PAIR, so in LisP and Scheme you cannot find such a recursive function
>> to do this without at least at the end reversing the list.
>>
>> here is my last version:
>>
>> ;; map-nil-iter-optim-tail-calls : 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-iter-optim-tail-calls + '() '((1 2 3) (4 5 6)))  -> '(9 7 5)
>> ;; (map-nil-iter-optim-tail-calls (lambda (a b) (if (= a 2) '() (+ a
>> b))) '() '((1 2 3) (4 5 6))) -> '(9 5)
>> (define map-nil-iter-optim-tail-calls
>>
>>   (lambda (function result lists)
>>
>>     (letrec ((some?
>>           (lambda (fct list)
>>         ;; returns #t 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.
>>
>>       (if (some? null? lists)
>>
>>       result
>>
>>       (let* ((funct-result (apply function (map car lists))))
>>
>>         (if (null? funct-result)
>>
>>         (map-nil-iter-optim-tail-calls function result (map cdr lists))
>>
>>         (map-nil-iter-optim-tail-calls
>>          function
>>          (cons funct-result result) ;; cons now create a reversed result list
>>          (map cdr lists))))))))
>>
>>
>> ;; (map-nil-iter-optim-tail-calls-call +  '(1 2 3) '(4 5 6))  -> '(5 7 9)
>> ;; (map-nil-iter-optim-tail-calls-call (lambda (a b) (if (= a 2) '()
>> (+ a b))) '(1 2 3) '(4 5 6))  -> '(5 9)
>> (define map-nil-iter-optim-tail-calls-call
>>   (lambda (function list1 . more-lists)
>>     (reverse ;; cons had created a reversed result list
>>      (apply map-nil-iter-optim-tail-calls
>>         function
>>         '()
>>         (list
>>          (cons list1 more-lists))))))
>>
>>
>> regards,
>>
>> Damien
>>
>> On Sat, Mar 25, 2017 at 11:56 PM, Sudarshan S Chawathe <chaw@eip10.org> wrote:
>>>> From: Damien MATTEI <Damien.Mattei@unice.fr>
>>>> Date: Tue, 21 Mar 2017 15:00:57 +0100
>>>>
>>>> yes, thank you, but i try to stay in a functional programming style
>>>> and avo= id "loop" that make code unreadable and hard to debug,
>>>
>>> I suspect I may be misunderstanding your quest, but I don't see a
>>> significant difference between a 'named let' and a nested function
>>> definition (with respect to being functional programming).  Perhaps I
>>> should have used a name 'recur' instead of 'loop' in my earlier version.
>>>
>>> For example, if we wish to avoid named let altogether for some reason,
>>> we could use the following variant of my earlier implementation.
>>>
>>> (define (map/remove-nulls-1 proc . lsts)
>>>   (define (f lsts result)
>>>     (if (any null? lsts)
>>>         (reverse result)
>>>         (f (map cdr lsts)
>>>            (let ((proc-result (apply proc
>>>                                      (map car lsts))))
>>>              (if (null? proc-result)
>>>                  result
>>>                  (cons proc-result
>>>                        result))))))
>>>   (f lsts '()))
>>>
>>> Or, going another way, we could use fold:
>>>
>>> (define (map/remove-nulls-2 proc . lsts)
>>>   (reverse (apply fold
>>>                   (lambda fargs
>>>                     (let ((accum (last fargs))
>>>                           (pargs (drop-right fargs 1)))
>>>                       (let ((r (apply proc pargs)))
>>>                         (if (null? r)
>>>                             accum
>>>                             (cons r accum)))))
>>>                   '()
>>>                   lsts)))
>>>
>>> As before, I'm using some SRFI 1 procedures for convenience; they can be
>>> avoided easily: any, fold, last, drop-right.
>>>
>>> Both the above versions, like the one I posted earlier, work without
>>> problems in Kawa without needing the --full-tailcalls option (i.e., Kawa
>>> properly detects and eliminates and simple cases of tail calls they
>>> use).  The slight awkwardness of last/drop-right is due to the
>>>
>>> But, as I noted before, perhaps I'm missing the main point of the
>>> original question.
>>>
>>> Regards,
>>>
>>> -chaw
>>>
>>>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]