Aller au contenu

Messages recommandés

Posté(e)

Bonjour à tous,

 

Voilà j’ai eu un petit souci dans l’écriture d’un de mes codes avec l’emploi de la fonction apply, petit souci que j’ai facilement contourné avec l’emploi de cons + eval.

 

 

Pour résumer,soit une liste d’arguments variables et quelconques (mais toujours valide) du type :

 (setq argmt '("_pline" '(0 0) "LA" 3 "" '(100 0) "D" "" 4 '(0 100) "C"))

 

Que je souhaite soumettre à la fonction command

 

Avec cette syntaxe, cela ne fonctionne pas..

 (apply 'command argmt)

 

Alors qu’avec la suivante tous se déroule comme espéré.

 (eval (cons 'command argmt))

 

 

Bizare, jusqu’ici j’ai toujours pensé que (apply ‘fun liste) étais équivalent à (eval (cons ‘fun liste)), hé bien non. Amusant n’est ce pas… :casstet:

 

Surtout si je me reporte à l’aide qui dit que :

La fonction apply est compatible avec les fonctions internes (sous-programmes) et avec les fonctions définies par l'utilisateur (celles créées avec defun ou lambda).

 

A croire que la fonction command fait exception à la règle.. ;)

 

Cordialement Bruno

 

 

Apprendre => Prendre => Rendre

Posté(e)
A croire que la fonction command fait exception à la règle.. ;)

 

J'allais le dire !

 

Command n'est pas interprété directement. En ce sens il se distingue largement d'un lambda ou d'une fonction lisp.

 

Mais sinon, il y a quand même des nuances entres tes 2 exemples : l'un appliquerait un "command" à une liste, l'autre évalue la concaténation de CONS....

Je lis souvent "en Français" pour formuler les choses.

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

./__\.
(.°=°.)
Posté(e)

Bonsoir Tramber,

 

Command n'est pas interprété directement.

Pourquoi pas ! Une explication qui en vaut une autre, j’entend ce que tu dis mais cela ne me convainc que très moyennement, personnellement je crois plus en un bug..

 

il se distingue largement d'un lambda ou d'une fonction lisp

command est une fonction lisp, l’expression (type command) retourne SUBR

 

 

Sinon personnellement je formulerai plutôt l’un applique la fonction command à tous les éléments de la liste, et l’autre évalue la liste «quoté » (command "_pline" '(0 0) "LA" 3 "" '(100 0) "D" "" 4 '(0 100) "C"))

 

Mais je ne vois pas de réelle différence dans ces 2 formulations car :

 (defun apply2 (F L)
 (eval (cons F L))
) ;_ Fin de defun

_$ (apply '+ '(1 2 3))
6
_$ (apply2 '+ '(1 2 3))
6
_$ (apply 'strcat '("a" "b" "c"))
"abc"
_$ (apply2 'strcat '("a" "b" "c"))
"abc"

 

A+ Bruno

 

Apprendre => Prendre => Rendre

Posté(e)

Salut,

 

Non, je ne pense pas qu'on puisse parler de bug.

 

La fonction LISP command est, de fait un peu particulière dans la mesure où elle n'utilise pas directement les arguments qui lui sont passés mais les évalue et les passe un par un à AutoCAD en réponse aux invites.

The command function evaluates each argument and sends it to AutoCAD in response to successive prompts.

 

Il y a donc un niveau d'évaluation supplémentaire et on peut raisonnablement penser que "l'évaluation" de chaque argument faite par command consiste à convertir la donnée en chaine pour la passer à la ligne de commande.

Utiliser (apply 'command ...) avec une liste quotée contenant des élément d'un type autre que STR ne permet pas cette évaluation mais les formes suivantes fonctionnent.

 

(apply 'command '("_pline" "0,0" "LA" "3" "" "100,0" "D" "" "4" "0,100" "C"))

(apply 'command (list "_pline" '(0 0) "LA" 3 "" '(100 0) "D" "" 4 '(0 100) "C"))

 

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Command, quelque soit la facon dont il est lancé, est en mesure d'appeler des lisp. Par définition. Ce qui n'est le cas d'aucune fonction dont nous disposons pour programmer. A moins que je ne me trompe

(exception à faire éventuellement pour les fonctions du type C:RENDER [nostalgie, il ]).

 

Je ne suis pas du tout théoricien. C'est le moins que l'on puisse dire. Je comprends beaucoup mieux la RdM ou la chanson française (!). Mais je sais que command est un tour de passe, pas une fonction autolisp ou Vlisp.

 

command est une fonction lisp, l’expression (type command) retourne SUBR

 

Je ne peux le nier dans cette acception. Mais c:mafonction ou *error* et myFun aussi à ce compte là !

 

 

 

[Edité le 12/4/2011 par Tramber]

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

./__\.
(.°=°.)
Posté(e)
Command, quelque soit la facon dont il est lancé, est en mesure d'appeler des lisp. Par définition. Ce qui n'est le cas d'aucune fonction dont nous disposons pour programmer. A moins que je ne me trompe

(exception à faire éventuellement pour les fonctions du type C:RENDER [nostalgie, il ]).

 

Je ne suis pas du tout théoricien. C'est le moins que l'on puisse dire. Je comprends beaucoup mieux la RdM ou la chanson française (!). Mais je sais que command est un tour de passe, pas une fonction autolisp ou Vlisp.

 

command est une fonction lisp, l’expression (type command) retourne SUBR

 

Je ne peux le nier dans cette acception. Mais c:mafonction ou *error* et myFun aussi à ce compte là !

 

[Edité le 12/4/2011 par Tramber]

 

Je ne comprends pas ce que tu veux dire Tramber.

 

Toute fonction LISP peut en appeler d'autres, un (defun ...) contient généralement plusieurs appels de fonction (qui peuvent eux aussi contenir, etc.).

 

Bien sur que c:mafonction ou *error* et myFun sont des fonctions LISP au même titre que les fonctions natives.

Le propre des langages fonctionnels (LISP, OCaml, F#, ...) est de définir de nouvelles fonctions qui sont, tout comme les fonctions natives, des "valeurs de première classe" c-a-d utilisables comme les autres types de valeurs : on peut les (ré)affecter à un symbole avec setq, les "annihiler" (setq defun nil), les passer comme arguments à des fonctions dites "d'ordre supérieur"...

 

Pour finir, il y a effectivement une différence entre (apply 'fun lst) et (eval (cons 'fun lst)) qui relève de la nature de l'argument lst sans être directement liée à la fonction (command ou autre).

Si la liste passée comme argument à apply est une liste quotée, elle n'est pas évaluée, par contre (eval (cons 'fun lst)) évaluera toujours la liste construite avec 'fun et lst.

 

