guile-user
[Top][All Lists]
Advanced

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

Re: cond(itionals) with optional execution of statements


From: Damien Mattei
Subject: Re: cond(itionals) with optional execution of statements
Date: Mon, 13 Sep 2021 12:04:53 +0200

hello Zelphir,
i will answer in mail, note that some answers are perhaps already in my
previous mail in the mailing list

On Sun, Sep 12, 2021 at 8:36 PM Zelphir Kaltstahl <
zelphirkaltstahl@posteo.de> wrote:

> Hi Damien!
>
> I see! Indeed, some indentation happening there. I get the point now,
> thank you. Could be well worth it, but it depends on how much you get out
> of it, compared to how much additional mental load you get for introducing
> a new control flow concept.
>
yes i agree. i have not developped a lot with this control flow condx , we
can do the same in a python style with a few 'if' and 'return' and 'when'
and that give already enought lisibility, but as cond exist in Scheme
historically but well used todays i wanted to improve it a bit.
'condx' overpass the cond limitation, cond limitation are the causes that
force me to introduce 'return' in 'def'inition of function 'de base' i
think we must include 'return' in every function definition and my keyword
'def' (see previous mail) is derived from python ,it is shorter ans save a
few char in indentation too...

> Sometimes it is worth taking a step back and refactoring part of the logic
> out into a separate procedure, which then starts at a lower level of
> indentation again, avoiding the problem. I don't know your scenario though,
> so this is only a general idea.
>
> I would probably write the `cond` version a bit different, to avoid
> `begin` and break a few lines at other places to avoid the indentation
> taking a lot of horizontal space. I am not sure it makes sense in your
> context, but here it is:
>
> ~~~~
> (define (ssigma-proto L t)
>
>   (set! cpt {cpt + 1})
>
>   (define ls (length L))
>   (define dyn (array-ref dyna ls t))
>
>   ;; dyna[ls][t] means 0: unknown solution, 1: solution found, 2: no solution
>
>   (cond
>    [(not (zero? dyn)) (one? dyn)]
>    [(null? L) (array-set! dyna 2 ls t) #f] ;; return #f
>    [else
>     (let [(c (first L))]
>       (cond
>        [{c = t} ;; c is the solution
>         (array-set! dyna 1 ls t)
>         #t] ;; return #t
>        [else
>         (let [(R (rest L))]
>           (cond
>            [{c > t}   ;; continue searching a solution in the rest
>             (let [(s (ssigma-proto R t))]
>               (array-set! dyna (one-two s) ls t)
>               s)] ;; return s
>            [else
>             ;; c < t at this point
>             ;; c is part of the solution or his approximation
>             ;; or c is not part of solution
>             (let [(s {(ssigma-proto R {t - c}) or (ssigma-proto R t)})]
>               (array-set! dyna (one-two s) ls t)
>               s)]))]))]))
> ~~~~
>
> (Removed some empty lines for brevity in this e-mail. Sometimes I like
> good empty lines too! Could the `set!` be replaced using a `define`?)
>

if you look at my previous mail the code i inserted at end ,it goes in the
same sense

> I guess the expressions in braces are using infix operations like the `or`
> or `=` in the condition of `{c = t}`.
>
yes it is not developped by me but it is in SRFI 105 named 'curly infix':
https://srfi.schemers.org/srfi-105/srfi-105.html
a great SRFI ! i think, that scheme needs a bit of infix for some
mathematical expression or testing ,it allow to write
expression as in natural language {x > 3} is easiest to understand than (>
x 3),all is explained in the part RATIONALE of the SRFI
if you want to use it with guile,as far as i remember you just have to add
this in your .guile file:
(read-enable 'curly-infix)
to have it activated everywhere in code, it is fully compatible with other
features of Scheme

SRFI 105 also allow to use notation like {dyna[ls t]} for array and
notation for functions such as {sin(x)}

i'm developping an extension to  scheme that will allow more things (see
example in previous mail), i just have to package it in a module and write
some documentation about it, i hope to release it first for Guile  in this
month and for other scheme implementation later...

Damien


Best regards,
> Zelphir
> On 9/12/21 7:05 PM, Damien Mattei wrote:
>
> Hello Zelphir,
>
> condx evaluate all code(s) in the 'exec' block until a conditional is
> true, it then evaluate the consequent code of course.
> So ,yes your true it saves a lot of nesting parenthesis as in this example:
>
> here a code with condx and without it:
>
>
> (define (ssigma-proto-condx L t)
>
>   (set! cpt {cpt + 1})
>
>   (define ls (length L))
>   (define dyn (array-ref dyna ls t))
>
>   ;; dyna[ls][t] means 0: unknown solution, 1: solution found, 2: no solution
>
>   (condx [(not (zero? dyn)) (one? dyn)]
>        [(null? L) (array-set! dyna 2 ls t) #f] ;; return #f
>       
>        [exec (define c (first L))]
>       
>        ;; c is the solution
>        [{c = t} (array-set! dyna 1 ls t) #t]  ;; return #t
>       
>        [exec (define R (rest L))]
>       
>        ;; continue searching a solution in the rest
>        [{c > t} (define s (ssigma-proto R t))
>         (array-set! dyna
>                     (one-two s)
>                     ls t)
>         s] ;; return s
>                       
>        ;; else :
>        ;; c < t at this point
>        ;; c is part of the solution or his approximation
>        ;; or c is not part of solution
>        [else (define s {(ssigma-proto R {t - c}) or (ssigma-proto R t)})
>              (array-set! dyna (one-two s)
>                          ls t)
>              s]))
>
>
> without condx:
>
>
>
> (define (ssigma-proto L t)
>
>   (set! cpt {cpt + 1})
>
>   (define ls (length L))
>   (define dyn (array-ref dyna ls t))
>
>   ;; dyna[ls][t] means 0: unknown solution, 1: solution found, 2: no solution
>
>   (cond [(not (zero? dyn)) (one? dyn)]
>       [(null? L) (array-set! dyna 2 ls t) #f] ;; return #f
>       
>       [else (let [(c (first L))]
>               
>               (if {c = t} ;; c is the solution
>               
>                   (begin
>                     (array-set! dyna 1 ls t)
>                     #t)  ;; return #t
>
>                   ;; else
>                   (let [(R (rest L))]
>               
>                     (if {c > t}   ;; continue searching a solution in the rest
>                       
>                         (let [(s (ssigma-proto R t))]
>                           (array-set! dyna
>                                       (one-two s)
>                                       ls t)
>                       
>                           s) ;; return s
>                       
>                         ;; else
>                         ;; c < t at this point
>                         ;; c is part of the solution or his approximation
>                         ;; or c is not part of solution
>                         (let [(s {(ssigma-proto R {t - c}) or (ssigma-proto R 
> t)})]
>                           (array-set! dyna (one-two s)
>                                       ls t)
>                           s)))))
>             ] ))
>
>
> there a lot more of indentation and nesting.
>
> Note also that the use of let () in condx definition allow to use define
> in consequent and 'exec' block.
>
> Damien
>
>
> On Sun, Sep 12, 2021 at 11:41 AM Zelphir Kaltstahl <
> zelphirkaltstahl@posteo.de> wrote:
>
>> Hello Damien!
>>
>> I am not sure I understand the reasoning behind condx: I think cond is
>> already a
>> macro, which only evaluates a consequent, if the predicate of its case is
>> #t.
>> Additionally multiple expressions are possible in each branch.
>>
>> To clarify, I ask: What is the case, where condx does or does not
>> evaluate some
>> code, when cond would not or would? Or is it rather about the different
>> nesting
>> / sequence of expressions, which condx seems to enable? I think the flow
>> you
>> demonstrate might save a bit of nesting.
>>
>> Best regards,
>> Zelphir
>>
>> On 9/11/21 11:14 AM, Damien Mattei wrote:
>> > hello,
>> >
>> > i wrote a little macro (file condx.scm)  that allow :  cond(itionals)
>> with
>> > optional execution of statements before:
>> >
>> > (define-syntax condx
>> >   (syntax-rules (exec)
>> >     ((_)
>> >      (error 'condx "No else clause"))
>> >     ((_ (else e ...))
>> >      (let () e ...))
>> >     ((_ (exec s ...) d1 ...)
>> >      (let () s ... (condx d1 ...)))
>> >     ((_ (t e ...) tail ...)
>> >      (if t
>> >          (let () e ...)
>> >          (condx tail ...)))))
>> >
>> > use it like that:
>> >
>> > mattei@macbook-pro-touch-bar library-FunctProg % guile
>> > GNU Guile 3.0.7
>> > Copyright (C) 1995-2021 Free Software Foundation, Inc.
>> >
>> > Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
>> > This program is free software, and you are welcome to redistribute it
>> > under certain conditions; type `,show c' for details.
>> >
>> > Enter `,help' for help.
>> > scheme@(guile-user)> (load "condx.scm")
>> > ;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0
>> > ;;;       or pass the --no-auto-compile argument to disable.
>> > ;;; compiling /Users/mattei/Dropbox/git/library-FunctProg/condx.scm
>> > ;;; compiled
>> >
>> /Users/mattei/.cache/guile/ccache/3.0-LE-8-4.5/Users/mattei/Dropbox/git/library-FunctProg/condx.scm.go
>> > scheme@(guile-user)> (define x 1)
>> >
>> > (condx ((= x 7) 'never)
>> >         (exec
>> >           (define y 3)
>> >           (set! x 7))
>> >         ((= y 1) 'definitely_not)
>> >         (exec
>> >           (set! y 10)
>> >           (define z 2))
>> >         ((= x 7) (+ x y z))
>> >         (else 'you_should_not_be_here))
>> > $1 = 19
>> >
>> > i share it to have idea about critics or idea to improve it as it will
>> be
>> > part of  a Scheme extension to scheme language that will include other
>> > features....
>> >
>> > have a good day
>> >
>> > Damien
>>
>> --
>> repositories: https://notabug.org/ZelphirKaltstahl
>>
>> --
> repositories: https://notabug.org/ZelphirKaltstahl
>
>


reply via email to

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