Quelques commentaires sur R3
guest214-Jan-2008/15:18:07+1:00
Dans R3, les mezzanines vont davantage profiter du travail collaboratif via Devbase.
Pour exemple j'ai soumis il y'a quelques semaines plusieurs propositions
qui ont malheureusement été rejetées mise à part 2,3 évolutions sur la fonction replace.
C'est vrai que c'est assez frustrant de voir ses propositions rejetées mais il faut admettre
que ce qui peut sembler génial pour soi ne l'est probablement pas pour les autres.

La fonction replace a toujours été sous employée (à mon sens) à cause de certaines
petites limitations très énervantes.

Les nouveautés sont:

-- Utilisation des bitset! comme argument de recherche:

digits: charset "123456789"
replace/all "abc1de2de3" digits "_"
== "abc_de_de_"

-- Raffinement /tail pour enchainer des remplacements sans recommencer au début de la série.
(comme le /tail de find)

str: "a b c a b c"
str: replace/tail "b" "1"
str: head replace "a" "2"
== "a 1 c 2 b c"

-- Utilisation de functors (fonctions de remplacement)

repl: func [str][str/1: str/1 + 1]
replace/all [1 2 3 4 5 6 7 8 9] integer! :repl
== [2 3 4 5 6 7 8 9 10]

-- *Refusé* Utilisation de règles de parsings comme paramètre de recherche
replace [a ba 1 ca d ] ['ba | 'ca] 'bc


***
D'une façon générale, de nombreuses mezzanines vont accepter des fonctions en argument.
Ajoutez à cela, un nouveau type de fonction 'closure' qui va permettre d'étendre l'usage de
nombreuses mezzanines (employabilité aurait dit Ségolène).

Je donne un exemple.
On définit la fonction 'cycle qui renvoie l'une après l'autre les valeurs d'une série, puis
qui recommence au début de la série.

cycle: closure [s][also first+ s if tail? s [s: head s]]

son fonctionnement est le suivant:
>> s: cycle [1 2 3]
>> s
== 1
>> s
== 2
>> s
== 3
>> s
== 1
>> s
== 2
>> ...


Utilisée en combinaison avec la fonction replace, ça peut donner ceci
>> replace/all "_ _ _,_ _ _" "_" cycle [1 2 3]
== "1 2 3,1 2 3"

Voilà, a vous d'imaginer tout ce qu'il sera possible de faire mais à n'en pas douter nos scripts
vont devenir encore plus compacts et expressifs.
Goldevil14-Jan-2008/15:37:44+1:00
Cette notion de closure m'intrigue et m'intéresse beaucoup. J'en ai souvent entendu parlé mais je ne me suis jamais plongé dans cette logique.

Une closure, si j'ai bien compris, diffère d'une fonction sur un point essentiel. Les variables locales à la fonction sont en quelque sorte persistantes et "vivent" même après être sorti de la closure. Dans ton exemple il s'agit de s.
Est-ce bien cela ?

Mais la variable s dans la ligne s: cycle [1 2 3] est-elle la même que celle dans la définition de la closure ?

A part cela ton exemple n'a pas l'air de fonctionner avec ma version de R3 alpha. J'obtiens toujours la valeur 1. Peut-être est-ce que tu as testé sur une autre version ou n'est tout simplement pas encore implémenté.

A part cela 'also et 'first+ sont typiquement des nouveautés hyper utiles issue de l'expérience de certaine développeurs. On peut faire sans cela mais on allège grandement le code à les utiliser.
guest214-Jan-2008/15:57:19+1:00
Oui une erreur s'est glissée dans ma définition de la fonction cycle:

cycle: closure [s][does [also first+ s if tail? s [s: head s]]]

en fait on voit l'utilité d'une fonction closure dans l'exemple suivant:

si je définis la fonction cycle sans closure:
cycle: func [s][does [also first+ s if tail? s [s: head s]]]

a: cycle [1 2 3]
>> a
on obtient l'erreur suivante: ** s n'a pas de contexte

La différence, c'est qu'une closure (ça fait bizarre, comment dirait-on en Français ?) va créer une instance locale et persistante de la variable 's pour la fonction 'a.

Pour simuler la fonction closure en R2, il faudrait écrire:
cycle: func [aa][use [a] [a: aa does [also first+ a if tail? a [a: head a]]] ]

L'usage d'une fonction closure est plus éléguant.
DocKimbel14-Jan-2008/16:53:52+1:00
Salut,

Juste pour information :

* "Closure" se dit "Fermeture" en français (voir http://fr.wikipedia.org/wiki/Fermeture_%28informatique%29).

* Les "closures", en soi, n'apportent rien de nouveau à REBOL. En effet, elles ont été introduites dans R3 pour "mettre au propre" le type function! de R2 qui est déjà un "closure" (mais sans le dire clairement). Dans R3, le comportement des fonctions par défaut est de limiter la durée de vie des variables locales à la durée d'exécution de la fonction (gain en vitesse et mémoire, car les variables locales sont alloués sur la pile et détruites en sortie de fonction). Les "closures" ont été ajoutés pour permettre de revenir au fonctionnement de R2, quand on le souhaite. Pour s'en convaincre, je reprends l'exemple cité plus haut, mais en R2 :

also: func [v1 v2][v1]
first+: func ['w][set :w next get :w pick get :w -1]

cycle: func [s][does [also first+ s if tail? s [s: head s]]]

>> a: cycle [1 2 3]
>> a
== 1
>> a
== 2
>> a
== 3
>> a
== 1

En résumé: en R3, par défaut, on a des fonctions plus rapides et moins gourmandes en mémoire, mais, grâce aux "closures" on peut revenir au fonctionnement R2 et bénéficier de la persistances des valeurs.
guest214-Jan-2008/17:11:47+1:00
Bien vu Dock

Pour info, voici la liste des nouvelles fonctions présentes actuellement dans la R3:
(Quand il n'y a pas d'aide sur la fonction, j'imprime le premier paramètre)


percent? action! Returns TRUE if it is this type.
unicode? action! Returns TRUE if it is this type.
vector? action! Returns TRUE if it is this type.
map? action! Returns TRUE if it is this type.
get-path? action! Returns TRUE if it is this type.
typeset? action! Returns TRUE if it is this type.
rebcode? action! Returns TRUE if it is this type.
closure? action! Returns TRUE if it is this type.
frame? action! Returns TRUE if it is this type.
module? action! Returns TRUE if it is this type.
task? action! Returns TRUE if it is this type.
gob? action! Returns TRUE if it is this type.
handle? action! Returns TRUE if it is this type.
utype? action! Returns TRUE if it is this type.
past? action! Returns TRUE if a series index is past its tail.
spec-of action! Returns the value's specifications.
take action! Copies and removes from series. (Modifies)
swap action! Swaps elements of a series. (Modifies)
create action! Send port a create command.
open? action! Returns TRUE if port is open.
ajoin native! Joins a block of values into a new string.
also native! Returns the first value, but also evaluates the second.
apply native! Apply a function to a reduced block of arguments.
continue native! Throws control back to top of loop.
find-script native! Find script header.
deline native! Converts string terminators to standard format, e.g. CRLF to LF. (Modifies)
enline native! Converts standard string terminators to current OS format, e.g. LF to CRLF. (Modifies)
delect native! Parses a common form of dialects. Returns updated input block.
transcode native! Translates code/data from string into value. Returns [value next-source].
wake-up native! Awake and update a port with event.
map-inner native! Computes the inner-most grapical object and coordinate.
map-outer native! Computes the outer-most grapical object and coordinate.
cursor native! Changes the mouse cursor image.
++ native! Post-increment an integer or series index. Return prior value.
-- native! Pre-decrement an integer or series index. Return new value.
first+ native! Return FIRST of series, and increment the series index.
resolve native! Set known values in target from those given by the source.
conjure native! Invokes special debugging modes for reliability testing purposes.
ds native! none
load-jpeg native! data
closure function! Defines a closure function.
task function! Creates a task.
module function! Creates a module.
cause-error function! Causes an immediate error throw with the provided information.
import function! Locate, load, make, and set local bindings for module.
find-module function! Search for system module with matching name and version.
insert-module function! Insert a module into system module list. I version matches, replace.
collect function! Collects block evaluation, at EMIT calls, into a result block.
format function! Format a string according to the format dialect.
printf function! Formatted print.
split function! Split a series into pieces; fixed or variable size, fixed number, or at delimiters
generate-series closure! Make a function that returns the values in a series one at a time.
generate-cycle closure! Make a function that returns the values in a series one at a time, wrapping.
scalar? function! Return TRUE if value is any type of scalar.
ls function! Print contents of a directory (ls).
pwd native! Returns the current directory path.
rm action! Send port a delete command.
mkdir function! Creates the specified directory. No error if already exists.
cd function! Change directory (shell shortcut function).
more function! Print file (shell shortcut function).
in-dir function! Evaluate a block while in a directory.
to-relative-file function! Returns the relative portion of a file if in a subdirectory, or the original if not.
boot-print function! Prints boot info
splash function! local
make-scheme function! Make a scheme from a specification and add it to the system.
handle-events function! Adds a handler to the view event system.
unhandle-events function! Removes a handler from the view event system.
handled-events? function! Returns event handler object matching a given name.
init-view-system function! Initialize the View subsystem.
funco function! Defines a function, but does not copy spec or body.
to-end function! value
to-unset function! value
to-percent function! value
to-unicode function! value
to-vector function! value
to-map function! value
to-get-path function! value
to-typeset function! value
to-native function! value
to-action function! value
to-routine function! value
to-rebcode function! value
to-op function! value
to-closure function! value
to-function function! value
to-frame function! value
to-object function! value
to-module function! value
to-task function! value
to-gob function! value
to-event function! value
to-handle function! value
to-struct function! value
to-utype function! value
queue-show function! gob
show-queued function! none
make-face* function! Create a VID face (low level)
init-face function! Initialize a VID face (low level)
set-if function! word
layout-panel function! Layout a panel face
show-face function! Show a face
override closure! Override a function
mrd-process function! drawing
make-resizable-drawing function! Create a draw block that can be easily resized (returns object!)
rd-apply-map function! drawing
resize-drawing function! Resize a resizable drawing created with MAKE-RESIZABLE-DRAWING
bind-func function! f
multiply-gradient function! gradient
sum-pair function! pair
set-corners function! object
sync-op function! port
read-sync-awake function! event
do-request function! Perform an HTTP request
http-awake function! event
check-response function! port
make-http-request function! Create an HTTP request (returns string!)
parse-write-dialect function! port
check-data function! port
do-redirect function! port
guest214-Jan-2008/17:16:25+1:00
ah ah j'avais pas fait gaffe, la fonction cycle existe bel et bien mais a été renommée generate-cycle dans la version actuelle.

>> source generate-cycle
generate-cycle: make closure! [[
    {Make a function that returns the values in a series one at a time, wrapping.}
    x [series!] "The series to cycle through"
][
    does [also first+ x if tail? x [x: head x]]
]]
Goldevil14-Jan-2008/23:46:28+1:00
OK. Ca devient beaucoup plus clair pour moi avec vos explications à tous les deux.
En fait, j'imagine que l'implémentation d'une closure (du point de vue du compilateur/interpréteur) est plus complexe et/ou plus lourd qu'une fonction car il faut stocker les données ailleurs que sur la pile qui se vide dès la sortie de la fonction.

Je suis impressionné par la liste des nouvelles fonctions. Je constate que ++ et -- a fini par débarquer dans Rebol

Login required to Post.


Powered by RebelBB and REBOL 2.7.8.4.2