(apply '+ '(1 (+ 1 1) 3)) retourne une erreur : type d'argument incorrect: numberp: (+ 1 1)

(apply '+ (list 1 (+ 1 1) 3)) retourne 6

(eval (cons '+ '(1 (+ 1 1) 3))) retourne 6

 

 

 

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)
Je ne comprends pas ce que tu veux dire Tramber.

 

Euh,....! ? oui, là, plus rien d'intéressant :cool:

 

J'entends juste que command n'est pas une fonction comme les autres natives. C'est surtout là mon propos. J'arrive à piger que (apply 'command argmt) ne fonctionne pas et ca s'arrête là !

 

Hoppla

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

./__\.
(.°=°.)
Posté(e)

J'entends juste que command n'est pas une fonction comme les autres natives. C'est surtout là mon propos. J'arrive à piger que (apply 'command argmt) ne fonctionne pas et ca s'arrête là !

 

Si, command est une fonction comme les autres.

La subtilité est à regarder du côté de apply en fonction de argmt : apply n'évalue pas la liste qui lui est passée en argument.

Cette liste, si c'est une liste quotée ne peut donc pas contenir d'appel de fonction ou de sous-liste quotées (ces dernières étant aussi des appel de la fonction quote). mais ne doit contenir que des valeurs du ou des types requis par la fonction.

 

(setq arg1 '("_pline" '(0 0) "LA" 3 "" '(100 0) "D" "" 4 '(0 100) "C")) => ("_pline" (QUOTE (0 0)) "LA" 3 "" (QUOTE (100 0)) "D" "" 4 (QUOTE (0 100)) "C")

(setq arg2 (list "_pline" '(0 0) "LA" 3 "" '(100 0) "D" "" 4 '(0 100) "C")) => ("_pline" (0 0) "LA" 3 "" (100 0) "D" "" 4 (0 100) "C")

(setq arg1 '("_pline" "0,0" "LA" 3 "" "100,0" "D" "" 4 "0,100" "C")) => ("_pline" "0,0" "LA" 3 "" "100,0" "D" "" 4 "0,100" "C")

 

(apply 'command arg1) => erreur

(apply 'command arg2) => fonctionne

(apply 'command arg3) => fonctionne

 

Et c'est exactement le même principe avec d'autres fonctions:

 

(setq sep (chr 32)) => " "

(setq arg1 '("Ceci" (chr 32) "est" (chr 32) "un" (chr 32) "test")) => ("Ceci" (CHR 32) "est" (CHR 32 "un" (CHR 32) "test")

(setq arg2 (list "Ceci" (chr 32) "est" (chr 32) "un" (chr 32) "test")) => ("Ceci" " " "est" " " "un" " " "test")

(setq arg3 '("Ceci" sep "est" sep "un" sep "test")) => ("Ceci" SEP "est" SEP "un" SEP "test")

(setq arg4 '("Ceci" " " "est" " " "un" " " "test")) => ("Ceci" " " "est" " " "un" " " "test")

 

(apply 'strcat arg1) => ; erreur: type d'argument incorrect: stringp (CHR 32)

(apply 'strcat arg2) => "Ceci est un test"

(apply 'strcat arg3) => ; erreur: type d'argument incorrect: stringp SEP

(apply 'strcat arg4) => "Ceci est un test"

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Bonsoir,

 

je ne pense pas qu'on puisse parler de bug

Effectivement je pense avoir conclu un peu hâtivement hier soir. J'avais également un peu avancé sur la question depuis avant de vous lire.

 

Merci (gile) pour cette brillante démonstration et explications, l’emploi du quote explique bien des choses, je m’en veux un peu de ne pas avoir percuté plus vite.. surtout que tu l’avais déjà fait ici à mon intention ..

Pour que s-nth retourne la position du symbole auquel la valeur 11.0 est affectée, il faut permettre l'évaluation des symbole, donc ne pas utiliser de liste quotée mais construire la liste avec la fonction list : (list a b c d e) retourne (10.0 11.0 12.0 14.0)

 

A+ Bruno

(Ps: Désolé de t'avoir fait radoter..)

 

 

 

[Edité le 12/4/2011 par VDH-Bruno]

Apprendre => Prendre => Rendre

Posté(e)

Command, quelque soit la facon dont il est lancé, est en mesure d'appeler des lisp. Par définition. Ce qui n'est le cas d'aucune fonction dont nous disposons pour programmer. A moins que je ne me trompe

 

J’espère également ne pas me tromper en disant que Tramber fait peut être une confusion entre la programmation fonctionnel et la notion de « réentrance » qui il me semble est limité en Lisp..

 

Mais bon je dis cela de mémoire car je n’ai jamais eu l’occasion de me confronté cette notion, j’ai lu à ce sujet (c’était à mes débuts en me documentant mais je ne sais plus ou) une explication de serge camiré ou de kamal boutura il me semble.. Explication que je n’étais pas encore à l’époque en mesure d’assimiler, dommage que je ne puisse la retrouver, je suis sur que cela me parlerai plus maintenant..

 

Je dis cela mais je dois avouer que c’est très flou pour moi..

A+

 

Apprendre => Prendre => Rendre

Posté(e)

Si command attend des arguments d'une manière différente, je l'entend comme "différente des autres". Même si ces concepts sont éclairants, ils me dépassent.

Quand il faut envoyer du command construit, j'utilise EVAL depuis toujours....

Mais c'est bien de se poser de telles questions.....

 

Le mot "réentrance" est très joli, je ne serais pas surpris d'apprendre qu'il soit relayé par un canadien francophone comme Serge.

 

Donc quand tu dis :

 

J’espère également ne pas me tromper en disant que Tramber fait peut être une confusion entre la programmation fonctionnel et la notion de « réentrance » qui il me semble est limité en Lisp...

 

Tu risques guère de te tromper ! Comment con-fondre ce qui dans mon esprit n'est pas encore séparé et que je ne connais pas !? :)

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

./__\.
(.°=°.)
Posté(e)

Bonsoir Tramber

 

Bon là je vais essayer de le faire de mémoire (lecture vieille de 6 mois) car je n’ai pas réussi à retrouver le sujet que j’avais en tête même après 2 heures de recherche..

 

Le mot "réentrance" est très joli,

 

Par le terme réentrant, il fallait entendre qu’il n’est pas possible en Lisp (il me semble) d’invoquer une commande écrite en Lisp à partir d’une autre commande écrite en Lisp (attention je parle de commande et plus de fonction Lisp).

 

L’explication en question portait notamment sur l’invocation de façon transparente d’une commande Lisp à partir d’une autre commande écrite en Lisp (d’où le terme de réentrance en Lisp). Alors que d’autres langages sous AutoCAD le permettraient notamment le C dans une limite de 4 niveaux, sur ce dernier point je fait peut être erreur, je ne suis sur de rien..

 

Si il fallait approfondir le sujet j’espère que d’autres intervenants viendraient à mon secours car à mon niveau je ne peux actuellement aller plus loin dans l’explication.

 

A+

 

 

Apprendre => Prendre => Rendre

Posté(e)

Nous sommes d'accord (pour le C, je ne sais pas).

 

Ce qui est joli dans le terme c'est que nous avons un mix entre le "ré" et le "entrance" qui est anglais....à moins que.

Voilà, c'est tout, je trouvais ça joli !

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

./__\.
(.°=°.)

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité