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